ComboBoxLib — Dropdown List Control Library
Complete functionality for creating and managing dropdown list (combo box) controls in Plan9Basic. A combo box shows one selected item with an expandable dropdown list of choices. Features include item management, index-based selection, search by text, dropdown size control, alignment and margins, focus control, drag support, and a comprehensive event system. 101 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | combobox_error, errormsg$, strerror$, clearerror |
| Creation & Destruction | 3 | combobox# (2 overloads), combobox_free |
| Items Management | 8 | add, insert, delete, clear, count, item (get/set), indexof |
| Selection | 4 | itemindex (get/set), selected$, dropdowncount (get/set) |
| Position & Size | 14 | x, y, width, height (get/set), bounds#, move#, size# |
| Alignment & Margins | 12 | align (get/set), margin#, margins#, marginleft/top/right/bottom (get/set) |
| Visibility & State | 6 | visible, enabled, opacity (get/set) |
| Focus | 5 | isfocused, setfocus#, resetfocus#, taborder (get/set) |
| Interaction | 6 | canfocus, hittest, dragmode (get/set) |
| Tag & Parent | 6 | tag (get/set), parent# (get/set), bringtofront#, sendtoback# |
| Events | 33 | 15 event types × set/get + clearcallbacks# |
Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | Win32/Win64 |
| Linux | ✅ Full Support | GTK-based |
| Android | ✅ Full Support | Native picker on mobile |
Error Handling
| Function | Signature | Description |
|---|---|---|
combobox_error() | combobox_error@ | Last error code (0 = no error) |
combobox_errormsg$() | combobox_errormsg$@ | Last error message as string |
combobox_strerror$(code) | combobox_strerror$@n | Description for a given error code |
combobox_clearerror() | combobox_clearerror@ | Clear the error state |
Numeric Values Reference
Control Alignment combobox_align#
| Value | Description |
|---|---|
| 0 | None (absolute positioning) |
| 1 | Top |
| 2 | Left |
| 3 | Right |
| 4 | Bottom |
| 9 | Client (fill parent) |
Drag Mode combobox_dragmode#
| Value | Description |
|---|---|
| 0 | None (default) |
| 1 | Automatic drag enabled |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
combobox#(parent#) | combobox#@# | Create combo box with default position (0, 0) |
combobox#(parent#, x, y, w, h) | combobox#@#nnnn | Create with position and size |
combobox_free(cb#) | combobox_free@# | Destroy combo box and release resources |
let cb# = combobox#(frm#, 50, 50, 200, 30) ' Cleanup combobox_free(cb#)
Items Management
| Function | Signature | Description |
|---|---|---|
combobox_add(cb#, text$) | combobox_add@#$ | Add item to the end of the list; returns the new index |
combobox_insert(cb#, index, text$) | combobox_insert@#n$ | Insert item at a specific index (0-based) |
combobox_delete(cb#, index) | combobox_delete@#n | Delete item at the given index |
combobox_clear(cb#) | combobox_clear@# | Remove all items from the list |
combobox_count(cb#) | combobox_count@# | Get the number of items |
combobox_item$(cb#, index) | combobox_item$@#n | Get the text of an item by index |
combobox_item#(cb#, index, text$) | combobox_item#@#n$ | Set the text of an item by index |
combobox_indexof(cb#, text$) | combobox_indexof@#$ | Find item by text; returns index or -1 if not found |
' Build a list combobox_add(cb#, "Apple") combobox_add(cb#, "Banana") combobox_add(cb#, "Cherry") println "Items: " + str$(combobox_count(cb#)) ' 3 ' Find an item let idx = combobox_indexof(cb#, "Banana") ' Returns 1 ' Modify an item combobox_item#(cb#, 1, "Blueberry") ' Insert at position 0 combobox_insert(cb#, 0, "Avocado") ' Delete first item combobox_delete(cb#, 0) ' Clear all combobox_clear(cb#)
Selection
| Function | Signature | Description |
|---|---|---|
combobox_itemindex(cb#) | combobox_itemindex@# | Get the selected index (-1 if nothing selected) |
combobox_itemindex#(cb#, index) | combobox_itemindex#@#n | Set the selected index |
combobox_selected$(cb#) | combobox_selected$@# | Get the text of the selected item |
combobox_dropdowncount(cb#) | combobox_dropdowncount@# | Get number of visible items in the dropdown |
combobox_dropdowncount#(cb#, n) | combobox_dropdowncount#@#n | Set number of visible items in the dropdown |
' Select first item combobox_itemindex#(cb#, 0) ' Read selection let idx = combobox_itemindex(cb#) let txt$ = combobox_selected$(cb#) println "Selected [" + str$(idx) + "]: " + txt$ ' Show more items in the dropdown combobox_dropdowncount#(cb#, 8)
combobox_itemindex returns -1 when no item is selected. Always check for -1 before accessing the selected text.Position & Size
| Function | Signature | Description |
|---|---|---|
combobox_x(cb#) | combobox_x@# | Get X position |
combobox_x#(cb#, x) | combobox_x#@#n | Set X position |
combobox_y(cb#) | combobox_y@# | Get Y position |
combobox_y#(cb#, y) | combobox_y#@#n | Set Y position |
combobox_width(cb#) | combobox_width@# | Get width |
combobox_width#(cb#, w) | combobox_width#@#n | Set width |
combobox_height(cb#) | combobox_height@# | Get height |
combobox_height#(cb#, h) | combobox_height#@#n | Set height |
combobox_bounds#(cb#, x, y, w, h) | combobox_bounds#@#nnnn | Set position and size in one call |
combobox_move#(cb#, x, y) | combobox_move#@#nn | Set position only |
combobox_size#(cb#, w, h) | combobox_size#@#nn | Set size only |
combobox_bounds#(cb#, 50, 50, 200, 30)
Alignment & Margins
When combobox_align# is set to a value other than 0, the combo box is automatically positioned by its parent. Margins control spacing when alignment is active.
| Function | Signature | Description |
|---|---|---|
combobox_align(cb#) | combobox_align@# | Get control alignment mode |
combobox_align#(cb#, n) | combobox_align#@#n | Set control alignment (0=none, 1=top, 2=left, 3=right, 4=bottom, 9=client) |
combobox_margin#(cb#, n) | combobox_margin#@#n | Set uniform margin on all four sides |
combobox_margins#(cb#, l, t, r, b) | combobox_margins#@#nnnn | Set individual margins (left, top, right, bottom) |
combobox_marginleft(cb#) | combobox_marginleft@# | Get left margin |
combobox_marginleft#(cb#, n) | combobox_marginleft#@#n | Set left margin |
combobox_margintop(cb#) | combobox_margintop@# | Get top margin |
combobox_margintop#(cb#, n) | combobox_margintop#@#n | Set top margin |
combobox_marginright(cb#) | combobox_marginright@# | Get right margin |
combobox_marginright#(cb#, n) | combobox_marginright#@#n | Set right margin |
combobox_marginbottom(cb#) | combobox_marginbottom@# | Get bottom margin |
combobox_marginbottom#(cb#, n) | combobox_marginbottom#@#n | Set bottom margin |
' Dock to top of a panel combobox_align#(cb#, 1) combobox_margin#(cb#, 5)
Visibility & State
| Function | Signature | Description |
|---|---|---|
combobox_visible(cb#) | combobox_visible@# | Get visibility (0/1) |
combobox_visible#(cb#, n) | combobox_visible#@#n | Set visibility (0=hidden, 1=visible) |
combobox_enabled(cb#) | combobox_enabled@# | Get enabled state (0/1) |
combobox_enabled#(cb#, n) | combobox_enabled#@#n | Set enabled state (0=disabled/grayed, 1=enabled) |
combobox_opacity(cb#) | combobox_opacity@# | Get opacity (0.0–1.0) |
combobox_opacity#(cb#, value) | combobox_opacity#@#n | Set opacity (0.0=transparent, 1.0=opaque) |
' Disable until a prerequisite is met combobox_enabled#(cbCity#, 0) ' Enable after country is selected combobox_enabled#(cbCity#, 1)
Focus
| Function | Signature | Description |
|---|---|---|
combobox_isfocused(cb#) | combobox_isfocused@# | Is this combo box focused? (0/1) |
combobox_setfocus#(cb#) | combobox_setfocus#@# | Give keyboard focus |
combobox_resetfocus#(cb#) | combobox_resetfocus#@# | Release focus |
combobox_taborder(cb#) | combobox_taborder@# | Get tab order index |
combobox_taborder#(cb#, n) | combobox_taborder#@#n | Set tab order index |
combobox_taborder#(cbCountry#, 1) combobox_taborder#(cbCity#, 2)
Interaction
| Function | Signature | Description |
|---|---|---|
combobox_canfocus(cb#) | combobox_canfocus@# | Get whether combo box can receive focus (0/1) |
combobox_canfocus#(cb#, n) | combobox_canfocus#@#n | Set whether combo box can receive focus |
combobox_hittest(cb#) | combobox_hittest@# | Get hit-test state (0/1) |
combobox_hittest#(cb#, n) | combobox_hittest#@#n | Enable/disable mouse hit testing |
combobox_dragmode(cb#) | combobox_dragmode@# | Get drag mode (0=none, 1=automatic) |
combobox_dragmode#(cb#, n) | combobox_dragmode#@#n | Set drag mode |
Tag & Parent
| Function | Signature | Description |
|---|---|---|
combobox_tag(cb#) | combobox_tag@# | Get user-defined integer tag |
combobox_tag#(cb#, n) | combobox_tag#@#n | Set user-defined integer tag |
combobox_parent#(cb#) | combobox_parent#@# | Get parent control pointer |
combobox_parent#(cb#, parent#) | combobox_parent#@## | Move combo box to a different parent |
combobox_bringtofront#(cb#) | combobox_bringtofront#@# | Bring to front of Z-order |
combobox_sendtoback#(cb#) | combobox_sendtoback#@# | Send to back of Z-order |
Events
Each event has a setter (combobox_onXXX#(cb#, func$)) and a getter (combobox_onXXX$(cb#)). Use combobox_clearcallbacks#(cb#) to disconnect all callbacks at once.
Selection & Focus Events
| Event Setter | Getter | Callback Signature | When It Fires |
|---|---|---|---|
combobox_onchange#(cb#, func$) | combobox_onchange$(cb#) | function name(sender#) | When the selected item changes |
combobox_onclick#(cb#, func$) | combobox_onclick$(cb#) | function name(sender#) | When the combo box is clicked |
combobox_ondblclick#(cb#, func$) | combobox_ondblclick$(cb#) | function name(sender#) | When double-clicked |
combobox_onenter#(cb#, func$) | combobox_onenter$(cb#) | function name(sender#) | When the control receives focus |
combobox_onexit#(cb#, func$) | combobox_onexit$(cb#) | function name(sender#) | When the control loses focus |
combobox_itemindex# changes the selection programmatically.Keyboard Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
combobox_onkeydown#(cb#, func$) | combobox_onkeydown$(cb#) | function name(sender#, key, keychar$, shift$) |
combobox_onkeyup#(cb#, func$) | combobox_onkeyup$(cb#) | function name(sender#, key, keychar$, shift$) |
Mouse Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
combobox_onmousedown#(cb#, func$) | combobox_onmousedown$(cb#) | function name(sender#, button, x, y, shift$) |
combobox_onmouseup#(cb#, func$) | combobox_onmouseup$(cb#) | function name(sender#, button, x, y, shift$) |
combobox_onmousemove#(cb#, func$) | combobox_onmousemove$(cb#) | function name(sender#, x, y, shift$) |
combobox_onmouseenter#(cb#, func$) | combobox_onmouseenter$(cb#) | function name(sender#) |
combobox_onmouseleave#(cb#, func$) | combobox_onmouseleave$(cb#) | function name(sender#) |
Other Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
combobox_onresize#(cb#, func$) | combobox_onresize$(cb#) | function name(sender#) |
combobox_ondragenter#(cb#, func$) | combobox_ondragenter$(cb#) | function name(sender#) |
combobox_ondragover#(cb#, func$) | combobox_ondragover$(cb#) | function name(sender#) |
combobox_ondragdrop#(cb#, func$) | combobox_ondragdrop$(cb#) | function name(sender#) |
combobox_ondragleave#(cb#, func$) | combobox_ondragleave$(cb#) | function name(sender#) |
combobox_clearcallbacks#(cb#) | — | Disconnect all event callbacks |
Complete Examples
Country Selection
function OnCountrySelected(sender#) println "You selected: " + combobox_selected$(sender#) endfunction let frm# = form#("Country Selector", 400, 200) form_position#(frm#, 4) let lblCountry# = label#(frm#, "Select your country:") label_move#(lblCountry#, 50, 30) let cbCountry# = combobox#(frm#, 50, 55, 200, 30) combobox_add(cbCountry#, "United States") combobox_add(cbCountry#, "United Kingdom") combobox_add(cbCountry#, "Canada") combobox_add(cbCountry#, "Australia") combobox_add(cbCountry#, "Germany") combobox_add(cbCountry#, "Brazil") combobox_dropdowncount#(cbCountry#, 6) combobox_onchange#(cbCountry#, "OnCountrySelected") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Linked ComboBoxes (Country → City)
function OnCountryChanged(sender#) local country$ country$ = combobox_selected$(sender#) combobox_clear(cbCity#) if country$ = "USA" then combobox_add(cbCity#, "New York") combobox_add(cbCity#, "Los Angeles") combobox_add(cbCity#, "Chicago") elseif country$ = "UK" then combobox_add(cbCity#, "London") combobox_add(cbCity#, "Manchester") elseif country$ = "Brazil" then combobox_add(cbCity#, "S\u00e3o Paulo") combobox_add(cbCity#, "Rio de Janeiro") endif combobox_enabled#(cbCity#, 1) combobox_itemindex#(cbCity#, 0) endfunction let cbCountry# = Pointer#(0) let cbCity# = Pointer#(0) let frm# = form#("Location", 400, 200) form_position#(frm#, 4) label#(frm#, "Country:", 50, 20) cbCountry# = combobox#(frm#, 50, 45, 200, 30) combobox_add(cbCountry#, "USA") combobox_add(cbCountry#, "UK") combobox_add(cbCountry#, "Brazil") combobox_onchange#(cbCountry#, "OnCountryChanged") label#(frm#, "City:", 50, 90) cbCity# = combobox#(frm#, 50, 115, 200, 30) combobox_enabled#(cbCity#, 0) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Item Search
function OnSearch(sender#) local search$, idx search$ = edit_text$(edtSearch#) idx = combobox_indexof(cb#, search$) if idx >= 0 then combobox_itemindex#(cb#, idx) label_text#(lblResult#, "Found at index " + str$(idx)) else label_text#(lblResult#, "Not found") endif endfunction let frm# = form#("Search Demo", 400, 250) form_position#(frm#, 4) let cb# = combobox#(frm#, 20, 20, 200, 30) combobox_add(cb#, "Apple") combobox_add(cb#, "Banana") combobox_add(cb#, "Cherry") combobox_add(cb#, "Date") combobox_add(cb#, "Elderberry") label#(frm#, "Search:", 20, 70) let edtSearch# = edit#(frm#, 20, 92, 200, 28) let btnSearch# = button#(frm#, "Find", 230, 92, 60, 28) button_onclick#(btnSearch#, "OnSearch") let lblResult# = label#(frm#, "") label_move#(lblResult#, 20, 140) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Dynamic Item Management
function OnAdd(sender#) local txt$ txt$ = edit_text$(edtItem#) if len(txt$) > 0 then combobox_add(cb#, txt$) edit_text#(edtItem#, "") UpdateCount() endif endfunction function OnRemove(sender#) local idx idx = combobox_itemindex(cb#) if idx >= 0 then combobox_delete(cb#, idx) UpdateCount() endif endfunction function OnClear(sender#) combobox_clear(cb#) UpdateCount() endfunction function UpdateCount() label_text#(lblCount#, "Items: " + str$(combobox_count(cb#))) endfunction let frm# = form#("Item Manager", 400, 250) form_position#(frm#, 4) let cb# = combobox#(frm#, 20, 20, 200, 30) let edtItem# = edit#(frm#, 20, 65, 200, 28) edit_prompt#(edtItem#, "New item text...") let btnAdd# = button#(frm#, "Add", 230, 65, 60, 28) let btnRemove# = button#(frm#, "Remove", 230, 20, 70, 28) let btnClear# = button#(frm#, "Clear All", 310, 20, 75, 28) button_onclick#(btnAdd#, "OnAdd") button_onclick#(btnRemove#, "OnRemove") button_onclick#(btnClear#, "OnClear") let lblCount# = label#(frm#, "Items: 0") label_move#(lblCount#, 20, 110) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Best Practices
| Practice | Why |
|---|---|
Use combobox_onchange# as the primary event | Fires when the selection actually changes |
Check for combobox_itemindex(cb#) = -1 | No item is selected; avoid accessing invalid selection |
Use combobox_dropdowncount# for long lists | Shows more items in the dropdown, reducing scrolling |
Use combobox_indexof to find items by text | Returns -1 if not found; avoids manual loops |
| Disable dependent combo boxes until ready | Use combobox_enabled#(cb#, 0) until a prerequisite is met |
Set combobox_taborder# | Enables logical Tab navigation between form controls |
Use combobox_tag# for shared callbacks | Identify which combo box changed without global variable lookups |
Quick Reference
| Function | Signature | Description |
|---|---|---|
combobox_error / errormsg$ / strerror$ / clearerror | various | Error handling (4) |
combobox#(parent#[, x, y, w, h]) | various | Create (2 overloads) |
combobox_free(cb#) | combobox_free@# | Destroy |
combobox_add / insert / delete / clear / count / item / indexof | various | Items management (8) |
combobox_itemindex / selected$ / dropdowncount | various | Selection (5) |
combobox_x/y/width/height (get/set) / bounds# / move# / size# | various | Position & size (14) |
combobox_align / margin# / margins# / margin[left/top/right/bottom] | various | Alignment & margins (12) |
combobox_visible / enabled / opacity | various | Visibility & state (6) |
combobox_isfocused / setfocus# / resetfocus# / taborder | various | Focus (5) |
combobox_canfocus / hittest / dragmode | various | Interaction (6) |
combobox_tag / parent# / bringtofront# / sendtoback# | various | Tag & parent (6) |
combobox_onchange/onclick/ondblclick/onenter/onexit/onkeydown/onkeyup/onmousedown/up/move/enter/leave/onresize/ondragenter/over/drop/leave | various | Events set+get (32) |
combobox_clearcallbacks# | combobox_clearcallbacks#@# | Disconnect all events |
101 functions. Part of the Plan9Basic GUI library system.