LineLib — Line Shape Library
Lines connect two points within a bounding rectangle and can be styled with different colors, thicknesses, dash patterns, and end caps. Lines are ideal for diagrams, connectors, separators, crosshairs, grids, and decorative elements. Unlike other shape controls, lines have no fill property — they are drawn using only stroke properties. 80 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | line_error, errormsg$, strerror$, clearerror |
| Creation & Destruction | 4 | line# (3 overloads), line_free |
| Line Type | 2 | linetype (get/set) |
| Stroke | 11 | stroke$ / stroke# / strokenone#, thickness, dash, cap, join (get/set) |
| Position & Size | 11 | 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 | 8 | visible, enabled, opacity, hittest (get/set) |
| Tag, Rotation & Parent | 9 | tag, rotation (get/set), parent# (get/set), bringtofront#, sendtoback#, invalidate# |
| Events | 19 | 9 event types × set/get + clearcallbacks# |
Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | Win32/Win64 |
| Linux | ✅ Full Support | GTK-based |
| Android | ✅ Full Support | Hardware-accelerated |
Error Handling
| Function | Signature | Description |
|---|---|---|
line_error() | line_error@ | Last error code (0 = no error) |
line_errormsg$() | line_errormsg$@ | Last error message as string |
line_strerror$(code) | line_strerror$@n | Description for a given error code |
line_clearerror() | line_clearerror@ | Clear the error state |
Line Type
The line_linetype property determines how the line is drawn within its bounding rectangle:
| Value | Type | Description |
|---|---|---|
| 0 | Diagonal | Line from top-left to bottom-right corner (default) |
| 1 | Top | Horizontal line along the top edge of bounding box |
| 2 | Left | Vertical line along the left edge of bounding box |
' Diagonal line (default, type 0) let diag# = line#(frm#, 10, 10, 200, 100) ' Horizontal separator (type 1 = Top) let hLine# = line#(frm#, 10, 50, 300, 1) line_linetype#(hLine#, 1) ' Vertical separator (type 2 = Left) let vLine# = line#(frm#, 50, 10, 1, 200) line_linetype#(vLine#, 2)
ⓘ Note: For horizontal lines, use line type 1 (Top) with a small height. For vertical lines, use line type 2 (Left) with a small width, or use the default diagonal type with width=1.
Numeric Values Reference
Control Alignment line_align#
| Value | Description |
|---|---|
| 0 | None (absolute positioning) |
| 1 | Top |
| 2 | Left |
| 3 | Right |
| 4 | Bottom |
| 9 | Client (fill parent) |
Stroke Dash Style line_strokedash#
| Value | Style |
|---|---|
| 0 | Solid |
| 1 | Dash |
| 2 | Dot |
| 3 | DashDot |
| 4 | DashDotDot |
Stroke Cap Style line_strokecap#
| Value | Style |
|---|---|
| 0 | Flat |
| 1 | Round |
Stroke Join Style line_strokejoin#
| Value | Style |
|---|---|
| 0 | Miter |
| 1 | Round |
| 2 | Bevel |
Line Type line_linetype#
| Value | Type |
|---|---|
| 0 | Diagonal (top-left to bottom-right) |
| 1 | Top (horizontal along top edge) |
| 2 | Left (vertical along left edge) |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
line#(parent#) | line#@# | Create with default size |
line#(parent#, w, h) | line#@#nn | Create with specified size |
line#(parent#, x, y, w, h) | line#@#nnnn | Create with position and size |
line_free(line#) | line_free@# | Destroy line shape |
' Simple diagonal line let ln# = line#(frm#, 50, 50, 200, 100) line_stroke#(ln#, "#e74c3c") line_strokethickness#(ln#, 3)
ⓘ Note: Lines have no fill property. All visual styling is done through stroke properties (color, thickness, dash, cap, join).
Stroke Properties
| Function | Signature | Description |
|---|---|---|
line_stroke$(line#) | line_stroke$@# | Get stroke color |
line_stroke#(line#, color$) | line_stroke#@#$ | Set stroke color |
line_strokenone#(line#) | line_strokenone#@# | Remove stroke (invisible line) |
line_strokethickness(line#) | line_strokethickness@# | Get stroke thickness |
line_strokethickness#(line#, n) | line_strokethickness#@#n | Set stroke thickness |
line_strokedash(line#) | line_strokedash@# | Get dash style (0–4) |
line_strokedash#(line#, n) | line_strokedash#@#n | Set dash style |
line_strokecap(line#) | line_strokecap@# | Get cap style (0=Flat, 1=Round) |
line_strokecap#(line#, n) | line_strokecap#@#n | Set cap style |
line_strokejoin(line#) | line_strokejoin@# | Get join style (0=Miter, 1=Round, 2=Bevel) |
line_strokejoin#(line#, n) | line_strokejoin#@#n | Set join style |
' Thick dashed line with round caps line_stroke#(ln#, "#3498db") line_strokethickness#(ln#, 4) line_strokedash#(ln#, 1) line_strokecap#(ln#, 1)
ⓘ Note: Round stroke caps (
line_strokecap#(ln#, 1)) round off the endpoints of the line instead of cutting them flat. This looks significantly better on thicker lines.Position & Size
| Function | Signature | Description |
|---|---|---|
line_x(line#) | line_x@# | Get X position |
line_x#(line#, x) | line_x#@#n | Set X position |
line_y(line#) | line_y@# | Get Y position |
line_y#(line#, y) | line_y#@#n | Set Y position |
line_width(line#) | line_width@# | Get width (horizontal extent) |
line_width#(line#, w) | line_width#@#n | Set width |
line_height(line#) | line_height@# | Get height (vertical extent) |
line_height#(line#, h) | line_height#@#n | Set height |
line_bounds#(line#, x, y, w, h) | line_bounds#@#nnnn | Set position and size |
line_move#(line#, x, y) | line_move#@#nn | Set position only |
line_size#(line#, w, h) | line_size#@#nn | Set size only |
Alignment & Margins
| Function | Signature | Description |
|---|---|---|
line_align(line#) | line_align@# | Get alignment |
line_align#(line#, n) | line_align#@#n | Set alignment |
line_margin#(line#, n) | line_margin#@#n | Set uniform margin on all four sides |
line_margins#(line#, l, t, r, b) | line_margins#@#nnnn | Set individual margins |
line_marginleft(line#) | line_marginleft@# | Get left margin |
line_marginleft#(line#, n) | line_marginleft#@#n | Set left margin |
line_margintop(line#) | line_margintop@# | Get top margin |
line_margintop#(line#, n) | line_margintop#@#n | Set top margin |
line_marginright(line#) | line_marginright@# | Get right margin |
line_marginright#(line#, n) | line_marginright#@#n | Set right margin |
line_marginbottom(line#) | line_marginbottom@# | Get bottom margin |
line_marginbottom#(line#, n) | line_marginbottom#@#n | Set bottom margin |
Visibility & State
| Function | Signature | Description |
|---|---|---|
line_visible(line#) | line_visible@# | Get visibility (0/1) |
line_visible#(line#, n) | line_visible#@#n | Set visibility |
line_enabled(line#) | line_enabled@# | Get enabled state (0/1) |
line_enabled#(line#, n) | line_enabled#@#n | Set enabled state |
line_opacity(line#) | line_opacity@# | Get opacity (0.0–1.0) |
line_opacity#(line#, n) | line_opacity#@#n | Set opacity |
line_hittest(line#) | line_hittest@# | Get hit-test state (0/1) |
line_hittest#(line#, n) | line_hittest#@#n | Enable/disable mouse hit testing |
⚠ Warning: Set
line_hittest#(line#, 1) before assigning mouse event handlers. Without hit testing enabled, the line will not receive mouse events.Tag, Rotation & Parent
| Function | Signature | Description |
|---|---|---|
line_tag(line#) | line_tag@# | Get user-defined integer tag |
line_tag#(line#, n) | line_tag#@#n | Set user-defined integer tag |
line_rotation(line#) | line_rotation@# | Get rotation angle in degrees |
line_rotation#(line#, angle) | line_rotation#@#n | Set rotation angle |
line_parent#(line#) | line_parent#@# | Get parent control pointer |
line_parent#(line#, parent#) | line_parent#@## | Move to a different parent |
line_bringtofront#(line#) | line_bringtofront#@# | Bring to front of Z-order |
line_sendtoback#(line#) | line_sendtoback#@# | Send to back of Z-order |
line_invalidate#(line#) | line_invalidate#@# | Force the line to redraw |
ⓘ Note:
line_rotation# rotates the entire bounding box around the line’s center. This is different from changing line_linetype# — rotation applies a visual transform, while line type controls which path the line follows within its bounds.Events
Each event has a setter (line_onXXX#) and a getter (line_onXXX$). Use line_clearcallbacks#(line#) to disconnect all callbacks at once.
Mouse Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
line_onclick#(line#, func$) | line_onclick$(line#) | function name(sender#) |
line_ondblclick#(line#, func$) | line_ondblclick$(line#) | function name(sender#) |
line_onmousedown#(line#, func$) | line_onmousedown$(line#) | function name(sender#, button, x, y, shift$) |
line_onmouseup#(line#, func$) | line_onmouseup$(line#) | function name(sender#, button, x, y, shift$) |
line_onmousemove#(line#, func$) | line_onmousemove$(line#) | function name(sender#, x, y, shift$) |
line_onmouseenter#(line#, func$) | line_onmouseenter$(line#) | function name(sender#) |
line_onmouseleave#(line#, func$) | line_onmouseleave$(line#) | function name(sender#) |
line_onmousewheel#(line#, func$) | line_onmousewheel$(line#) | function name(sender#, delta) |
Other Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
line_onresize#(line#, func$) | line_onresize$(line#) | function name(sender#) |
line_clearcallbacks#(line#) | — | Disconnect all event callbacks |
Complete Examples
Diagonal Line
let frm# = form#("Diagonal Line", 300, 300) form_position#(frm#, 4) let ln# = line#(frm#, 50, 50, 200, 150) line_stroke#(ln#, "#3498db") line_strokethickness#(ln#, 3) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Horizontal Separator
let frm# = form#("Separator", 400, 200) form_position#(frm#, 4) let lbl1# = label#(frm#, "Section 1") label_bounds#(lbl1#, 20, 30, 200, 25) ' Horizontal separator line (type 1 = Top) let sep# = line#(frm#, 20, 70, 360, 1) line_linetype#(sep#, 1) line_stroke#(sep#, "#bdc3c7") line_strokethickness#(sep#, 1) let lbl2# = label#(frm#, "Section 2") label_bounds#(lbl2#, 20, 90, 200, 25) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Dash Styles Showcase
let frm# = form#("Dash Styles", 400, 300) form_position#(frm#, 4) ' Solid (dash = 0) let ln1# = line#(frm#, 50, 40, 300, 1) line_linetype#(ln1#, 1) line_stroke#(ln1#, "#2c3e50") line_strokethickness#(ln1#, 2) line_strokedash#(ln1#, 0) let lbl1# = label#(frm#, "Solid") label_bounds#(lbl1#, 50, 45, 100, 20) ' Dash (dash = 1) let ln2# = line#(frm#, 50, 90, 300, 1) line_linetype#(ln2#, 1) line_stroke#(ln2#, "#2c3e50") line_strokethickness#(ln2#, 2) line_strokedash#(ln2#, 1) let lbl2# = label#(frm#, "Dash") label_bounds#(lbl2#, 50, 95, 100, 20) ' Dot (dash = 2) let ln3# = line#(frm#, 50, 140, 300, 1) line_linetype#(ln3#, 1) line_stroke#(ln3#, "#2c3e50") line_strokethickness#(ln3#, 2) line_strokedash#(ln3#, 2) let lbl3# = label#(frm#, "Dot") label_bounds#(lbl3#, 50, 145, 100, 20) ' DashDot (dash = 3) let ln4# = line#(frm#, 50, 190, 300, 1) line_linetype#(ln4#, 1) line_stroke#(ln4#, "#2c3e50") line_strokethickness#(ln4#, 2) line_strokedash#(ln4#, 3) let lbl4# = label#(frm#, "DashDot") label_bounds#(lbl4#, 50, 195, 100, 20) ' DashDotDot (dash = 4) let ln5# = line#(frm#, 50, 240, 300, 1) line_linetype#(ln5#, 1) line_stroke#(ln5#, "#2c3e50") line_strokethickness#(ln5#, 2) line_strokedash#(ln5#, 4) let lbl5# = label#(frm#, "DashDotDot") label_bounds#(lbl5#, 50, 245, 100, 20) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Crosshairs
let frm# = form#("Crosshairs", 300, 300) form_position#(frm#, 4) ' Horizontal crosshair let hLine# = line#(frm#, 0, 150, 300, 1) line_linetype#(hLine#, 1) line_stroke#(hLine#, "#e74c3c") line_strokethickness#(hLine#, 1) ' Vertical crosshair let vLine# = line#(frm#, 150, 0, 1, 300) line_linetype#(vLine#, 2) line_stroke#(vLine#, "#e74c3c") line_strokethickness#(vLine#, 1) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Grid Pattern
let frm# = form#("Grid", 320, 320) form_position#(frm#, 4) let spacing = 40 let gridSize = 280 let startX = 20 let startY = 20 ' Draw horizontal grid lines for i = 0 to 7 let ln# = line#(frm#, startX, startY + i * spacing, gridSize, 1) line_linetype#(ln#, 1) line_stroke#(ln#, "#bdc3c7") line_strokethickness#(ln#, 1) next i ' Draw vertical grid lines for i = 0 to 7 let ln# = line#(frm#, startX + i * spacing, startY, 1, gridSize) line_linetype#(ln#, 2) line_stroke#(ln#, "#bdc3c7") line_strokethickness#(ln#, 1) next i form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Interactive Connector
let frm# = form#("Connector", 400, 300) form_position#(frm#, 4) ' Two boxes connected by a line let box1# = rectangle#(frm#, 30, 100, 100, 60) rectangle_fill#(box1#, "#3498db") let box2# = rectangle#(frm#, 270, 100, 100, 60) rectangle_fill#(box2#, "#e74c3c") ' Connecting line between boxes let conn# = line#(frm#, 130, 130, 140, 1) line_linetype#(conn#, 1) line_stroke#(conn#, "#2c3e50") line_strokethickness#(conn#, 2) line_strokedash#(conn#, 1) line_strokecap#(conn#, 1) let lbl1# = label#(frm#, "Start") label_bounds#(lbl1#, 55, 115, 50, 25) let lbl2# = label#(frm#, "End") label_bounds#(lbl2#, 303, 115, 50, 25) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Best Practices
| Practice | Why |
|---|---|
Use line_linetype#(ln#, 1) for horizontal lines | Draws along the top edge — clean horizontal separator |
Use line_linetype#(ln#, 2) for vertical lines | Draws along the left edge — clean vertical separator |
Use line_strokecap#(ln#, 1) for round ends | Much better visual on thicker lines |
Set hittest = 1 for interactive lines | Required for mouse events to fire on the line |
Use line_bounds# to set position and size at once | More efficient than four separate property calls |
Use line_strokedash# for visual variety | Dashed and dotted lines distinguish connector types in diagrams |
| Keep stroke thickness ≥ 2 for dashed patterns | Dash patterns look best at thicknesses of 2 or more |
Use line_opacity# for subtle grid lines | Semi-transparent lines make effective background grids |
Quick Reference
| Function | Signature | Description |
|---|---|---|
line_error / errormsg$ / strerror$ / clearerror | various | Error handling (4) |
line#(parent#[, w, h] | [, x, y, w, h]) | various | Create (3 overloads) |
line_free(line#) | line_free@# | Destroy |
line_linetype (get/set) | various | Line type: 0=Diagonal, 1=Top, 2=Left (2) |
line_stroke$ / stroke# / strokenone# / strokethickness / strokedash / strokecap / strokejoin | various | Stroke (11) |
line_x/y/width/height (get/set) / bounds# / move# / size# | various | Position & size (11) |
line_align / margin# / margins# / margin[left/top/right/bottom] | various | Alignment & margins (12) |
line_visible / enabled / opacity / hittest | various | Visibility & state (8) |
line_tag / rotation / parent# / bringtofront# / sendtoback# / invalidate# | various | Tag, rotation & parent (9) |
line_onclick/ondblclick/onmousedown/up/move/enter/leave/onmousewheel/onresize | various | Events set+get (18) |
line_clearcallbacks# | line_clearcallbacks#@# | Disconnect all events |
80 functions. Part of the Plan9Basic GUI shape library system.