RoundRectLib — Rounded Rectangle Shape Library

Rounded rectangles with a single, uniform corner radius for all four corners. Simpler than RectangleLib (which offers separate X/Y radii and per-corner/per-side bitmasks), RoundRectLib is ideal for cards, pill badges, toggle tracks, modern UI containers, and any shape that needs evenly rounded corners. 83 functions.

CategoryCountDescription
Error Handling4roundrect_error, errormsg$, strerror$, clearerror
Creation & Destruction4roundrect# (3 overloads), roundrect_free
Corner Radius2corners (get/set) — single value for all corners
Fill3fill$ (get), fill# (set), fillnone#
Stroke11stroke$ / stroke# / strokenone#, thickness, dash, cap, join (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 & 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
roundrect_error()roundrect_error@Last error code (0 = no error)
roundrect_errormsg$()roundrect_errormsg$@Last error message as string
roundrect_strerror$(code)roundrect_strerror$@nDescription for a given error code
roundrect_clearerror()roundrect_clearerror@Clear the error state

Numeric Values Reference

Control Alignment roundrect_align#

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

Stroke Dash Style roundrect_strokedash#

ValueStyle
0Solid
1Dash
2Dot
3DashDot
4DashDotDot

Stroke Cap Style roundrect_strokecap#

ValueStyle
0Flat
1Round

Stroke Join Style roundrect_strokejoin#

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

Creation & Destruction

FunctionSignatureDescription
roundrect#(parent#)roundrect#@#Create with default size
roundrect#(parent#, w, h)roundrect#@#nnCreate with specified size
roundrect#(parent#, x, y, w, h)roundrect#@#nnnnCreate with position and size
roundrect_free(rr#)roundrect_free@#Destroy rounded rectangle
╯ plan9basic
let rr# = roundrect#(frm#, 50, 50, 150, 100)
roundrect_fill#(rr#, "#9b59b6")
roundrect_stroke#(rr#, "#8e44ad")
roundrect_strokethickness#(rr#, 2)
roundrect_corners#(rr#, 15)

Corner Radius

FunctionSignatureDescription
roundrect_corners(rr#)roundrect_corners@#Get corner radius
roundrect_corners#(rr#, radius)roundrect_corners#@#nSet corner radius (uniform for all four corners)
╯ plan9basic
' Slightly rounded
roundrect_corners#(rr#, 5)

' Moderately rounded
roundrect_corners#(rr#, 15)

' Pill shape (radius = half the height)
' For a 40px-tall shape: radius 20
roundrect_corners#(rr#, 20)

' Sharp corners (no rounding)
roundrect_corners#(rr#, 0)
ⓘ Note: Pill shape: Set the corner radius to half the height. For example, a shape that is 40 pixels tall becomes a pill with roundrect_corners#(rr#, 20).
ⓘ Note: Unlike RectangleLib, which has separate X/Y radii and per-corner bitmasks, RoundRectLib applies a single radius to all four corners. Use RectangleLib when you need different corners rounded differently.

Fill Properties

FunctionSignatureDescription
roundrect_fill$(rr#)roundrect_fill$@#Get fill color as hex string
roundrect_fill#(rr#, color$)roundrect_fill#@#$Set fill color ("#RRGGBB" or "#AARRGGBB")
roundrect_fillnone#(rr#)roundrect_fillnone#@#Remove fill (fully transparent body)
ⓘ Note: Use #AARRGGBB format for semi-transparent fills. Alpha ranges from 00 (transparent) to FF (opaque).

Stroke Properties

FunctionSignatureDescription
roundrect_stroke$(rr#)roundrect_stroke$@#Get stroke color
roundrect_stroke#(rr#, color$)roundrect_stroke#@#$Set stroke color
roundrect_strokenone#(rr#)roundrect_strokenone#@#Remove stroke (no border)
roundrect_strokethickness(rr#)roundrect_strokethickness@#Get stroke thickness
roundrect_strokethickness#(rr#, n)roundrect_strokethickness#@#nSet stroke thickness
roundrect_strokedash(rr#)roundrect_strokedash@#Get dash style (0–4)
roundrect_strokedash#(rr#, n)roundrect_strokedash#@#nSet dash style
roundrect_strokecap(rr#)roundrect_strokecap@#Get cap style (0=Flat, 1=Round)
roundrect_strokecap#(rr#, n)roundrect_strokecap#@#nSet cap style
roundrect_strokejoin(rr#)roundrect_strokejoin@#Get join style (0=Miter, 1=Round, 2=Bevel)
roundrect_strokejoin#(rr#, n)roundrect_strokejoin#@#nSet join style

Position & Size

FunctionSignatureDescription
roundrect_x(rr#)roundrect_x@#Get X position
roundrect_x#(rr#, x)roundrect_x#@#nSet X position
roundrect_y(rr#)roundrect_y@#Get Y position
roundrect_y#(rr#, y)roundrect_y#@#nSet Y position
roundrect_width(rr#)roundrect_width@#Get width
roundrect_width#(rr#, w)roundrect_width#@#nSet width
roundrect_height(rr#)roundrect_height@#Get height
roundrect_height#(rr#, h)roundrect_height#@#nSet height
roundrect_bounds#(rr#, x, y, w, h)roundrect_bounds#@#nnnnSet position and size
roundrect_move#(rr#, x, y)roundrect_move#@#nnSet position only
roundrect_size#(rr#, w, h)roundrect_size#@#nnSet size only

Alignment & Margins

FunctionSignatureDescription
roundrect_align(rr#)roundrect_align@#Get alignment
roundrect_align#(rr#, n)roundrect_align#@#nSet alignment
roundrect_margin#(rr#, n)roundrect_margin#@#nSet uniform margin on all four sides
roundrect_margins#(rr#, l, t, r, b)roundrect_margins#@#nnnnSet individual margins
roundrect_marginleft(rr#)roundrect_marginleft@#Get left margin
roundrect_marginleft#(rr#, n)roundrect_marginleft#@#nSet left margin
roundrect_margintop(rr#)roundrect_margintop@#Get top margin
roundrect_margintop#(rr#, n)roundrect_margintop#@#nSet top margin
roundrect_marginright(rr#)roundrect_marginright@#Get right margin
roundrect_marginright#(rr#, n)roundrect_marginright#@#nSet right margin
roundrect_marginbottom(rr#)roundrect_marginbottom@#Get bottom margin
roundrect_marginbottom#(rr#, n)roundrect_marginbottom#@#nSet bottom margin

Visibility & State

FunctionSignatureDescription
roundrect_visible(rr#)roundrect_visible@#Get visibility (0/1)
roundrect_visible#(rr#, n)roundrect_visible#@#nSet visibility
roundrect_enabled(rr#)roundrect_enabled@#Get enabled state (0/1)
roundrect_enabled#(rr#, n)roundrect_enabled#@#nSet enabled state
roundrect_opacity(rr#)roundrect_opacity@#Get opacity (0.0–1.0)
roundrect_opacity#(rr#, n)roundrect_opacity#@#nSet opacity
roundrect_hittest(rr#)roundrect_hittest@#Get hit-test state (0/1)
roundrect_hittest#(rr#, n)roundrect_hittest#@#nEnable/disable mouse hit testing
⚠ Warning: Set roundrect_hittest#(rr#, 1) before assigning mouse event handlers. Without hit testing, the shape will not receive mouse events.

Tag, Rotation & Parent

FunctionSignatureDescription
roundrect_tag(rr#)roundrect_tag@#Get user-defined integer tag
roundrect_tag#(rr#, n)roundrect_tag#@#nSet user-defined integer tag
roundrect_rotation(rr#)roundrect_rotation@#Get rotation angle in degrees
roundrect_rotation#(rr#, angle)roundrect_rotation#@#nSet rotation angle
roundrect_parent#(rr#)roundrect_parent#@#Get parent control pointer
roundrect_parent#(rr#, parent#)roundrect_parent#@##Move to a different parent
roundrect_bringtofront#(rr#)roundrect_bringtofront#@#Bring to front of Z-order
roundrect_sendtoback#(rr#)roundrect_sendtoback#@#Send to back of Z-order
roundrect_invalidate#(rr#)roundrect_invalidate#@#Force the shape to redraw

Events

Each event has a setter (roundrect_onXXX#) and a getter (roundrect_onXXX$). Use roundrect_clearcallbacks#(rr#) to disconnect all callbacks at once.

Mouse Events

Event SetterGetterCallback Signature
roundrect_onclick#(rr#, func$)roundrect_onclick$(rr#)function name(sender#)
roundrect_ondblclick#(rr#, func$)roundrect_ondblclick$(rr#)function name(sender#)
roundrect_onmousedown#(rr#, func$)roundrect_onmousedown$(rr#)function name(sender#, button, x, y, shift$)
roundrect_onmouseup#(rr#, func$)roundrect_onmouseup$(rr#)function name(sender#, button, x, y, shift$)
roundrect_onmousemove#(rr#, func$)roundrect_onmousemove$(rr#)function name(sender#, x, y, shift$)
roundrect_onmouseenter#(rr#, func$)roundrect_onmouseenter$(rr#)function name(sender#)
roundrect_onmouseleave#(rr#, func$)roundrect_onmouseleave$(rr#)function name(sender#)
roundrect_onmousewheel#(rr#, func$)roundrect_onmousewheel$(rr#)function name(sender#, delta)

Other Events

Event SetterGetterCallback Signature
roundrect_onresize#(rr#, func$)roundrect_onresize$(rr#)function name(sender#)
roundrect_clearcallbacks#(rr#)Disconnect all event callbacks

RoundRect vs Rectangle

FeatureRoundRectRectangle
Corner radiusSingle value (all corners uniform)Separate X and Y radii
Per-corner control❌ All corners same✅ Bitmask selects which corners are rounded
Per-side control❌ All sides drawn✅ Bitmask selects which sides are drawn
Corner functionscorners#(rr#, r) — 1 parametercorners#(rect#, rx, ry) — 2 parameters
Function count8390 (extra: sides, cornersflags, xradius, yradius)
Best forCards, pills, badges, toggles, simple UITab headers, partial borders, complex shapes
ⓘ Note: Choose RoundRectLib when all corners should be rounded equally. Choose RectangleLib when you need different radii per axis, selective corner rounding, or partial borders.

Complete Examples

Interactive Cards

╯ cards.bas
let frm# = form#("Cards", 450, 200)
form_position#(frm#, 4)

' Card 1
let card1# = roundrect#(frm#, 20, 30, 120, 80)
roundrect_fill#(card1#, "#3498db")
roundrect_corners#(card1#, 10)
roundrect_strokenone#(card1#)
roundrect_hittest#(card1#, 1)
roundrect_tag#(card1#, 1)
roundrect_onclick#(card1#, "OnCardClick")
roundrect_onmouseenter#(card1#, "OnCardEnter")
roundrect_onmouseleave#(card1#, "OnCardLeave")

let lbl1# = label#(frm#, "Option A")
label_bounds#(lbl1#, 20, 60, 120, 20)
label_textalign#(lbl1#, 0)
label_fontcolor#(lbl1#, "#FFFFFF")

' Card 2
let card2# = roundrect#(frm#, 160, 30, 120, 80)
roundrect_fill#(card2#, "#2ecc71")
roundrect_corners#(card2#, 10)
roundrect_strokenone#(card2#)
roundrect_hittest#(card2#, 1)
roundrect_tag#(card2#, 2)
roundrect_onclick#(card2#, "OnCardClick")
roundrect_onmouseenter#(card2#, "OnCardEnter")
roundrect_onmouseleave#(card2#, "OnCardLeave")

let lbl2# = label#(frm#, "Option B")
label_bounds#(lbl2#, 160, 60, 120, 20)
label_textalign#(lbl2#, 0)
label_fontcolor#(lbl2#, "#FFFFFF")

' Card 3
let card3# = roundrect#(frm#, 300, 30, 120, 80)
roundrect_fill#(card3#, "#e74c3c")
roundrect_corners#(card3#, 10)
roundrect_strokenone#(card3#)
roundrect_hittest#(card3#, 1)
roundrect_tag#(card3#, 3)
roundrect_onclick#(card3#, "OnCardClick")
roundrect_onmouseenter#(card3#, "OnCardEnter")
roundrect_onmouseleave#(card3#, "OnCardLeave")

let lbl3# = label#(frm#, "Option C")
label_bounds#(lbl3#, 300, 60, 120, 20)
label_textalign#(lbl3#, 0)
label_fontcolor#(lbl3#, "#FFFFFF")

let lblStatus# = label#(frm#, "Click a card")
label_move#(lblStatus#, 20, 140)

form_show(frm#)

function OnCardClick(sender#)
    label_text#(lblStatus#, "Selected card: " + str$(roundrect_tag(sender#)))
endfunction

function OnCardEnter(sender#)
    roundrect_opacity#(sender#, 0.8)
endfunction

function OnCardLeave(sender#)
    roundrect_opacity#(sender#, 1.0)
endfunction

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

Pill Badges

╯ badges.bas
let frm# = form#("Badges", 400, 150)
form_position#(frm#, 4)

' Success badge
let b1# = roundrect#(frm#, 20, 30, 80, 30)
roundrect_fill#(b1#, "#27ae60")
roundrect_corners#(b1#, 15)
roundrect_strokenone#(b1#)

let t1# = label#(frm#, "Success")
label_bounds#(t1#, 20, 35, 80, 20)
label_textalign#(t1#, 0)
label_fontcolor#(t1#, "#FFFFFF")

' Warning badge
let b2# = roundrect#(frm#, 120, 30, 80, 30)
roundrect_fill#(b2#, "#f39c12")
roundrect_corners#(b2#, 15)
roundrect_strokenone#(b2#)

let t2# = label#(frm#, "Warning")
label_bounds#(t2#, 120, 35, 80, 20)
label_textalign#(t2#, 0)
label_fontcolor#(t2#, "#FFFFFF")

' Error badge
let b3# = roundrect#(frm#, 220, 30, 80, 30)
roundrect_fill#(b3#, "#c0392b")
roundrect_corners#(b3#, 15)
roundrect_strokenone#(b3#)

let t3# = label#(frm#, "Error")
label_bounds#(t3#, 220, 35, 80, 20)
label_textalign#(t3#, 0)
label_fontcolor#(t3#, "#FFFFFF")

' Info badge
let b4# = roundrect#(frm#, 320, 30, 60, 30)
roundrect_fill#(b4#, "#2980b9")
roundrect_corners#(b4#, 15)
roundrect_strokenone#(b4#)

let t4# = label#(frm#, "Info")
label_bounds#(t4#, 320, 35, 60, 20)
label_textalign#(t4#, 0)
label_fontcolor#(t4#, "#FFFFFF")

form_show(frm#)

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

Toggle Switch

╯ toggle.bas
let frm# = form#("Toggle", 200, 120)
form_position#(frm#, 4)

let isOn = 0

' Track (background)
let track# = roundrect#(frm#, 60, 40, 80, 40)
roundrect_corners#(track#, 20)
roundrect_fill#(track#, "#bdc3c7")
roundrect_strokenone#(track#)
roundrect_hittest#(track#, 1)
roundrect_onclick#(track#, "OnToggle")

' Thumb (knob)
let thumb# = roundrect#(frm#, 62, 42, 36, 36)
roundrect_corners#(thumb#, 18)
roundrect_fill#(thumb#, "#FFFFFF")
roundrect_stroke#(thumb#, "#95a5a6")
roundrect_strokethickness#(thumb#, 1)

form_show(frm#)

function OnToggle(sender#)
    if isOn = 0 then
        isOn = 1
        roundrect_fill#(track#, "#27ae60")
        roundrect_x#(thumb#, 102)
    else
        isOn = 0
        roundrect_fill#(track#, "#bdc3c7")
        roundrect_x#(thumb#, 62)
    endif
endfunction

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

Notification Toast

╯ toast.bas
let frm# = form#("Toast Demo", 400, 250)
form_position#(frm#, 4)

' Toast background
let toast# = roundrect#(frm#, 50, 180, 300, 50)
roundrect_fill#(toast#, "#2c3e50")
roundrect_corners#(toast#, 8)
roundrect_strokenone#(toast#)
roundrect_opacity#(toast#, 0.0)

let lblToast# = label#(frm#, "File saved successfully!")
label_bounds#(lblToast#, 50, 195, 300, 20)
label_textalign#(lblToast#, 0)
label_fontcolor#(lblToast#, "#FFFFFF")
label_visible#(lblToast#, 0)

let btnShow# = button#(frm#, "Show Toast")
button_bounds#(btnShow#, 140, 80, 120, 35)
button_onclick#(btnShow#, "OnShowToast")

let fadeStep = 0

let tmr# = timer#()
timer_interval#(tmr#, 30)
timer_ontimer#(tmr#, "OnFade")

form_show(frm#)

function OnShowToast(sender#)
    fadeStep = 1
    roundrect_opacity#(toast#, 0.0)
    label_visible#(lblToast#, 1)
    timer_start#(tmr#)
endfunction

function OnFade(sender#) local op
    op = roundrect_opacity(toast#)
    if fadeStep = 1 then
        ' Fade in
        op = op + 0.1
        if op >= 0.9 then
            op = 0.9
            fadeStep = 2
        endif
    elseif fadeStep = 2 then
        ' Fade out
        op = op - 0.05
        if op <= 0 then
            op = 0
            fadeStep = 0
            label_visible#(lblToast#, 0)
            timer_stop#(tmr#)
        endif
    endif
    roundrect_opacity#(toast#, op)
endfunction

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

Best Practices

PracticeWhy
Set hittest = 1 for interactive shapesRequired for mouse events to fire
Use half-height radius for pill shapesroundrect_corners#(rr#, height/2) creates a perfect pill
Use roundrect_strokenone# for modern cardsBorderless fills look cleaner for card UIs
Use opacity for hover feedbackChange opacity on mouse enter/leave for subtle interaction cues
Overlay labels for button-like elementsPosition a label on top of a RoundRect for custom-styled buttons
Use tag for shared callbacksDistinguish multiple shapes with roundrect_tag(sender#)
Choose RoundRect over Rectangle for simple cornersFewer parameters, cleaner API when all corners are uniform

Quick Reference

FunctionSignatureDescription
roundrect_error / errormsg$ / strerror$ / clearerrorvariousError handling (4)
roundrect#(parent#[, w, h] | [, x, y, w, h])variousCreate (3 overloads)
roundrect_free(rr#)roundrect_free@#Destroy
roundrect_corners (get/set)variousCorner radius (2)
roundrect_fill$ / fill# / fillnone#variousFill (3)
roundrect_stroke$ / stroke# / strokenone# / strokethickness / strokedash / strokecap / strokejoinvariousStroke (11)
roundrect_x/y/width/height (get/set) / bounds# / move# / size#variousPosition & size (14)
roundrect_align / margin# / margins# / margin[left/top/right/bottom]variousAlignment & margins (12)
roundrect_visible / enabled / opacity / hittestvariousVisibility & state (8)
roundrect_tag / rotation / parent# / bringtofront# / sendtoback# / invalidate#variousTag, rotation & parent (8)
roundrect_onclick/ondblclick/onmousedown/up/move/enter/leave/onmousewheel/onresizevariousEvents set+get (18)
roundrect_clearcallbacks#roundrect_clearcallbacks#@#Disconnect all events

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