RectangleLib — Rectangle Shape Library

Rectangular shapes for drawing backgrounds, borders, color displays, visual containers, progress indicators, and decorative elements. Features fill and stroke styling, rounded corners, selective side/corner rendering via bitmasks, rotation, and a complete mouse event system. 90 functions.

CategoryCountDescription
Error Handling4rectangle_error, errormsg$, strerror$, clearerror
Creation & Destruction4rectangle# (3 overloads), rectangle_free
Fill3fill$ (get), fill# (set), fillnone#
Stroke11stroke$ / stroke# / strokenone#, thickness, dash, cap, join (get/set)
Corner Radius5xradius, yradius (get/set), corners#
Sides & Corner Flags4sides, cornersflags (get/set bitmask)
Position & Size14x, y, width, height (get/set), bounds#, move#, size#
Alignment & Margins12align (get/set), margin#, margins#, marginleft/top/right/bottom (get/set)
Visibility & State8visible, enabled, opacity, hittest (get/set)
Tag, Rotation & Parent8tag, rotation (get/set), parent# (get/set), bringtofront#, sendtoback#, invalidate#
Events199 event types × set/get + clearcallbacks#

Cross-Platform Support

PlatformStatusNotes
Windows✅ Full SupportWin32/Win64
Linux✅ Full SupportGTK-based
Android✅ Full SupportHardware-accelerated

Error Handling

FunctionSignatureDescription
rectangle_error()rectangle_error@Last error code (0 = no error)
rectangle_errormsg$()rectangle_errormsg$@Last error message as string
rectangle_strerror$(code)rectangle_strerror$@nDescription for a given error code
rectangle_clearerror()rectangle_clearerror@Clear the error state

Numeric Values Reference

Control Alignment rectangle_align#

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

Stroke Dash Style rectangle_strokedash#

ValueStyle
0Solid
1Dash
2Dot
3DashDot
4DashDotDot

Stroke Cap Style rectangle_strokecap#

ValueStyle
0Flat
1Round

Stroke Join Style rectangle_strokejoin#

ValueStyle
0Miter (sharp corners)
1Round
2Bevel (cut corners)

Sides Bitmask rectangle_sides#

ValueSideExample
1TopTop border only
2LeftLeft border only
4BottomBottom border only
8RightRight border only
15All sides (default)Complete border
5Top + Bottom (1+4)Horizontal lines only
10Left + Right (2+8)Vertical lines only
14Left + Bottom + Right (2+4+8)Open top (underline box)
ⓘ Note: Combine side values by adding them: Top (1) + Bottom (4) = 5 shows only horizontal borders. Use 15 for all sides (default).

Corners Bitmask rectangle_cornersflags#

ValueCornerExample
1Top-LeftRound top-left only
2Top-RightRound top-right only
4Bottom-LeftRound bottom-left only
8Bottom-RightRound bottom-right only
15All corners (default)Fully rounded
3Top-Left + Top-Right (1+2)Rounded top, sharp bottom
12Bottom-Left + Bottom-Right (4+8)Sharp top, rounded bottom
ⓘ Note: Combine corner values by adding them. Use with rectangle_corners# to set the radius, then rectangle_cornersflags# to choose which corners are rounded.

Creation & Destruction

FunctionSignatureDescription
rectangle#(parent#)rectangle#@#Create rectangle with default size
rectangle#(parent#, w, h)rectangle#@#nnCreate with specified size
rectangle#(parent#, x, y, w, h)rectangle#@#nnnnCreate with position and size
rectangle_free(rect#)rectangle_free@#Destroy rectangle shape
╯ plan9basic
let rect# = rectangle#(frm#, 50, 50, 150, 100)
rectangle_fill#(rect#, "#3498db")
rectangle_stroke#(rect#, "#2980b9")
rectangle_strokethickness#(rect#, 2)

Fill Properties

FunctionSignatureDescription
rectangle_fill$(rect#)rectangle_fill$@#Get fill color as hex string
rectangle_fill#(rect#, color$)rectangle_fill#@#$Set fill color ("#RRGGBB" or "#AARRGGBB")
rectangle_fillnone#(rect#)rectangle_fillnone#@#Remove fill (fully transparent body)
╯ plan9basic
rectangle_fill#(rect#, "#FF0000")       ' Solid red
rectangle_fill#(rect#, "#80FF0000")   ' Semi-transparent red
rectangle_fillnone#(rect#)              ' Outline only
ⓘ Note: Use #AARRGGBB format for semi-transparent fills. Alpha ranges from 00 (transparent) to FF (opaque).

Stroke Properties

FunctionSignatureDescription
rectangle_stroke$(rect#)rectangle_stroke$@#Get stroke color as hex string
rectangle_stroke#(rect#, color$)rectangle_stroke#@#$Set stroke color
rectangle_strokenone#(rect#)rectangle_strokenone#@#Remove stroke (no border)
rectangle_strokethickness(rect#)rectangle_strokethickness@#Get stroke thickness
rectangle_strokethickness#(rect#, n)rectangle_strokethickness#@#nSet stroke thickness
rectangle_strokedash(rect#)rectangle_strokedash@#Get dash style (0–4)
rectangle_strokedash#(rect#, n)rectangle_strokedash#@#nSet dash style
rectangle_strokecap(rect#)rectangle_strokecap@#Get cap style (0=Flat, 1=Round)
rectangle_strokecap#(rect#, n)rectangle_strokecap#@#nSet cap style
rectangle_strokejoin(rect#)rectangle_strokejoin@#Get join style (0=Miter, 1=Round, 2=Bevel)
rectangle_strokejoin#(rect#, n)rectangle_strokejoin#@#nSet join style
╯ plan9basic
' Solid black border
rectangle_stroke#(rect#, "#000000")
rectangle_strokethickness#(rect#, 2)

' Dashed border
rectangle_strokedash#(rect#, 1)

' No border
rectangle_strokenone#(rect#)

Corner Radius

FunctionSignatureDescription
rectangle_xradius(rect#)rectangle_xradius@#Get horizontal corner radius
rectangle_xradius#(rect#, n)rectangle_xradius#@#nSet horizontal corner radius
rectangle_yradius(rect#)rectangle_yradius@#Get vertical corner radius
rectangle_yradius#(rect#, n)rectangle_yradius#@#nSet vertical corner radius
rectangle_corners#(rect#, xr, yr)rectangle_corners#@#nnSet both corner radii in one call
╯ plan9basic
' Uniform rounded corners
rectangle_corners#(rect#, 10, 10)

' Pill shape (radius = half height)
rectangle_corners#(rect#, 25, 25)

' Sharp corners (default)
rectangle_corners#(rect#, 0, 0)

Sides & Corner Flags

FunctionSignatureDescription
rectangle_sides(rect#)rectangle_sides@#Get sides bitmask
rectangle_sides#(rect#, flags)rectangle_sides#@#nSet which sides to draw (bitmask: 1=Top, 2=Left, 4=Bottom, 8=Right)
rectangle_cornersflags(rect#)rectangle_cornersflags@#Get corners bitmask
rectangle_cornersflags#(rect#, flags)rectangle_cornersflags#@#nSet which corners are rounded (bitmask: 1=TL, 2=TR, 4=BL, 8=BR)
╯ plan9basic
' Only show top and bottom borders
rectangle_sides#(rect#, 5)       ' 1 (Top) + 4 (Bottom)

' Round only the top corners
rectangle_corners#(rect#, 10, 10)
rectangle_cornersflags#(rect#, 3) ' 1 (TL) + 2 (TR)

' Card with rounded top, sharp bottom
rectangle_corners#(rect#, 12, 12)
rectangle_cornersflags#(rect#, 3) ' Top-Left + Top-Right only
ⓘ Note: These bitmask properties enable complex shapes like tab headers (rounded top, flat bottom), underline boxes (open top), and partial borders.

Position & Size

FunctionSignatureDescription
rectangle_x(rect#)rectangle_x@#Get X position
rectangle_x#(rect#, x)rectangle_x#@#nSet X position
rectangle_y(rect#)rectangle_y@#Get Y position
rectangle_y#(rect#, y)rectangle_y#@#nSet Y position
rectangle_width(rect#)rectangle_width@#Get width
rectangle_width#(rect#, w)rectangle_width#@#nSet width
rectangle_height(rect#)rectangle_height@#Get height
rectangle_height#(rect#, h)rectangle_height#@#nSet height
rectangle_bounds#(rect#, x, y, w, h)rectangle_bounds#@#nnnnSet position and size in one call
rectangle_move#(rect#, x, y)rectangle_move#@#nnSet position only
rectangle_size#(rect#, w, h)rectangle_size#@#nnSet size only

Alignment & Margins

FunctionSignatureDescription
rectangle_align(rect#)rectangle_align@#Get alignment
rectangle_align#(rect#, n)rectangle_align#@#nSet alignment
rectangle_margin#(rect#, n)rectangle_margin#@#nSet uniform margin on all four sides
rectangle_margins#(rect#, l, t, r, b)rectangle_margins#@#nnnnSet individual margins
rectangle_marginleft(rect#)rectangle_marginleft@#Get left margin
rectangle_marginleft#(rect#, n)rectangle_marginleft#@#nSet left margin
rectangle_margintop(rect#)rectangle_margintop@#Get top margin
rectangle_margintop#(rect#, n)rectangle_margintop#@#nSet top margin
rectangle_marginright(rect#)rectangle_marginright@#Get right margin
rectangle_marginright#(rect#, n)rectangle_marginright#@#nSet right margin
rectangle_marginbottom(rect#)rectangle_marginbottom@#Get bottom margin
rectangle_marginbottom#(rect#, n)rectangle_marginbottom#@#nSet bottom margin

Visibility & State

FunctionSignatureDescription
rectangle_visible(rect#)rectangle_visible@#Get visibility (0/1)
rectangle_visible#(rect#, n)rectangle_visible#@#nSet visibility
rectangle_enabled(rect#)rectangle_enabled@#Get enabled state (0/1)
rectangle_enabled#(rect#, n)rectangle_enabled#@#nSet enabled state
rectangle_opacity(rect#)rectangle_opacity@#Get opacity (0.0–1.0)
rectangle_opacity#(rect#, n)rectangle_opacity#@#nSet opacity
rectangle_hittest(rect#)rectangle_hittest@#Get hit-test state (0/1)
rectangle_hittest#(rect#, n)rectangle_hittest#@#nEnable/disable mouse hit testing
⚠ Warning: Set rectangle_hittest#(rect#, 1) before assigning mouse event handlers. Without hit testing, the shape won't receive mouse events.

Tag, Rotation & Parent

FunctionSignatureDescription
rectangle_tag(rect#)rectangle_tag@#Get user-defined integer tag
rectangle_tag#(rect#, n)rectangle_tag#@#nSet user-defined integer tag
rectangle_rotation(rect#)rectangle_rotation@#Get rotation angle in degrees
rectangle_rotation#(rect#, angle)rectangle_rotation#@#nSet rotation angle
rectangle_parent#(rect#)rectangle_parent#@#Get parent control pointer
rectangle_parent#(rect#, parent#)rectangle_parent#@##Move rectangle to a different parent
rectangle_bringtofront#(rect#)rectangle_bringtofront#@#Bring to front of Z-order
rectangle_sendtoback#(rect#)rectangle_sendtoback#@#Send to back of Z-order
rectangle_invalidate#(rect#)rectangle_invalidate#@#Force the rectangle to redraw

Events

Each event has a setter (rectangle_onXXX#(rect#, func$)) and a getter (rectangle_onXXX$(rect#)). Use rectangle_clearcallbacks#(rect#) to disconnect all callbacks at once.

Mouse Events

Event SetterGetterCallback Signature
rectangle_onclick#(rect#, func$)rectangle_onclick$(rect#)function name(sender#)
rectangle_ondblclick#(rect#, func$)rectangle_ondblclick$(rect#)function name(sender#)
rectangle_onmousedown#(rect#, func$)rectangle_onmousedown$(rect#)function name(sender#, button, x, y, shift$)
rectangle_onmouseup#(rect#, func$)rectangle_onmouseup$(rect#)function name(sender#, button, x, y, shift$)
rectangle_onmousemove#(rect#, func$)rectangle_onmousemove$(rect#)function name(sender#, x, y, shift$)
rectangle_onmouseenter#(rect#, func$)rectangle_onmouseenter$(rect#)function name(sender#)
rectangle_onmouseleave#(rect#, func$)rectangle_onmouseleave$(rect#)function name(sender#)
rectangle_onmousewheel#(rect#, func$)rectangle_onmousewheel$(rect#)function name(sender#, delta)

Other Events

Event SetterGetterCallback Signature
rectangle_onresize#(rect#, func$)rectangle_onresize$(rect#)function name(sender#)
rectangle_clearcallbacks#(rect#)Disconnect all event callbacks

Complete Examples

Color Palette (Interactive)

╯ palette.bas
let frm# = form#("Color Palette", 400, 300)
form_position#(frm#, 4)

colors# = sdim#(6)
colors#$[1] = "#e74c3c" : colors#$[2] = "#3498db"
colors#$[3] = "#2ecc71" : colors#$[4] = "#f1c40f"
colors#$[5] = "#9b59b6" : colors#$[6] = "#1abc9c"

let x = 20
let y = 20
for i = 1 to 6
    let r# = rectangle#(frm#, x, y, 80, 80)
    rectangle_fill#(r#, colors#$[i])
    rectangle_stroke#(r#, "#333333")
    rectangle_strokethickness#(r#, 2)
    rectangle_corners#(r#, 8, 8)
    rectangle_tag#(r#, i)
    rectangle_hittest#(r#, 1)
    rectangle_onclick#(r#, "OnColorClick")
    x = x + 100
    if x > 300 then
        x = 20 : y = y + 100
    endif
next

let lblSel# = label#(frm#, "Click a color")
label_move#(lblSel#, 20, 230)

form_show(frm#)

function OnColorClick(sender#) local idx
    idx = rectangle_tag(sender#)
    label_text#(lblSel#, "Selected: " + colors#$[idx])
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Custom Progress Bar

╯ progress.bas
let frm# = form#("Loading", 300, 150)
form_position#(frm#, 4)

' Background bar
let bgRect# = rectangle#(frm#, 30, 50, 240, 30)
rectangle_fill#(bgRect#, "#ecf0f1")
rectangle_corners#(bgRect#, 5, 5)

' Foreground bar (grows)
let fgRect# = rectangle#(frm#, 30, 50, 0, 30)
rectangle_fill#(fgRect#, "#3498db")
rectangle_corners#(fgRect#, 5, 5)

let lblPct# = label#(frm#, "0%")
label_bounds#(lblPct#, 130, 90, 40, 20)
label_textalign#(lblPct#, 0)

let tmr# = timer#()
timer_interval#(tmr#, 50)
timer_ontimer#(tmr#, "OnTick")
timer_start#(tmr#)

form_show(frm#)

function OnTick(sender#) local w, pct
    w = rectangle_width(fgRect#) + 2
    if w > 240 then
        timer_stop#(tmr#)
        label_text#(lblPct#, "Done!")
    else
        rectangle_width#(fgRect#, w)
        pct = int(w / 240 * 100)
        label_text#(lblPct#, str$(pct) + "%")
    endif
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Interactive Hover Effect

╯ hover.bas
let frm# = form#("Hover Demo", 350, 200)
form_position#(frm#, 4)

let rect# = rectangle#(frm#, 100, 50, 150, 100)
rectangle_fill#(rect#, "#3498db")
rectangle_stroke#(rect#, "#2980b9")
rectangle_strokethickness#(rect#, 2)
rectangle_corners#(rect#, 10, 10)
rectangle_hittest#(rect#, 1)
rectangle_onmouseenter#(rect#, "OnEnter")
rectangle_onmouseleave#(rect#, "OnLeave")

let lbl# = label#(frm#, "Hover over the rectangle")
label_move#(lbl#, 80, 170)

form_show(frm#)

function OnEnter(sender#)
    rectangle_fill#(sender#, "#2980b9")
    rectangle_strokethickness#(sender#, 4)
endfunction

function OnLeave(sender#)
    rectangle_fill#(sender#, "#3498db")
    rectangle_strokethickness#(sender#, 2)
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Checkerboard Pattern

╯ checkerboard.bas
let frm# = form#("Checkerboard", 340, 340)
form_position#(frm#, 4)

let size = 40
for row = 0 to 7
    for col = 0 to 7
        let r# = rectangle#(frm#, col * size + 10, row * size + 10, size, size)
        rectangle_strokenone#(r#)
        if (row + col) mod 2 = 0 then
            rectangle_fill#(r#, "#8B4513")
        else
            rectangle_fill#(r#, "#DEB887")
        endif
    next
next

form_show(frm#)

while form_visible(frm#) = 1
    processmessages()
end while

Border Styles Demo

╯ borders.bas
let frm# = form#("Border Styles", 450, 200)
form_position#(frm#, 4)

for i = 0 to 3
    let r# = rectangle#(frm#, 20 + i * 100, 50, 80, 60)
    rectangle_fill#(r#, "#FFFFFF")
    rectangle_stroke#(r#, "#333333")
    rectangle_strokethickness#(r#, 2)
    rectangle_strokedash#(r#, i)
next

form_show(frm#)

while form_visible(frm#) = 1
    processmessages()
end while

Best Practices

PracticeWhy
Set hittest = 1 for interactive rectanglesRequired for mouse events to fire on shapes
Use rectangle_corners# for rounded lookShortcut to set both xradius and yradius at once
Combine corners# + cornersflags#Enables tab headers, cards, and other partial-rounding effects
Use rectangle_sides# for partial bordersDraw only specific sides (e.g., bottom-only underline effect)
Use fillnone# for outline-only shapesTransparent body, visible border only
Use strokenone# for borderless fillsSolid color blocks without borders
Use #AARRGGBB for semi-transparent fillsOverlay effects without fully obscuring content
Use rectangle_rotation# for rotated shapesDegrees; rotates around the center of the rectangle
Use tag for shared callbacksDistinguish multiple rectangles with rectangle_tag(sender#)

Quick Reference

FunctionSignatureDescription
rectangle_error / errormsg$ / strerror$ / clearerrorvariousError handling (4)
rectangle#(parent#[, w, h] | [, x, y, w, h])variousCreate (3 overloads)
rectangle_free(rect#)rectangle_free@#Destroy
rectangle_fill$ / fill# / fillnone#variousFill (3)
rectangle_stroke$ / stroke# / strokenone# / strokethickness / strokedash / strokecap / strokejoinvariousStroke (11)
rectangle_xradius / yradius / corners#variousCorner radius (5)
rectangle_sides / cornersflags (get/set)variousSide & corner bitmasks (4)
rectangle_x/y/width/height (get/set) / bounds# / move# / size#variousPosition & size (14)
rectangle_align / margin# / margins# / margin[left/top/right/bottom]variousAlignment & margins (12)
rectangle_visible / enabled / opacity / hittestvariousVisibility & state (8)
rectangle_tag / rotation / parent# / bringtofront# / sendtoback# / invalidate#variousTag, rotation & parent (8)
rectangle_onclick/ondblclick/onmousedown/up/move/enter/leave/onmousewheel/onresizevariousEvents set+get (18)
rectangle_clearcallbacks#rectangle_clearcallbacks#@#Disconnect all events

90 functions. Part of the Plan9Basic GUI shape library system.