EllipseLib — Ellipse Shape Library

Oval shapes defined by independent width and height dimensions. Use EllipseLib when you need non-uniform circular shapes — ovals, eggs, decorative frames, and stretched indicators. For perfect circles (width = height), CircleLib provides an identical API. 81 functions.

CategoryCountDescription
Error Handling4ellipse_error, errormsg$, strerror$, clearerror
Creation & Destruction4ellipse# (3 overloads), ellipse_free
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
ellipse_error()ellipse_error@Last error code (0 = no error)
ellipse_errormsg$()ellipse_errormsg$@Last error message as string
ellipse_strerror$(code)ellipse_strerror$@nDescription for a given error code
ellipse_clearerror()ellipse_clearerror@Clear the error state

Numeric Values Reference

Control Alignment ellipse_align#

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

Stroke Dash Style ellipse_strokedash#

ValueStyle
0Solid
1Dash
2Dot
3DashDot
4DashDotDot

Stroke Cap Style ellipse_strokecap#

ValueStyle
0Flat
1Round

Stroke Join Style ellipse_strokejoin#

ValueStyle
0Miter
1Round
2Bevel

Creation & Destruction

FunctionSignatureDescription
ellipse#(parent#)ellipse#@#Create with default size
ellipse#(parent#, w, h)ellipse#@#nnCreate with specified size
ellipse#(parent#, x, y, w, h)ellipse#@#nnnnCreate with position and size
ellipse_free(ell#)ellipse_free@#Destroy ellipse shape
╯ plan9basic
' Wide oval
let ell# = ellipse#(frm#, 50, 50, 200, 100)
ellipse_fill#(ell#, "#3498db")
ellipse_stroke#(ell#, "#2c3e50")
ellipse_strokethickness#(ell#, 2)

' Tall oval
let tall# = ellipse#(frm#, 270, 20, 80, 160)
ellipse_fill#(tall#, "#e74c3c")
ellipse_strokenone#(tall#)
ⓘ Note: An ellipse with equal width and height renders as a perfect circle. For circle-specific work, consider using CircleLib which provides the same API.

Fill Properties

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

Stroke Properties

FunctionSignatureDescription
ellipse_stroke$(ell#)ellipse_stroke$@#Get stroke color
ellipse_stroke#(ell#, color$)ellipse_stroke#@#$Set stroke color
ellipse_strokenone#(ell#)ellipse_strokenone#@#Remove stroke (no border)
ellipse_strokethickness(ell#)ellipse_strokethickness@#Get stroke thickness
ellipse_strokethickness#(ell#, n)ellipse_strokethickness#@#nSet stroke thickness
ellipse_strokedash(ell#)ellipse_strokedash@#Get dash style (0–4)
ellipse_strokedash#(ell#, n)ellipse_strokedash#@#nSet dash style
ellipse_strokecap(ell#)ellipse_strokecap@#Get cap style (0=Flat, 1=Round)
ellipse_strokecap#(ell#, n)ellipse_strokecap#@#nSet cap style
ellipse_strokejoin(ell#)ellipse_strokejoin@#Get join style (0=Miter, 1=Round, 2=Bevel)
ellipse_strokejoin#(ell#, n)ellipse_strokejoin#@#nSet join style
ⓘ Note: Dash styles are more visible with thicker strokes. Use ellipse_strokethickness#(ell#, 3) or higher for clear dashed/dotted borders.

Position & Size

FunctionSignatureDescription
ellipse_x(ell#)ellipse_x@#Get X position
ellipse_x#(ell#, x)ellipse_x#@#nSet X position
ellipse_y(ell#)ellipse_y@#Get Y position
ellipse_y#(ell#, y)ellipse_y#@#nSet Y position
ellipse_width(ell#)ellipse_width@#Get width
ellipse_width#(ell#, w)ellipse_width#@#nSet width
ellipse_height(ell#)ellipse_height@#Get height
ellipse_height#(ell#, h)ellipse_height#@#nSet height
ellipse_bounds#(ell#, x, y, w, h)ellipse_bounds#@#nnnnSet position and size
ellipse_move#(ell#, x, y)ellipse_move#@#nnSet position only
ellipse_size#(ell#, w, h)ellipse_size#@#nnSet size only
ⓘ Note: X/Y coordinates specify the top-left corner of the bounding box, not the center. An ellipse at (50, 50) with size (200, 100) has its center at (150, 100).

Alignment & Margins

FunctionSignatureDescription
ellipse_align(ell#)ellipse_align@#Get alignment
ellipse_align#(ell#, n)ellipse_align#@#nSet alignment
ellipse_margin#(ell#, n)ellipse_margin#@#nSet uniform margin on all four sides
ellipse_margins#(ell#, l, t, r, b)ellipse_margins#@#nnnnSet individual margins
ellipse_marginleft(ell#)ellipse_marginleft@#Get left margin
ellipse_marginleft#(ell#, n)ellipse_marginleft#@#nSet left margin
ellipse_margintop(ell#)ellipse_margintop@#Get top margin
ellipse_margintop#(ell#, n)ellipse_margintop#@#nSet top margin
ellipse_marginright(ell#)ellipse_marginright@#Get right margin
ellipse_marginright#(ell#, n)ellipse_marginright#@#nSet right margin
ellipse_marginbottom(ell#)ellipse_marginbottom@#Get bottom margin
ellipse_marginbottom#(ell#, n)ellipse_marginbottom#@#nSet bottom margin

Visibility & State

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

Tag, Rotation & Parent

FunctionSignatureDescription
ellipse_tag(ell#)ellipse_tag@#Get user-defined integer tag
ellipse_tag#(ell#, n)ellipse_tag#@#nSet user-defined integer tag
ellipse_rotation(ell#)ellipse_rotation@#Get rotation angle in degrees
ellipse_rotation#(ell#, angle)ellipse_rotation#@#nSet rotation angle
ellipse_parent#(ell#)ellipse_parent#@#Get parent control pointer
ellipse_parent#(ell#, parent#)ellipse_parent#@##Move to a different parent
ellipse_bringtofront#(ell#)ellipse_bringtofront#@#Bring to front of Z-order
ellipse_sendtoback#(ell#)ellipse_sendtoback#@#Send to back of Z-order
ellipse_invalidate#(ell#)ellipse_invalidate#@#Force the shape to redraw
ⓘ Note: Unlike circles, rotation is visible on ellipses because width ≠ height. A 45° rotated ellipse creates a diamond-like oval.

Events

Each event has a setter (ellipse_onXXX#) and a getter (ellipse_onXXX$). Use ellipse_clearcallbacks#(ell#) to disconnect all callbacks at once.

Mouse Events

Event SetterGetterCallback Signature
ellipse_onclick#(ell#, func$)ellipse_onclick$(ell#)function name(sender#)
ellipse_ondblclick#(ell#, func$)ellipse_ondblclick$(ell#)function name(sender#)
ellipse_onmousedown#(ell#, func$)ellipse_onmousedown$(ell#)function name(sender#, button, x, y, shift$)
ellipse_onmouseup#(ell#, func$)ellipse_onmouseup$(ell#)function name(sender#, button, x, y, shift$)
ellipse_onmousemove#(ell#, func$)ellipse_onmousemove$(ell#)function name(sender#, x, y, shift$)
ellipse_onmouseenter#(ell#, func$)ellipse_onmouseenter$(ell#)function name(sender#)
ellipse_onmouseleave#(ell#, func$)ellipse_onmouseleave$(ell#)function name(sender#)
ellipse_onmousewheel#(ell#, func$)ellipse_onmousewheel$(ell#)function name(sender#, delta)

Other Events

Event SetterGetterCallback Signature
ellipse_onresize#(ell#, func$)ellipse_onresize$(ell#)function name(sender#)
ellipse_clearcallbacks#(ell#)Disconnect all event callbacks

Ellipse vs Circle

FeatureEllipseCircle
DimensionsWidth and height can differWidth = height for true circle
Rotation effectVisible (oval rotates)No visible effect (symmetric)
APIIdentical (81 functions each)Identical (81 functions each)
Best forOvals, eggs, decorative frames, stretched shapesDots, indicators, avatars, buttons
ⓘ Note: EllipseLib and CircleLib have identical APIs (81 functions each). The only practical difference is whether you set width ≠ height (ellipse) or width = height (circle). Choose based on intent and code readability.

Complete Examples

Oval Gallery

╯ gallery.bas
let frm# = form#("Oval Gallery", 400, 300)
form_position#(frm#, 4)

' Wide oval
let e1# = ellipse#(frm#, 20, 30, 180, 90)
ellipse_fill#(e1#, "#3498db")
ellipse_stroke#(e1#, "#2c3e50")
ellipse_strokethickness#(e1#, 2)

' Tall oval
let e2# = ellipse#(frm#, 220, 20, 80, 160)
ellipse_fill#(e2#, "#e74c3c")
ellipse_strokenone#(e2#)

' Ring (hollow oval)
let e3# = ellipse#(frm#, 50, 150, 150, 80)
ellipse_fillnone#(e3#)
ellipse_stroke#(e3#, "#27ae60")
ellipse_strokethickness#(e3#, 4)

' Dashed oval
let e4# = ellipse#(frm#, 230, 190, 140, 80)
ellipse_fill#(e4#, "#f0f0f0")
ellipse_stroke#(e4#, "#9b59b6")
ellipse_strokethickness#(e4#, 3)
ellipse_strokedash#(e4#, 1)

form_show(frm#)

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

Interactive Ellipse (Hover + Click)

╯ interactive.bas
let frm# = form#("Interactive Ellipse", 400, 300)
form_position#(frm#, 4)

let ell# = ellipse#(frm#, 100, 75, 200, 150)
ellipse_fill#(ell#, "#9b59b6")
ellipse_stroke#(ell#, "#8e44ad")
ellipse_strokethickness#(ell#, 2)
ellipse_hittest#(ell#, 1)
ellipse_onclick#(ell#, "OnClick")
ellipse_onmouseenter#(ell#, "OnEnter")
ellipse_onmouseleave#(ell#, "OnLeave")

let lblInfo# = label#(frm#, "Hover or click the ellipse")
label_move#(lblInfo#, 100, 250)

form_show(frm#)

function OnClick(sender#)
    ellipse_fill#(sender#, "#e74c3c")
    label_text#(lblInfo#, "Clicked! Color changed to red.")
endfunction

function OnEnter(sender#)
    ellipse_opacity#(sender#, 0.7)
endfunction

function OnLeave(sender#)
    ellipse_opacity#(sender#, 1.0)
endfunction

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

Rotating Ellipse Animation

╯ rotating.bas
let frm# = form#("Rotating Ellipse", 300, 300)
form_position#(frm#, 4)

let ell# = ellipse#(frm#, 50, 75, 200, 100)
ellipse_fill#(ell#, "#3498db")
ellipse_stroke#(ell#, "#2c3e50")
ellipse_strokethickness#(ell#, 2)

let angle = 0

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

form_show(frm#)

function OnRotate(sender#)
    angle = angle + 2
    if angle >= 360 then angle = 0
    ellipse_rotation#(ell#, angle)
endfunction

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

Orbital Animation

╯ orbit.bas
let frm# = form#("Orbit", 350, 350)
form_position#(frm#, 4)

' Center body (sun)
let sun# = ellipse#(frm#, 140, 140, 60, 60)
ellipse_fill#(sun#, "#f1c40f")
ellipse_strokenone#(sun#)

' Orbiting body (planet)
let planet# = ellipse#(frm#, 30, 155, 30, 30)
ellipse_fill#(planet#, "#3498db")
ellipse_strokenone#(planet#)

' Orbit ring (decoration)
let orbit# = ellipse#(frm#, 25, 75, 290, 200)
ellipse_fillnone#(orbit#)
ellipse_stroke#(orbit#, "#bdc3c7")
ellipse_strokethickness#(orbit#, 1)
ellipse_strokedash#(orbit#, 2)

let orbitAngle = 0

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

form_show(frm#)

function OnOrbit(sender#) local px, py, radians
    orbitAngle = orbitAngle + 2
    if orbitAngle >= 360 then orbitAngle = 0
    radians = orbitAngle * 3.14159 / 180
    px = 170 + cos(radians) * 145 - 15
    py = 175 + sin(radians) * 100 - 15
    ellipse_move#(planet#, px, py)
endfunction

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

Best Practices

PracticeWhy
Set hittest = 1 for interactive ellipsesRequired for mouse events to fire on shapes
Use ellipse_rotation# for animated effectsRotation is visible on ellipses (unlike circles)
Use fillnone# for ring/outline shapesTransparent body with stroke creates hollow ovals
Use ellipse_move# for animationMore efficient than setting x and y separately
Use opacity for hover feedbackChange opacity on mouse enter/leave
Use tag in shared callbacksIdentify shapes with ellipse_tag(sender#)
Dash styles need thicker strokesUse strokethickness 3+ for visible dashed/dotted borders

Quick Reference

FunctionSignatureDescription
ellipse_error / errormsg$ / strerror$ / clearerrorvariousError handling (4)
ellipse#(parent#[, w, h] | [, x, y, w, h])variousCreate (3 overloads)
ellipse_free(ell#)ellipse_free@#Destroy
ellipse_fill$ / fill# / fillnone#variousFill (3)
ellipse_stroke$ / stroke# / strokenone# / strokethickness / strokedash / strokecap / strokejoinvariousStroke (11)
ellipse_x/y/width/height (get/set) / bounds# / move# / size#variousPosition & size (14)
ellipse_align / margin# / margins# / margin[left/top/right/bottom]variousAlignment & margins (12)
ellipse_visible / enabled / opacity / hittestvariousVisibility & state (8)
ellipse_tag / rotation / parent# / bringtofront# / sendtoback# / invalidate#variousTag, rotation & parent (8)
ellipse_onclick/ondblclick/onmousedown/up/move/enter/leave/onmousewheel/onresizevariousEvents set+get (18)
ellipse_clearcallbacks#ellipse_clearcallbacks#@#Disconnect all events

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