Reflex GLX
The UI library. GLX provides a GPU-accelerated, stylesheet-driven widget toolkit with a scene-graph architecture. This is the largest module and where most application development happens.
Event Constants
Events are identified by Key32 constants. Bind to these using BindEvent() or handle them in OnEvent().
| Constant | When Fired |
|---|---|
| kMouseDown | Mouse button pressed |
| kMouseUp | Mouse button released |
| kMouseDrag | Mouse moved while button held |
| kMouseEnter | Cursor enters object bounds |
| kMouseLeave | Cursor leaves object bounds |
| kMouseWheel | Scroll wheel |
| kKeyDown | Key pressed |
| kKeyUp | Key released |
| kCharacter | Character input (after key translation) |
| kFocus | Object gained focus |
| kLoseFocus | Object lost focus |
| kTransaction | Value change (sliders, text areas, etc.) |
| kDragDrop | Internal drag-drop completed |
| kDragEnter | Drag entered object bounds |
| kDragOver | Drag over object |
| kDragLeave | Drag left object bounds |
| kDropExternal | External file drop |
Enumerations
Flag and enum constants that control layout flow, alignment, animation curves, interaction modes, and more.
FlowFlags
Controls how children are laid out within a container. Flags can be combined with bitwise OR — for example, kFlowY | kFlowInvert for bottom-to-top vertical flow.
kFlowX // Horizontal arrangement (default)kFlowY // Vertical arrangementkFlowInvert // Reverse order (right-to-left or bottom-to-top)kFlowCenter // Center items along flow axisOrientation
Controls alignment on the orthogonal axis (perpendicular to flow direction).
kOrientationNear // Top (in horizontal flow) or Left (in vertical flow)kOrientationCenter // CenteredkOrientationFar // Bottom (in horizontal flow) or Right (in vertical flow)kOrientationFit // Stretch to fill orthogonal axisAlignment
Nine-point alignment used by AddFloat() and other positioning functions.
kAlignmentTopLeft kAlignmentTop kAlignmentTopRightkAlignmentLeft kAlignmentCenter kAlignmentRightkAlignmentBottomLeft kAlignmentBottom kAlignmentBottomRightClickFlags
kClickFlagRmb // Right mouse buttonkClickFlagDbl // Double clickCurve
Easing curves for animations.
kCurveLinearkCurveEaseIn2x, kCurveEaseIn3xkCurveEaseOut2x, kCurveEaseOut3xkCurveEaseInOutCos, kCurveEaseInOut2xTransactionStage
kTransactionStageNonekTransactionStageBegin // User started interactingkTransactionStagePerform // Value changingkTransactionStageEnd // User finished interactingkTransactionStageCancel // Interaction cancelledSelectionMode
Used by AbstractList and its derivatives.
kSelectionModeSingle // One item at a timekSelectionModeMulti // Multiple with Shift/CtrlkSelectionModeMultiToggle // Toggle each item independentlyType Aliases
GLX re-exports common System types under shorter names for convenience within UI code.
using Colour = System::Colour;using ColourPoints = Array<Tuple<Point<Float32>, System::Colour>>;using KeyCode = System::KeyCode;using ModifierKeys = System::ModifierKeys;using MouseCursor = System::MouseCursor;using Point = System::fPoint;using Points = Array<Point<Float32>>;using Rect = System::fRect;using Size = System::fSize;Layout Functions
The primary functions for building UI hierarchies. GLX uses a flow-based layout system similar in concept to CSS Flexbox.
Adding Children
// Inline — participates in flow layoutTRef<Object> AddInline(Object& parent, Object& child, Orientation ortho_position);
// InlineFlex — inline but stretches to fill remaining spaceTRef<Object> AddInlineFlex(Object& parent, Object& child, Orientation ortho_position);
// Stretch — fills all remaining spaceTRef<Object> AddStretch(Object& parent, Object& child);
// Float — overlaid on top of flow, positioned by alignmentTRef<Object> AddFloat(Object& parent, Object& child, Orientation x_position, Orientation y_position);TRef<Object> AddFloat(Object& parent, Object& child, Alignment alignment);
// Absolute — precise position (use sparingly)TRef<Object> AddAbsolute(Object& parent, Object& child);TRef<Object> AddAbsolute(Object& parent, Object& child, Point position);Flow & Sizing
void SetFlow(Object& object, FlowFlags flags);void EnableAutoFit(Object& object, bool x, bool y); // Shrink-to-contentvoid SetBounds(Object& object, Key32 id, const Size& min, const Size& max);void UnsetBounds(Object& object, Key32 id);const Pair<Size<Float32>, Size<Float32>>& GetBounds(const Object& object, Key32 id);void SetClip(Object& object, Key32 id, bool x, bool y); // Enable clippingPair<bool,bool> GetClip(const Object& object, Key32 id);void UnsetClip(Object& object, Key32 id);Example: Vertical Layout
A vertical panel with a fixed-height header and a body that fills the remaining space.
auto panel = New<GLX::Object>();GLX::SetFlow(panel, GLX::kFlowY);
auto header = New<GLX::Object>();auto body = New<GLX::Object>();
GLX::AddInline(panel, header); // Fixed height headerGLX::AddInlineFlex(panel, body); // Body fills remaining spaceExample: Floating Overlay
A menu button floated in the top-right corner of a card, independent of the card's flow layout.
auto card = New<GLX::Object>();GLX::SetFlow(card, GLX::kFlowY);
GLX::AddInline(card, title);GLX::AddInline(card, preview);
// Float a menu button in the top-right cornerauto menuBtn = New<GLX::Button>(L"⋯");GLX::AddFloat(card, menuBtn, GLX::kAlignmentTopRight);Position Queries
Rect CalculateAbsoluteRect(const Object& object);Rect CalculateRelativeRect(const Object& parent, const Object& object);Pair<Point<Float32>, Size<Float32>> CalculateAbs(const Object& object);Pair<Point<Float32>, Size<Float32>> CalculateAbs(const Object& parent, const Object& object);Child Lookup
Idx LookupIndex(const Object& child); // Index within parentIdx LookupBranchIndex(const Object& parent, const Object& child);TRef<Object> LookupChildAtIndex(Object& parent, UInt32 idx);bool BranchContains(const Object& parent, const Object& child);Object* QueryChildById(Object& parent, Key32 id, Object* fallback);Object* QueryElementById(Object& object, Key32 id, Object* fallback);Drawing & Geometry Functions
Low-level drawing helpers that build point arrays and colour-point arrays for the renderer.
Rectangles
void AddRectFill(Points& points, const Rect& rect);void AddRectFill(ColourPoints& colour_points, const Colour& colour, const Rect& rect);void AddRectOutline(Points& points, const Rect& rect, const Margin& width, Size pixel_size);Rounded Rectangles
void AddRoundedFill(Points& points, const Rect& rect, const Margin& corners, Float32 corner_step);void AddRoundedOutline(Points& points, const Rect& rect, const Margin& width, const Margin& corners, Float32 corner_step);Ellipses & Arcs
void AddEllipseFill(Points& points, const Rect& rect, Float32 start, Float32 sweep);void AddEllipseOutline(Points& points, const Rect& rect, Size width, Float32 start, Float32 sweep);Triangles
void AddTriangleFill(Points& points, const Rect& rect, Alignment direction);void AddTriangleOutline(Points& points, const Rect& rect, Float32 width, Alignment direction, Size pixel_size);void AddRoundedTriangleFill(Points& points, const Rect& rect, Float32 corner, Alignment direction, Size pixel_size);Lines & Paths
void AddDottedLine(Points& points, Point from, Point to, Size pixel_size);void AddPath(Points& points, const ArrayView<Point<Float32>>& path, Float32 width, bool closed, Size pixel_size);Polygons
void AddPolygonFill(Points& points, const ArrayView<Point<Float32>>& input);Gradients
void AddGradientFill(ColourPoints& colour_points, const Colour& from, const Colour& to, const Rect& rect, bool y);void AddPointsWithColour(ColourPoints& colour_points, const Colour& colour, const ArrayView<Point<Float32>>& input);void AddPointsWithGradient(ColourPoints& colour_points, const Colour& from, const Colour& to, bool y, const ArrayView<Point<Float32>>& input, const ArrayView<Point<Float32>>& rect);Colour
Colour RGB(UInt8 grey);Colour RGB(UInt8 grey, UInt8 alpha);Colour RGB(UInt8 red, UInt8 green, UInt8 blue);Colour RGB(UInt8 red, UInt8 green, UInt8 blue, UInt8 alpha);Transforms
Modify point arrays in-place. ColourPoint variants of all three are also available.
void Translate(const ArrayRegion<Point<Float32>>& points, Point offset);void Rotate(const ArrayRegion<Point<Float32>>& points, Point origin, Float32 angle_normalised);void Rescale(const ArrayRegion<Point<Float32>>& points, Size scale);Custom Drawing
Register a callback that provides a custom graphic layer for an object. The callback receives the current size and returns a renderer graphic.
void SetGraphicLayerOnDraw(Object& object, Key32 id, const Function<TRef<System::Renderer::Graphic>(Size)>& callback);void UnsetGraphicLayerOnDraw(Object& object, Key32 id);State & Activation
Control object visibility, interaction state, selection, and opacity.
Activation
Activated objects are visible and interactive. Deactivated objects are hidden and excluded from layout.
void Activate(Object& object, bool state);void ActivateBranch(Object& object, bool state); // Recursivebool IsActive(const Object& object);State Flags
void SetState(Object& object, Key32 state, bool value);bool ToggleState(Object& object, Key32 state);Selection
void Select(Object& object, bool select);void SelectBranch(Object& object, bool select); // Recursivevoid SelectChildren(Object& object, bool select);bool IsSelected(const Object& object);Opacity
void SetOpacity(Object& object, Key32 id, Float32 opacity);Float32 GetOpacity(const Object& object, Key32 id);void UnsetOpacity(Object& object, Key32 id);Text
Set and retrieve text content on any GLX object.
void SetText(Object& object, const WString& value, Key32 id_opt);WString::View GetText(const Object& object, Key32 id_opt);void ClearText(Object& object, Key32 id_opt);Example
auto label = New<GLX::Object>();GLX::SetText(label, L"Hello, World!");
auto text = GLX::GetText(label); // L"Hello, World!"Events & Input
Bind callbacks to events, emit and send events through the object tree, query event properties, and control mouse and focus behaviour.
Binding Events
void BindEvent(Object& object, Key32 event_id, const Function<bool(Object&, Event&)>& callback);void BindEventVoid(Object& object, Key32 event_id, const Function<void()>& callback);void UnbindEvent(Object& object, Key32 event_id);
// Shortcut for click handlingTRef<Object> BindClick(Object& object, const Function<void()>& callback);
// Set a delegate for event processingvoid SetEventDelegate(Object& object, Key32 delegate_id, const Function<bool(Object&, Event&)>& callback);Emitting Events
bool Emit(Object& src, Key32 id, VARGS... id_value_pairs); // Bubble upbool Send(Object& src, Key32 id, VARGS... id_value_pairs); // Send downEvent Queries
UInt8 GetClickFlags(const Event& e);WChar GetKeyCharacter(const Event& e);KeyCode GetKeyCode(const Event& e);UInt8 GetModifierKeys(const Event& e);bool IsDoubleClick(const Event& e);bool IsLeftClick(const Event& e);bool IsRightClick(const Event& e);const Event* QueryAntecedent(const Event& e, Key32 id, const Event* fallback);Mouse
void EnableMouse(Object& object, bool enable, bool intercept);void EnableMouseCapture(Object& object, bool enable, bool incremental);Point GetMousePosition(const Object& object);Point GetMouseDrag(const Object& object, Point mouse_delta);The combination of enable and intercept flags determines how an object interacts with mouse events:
| enable | intercept | Mode | Behaviour |
|---|---|---|---|
| false | false | Thru | Invisible to mouse |
| true | false | Passive | Receives events, passes through |
| false | true | Reject | Blocks mouse, no events |
| true | true | Active | Receives events, blocks propagation |
Enter & Exit
Visibility transitions for showing and hiding objects.
void Enter(Object& object, UInt8 flags); // Show/activatevoid Exit(Object& object, bool detach); // Hide/deactivateFocus
// Object::Focus() is a member functionvoid FocusBranch(Object& branch_root);void RedirectFocus(Object& branch_root, Object& object);Context Menus
Reference<Menu> OpenContextMenu(Object& src, Key32 context_opt);void CloseContextMenu();Example: Right-Click Context Menu
GLX::BindEvent(*myObject, GLX::kMouseDown, [](Object& src, Event& e) { if (GLX::IsRightClick(e)) { auto menu = GLX::OpenContextMenu(src); GLX::BindClick(*menu->AddItem(L"Delete"), [&src]() { // Handle delete }); return true; } return false;});Animation System
GLX provides a rich animation system with interpolated tweens, callback-driven animations, sequential playlists, and clock-based execution.
Running Animations
void Run(Object& target, Key32 id, Animation& scene);void Run(Object& target, Key32 id, Float32 time, Animation& scene);void Run(Object& target, Key32 id, Float32 time, Curve curve, InterpolatedAnimation& scene);void Stop(Object& target, Key32 id);Interpolated Animations
Tween between values over time. Use the generic callback variant or the typed property helpers.
TRef<InterpolatedAnimation> CreateInterpolatedAnimation(const Function<void(Object&, Float32)>& callback);TRef<InterpolatedAnimation> CreateFloatPropertyAnimation(Key32 property_id, Float32 from, Float32 to);TRef<InterpolatedAnimation> CreateColourPropertyAnimation(Key32 property_id, const Colour& from, const Colour& to);TRef<InterpolatedAnimation> CreateMarginPropertyAnimation(Key32 property_id, const Margin& from, const Margin& to);TRef<InterpolatedAnimation> CreatePointPropertyAnimation(Key32 property_id, Point from, Point to);TRef<InterpolatedAnimation> CreateSizePropertyAnimation(Key32 property_id, Size from, Size to);TRef<InterpolatedAnimation> CreatePositionAnimation(bool y, Float32 from, Float32 to);TRef<InterpolatedAnimation> CreateOpacityAnimation(Object& target, Key32 id, Float32 from, Float32 to);TRef<InterpolatedAnimation> CreateWaitAnimation();Special Types
TRef<Animation> CreateCallbackAnimation(const Function<void(Object&)>& callback);TRef<Animation> CreateLogarithmicAnimation(Float32 from, Float32 to, const Function<void(Object&, Float32)>& callback, Float32 decay_factor);TRef<Animation> CreateMaxBoundsAnimation(Key32 bounds_id, bool yaxis, Float32 from, Float32 to);TRef<Animation> CreateStateAnimation(Key32 state);Animation Classes
Animation (Base)
class Animation : Object { void SetTime(Float32 time); void SetTarget(Object& target); void Play();};InterpolatedAnimation
class InterpolatedAnimation : Animation { };ContainerAnimation
Holds multiple animations. Multi plays them simultaneously,PlayList plays them sequentially.
class ContainerAnimation : Animation { void Clear(); void Add(Animation& animation);};
class Multi : ContainerAnimation { };
class PlayList : ContainerAnimation { void EnableLoop(bool enable);};Clocks
Animation clocks provide per-frame or periodic callbacks, independent of the animation pipeline.
// Per-frame callback (receives delta time)TRef<Object> CreateAnimationClock(const Function<void(Float32)>& callback);void AttachAnimationClock(Object& object, Key32 id, const Function<void(Float32)>& callback);
// Periodic callback (fixed interval)TRef<Object> CreatePeriodicClock(Float32 delay, Float32 interval, const Function<void()>& callback);void AttachPeriodicClock(Object& object, Key32 id, Float32 delay, Float32 interval, const Function<void()>& callback);
void DetachClock(Object& object, Key32 id);Style System
GLX uses a stylesheet-driven styling model. Styles are hierarchical property sets that can be loaded from files and applied to objects.
Applying Styles
// Object::SetStyle(const Style& style) is a member function
void SetOnStyle(Object& object, const Function<void(const Style&)>& callback, Key32 delegate_id_opt);Style Lookup
ConstTRef<Style> FindStyle(const Object& object, Key32 id);ConstTRef<Style> FindStyle(const Style& style, Key32 id);Loading Stylesheets
ConstTRef<StyleSheet> RetrieveStyleSheet(const WString::View& path, const Data::PropertySet& options_opt);Style Class
class Style : Data::PropertySet { const Key32 id;
void SetParent(Style& child); void Clear(); void InsertBefore(Style& child); void InsertAfter(Style& child); void Detach(); void Attach(Style& child);};
class StyleSheet : Style { const Key32 path;};Example
A typical OnSetStyle callback that distributes sub-styles to child objects.
void OnSetStyle(const GLX::Style& style){ m_header->SetStyle(style["Header"]); m_button->SetStyle(style["Button"]); m_card_style = style["Body"]["NoteCard"]; // Store for dynamic use}Utility Functions
Additional helper functions available in the GLX namespace.
void SetOnStyle(Object& object, const Function<void(const Style&)>& callback, Key32 delegate_id_opt);Registers a callback invoked whenever a style is applied to the object. This is the primary mechanism for propagating styles through a custom widget's internal hierarchy.
Widgets & Classes
The built-in widget library. Everything in GLX inherits from Object, which itself extends Data::PropertySet.
Object
The base UI element. All GLX widgets inherit from Object.
class Object : Data::PropertySet { // Hierarchy void SetParent(Object& child); void Clear(); // Remove all children void InsertBefore(Object& child); void InsertAfter(Object& child); void Detach(); // Remove from parent void SendBottom(); // Move to back of sibling order void SendTop(); // Move to front
// Cursor void SetMouseCursor(MouseCursor mousecursor); MouseCursor GetMouseCursor();
// Style void SetStyle(const Style& style); ConstTRef<Style> GetStyle();
// State void ClearState(Key32 state); void SetState(Key32 state); bool CheckState(Key32 state);
// Focus void Focus();
// Events bool ProcessEvent(Object& src, Event& e); bool Emit(Event& e);
// Layout void Accommodate(); void Realign(); void Update();
// Lifecycle callbacks (override these) void OnAttachWindow(); void OnDetachWindow(); void OnClock(Float32 delta); void OnUpdate(); void OnSetStyle(const Style& style); bool OnEvent(Object& src, Event& e);};Event
class Event : Data::PropertySet { Key32 id; TRef<Event> Clone();};Form
A header + body container. Base class for TabGroup and Accordion.
class Form : Object { const TRef<Object> body; const TRef<Label> header;};Label
A text label widget.
Button
Click-interactive element. Created with New<GLX::Button>(L"label").
TextArea
Multiline text editor with scrolling. Inherits from Scroller.
class TextArea : Scroller { void ClearText(); void SetText(const WString& label); WString::View GetText();};Example
auto editor = New<GLX::TextArea>(true); // MultilineGLX::SetText(*editor, L"Initial text\nLine 2");
GLX::BindEvent(*editor, GLX::kTransaction, [](Object& src, Event& e) { auto& editor = static_cast<GLX::TextArea&>(src); auto text = GLX::GetText(editor); // Text changed return true;});Menu
Context and dropdown menu. Inherits from Scroller.
class Menu : Scroller { void Clear(); TRef<Object> AddItem(const WString::View& label); TRef<Object> AddItem(TRef<Object> item); TRef<Object> AddSeparator(); TRef<Object> AddSubMenu(const WString::View& label); TRef<Object> AddSubMenu(TRef<Object> item); TRef<Object> GetParentItem(); void Open(WindowClient& window, const Rect& origin); bool IsOpen(); bool OpenSubMenu(Object& item);};Selector
Shows one panel at a time with optional transition animations.
class Selector : Object { void EnableContentAutoFit(bool enable); void Clear(); void AddPanel(TRef<Object> item, Key32 style_id_opt); void RemovePanel(UInt32 idx); UInt32 GetNumPanel(); TRef<Object> GetPanel(UInt32 idx); void SelectPanel(UInt32 idx); Idx GetCurrentIndex();};TabGroup
Tabbed interface combining tab buttons with a Selector. Inherits from Form.
class TabGroup : Form { void Clear(); TRef<Object> AddPanel(const WString::View& label, TRef<Object> content, Key32 style_id, Key32 tab_style_id); void RemovePanel(UInt32 idx); TRef<Selector> GetSelector();};Example
auto tabs = New<GLX::TabGroup>();tabs->AddPanel(L"Settings", New<SettingsPanel>());tabs->AddPanel(L"Profile", New<ProfilePanel>());
// Programmatic switchingtabs->GetSelector()->SelectPanel(1);Split
Resizable split container with a draggable divider. Enable resizing on children with Data::SetBool(*child, GLX::kresize, true).
class Split : Object { };AbstractViewPort / Scroller / Zoomable
Scrollable and zoomable containers with view-range control, scrollbar access, and auto-scroll support.
class AbstractViewPort : Object { void SetContent(Object& content, Key32 style_id_opt); TRef<Object> GetContent(); void InvertScrollAxis(bool invert); TRef<Object> CreateListener(const Function<void()>& callback);
// View range void SetMinViewRange(Size size); Size GetMinViewRange(); Size GetTotalViewRange(); void SetView(const Rect& view); const Rect& GetView(); Size GetPixelSize();
// Scrolling void StartScroll(bool yaxis, Float32 offset); void StopScroll(bool yaxis); void Reveal(bool yaxis, Float32 offset, Float32 range, Float32 padding, bool animate); void EnableAutoScroll(Float32 amount, bool scoped); void DisableAutoScroll();
// Access ConstTRef<Object> GetBody(); TRef<AbstractViewBar> GetViewBar(bool yaxis);};
class Scroller : AbstractViewPort { };class Zoomable : AbstractViewPort { };AbstractList / List / VirtualList
List containers with selection support.
class AbstractList : Object { void SetSelectionMode(SelectionMode mode); UInt32 GetNumItem(); void SelectAll(); void SelectNone(); bool Select(UInt32 idx, bool multi); void Deselect(UInt32 idx); bool SelectNext(bool extend); bool SelectPrev(bool extend); void EnumerateSelection(UInt32 start, UInt32 range, const Function<void(UInt idx, UInt n)>& callback); void Reveal(UInt32 idx);};
class List : AbstractList { };VirtualList
For large datasets — only creates visible items on demand.
class VirtualList : AbstractList { void SetPopulateCallback(const Function<void(UInt start, ArrayRegion<Reference<GLX::Object>> items, const GLX::Style& style)>& callback); void ClearItems(); void SetNumItem(UInt32 n, bool force_refresh); void Rebuild(); TRef<Object> GetItem(UInt32 idx);};RotarySlider
Interactive rotary knob control, common in audio applications.
class RotarySlider : Object { void SetSensitivity(Float32 pixels); bool SetRange(Float32 min, Float32 max, Float32 step); Pair<Range, Float32> GetRange(); void SetDefault(Float32 value); Float32 GetDefault(); void Reset(); bool SetValue(Float32 value); Float32 GetValue();};Other Widgets
| Class | Purpose |
|---|---|
| Popup | Overlay popup container |
| RangeBar | Scrollbar widget (inherits from AbstractViewBar) |
| WindowClient | Top-level window client (inherits from Object) |