ProgressBarLib — Progress Bar Control Library
Progress bar controls for displaying task completion, download progress, or any value within a defined range. Supports both horizontal and vertical orientations, configurable min/max ranges, timer-driven animation, and a full mouse/drag event system. 79 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | progressbar_error, errormsg$, strerror$, clearerror |
| Creation & Destruction | 3 | progressbar# (2 overloads), progressbar_free |
| Value Properties | 6 | value, min, max (get/set) |
| Orientation | 2 | orientation (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 | 10 | visible, enabled, opacity, hittest, dragmode (get/set) |
| Tag & Parent | 6 | tag (get/set), parent# (get/set), bringtofront#, sendtoback# |
| Events | 22 | 10 event types × set/get + clearcallbacks# |
Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | Win32/Win64 — native progress bar style |
| Linux | ✅ Full Support | GTK-based |
| Android | ✅ Full Support | Material-style progress |
Error Handling
| Function | Signature | Description |
|---|---|---|
progressbar_error() | progressbar_error@ | Last error code (0 = no error) |
progressbar_errormsg$() | progressbar_errormsg$@ | Last error message as string |
progressbar_strerror$(code) | progressbar_strerror$@n | Description for a given error code |
progressbar_clearerror() | progressbar_clearerror@ | Clear the error state |
Numeric Values Reference
Control Alignment progressbar_align#
| Value | Description |
|---|---|
| 0 | None (absolute positioning) |
| 1 | Top |
| 2 | Left |
| 3 | Right |
| 4 | Bottom |
| 9 | Client (fill parent) |
Orientation progressbar_orientation#
| Value | Description | Typical Size |
|---|---|---|
| 0 | Horizontal (default) | Wide × short (e.g., 300 × 25) |
| 1 | Vertical | Narrow × tall (e.g., 30 × 150) |
Drag Mode progressbar_dragmode#
| Value | Description |
|---|---|
| 0 | None (default) |
| 1 | Automatic drag enabled |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
progressbar#(parent#) | progressbar#@# | Create progress bar with default size |
progressbar#(parent#, x, y, w, h) | progressbar#@#nnnn | Create with position and size |
progressbar_free(pb#) | progressbar_free@# | Destroy progress bar and release resources |
let pb# = progressbar#(frm#, 20, 50, 360, 25) progressbar_min#(pb#, 0) progressbar_max#(pb#, 100) progressbar_value#(pb#, 0)
Value Properties
| Function | Signature | Description |
|---|---|---|
progressbar_value(pb#) | progressbar_value@# | Get current value |
progressbar_value#(pb#, n) | progressbar_value#@#n | Set current value |
progressbar_min(pb#) | progressbar_min@# | Get minimum value |
progressbar_min#(pb#, n) | progressbar_min#@#n | Set minimum value |
progressbar_max(pb#) | progressbar_max@# | Get maximum value |
progressbar_max#(pb#, n) | progressbar_max#@#n | Set maximum value |
' Standard 0-100 percentage range progressbar_min#(pb#, 0) progressbar_max#(pb#, 100) progressbar_value#(pb#, 50) ' 50% ' Custom range (e.g., steps in a process) progressbar_min#(pb#, 0) progressbar_max#(pb#, 4) ' 4 steps progressbar_value#(pb#, 2) ' Step 2 of 4 ' Read current progress let pct = progressbar_value(pb#) println str$(pct) + "%"
⚠ Warning: Always set
min and max before setting value. Setting a value outside the min/max range may produce unexpected results.ⓘ Note: The progress bar displays a filled portion proportional to
(value − min) / (max − min). For percentage-based progress, use min=0 and max=100.Orientation
| Function | Signature | Description |
|---|---|---|
progressbar_orientation(pb#) | progressbar_orientation@# | Get orientation (0=horizontal, 1=vertical) |
progressbar_orientation#(pb#, n) | progressbar_orientation#@#n | Set orientation |
' Horizontal (default) - wide and short let pbH# = progressbar#(frm#, 20, 30, 300, 25) progressbar_orientation#(pbH#, 0) ' Vertical - narrow and tall let pbV# = progressbar#(frm#, 20, 30, 30, 150) progressbar_orientation#(pbV#, 1)
ⓘ Note: When switching to vertical orientation, consider swapping the width and height values. A horizontal bar of 300×25 becomes a vertical bar of 30×150.
Position & Size
| Function | Signature | Description |
|---|---|---|
progressbar_x(pb#) | progressbar_x@# | Get X position |
progressbar_x#(pb#, x) | progressbar_x#@#n | Set X position |
progressbar_y(pb#) | progressbar_y@# | Get Y position |
progressbar_y#(pb#, y) | progressbar_y#@#n | Set Y position |
progressbar_width(pb#) | progressbar_width@# | Get width |
progressbar_width#(pb#, w) | progressbar_width#@#n | Set width |
progressbar_height(pb#) | progressbar_height@# | Get height |
progressbar_height#(pb#, h) | progressbar_height#@#n | Set height |
progressbar_bounds#(pb#, x, y, w, h) | progressbar_bounds#@#nnnn | Set position and size in one call |
progressbar_move#(pb#, x, y) | progressbar_move#@#nn | Set position only |
progressbar_size#(pb#, w, h) | progressbar_size#@#nn | Set size only |
Alignment & Margins
| Function | Signature | Description |
|---|---|---|
progressbar_align(pb#) | progressbar_align@# | Get control alignment |
progressbar_align#(pb#, n) | progressbar_align#@#n | Set alignment |
progressbar_margin#(pb#, n) | progressbar_margin#@#n | Set uniform margin on all four sides |
progressbar_margins#(pb#, l, t, r, b) | progressbar_margins#@#nnnn | Set individual margins |
progressbar_marginleft(pb#) | progressbar_marginleft@# | Get left margin |
progressbar_marginleft#(pb#, n) | progressbar_marginleft#@#n | Set left margin |
progressbar_margintop(pb#) | progressbar_margintop@# | Get top margin |
progressbar_margintop#(pb#, n) | progressbar_margintop#@#n | Set top margin |
progressbar_marginright(pb#) | progressbar_marginright@# | Get right margin |
progressbar_marginright#(pb#, n) | progressbar_marginright#@#n | Set right margin |
progressbar_marginbottom(pb#) | progressbar_marginbottom@# | Get bottom margin |
progressbar_marginbottom#(pb#, n) | progressbar_marginbottom#@#n | Set bottom margin |
' Full-width progress bar docked to bottom let pb# = progressbar#(frm#) progressbar_align#(pb#, 4) ' Bottom progressbar_height#(pb#, 8) ' Thin bar progressbar_margin#(pb#, 5) ' 5px gap all sides
Visibility & State
| Function | Signature | Description |
|---|---|---|
progressbar_visible(pb#) | progressbar_visible@# | Get visibility (0/1) |
progressbar_visible#(pb#, n) | progressbar_visible#@#n | Set visibility |
progressbar_enabled(pb#) | progressbar_enabled@# | Get enabled state (0/1) |
progressbar_enabled#(pb#, n) | progressbar_enabled#@#n | Set enabled state |
progressbar_opacity(pb#) | progressbar_opacity@# | Get opacity (0.0–1.0) |
progressbar_opacity#(pb#, value) | progressbar_opacity#@#n | Set opacity |
progressbar_hittest(pb#) | progressbar_hittest@# | Get hit-test state (0/1) |
progressbar_hittest#(pb#, n) | progressbar_hittest#@#n | Enable/disable mouse hit testing |
progressbar_dragmode(pb#) | progressbar_dragmode@# | Get drag mode (0=none, 1=auto) |
progressbar_dragmode#(pb#, n) | progressbar_dragmode#@#n | Set drag mode |
' Show progress bar only during operation progressbar_visible#(pb#, 0) ' Hidden initially ' When task starts progressbar_visible#(pb#, 1) ' Show progressbar_value#(pb#, 0) ' When task ends progressbar_visible#(pb#, 0) ' Hide again
Tag & Parent
| Function | Signature | Description |
|---|---|---|
progressbar_tag(pb#) | progressbar_tag@# | Get user-defined integer tag |
progressbar_tag#(pb#, n) | progressbar_tag#@#n | Set user-defined integer tag |
progressbar_parent#(pb#) | progressbar_parent#@# | Get parent control pointer |
progressbar_parent#(pb#, parent#) | progressbar_parent#@## | Move progress bar to a different parent |
progressbar_bringtofront#(pb#) | progressbar_bringtofront#@# | Bring to front of Z-order |
progressbar_sendtoback#(pb#) | progressbar_sendtoback#@# | Send to back of Z-order |
Events
Each event has a setter (progressbar_onXXX#(pb#, func$)) and a getter (progressbar_onXXX$(pb#)). Use progressbar_clearcallbacks#(pb#) to disconnect all callbacks at once.
Mouse Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
progressbar_onclick#(pb#, func$) | progressbar_onclick$(pb#) | function name(sender#) |
progressbar_ondblclick#(pb#, func$) | progressbar_ondblclick$(pb#) | function name(sender#) |
progressbar_onmousedown#(pb#, func$) | progressbar_onmousedown$(pb#) | function name(sender#, button, x, y, shift$) |
progressbar_onmouseup#(pb#, func$) | progressbar_onmouseup$(pb#) | function name(sender#, button, x, y, shift$) |
progressbar_onmousemove#(pb#, func$) | progressbar_onmousemove$(pb#) | function name(sender#, x, y, shift$) |
progressbar_onmouseenter#(pb#, func$) | progressbar_onmouseenter$(pb#) | function name(sender#) |
progressbar_onmouseleave#(pb#, func$) | progressbar_onmouseleave$(pb#) | function name(sender#) |
progressbar_onresize#(pb#, func$) | progressbar_onresize$(pb#) | function name(sender#) |
Drag Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
progressbar_ondragenter#(pb#, func$) | progressbar_ondragenter$(pb#) | function name(sender#) |
progressbar_ondragover#(pb#, func$) | progressbar_ondragover$(pb#) | function name(sender#) |
progressbar_ondragdrop#(pb#, func$) | progressbar_ondragdrop$(pb#) | function name(sender#) |
progressbar_ondragleave#(pb#, func$) | progressbar_ondragleave$(pb#) | function name(sender#) |
progressbar_clearcallbacks#(pb#) | — | Disconnect all event callbacks |
Timer-Driven Animation Pattern
Progress bars are almost always updated using a Timer. Blocking the UI thread with a loop prevents the progress bar from repainting. The standard pattern is:
| Step | Action | Code |
|---|---|---|
| 1 | Create timer with interval | timer_interval#(tmr#, 50) |
| 2 | Start timer when task begins | timer_start#(tmr#) |
| 3 | Increment value in OnTimer | progressbar_value#(pb#, val + 1) |
| 4 | Stop timer when complete | timer_stop#(tmr#) |
' Standard timer-driven progress pattern let tmr# = timer#() timer_interval#(tmr#, 50) timer_ontimer#(tmr#, "OnTick") function OnStart(sender#) progressbar_value#(pb#, 0) button_enabled#(btnStart#, 0) timer_start#(tmr#) endfunction function OnTick(sender#) local val val = progressbar_value(pb#) + 1 progressbar_value#(pb#, val) label_text#(lblPct#, str$(val) + "%") if val >= progressbar_max(pb#) then timer_stop#(tmr#) button_enabled#(btnStart#, 1) endif endfunction
⚠ Warning: Never use a blocking loop (
for i = 0 to 100 ... next) to animate a progress bar. The UI will freeze and the bar won't update visually. Always use a Timer for smooth animation.ⓘ Note: Timer intervals between 30–100 ms provide smooth animation. Faster intervals (30 ms) give smoother visuals; slower intervals (100 ms) use less CPU.
Complete Examples
File Download Simulation
function OnDownload(sender#) progressbar_value#(pb#, 0) button_enabled#(btnDownload#, 0) timer_start#(tmr#) endfunction function OnProgress(sender#) local val, pct$ val = progressbar_value(pb#) + rnd(5) + 1 if val > 100 then val = 100 progressbar_value#(pb#, val) pct$ = str$(int(val)) + "%" label_text#(lblPercent#, pct$) if val >= 100 then timer_stop#(tmr#) label_text#(lblFile#, "Download complete!") button_enabled#(btnDownload#, 1) endif endfunction let frm# = form#("Download Progress", 450, 180) form_position#(frm#, 4) let lblFile# = label#(frm#, "Downloading: large_file.zip") label_move#(lblFile#, 20, 20) let pb# = progressbar#(frm#, 20, 50, 410, 25) progressbar_max#(pb#, 100) let lblPercent# = label#(frm#, "0%") label_move#(lblPercent#, 200, 85) let btnDownload# = button#(frm#, "Start Download", 160, 120, 130, 35) button_onclick#(btnDownload#, "OnDownload") let tmr# = timer#() timer_interval#(tmr#, 100) timer_ontimer#(tmr#, "OnProgress") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Multi-Step Installation
function OnInstall(sender#) button_enabled#(btnInstall#, 0) label_text#(lblStep#, "Step 1: Copying files...") progressbar_value#(pb#, 1) pause(1) label_text#(lblStep#, "Step 2: Configuring...") progressbar_value#(pb#, 2) pause(1) label_text#(lblStep#, "Step 3: Installing components...") progressbar_value#(pb#, 3) pause(1) label_text#(lblStep#, "Step 4: Finalizing...") progressbar_value#(pb#, 4) pause(1) label_text#(lblStep#, "Installation complete!") button_text#(btnInstall#, "Close") button_enabled#(btnInstall#, 1) endfunction let frm# = form#("Installation", 400, 200) form_position#(frm#, 4) let lblStep# = label#(frm#, "Ready to install") label_move#(lblStep#, 20, 20) let pb# = progressbar#(frm#, 20, 55, 360, 20) progressbar_max#(pb#, 4) let btnInstall# = button#(frm#, "Install", 150, 100, 100, 35) button_onclick#(btnInstall#, "OnInstall") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Vertical Level Meters
let frm# = form#("Levels", 300, 250) form_position#(frm#, 4) ' CPU meter let pb1# = progressbar#(frm#, 50, 30, 30, 150) progressbar_orientation#(pb1#, 1) progressbar_max#(pb1#, 100) progressbar_value#(pb1#, 75) ' Memory meter let pb2# = progressbar#(frm#, 120, 30, 30, 150) progressbar_orientation#(pb2#, 1) progressbar_max#(pb2#, 100) progressbar_value#(pb2#, 50) ' Disk meter let pb3# = progressbar#(frm#, 190, 30, 30, 150) progressbar_orientation#(pb3#, 1) progressbar_max#(pb3#, 100) progressbar_value#(pb3#, 25) label#(frm#, "CPU", 50, 190) label#(frm#, "MEM", 117, 190) label#(frm#, "DISK", 183, 190) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Progress with Percentage Label
function OnRun(sender#) progressbar_value#(pb#, 0) timer_start#(tmr#) endfunction function OnTick(sender#) local val val = progressbar_value(pb#) + 1 progressbar_value#(pb#, val) label_text#(lblPct#, str$(val) + "%") if val >= 100 then timer_stop#(tmr#) endfunction let frm# = form#("Task Progress", 400, 150) form_position#(frm#, 4) let pb# = progressbar#(frm#, 20, 30, 360, 25) progressbar_max#(pb#, 100) let lblPct# = label#(frm#, "0%") label_bounds#(lblPct#, 180, 65, 40, 20) label_textalign#(lblPct#, 0) let btnRun# = button#(frm#, "Run Task", 150, 95, 100, 35) button_onclick#(btnRun#, "OnRun") let tmr# = timer#() timer_interval#(tmr#, 30) timer_ontimer#(tmr#, "OnTick") form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Best Practices
| Practice | Why |
|---|---|
Set min and max before value | Ensures the value falls within the valid range |
| Use Timers for animation | Blocking loops freeze the UI; timers allow smooth repainting |
| Use vertical orientation for level meters | progressbar_orientation#(pb#, 1) for CPU, memory, audio level displays |
| Pair with a Label for percentage | Progress bars have no built-in text; use label_text# to show “X%” |
| Disable buttons during processing | Prevents multiple clicks while a task runs |
| Timer interval 30–100 ms | 30 ms for smooth animation, 100 ms for less CPU usage |
| Hide when idle | Use progressbar_visible#(pb#, 0) when no task is running |
| Use custom ranges for steps | max = 4 for a 4-step installer is cleaner than calculating percentages |
Quick Reference
| Function | Signature | Description |
|---|---|---|
progressbar_error / errormsg$ / strerror$ / clearerror | various | Error handling (4) |
progressbar#(parent#[, x, y, w, h]) | various | Create (2 overloads) |
progressbar_free(pb#) | progressbar_free@# | Destroy |
progressbar_value / min / max (get/set) | various | Value properties (6) |
progressbar_orientation (get/set) | various | Orientation (2) |
progressbar_x/y/width/height (get/set) / bounds# / move# / size# | various | Position & size (14) |
progressbar_align / margin# / margins# / margin[left/top/right/bottom] | various | Alignment & margins (12) |
progressbar_visible / enabled / opacity / hittest / dragmode | various | Visibility & state (10) |
progressbar_tag / parent# / bringtofront# / sendtoback# | various | Tag & parent (6) |
progressbar_onclick/ondblclick/onmousedown/up/move/enter/leave/onresize/ondragenter/over/drop/leave | various | Events set+get (21) |
progressbar_clearcallbacks# | progressbar_clearcallbacks#@# | Disconnect all events |
79 functions. Part of the Plan9Basic GUI library system.