ButtonLib — Button Control Library
Complete functionality for creating and managing push-button controls in Plan9Basic. Buttons are the standard clickable interface element for triggering actions in GUI applets. 108 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | button_error, button_errormsg$, button_strerror$, button_clearerror |
| Creation & Destruction | 5 | button# (4 overloads), button_free |
| Text Content | 2 | button_text$ (get), button_text# (set) |
| Font Properties | 12 | fontfamily, fontsize, fontcolor, bold, italic, underline, strikeout (get/set) |
| Button-Specific | 6 | modalresult, default, cancel (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 | 6 | isfocused, setfocus#, resetfocus#, canfocus (get/set), taborder (get/set) |
| Interaction | 4 | hittest (get/set), dragmode (get/set) |
| Tag & Parent | 5 | tag (get/set), parent# (get/set), bringtofront#, sendtoback# |
| Events | 32 | 14 event types × set/get + clearcallbacks# + onresize |
Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | Win32/Win64 |
| Linux | ✅ Full Support | GTK-based |
| Android | ✅ Full Support | Mobile-optimized touch targets |
Error Handling
| Function | Signature | Description |
|---|---|---|
button_error() | button_error@ | Last error code (0 = no error) |
button_errormsg$() | button_errormsg$@ | Last error message as string |
button_strerror$(code) | button_strerror$@n | Description for a given error code |
button_clearerror() | button_clearerror@ | Clear the error state |
let btn# = button#(frm#, "OK") if button_error() <> 0 then println "Error: " + button_errormsg$() endif
Numeric Values Reference
Plan9Basic does not have built-in constants. You can define your own named values for readability:
' Alignment values let ALIGN_NONE = 0 let ALIGN_TOP = 1 let ALIGN_CLIENT = 9 ' Modal result values let MR_OK = 1 let MR_CANCEL = 2
Alignment Values button_align#
| Value | Description |
|---|---|
| 0 | None (absolute positioning) |
| 1 | Top |
| 2 | Left |
| 3 | Right |
| 4 | Bottom |
| 9 | Client (fill parent) |
| 11 | Center |
Modal Result Values button_modalresult#
| Value | Meaning |
|---|---|
| 0 | None |
| 1 | OK |
| 2 | Cancel |
| 6 | Yes |
| 7 | No |
Drag Mode Values button_dragmode#
| Value | Description |
|---|---|
| 0 | Manual (drag must be initiated by code) |
| 1 | Automatic (drag starts on mouse-down) |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
button#(parent#) | button#@# | Create button with default text "Button" |
button#(parent#, text$) | button#@#$ | Create with specified text |
button#(parent#, x, y, w, h) | button#@#nnnn | Create at position with size |
button#(parent#, text$, x, y, w, h) | button#@#$nnnn | Create with text, position, and size |
button_free(btn#) | button_free@# | Destroy button and release resources |
' Minimal creation let btn# = button#(frm#) ' With text let btn# = button#(frm#, "Click Me") ' Full creation let btn# = button#(frm#, "Save", 50, 100, 120, 40) ' Cleanup button_free(btn#)
ⓘ Note: The
parent# parameter must be a valid form or container control (panel, layout). The button is automatically added as a child of the parent.Text Content
| Function | Signature | Description |
|---|---|---|
button_text$(btn#) | button_text$@# | Get the button’s display text |
button_text#(btn#, text$) | button_text#@#$ | Set the button’s display text |
button_text#(btn#, "Save File") println "Button says: " + button_text$(btn#)
Font Properties
| Function | Signature | Description |
|---|---|---|
button_fontfamily$(btn#) | button_fontfamily$@# | Get font family name |
button_fontfamily#(btn#, family$) | button_fontfamily#@#$ | Set font family |
button_fontsize(btn#) | button_fontsize@# | Get font size |
button_fontsize#(btn#, size) | button_fontsize#@#n | Set font size |
button_fontcolor$(btn#) | button_fontcolor$@# | Get font color |
button_fontcolor#(btn#, color$) | button_fontcolor#@#$ | Set font color |
button_bold(btn#) | button_bold@# | Get bold state (0/1) |
button_bold#(btn#, n) | button_bold#@#n | Set bold (0/1) |
button_italic(btn#) | button_italic@# | Get italic state (0/1) |
button_italic#(btn#, n) | button_italic#@#n | Set italic (0/1) |
button_underline(btn#) | button_underline@# | Get underline state (0/1) |
button_underline#(btn#, n) | button_underline#@#n | Set underline (0/1) |
button_strikeout(btn#) | button_strikeout@# | Get strikeout state (0/1) |
button_strikeout#(btn#, n) | button_strikeout#@#n | Set strikeout (0/1) |
button_fontfamily#(btn#, "Arial") button_fontsize#(btn#, 14) button_fontcolor#(btn#, "#333333") button_bold#(btn#, 1) button_underline#(btn#, 1)
Button-Specific Properties
| Function | Signature | Description |
|---|---|---|
button_modalresult(btn#) | button_modalresult@# | Get modal result value |
button_modalresult#(btn#, n) | button_modalresult#@#n | Set modal result (0=none, 1=OK, 2=Cancel, 6=Yes, 7=No) |
button_default(btn#) | button_default@# | Get default state (0/1) |
button_default#(btn#, n) | button_default#@#n | Set as default button (responds to Enter key) |
button_cancel(btn#) | button_cancel@# | Get cancel state (0/1) |
button_cancel#(btn#, n) | button_cancel#@#n | Set as cancel button (responds to Escape key) |
' Dialog buttons with keyboard shortcuts let btnOK# = button#(frm#, "OK", 50, 100, 80, 30) button_default#(btnOK#, 1) ' Enter triggers this button button_modalresult#(btnOK#, 1) ' Sets form result to OK let btnCancel# = button#(frm#, "Cancel", 150, 100, 80, 30) button_cancel#(btnCancel#, 1) ' Escape triggers this button button_modalresult#(btnCancel#, 2) ' Sets form result to Cancel
ⓘ Note:
button_default# and button_cancel# work with the form’s keyboard handling. When the user presses Enter, the default button’s OnClick fires. When Escape is pressed, the cancel button’s OnClick fires.Position & Size
| Function | Signature | Description |
|---|---|---|
button_x(btn#) | button_x@# | Get X position |
button_x#(btn#, x) | button_x#@#n | Set X position |
button_y(btn#) | button_y@# | Get Y position |
button_y#(btn#, y) | button_y#@#n | Set Y position |
button_width(btn#) | button_width@# | Get width |
button_width#(btn#, w) | button_width#@#n | Set width |
button_height(btn#) | button_height@# | Get height |
button_height#(btn#, h) | button_height#@#n | Set height |
button_bounds#(btn#, x, y, w, h) | button_bounds#@#nnnn | Set position and size in one call |
button_move#(btn#, x, y) | button_move#@#nn | Set position only |
button_size#(btn#, w, h) | button_size#@#nn | Set size only |
' Position and size button_bounds#(btn#, 50, 100, 120, 40) ' Or separately button_move#(btn#, 50, 100) button_size#(btn#, 120, 40) println "At: " + str$(button_x(btn#)) + ", " + str$(button_y(btn#))
Alignment & Margins
When button_align# is set to a value other than 0, the button is automatically positioned by the parent container. Margins control spacing between the button and adjacent controls when alignment is active.
| Function | Signature | Description |
|---|---|---|
button_align(btn#) | button_align@# | Get alignment mode |
button_align#(btn#, n) | button_align#@#n | Set alignment (0=none, 1=top, 2=left, 3=right, 4=bottom, 9=client, 11=center) |
button_margin#(btn#, n) | button_margin#@#n | Set uniform margin on all four sides |
button_margins#(btn#, l, t, r, b) | button_margins#@#nnnn | Set individual margins (left, top, right, bottom) |
button_marginleft(btn#) | button_marginleft@# | Get left margin |
button_marginleft#(btn#, n) | button_marginleft#@#n | Set left margin |
button_margintop(btn#) | button_margintop@# | Get top margin |
button_margintop#(btn#, n) | button_margintop#@#n | Set top margin |
button_marginright(btn#) | button_marginright@# | Get right margin |
button_marginright#(btn#, n) | button_marginright#@#n | Set right margin |
button_marginbottom(btn#) | button_marginbottom@# | Get bottom margin |
button_marginbottom#(btn#, n) | button_marginbottom#@#n | Set bottom margin |
' Button docked to the bottom with 5px spacing button_align#(btn#, 4) ' Align bottom button_margin#(btn#, 5) ' 5px all sides ' Individual margins button_margins#(btn#, 10, 5, 10, 5)
Visibility & State
| Function | Signature | Description |
|---|---|---|
button_visible(btn#) | button_visible@# | Get visibility (0/1) |
button_visible#(btn#, n) | button_visible#@#n | Set visibility (0=hidden, 1=visible) |
button_enabled(btn#) | button_enabled@# | Get enabled state (0/1) |
button_enabled#(btn#, n) | button_enabled#@#n | Set enabled state (0=disabled/grayed, 1=enabled) |
button_opacity(btn#) | button_opacity@# | Get opacity (0.0–1.0) |
button_opacity#(btn#, value) | button_opacity#@#n | Set opacity (0.0=transparent, 1.0=opaque) |
' Disable a button during a long operation button_enabled#(btnSave#, 0) button_opacity#(btnSave#, 0.5) ' ... do work ... button_enabled#(btnSave#, 1) button_opacity#(btnSave#, 1.0)
Focus
| Function | Signature | Description |
|---|---|---|
button_isfocused(btn#) | button_isfocused@# | Is this button focused? (0/1) |
button_setfocus#(btn#) | button_setfocus#@# | Give keyboard focus to this button |
button_resetfocus#(btn#) | button_resetfocus#@# | Release focus from this button |
button_canfocus(btn#) | button_canfocus@# | Get whether the button can receive focus (0/1) |
button_canfocus#(btn#, n) | button_canfocus#@#n | Set whether the button can receive focus (0/1) |
button_taborder(btn#) | button_taborder@# | Get tab order index |
button_taborder#(btn#, n) | button_taborder#@#n | Set tab order index |
' Set logical tab order for a dialog button_taborder#(btnOK#, 1) button_taborder#(btnCancel#, 2) ' Give initial focus button_setfocus#(btnOK#)
Interaction
| Function | Signature | Description |
|---|---|---|
button_hittest(btn#) | button_hittest@# | Get hit-test state (0/1) |
button_hittest#(btn#, n) | button_hittest#@#n | Enable/disable mouse hit testing (0=click-through, 1=clickable) |
button_dragmode(btn#) | button_dragmode@# | Get drag mode (0=manual, 1=automatic) |
button_dragmode#(btn#, n) | button_dragmode#@#n | Set drag mode |
ⓘ Note: Setting
button_hittest#(btn#, 0) makes the button transparent to mouse clicks — clicks pass through to the control behind it. Useful for overlay decorations.Tag & Parent
| Function | Signature | Description |
|---|---|---|
button_tag(btn#) | button_tag@# | Get user-defined integer tag |
button_tag#(btn#, n) | button_tag#@#n | Set user-defined integer tag |
button_parent#(btn#) | button_parent#@# | Get parent control pointer |
button_parent#(btn#, parent#) | button_parent#@## | Move button to a different parent |
button_bringtofront#(btn#) | button_bringtofront#@# | Bring to front of Z-order |
button_sendtoback#(btn#) | button_sendtoback#@# | Send to back of Z-order |
' Use tags to identify buttons in a shared callback button_tag#(btnRed#, 1) button_tag#(btnGreen#, 2) button_tag#(btnBlue#, 3) function OnColorClick(sender#) local tag tag = button_tag(sender#) if tag = 1 then println "Red" elseif tag = 2 then println "Green" elseif tag = 3 then println "Blue" endif endfunction
Events
Each event has a setter (button_onXXX#(btn#, func$)) and a getter (button_onXXX$(btn#)) to assign or read the callback name. Use button_clearcallbacks#(btn#) to disconnect all callbacks at once.
| Event Setter | Getter | Callback Signature |
|---|---|---|
button_onclick#(btn#, func$) | button_onclick$(btn#) | function name(sender#) |
button_onenter#(btn#, func$) | button_onenter$(btn#) | function name(sender#) |
button_onexit#(btn#, func$) | button_onexit$(btn#) | function name(sender#) |
button_onkeydown#(btn#, func$) | button_onkeydown$(btn#) | function name(sender#, key, keychar$, shift$) |
button_onkeyup#(btn#, func$) | button_onkeyup$(btn#) | function name(sender#, key, keychar$, shift$) |
button_onmousedown#(btn#, func$) | button_onmousedown$(btn#) | function name(sender#, button, x, y, shift$) |
button_onmouseup#(btn#, func$) | button_onmouseup$(btn#) | function name(sender#, button, x, y, shift$) |
button_onmousemove#(btn#, func$) | button_onmousemove$(btn#) | function name(sender#, x, y, shift$) |
button_onmouseenter#(btn#, func$) | button_onmouseenter$(btn#) | function name(sender#) |
button_onmouseleave#(btn#, func$) | button_onmouseleave$(btn#) | function name(sender#) |
button_onresize#(btn#, func$) | button_onresize$(btn#) | function name(sender#) |
button_ondragenter#(btn#, func$) | button_ondragenter$(btn#) | function name(sender#) |
button_ondragover#(btn#, func$) | button_ondragover$(btn#) | function name(sender#) |
button_ondragdrop#(btn#, func$) | button_ondragdrop$(btn#) | function name(sender#) |
button_ondragleave#(btn#, func$) | button_ondragleave$(btn#) | function name(sender#) |
button_clearcallbacks#(btn#) | — | Disconnect all event callbacks |
' Click handler function OnButtonClick(sender#) println "Button clicked: " + button_text$(sender#) endfunction button_onclick#(btn#, "OnButtonClick")
' Mouse hover effect function OnMouseEnter(sender#) button_fontcolor#(sender#, "#0066CC") endfunction function OnMouseLeave(sender#) button_fontcolor#(sender#, "#000000") endfunction button_onmouseenter#(btn#, "OnMouseEnter") button_onmouseleave#(btn#, "OnMouseLeave")
Complete Examples
Click Counter
let clicks = 0 function OnClick(sender#) clicks = clicks + 1 button_text#(sender#, "Clicks: " + str$(clicks)) endfunction let frm# = form#("Counter", 300, 200) form_position#(frm#, 4) let btn# = button#(frm#, "Clicks: 0", 50, 70, 200, 50) button_fontsize#(btn#, 16) button_onclick#(btn#, "OnClick") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Dialog with OK / Cancel
let dlg# = Pointer#(0) function OnOK(sender#) form_modalresult#(dlg#, 1) form_close(dlg#) endfunction function OnCancel(sender#) form_modalresult#(dlg#, 2) form_close(dlg#) endfunction dlg# = form#("Confirm", 300, 150) form_position#(dlg#, 4) let btnOK# = button#(dlg#, "OK", 50, 100, 80, 30) button_default#(btnOK#, 1) button_onclick#(btnOK#, "OnOK") let btnCancel# = button#(dlg#, "Cancel", 170, 100, 80, 30) button_cancel#(btnCancel#, 1) button_onclick#(btnCancel#, "OnCancel") form_show(dlg#) while form_visible(dlg#) = 1 processmessages() end while
Color Picker with Tags
function OnColorClick(sender#) local tag, color$ tag = button_tag(sender#) if tag = 1 then color$ = "Red" elseif tag = 2 then color$ = "Green" elseif tag = 3 then color$ = "Blue" endif label_text#(lblResult#, "Selected: " + color$) endfunction let frm# = form#("Colors", 400, 150) form_position#(frm#, 4) let lblResult# = label#(frm#, "Select a color", 150, 100) let btnRed# = button#(frm#, "Red", 20, 40, 80, 40) button_tag#(btnRed#, 1) button_onclick#(btnRed#, "OnColorClick") let btnGreen# = button#(frm#, "Green", 120, 40, 80, 40) button_tag#(btnGreen#, 2) button_onclick#(btnGreen#, "OnColorClick") let btnBlue# = button#(frm#, "Blue", 220, 40, 80, 40) button_tag#(btnBlue#, 3) button_onclick#(btnBlue#, "OnColorClick") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Toolbar with Aligned Buttons
let frm# = form#("Toolbar Demo", 500, 400) form_position#(frm#, 4) ' Create a panel as toolbar container let toolbar# = panel#(frm#) panel_align#(toolbar#, 1) ' Align top panel_height#(toolbar#, 50) ' Buttons docked inside the toolbar let btnNew# = button#(toolbar#, "New") button_align#(btnNew#, 2) ' Align left button_width#(btnNew#, 80) button_margin#(btnNew#, 3) let btnOpen# = button#(toolbar#, "Open") button_align#(btnOpen#, 2) ' Align left button_width#(btnOpen#, 80) button_margin#(btnOpen#, 3) let btnSave# = button#(toolbar#, "Save") button_align#(btnSave#, 2) ' Align left button_width#(btnSave#, 80) button_margin#(btnSave#, 3) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Best Practices
| Practice | Why |
|---|---|
Always set button_onclick# | Buttons without handlers serve no purpose |
| Use meaningful text | Button text should clearly indicate the action |
Set button_default# and button_cancel# for dialogs | Improves keyboard navigation (Enter/Escape) |
Use button_tag# with shared callbacks | Identify which button was clicked without global variables |
Set button_taborder# | Ensures logical keyboard Tab navigation |
Initialize pointer variables with Pointer#(0) | Required before assigning in callbacks or conditional code |
Declare locals with LOCAL on the function line | Prevents accidental use of global variables in callbacks |
Use button_enabled#(btn#, 0) to prevent double-clicks | Disable during async operations, re-enable when complete |
Quick Reference
| Function | Signature | Description |
|---|---|---|
button_error / errormsg$ / strerror$ / clearerror | various | Error handling (4) |
button#(parent#[, text$][, x, y, w, h]) | various | Create button (4 overloads) |
button_free(btn#) | button_free@# | Destroy button |
button_text$ / text# | button_text$@#, button_text#@#$ | Text get/set |
button_fontfamily / fontsize / fontcolor / bold / italic / underline / strikeout | various | Font properties (14) |
button_modalresult / default / cancel | various | Button behavior (6) |
button_x/y/width/height (get/set) | various | Position & size (8) |
button_bounds# / move# / size# | various | Batch position/size (3) |
button_align / margin# / margins# / margin[left/top/right/bottom] | various | Alignment & margins (12) |
button_visible / enabled / opacity | various | State (6) |
button_isfocused / setfocus# / resetfocus# / canfocus / taborder | various | Focus (7) |
button_hittest / dragmode | various | Interaction (4) |
button_tag / parent# / bringtofront# / sendtoback# | various | Tag & parent (6) |
button_onclick/onenter/onexit/onkeydown/onkeyup/onmousedown/onmouseup/onmousemove/onmouseenter/onmouseleave/onresize/ondragenter/ondragover/ondragdrop/ondragleave | various | Events set+get (31) |
button_clearcallbacks# | button_clearcallbacks#@# | Disconnect all events |
108 functions. Part of the Plan9Basic GUI library system.