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.

CategoryCountDescription
Error Handling4button_error, button_errormsg$, button_strerror$, button_clearerror
Creation & Destruction5button# (4 overloads), button_free
Text Content2button_text$ (get), button_text# (set)
Font Properties12fontfamily, fontsize, fontcolor, bold, italic, underline, strikeout (get/set)
Button-Specific6modalresult, default, cancel (get/set)
Position & Size14x, y, width, height (get/set), bounds#, move#, size#
Alignment & Margins12align (get/set), margin#, margins#, marginleft/top/right/bottom (get/set)
Visibility & State6visible, enabled, opacity (get/set)
Focus6isfocused, setfocus#, resetfocus#, canfocus (get/set), taborder (get/set)
Interaction4hittest (get/set), dragmode (get/set)
Tag & Parent5tag (get/set), parent# (get/set), bringtofront#, sendtoback#
Events3214 event types × set/get + clearcallbacks# + onresize

Cross-Platform Support

PlatformStatusNotes
Windows✅ Full SupportWin32/Win64
Linux✅ Full SupportGTK-based
Android✅ Full SupportMobile-optimized touch targets

Error Handling

FunctionSignatureDescription
button_error()button_error@Last error code (0 = no error)
button_errormsg$()button_errormsg$@Last error message as string
button_strerror$(code)button_strerror$@nDescription for a given error code
button_clearerror()button_clearerror@Clear the error state
╯ plan9basic
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:

╯ plan9basic
' 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#

ValueDescription
0None (absolute positioning)
1Top
2Left
3Right
4Bottom
9Client (fill parent)
11Center

Modal Result Values button_modalresult#

ValueMeaning
0None
1OK
2Cancel
6Yes
7No

Drag Mode Values button_dragmode#

ValueDescription
0Manual (drag must be initiated by code)
1Automatic (drag starts on mouse-down)

Creation & Destruction

FunctionSignatureDescription
button#(parent#)button#@#Create button with default text "Button"
button#(parent#, text$)button#@#$Create with specified text
button#(parent#, x, y, w, h)button#@#nnnnCreate at position with size
button#(parent#, text$, x, y, w, h)button#@#$nnnnCreate with text, position, and size
button_free(btn#)button_free@#Destroy button and release resources
╯ plan9basic
' 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

FunctionSignatureDescription
button_text$(btn#)button_text$@#Get the button’s display text
button_text#(btn#, text$)button_text#@#$Set the button’s display text
╯ plan9basic
button_text#(btn#, "Save File")
println "Button says: " + button_text$(btn#)

Font Properties

FunctionSignatureDescription
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#@#nSet 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#@#nSet bold (0/1)
button_italic(btn#)button_italic@#Get italic state (0/1)
button_italic#(btn#, n)button_italic#@#nSet italic (0/1)
button_underline(btn#)button_underline@#Get underline state (0/1)
button_underline#(btn#, n)button_underline#@#nSet underline (0/1)
button_strikeout(btn#)button_strikeout@#Get strikeout state (0/1)
button_strikeout#(btn#, n)button_strikeout#@#nSet strikeout (0/1)
╯ plan9basic
button_fontfamily#(btn#, "Arial")
button_fontsize#(btn#, 14)
button_fontcolor#(btn#, "#333333")
button_bold#(btn#, 1)
button_underline#(btn#, 1)

Button-Specific Properties

FunctionSignatureDescription
button_modalresult(btn#)button_modalresult@#Get modal result value
button_modalresult#(btn#, n)button_modalresult#@#nSet 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#@#nSet as default button (responds to Enter key)
button_cancel(btn#)button_cancel@#Get cancel state (0/1)
button_cancel#(btn#, n)button_cancel#@#nSet as cancel button (responds to Escape key)
╯ plan9basic
' 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

FunctionSignatureDescription
button_x(btn#)button_x@#Get X position
button_x#(btn#, x)button_x#@#nSet X position
button_y(btn#)button_y@#Get Y position
button_y#(btn#, y)button_y#@#nSet Y position
button_width(btn#)button_width@#Get width
button_width#(btn#, w)button_width#@#nSet width
button_height(btn#)button_height@#Get height
button_height#(btn#, h)button_height#@#nSet height
button_bounds#(btn#, x, y, w, h)button_bounds#@#nnnnSet position and size in one call
button_move#(btn#, x, y)button_move#@#nnSet position only
button_size#(btn#, w, h)button_size#@#nnSet size only
╯ plan9basic
' 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.

FunctionSignatureDescription
button_align(btn#)button_align@#Get alignment mode
button_align#(btn#, n)button_align#@#nSet alignment (0=none, 1=top, 2=left, 3=right, 4=bottom, 9=client, 11=center)
button_margin#(btn#, n)button_margin#@#nSet uniform margin on all four sides
button_margins#(btn#, l, t, r, b)button_margins#@#nnnnSet individual margins (left, top, right, bottom)
button_marginleft(btn#)button_marginleft@#Get left margin
button_marginleft#(btn#, n)button_marginleft#@#nSet left margin
button_margintop(btn#)button_margintop@#Get top margin
button_margintop#(btn#, n)button_margintop#@#nSet top margin
button_marginright(btn#)button_marginright@#Get right margin
button_marginright#(btn#, n)button_marginright#@#nSet right margin
button_marginbottom(btn#)button_marginbottom@#Get bottom margin
button_marginbottom#(btn#, n)button_marginbottom#@#nSet bottom margin
╯ plan9basic
' 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

FunctionSignatureDescription
button_visible(btn#)button_visible@#Get visibility (0/1)
button_visible#(btn#, n)button_visible#@#nSet visibility (0=hidden, 1=visible)
button_enabled(btn#)button_enabled@#Get enabled state (0/1)
button_enabled#(btn#, n)button_enabled#@#nSet enabled state (0=disabled/grayed, 1=enabled)
button_opacity(btn#)button_opacity@#Get opacity (0.0–1.0)
button_opacity#(btn#, value)button_opacity#@#nSet opacity (0.0=transparent, 1.0=opaque)
╯ plan9basic
' 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

FunctionSignatureDescription
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#@#nSet whether the button can receive focus (0/1)
button_taborder(btn#)button_taborder@#Get tab order index
button_taborder#(btn#, n)button_taborder#@#nSet tab order index
╯ plan9basic
' Set logical tab order for a dialog
button_taborder#(btnOK#, 1)
button_taborder#(btnCancel#, 2)

' Give initial focus
button_setfocus#(btnOK#)

Interaction

FunctionSignatureDescription
button_hittest(btn#)button_hittest@#Get hit-test state (0/1)
button_hittest#(btn#, n)button_hittest#@#nEnable/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#@#nSet 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

FunctionSignatureDescription
button_tag(btn#)button_tag@#Get user-defined integer tag
button_tag#(btn#, n)button_tag#@#nSet 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
╯ plan9basic
' 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 SetterGetterCallback 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
╯ plan9basic
' Click handler
function OnButtonClick(sender#)
    println "Button clicked: " + button_text$(sender#)
endfunction

button_onclick#(btn#, "OnButtonClick")
╯ plan9basic
' 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

╯ counter.bas
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

╯ dialog.bas
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

╯ colors.bas
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

╯ toolbar.bas
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

PracticeWhy
Always set button_onclick#Buttons without handlers serve no purpose
Use meaningful textButton text should clearly indicate the action
Set button_default# and button_cancel# for dialogsImproves keyboard navigation (Enter/Escape)
Use button_tag# with shared callbacksIdentify 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 linePrevents accidental use of global variables in callbacks
Use button_enabled#(btn#, 0) to prevent double-clicksDisable during async operations, re-enable when complete

Quick Reference

FunctionSignatureDescription
button_error / errormsg$ / strerror$ / clearerrorvariousError handling (4)
button#(parent#[, text$][, x, y, w, h])variousCreate 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 / strikeoutvariousFont properties (14)
button_modalresult / default / cancelvariousButton behavior (6)
button_x/y/width/height (get/set)variousPosition & size (8)
button_bounds# / move# / size#variousBatch position/size (3)
button_align / margin# / margins# / margin[left/top/right/bottom]variousAlignment & margins (12)
button_visible / enabled / opacityvariousState (6)
button_isfocused / setfocus# / resetfocus# / canfocus / tabordervariousFocus (7)
button_hittest / dragmodevariousInteraction (4)
button_tag / parent# / bringtofront# / sendtoback#variousTag & parent (6)
button_onclick/onenter/onexit/onkeydown/onkeyup/onmousedown/onmouseup/onmousemove/onmouseenter/onmouseleave/onresize/ondragenter/ondragover/ondragdrop/ondragleavevariousEvents set+get (31)
button_clearcallbacks#button_clearcallbacks#@#Disconnect all events

108 functions. Part of the Plan9Basic GUI library system.