AgtWidgets — leaf controls, media, editors + dialog
AgtWidgets — leaf controls, media, editors + dialog
The concrete leaf widgets AGT ships. The text-bearing controls are
organized as a FOX-style inheritance chain:
AgtButton : AgtLabel : AgtFrame : AgtWidget. Each link
adds one focused responsibility on top of the previous: AgtFrame
contributes a configurable border + padded background, AgtLabel
adds a text caption inside the inner rect, AgtButton adds the
state machine + click contract. Beyond the chain, the module also
ships media widgets (AgtIcon / AgtImage / AgtSprite /
AgtAnimatedImage / AgtCanvas / AgtSpinner) and the editor
widgets (AgtEditBox for text, AgtHexBox + the AgtHexSource
byte-source family for hex/memory/IO) — all : AgtFrame.
Headers:
<agt/agt-frame.hpp>—AgtFrameborder + bg + padding (NONE / LINE / RAISED / SUNKEN / ROUNDED variants; per-side padding; virtualeffective_bg_colorhook)<agt/agt-label.hpp>—AgtLabelsingle-line text caption with horizontal alignment (LEFT / CENTER / RIGHT)<agt/agt-button.hpp>—AgtButtonhover + pressed state,AGT_SEL_COMMAND-emitting click contract, state-dependent bg palette, virtualon_clickedhook for state-bearing subclasses (CheckBox / RadioButton)<agt/agt-checkbox.hpp>—AgtCheckBoxbinary toggle with square indicator-<agt/agt-radio-button.hpp>—AgtRadioButtonmutually- exclusive selection with circle indicator + group via shared parent + target_id-<agt/agt-progress-bar.hpp>—AgtProgressBarnon-interactive value-fill display, horizontal or vertical<agt/agt-scale.hpp>—AgtScale(: AgtFrame) linear analog meter: the AgtProgressBar value/range model plus tick marks, colored threshold bands (green/amber/red zones), and a FILL (band-colored bar) or NEEDLE (zones + marker) indicator — a thermometer / VU-meter / bar gauge<agt/agt-dial.hpp>—AgtDial(: AgtFrame) circular needle gauge: value→needle-angle over a configurable sweep (default 270°) + tick marks; the instrument-cluster readout (RPM, temp, pressure). Needle/ticks composed from transform-aware dots<agt/agt-chart.hpp>—AgtChart(: AgtFrame) single-series line / strip chart: a fixed-capacity ring buffer of samples mapped to a polyline over an auto or fixed value range, with gridlines — the live-trace / history view (voltage ripple, temperature ramp).push()scrolls old samples off the left<agt/agt-slider.hpp>—AgtSliderinteractive draggable thumb on a track, emittingAGT_SEL_COMMANDon value change<agt/agt-edit-field.hpp>—AgtEditFieldsingle-line text input with cursor + click-drag selection, UTF-8-aware; anEchoModemasks the display (PASSWORD dots / NO_ECHO) and suppresses clipboard copy of a masked secret<agt/agt-image.hpp>—AgtImagenon-interactive widget that decodes PNG/JPEG/GIF/BMP viaaxl_pixmap_decodeand renders centered inside its frame<agt/agt-scrollbar.hpp>—AgtScrollBarproportional-thumb scrollbar; range is(total, page), position[0, total-page], thumb extent ∝page/total; track-click pages, thumb drags. Sibling toAgtSlider; emitsAGT_SEL_COMMANDonly on user-driven change (set_positionis silent)<agt/agt-listbox.hpp>—AgtListBoxscrolling single-selection list; rows are anaxl-arrayofaxl_strdup-ownedchar*(the data-structure policy’s first consumer), owns anAgtScrollBarchild; click / keyboard / wheel;ensure_visible(int)forces a row into view<agt/agt-separator.hpp>—AgtSeparatorthin divider line (horizontal or vertical), display-only; paints athickness-px rule centered on its minor axis, colour fromAgtPalette::separator<agt/agt-spacer.hpp>—AgtSpacerinvisible fixed-size layout strut (a bareAgtWidget, header-only); occupies its bounds in anAgtHBox/AgtVBoxbut draws nothing<agt/agt-toggle-button.hpp>—AgtToggleButtonlatching button (: AgtButton); a click flips a stickycheckedstate and the button renders sunken + active-filled while checked (state flipped inon_clickedbefore the SEL_COMMAND, à laAgtCheckBox)<agt/agt-group-box.hpp>—AgtGroupBoxtitled bordered container (: AgtFrame); a line border with a caption in a top-edge notch, reserving a top padding band so child content clears the title<agt/agt-status-bar.hpp>—AgtStatusBarchrome strip (: AgtFrame) with a left message + optional right-aligned field; unlikeAgtLabelit COPIES its text (status text is usually transient), freed in the destructor<agt/agt-switch.hpp>—AgtSwitchsliding on/off toggle (: AgtCheckBox); inherits the latched state + click, overridesdrawto paint a rounded pill track with a knob (left=off, right=on) plus the caption. Green “on” / grey “off”<agt/agt-menu-item.hpp>—AgtMenuItemselectable menu row (a borderlessAgtButtonwith left label + right-anchored shortcut + a keyboard-cursorhighlighted_state separate from mousehover_); used by theAgtMenuBar/AgtMenucomposites<agt/agt-dialog.hpp>—AgtDialogdialog base (: AgtWindow), modal or modeless. Modal (run(app)) blocks on theAgtAppmodal stack, grabs the seat, saves/restores focus, cycles Tab / Shift+Tab overcan_focus()children, and paints a frosted veil behind the content; returns a result code. Modeless (show(app)) floats over a fully-interactive parent — non-blocking, no grab, no veil; the surface is transparent with its input region clipped to the card so outside-card clicks fall through, and the outcome arrives viaset_on_close(target, id).AgtMessageBox/AgtPromptDialog(composite module) build on the modal path. See the design doc’s “Dialogs — modal and modeless” section<agt/agt-movable-frame.hpp>—AgtMovableFrame(: AgtVBox) a draggable container with a title-bar grip strip: a press on the bar grabs the window mouse-capture and repositions the frame with per-event delta math (drift-free), clamped inside its parent, and casts a soft drop shadow so it reads as floating. The draggable dialog cards are built on it<agt/agt-icon.hpp>—AgtIcon(: AgtFrame) decodes a small image (PNG/JPEG/GIF/BMP viaaxl_pixmap_decode) and renders it at its natural size; the still, fixed-size counterpart toAgtImage’s scaled fill<agt/agt-bitmap-button.hpp>—AgtBitmapButton(: AgtButton) a button whose face is an icon instead of (or beside) a caption — a decoded bitmap or a procedural stock icon (AgtStyle::StockIcon); the toolbar-button building block<agt/agt-spinner.hpp>—AgtSpinner(: AgtWidget) an animated busy indicator; aphase()-driven rotating arc on anaxl_looptimer, with a deterministic phase for visual baselines<agt/agt-light.hpp>—AgtLight(: AgtLabel) a status-light / LED indicator: a bezelled disc in a discrete state color (OFF/OK/WARN/ERROR/BUSY, themed viaAgtPalette::light), optionally blinking on anaxl_looptimer (deterministic phase for baselines), with an optional trailing caption — a column of these is a status panel<agt/agt-canvas.hpp>—AgtCanvas(: AgtFrame) a custom-paint surface that hands the consumer anAgtDrawContextcallback to draw arbitrary content inside the frame (charts, diagrams, custom gauges)<agt/agt-sprite.hpp>—AgtSprite(: AgtFrame) a sprite-sheet widget: animates a sub-rectangle of a borrowed sheet bitmap, frame cell by frame cell, on a loop timer (no-copyblit_rect)<agt/agt-animated-image.hpp>—AgtAnimatedImage(: AgtFrame) a flip-book of decoded frames cycled on a timer; the moving counterpart toAgtImage, the still analogue ofAgtSpinner’s motion<agt/agt-edit-box.hpp>—AgtEditBox(: AgtFrame) the multi-line, out-of-core text editor widget over anAxlPieceTreestore (undo/redo, find, soft word-wrap, style buffer); the core of theaxedittoolHex editor subsystem (the
hexviewtool + axedit’s hex view):<agt/agt-hex-box.hpp>—AgtHexBox(: AgtFrame) an offset | hex | ASCII editor widget over anAgtHexSource; nibble editing, selection, masked find, copy/paste, undo<agt/agt-hex-data-panel.hpp>—AgtHexDataPanel(: AgtFrame) a data inspector that decodes the bytes at the caret as int/float types (follows the hex box’s caret signal)<agt/agt-hex-source.hpp>—AgtHexSourcethe byte-source abstraction the hex widgets read/write through, plus its concrete backends:AgtPieceTreeHexSource(a file/text tree, read-only shared view),AgtRangeHexSource(base for fixed ranges),AgtMemoryHexSource(physical RAM) andAgtIoHexSource(x86 I/O ports), via axl-sdkaxl_mem_phys_*/axl_io_*
The chain rationale: every text-bearing widget benefits from AgtFrame’s border + bg machinery; every interactive widget benefits from AgtLabel’s text rendering. Future widgets (checkboxes, radio buttons, edit fields) slot into this chain at the appropriate level — none need to duplicate the bg-fill / border-stroke / text-centering code that AgtFrame + AgtLabel already own.
AgtFrame — bordered, padded background
AgtFrame is the second link in the chain. It contributes
three things every text-bearing or interactive widget benefits
from:
A background fill —
effective_bg_color()returns the color used bydraw()’s backgroundfill_rect. The method is virtual so subclasses with state-dependent backgrounds (notablyAgtButton::effective_bg_colorselecting among normal / hover / pressed / disabled) plug in without duplicating the bg-fill code.A configurable border —
set_border_stylepicks betweenAGT_FRAME_NONE(flat),AGT_FRAME_LINE(single-color outline),AGT_FRAME_RAISED(2D bevel: hilite top-left, shadow bottom-right),AGT_FRAME_SUNKEN(inverted bevel), andAGT_FRAME_ROUNDED(rounded-corner fill via axl-sdk’s G3 path API —set_corner_radiuscontrols the radius).set_border_widthcontrols thickness for the rectangular styles.THICK/GROOVE/RIDGEvariants are reserved further along the enum for additive future work.ROUNDED in v0.1 ships fill-only — RAISED/SUNKEN bevels on rounded corners need anti-aliased stroke on a rounded- rect path with hilite/shadow halves and are deferred as a polish item.
border_widthis accepted by the ctor for API uniformity but no border strokes are emitted in this style.Per-side padding —
set_padding(top, right, bottom, left)(CSS shorthand order; or a singleallvalue) shrinks the interior content rect that subclasses use for text / icon placement.inner_offset_xand friends return the inset from the widget’s top-left;inner_width/inner_heightreturn the interior dimensions (clamped to 0 when the frame is too small).
Subclasses that paint on top of the frame (AgtLabel,
AgtButton) call AgtFrame::draw(ctx) first to render the
background + border, then paint their own content inside the
inner rect.
Default palette
bg_color_defaults to a mid-grey (AXL_GFX_RGB(0x60, 0x60, 0x60)).hilite_color_defaults tobg + 0x30per channel (clamped at 0xFF) — lighter shade for the top-left of a raised bevel.shadow_color_defaults tobg - 0x30per channel (clamped at 0) — darker shade for the bottom-right.border_color_defaults tobg - 0x40per channel — used by the single-colorAGT_FRAME_LINEoutline.
set_bg_color recomputes the accents unless the caller has
individually pinned them via set_hilite_color and friends.
Set bg first, then customize accents, so the accent setters
take effect against the right bg.
AgtLabel — text caption on a frame
AgtLabel is the third link in the chain. It adds a single-
line text caption to AgtFrame’s bordered + padded background.
The text renders inside the inner rect (post-border,
post-padding) honoring AgtLabel::TextAlign for horizontal
placement; vertical is always center for now.
Composition
AgtLabel::draw calls AgtFrame::draw(ctx) first to paint
the bg + border, then positions ctx.draw_text_ttf(...) within
inner_offset_x() / inner_offset_y() /
inner_width() / inner_height(). Empty and NULL labels
suppress the draw_text_ttf op — the frame itself still paints,
so an AgtLabel with label = "" is a labelled-by-omission
bg tile.
Text rendering — TTF
AgtLabel renders text via anti-aliased vector glyphs using
axl_ttf_default() (axl-sdk’s built-in DejaVu Sans subset
covering ASCII + Latin-1 + typographic punctuation). Pixel
height is configurable per instance via set_text_size(float),
default 16.0f.
AgtCheckBox and AgtRadioButton inherit the text_size()
getter from AgtLabel and use the same TTF path for their
labels. Bitmap text is still available via the
ctx.draw_text(...) forwarder for callers that want pixel-grid
console glyphs (e.g. future debug overlays); see the render
module for both APIs.
Alignment
AGT_ALIGN_CENTER(default) — text centered horizontally within the inner rect.AGT_ALIGN_LEFT— text anchored toinner_offset_x.AGT_ALIGN_RIGHT— text right-anchored toinner_offset_x + inner_width - text_width.
Vertical alignment is always center (single-line labels have no other meaningful default). A future multi-line variant will introduce vertical-alignment flags.
Word-wrap (opt-in)
set_wrap(true) switches the label to a multi-line renderer:
the text greedily wraps to inner_width() on space boundaries,
embedded \n forces a break, and a single word wider than the
inner rect overflows on its own line rather than being split
mid-word. The wrapped block is vertically centered in the inner
rect; each line is horizontally aligned per text_align().
Default is OFF — the single-line path (the original behavior) is
untouched, so the wrap code never runs for Button / CheckBox /
RadioButton.
wrapped_height(avail_width) reports the pixel height the text
needs when wrapped to avail_width, so a container can size
itself to fit before laying out — AgtMessageBox uses it to grow
its card to the message body. Measurement uses
axl_ttf_measure_prefix (no per-glyph advance arrays); each line
is sliced into a stack buffer only at draw time for the
null-terminated axl_ttf_draw.
When the measured text width (axl_ttf_measure at
text_size()) exceeds inner_width() (a narrow widget with
a long caption), all alignments fall back to
inner_offset_x + LABEL_INSET so leading characters stay
visible instead of vanishing off the inner rect’s left edge.
Color
set_label_color— used whenenabled() == true. DefaultAXL_GFX_WHITE.set_disabled_label_color— used whenenabled() == false. DefaultAXL_GFX_RGB(0xA0, 0xA0, 0xA0).
Enabled state is inherited from AgtWidget (every widget can
opt into disabling — see the core module).
Defaults
AgtLabel deliberately defaults to border_style = AGT_FRAME_NONE and border_width = 0 (diverging from
AgtFrame’s default border_width = 1). Pairing NONE with a
non-zero border_width would inset inner_offset_x by a
wasted pixel without drawing a visible border; the AgtLabel
default keeps inner_offset_x == padding_left_ for the
borderless case. Bordered labels (status panels, group
headers) opt in via the ctor’s border and border_width
arguments.
AgtCheckBox — binary toggle
AgtCheckBox inherits AgtButton for the click contract,
target wiring, and hover/pressed state machine. Adds a
checked_ state field, a left-side square indicator (outline
inner check when checked), and a left-anchored label to the right of the indicator.
The ctor drops AgtButton’s raised-border default (back to
AGT_FRAME_NONE) so the indicator — not the surrounding
frame — is what reads as interactive. Consumers who want a
bordered checkbox re-enable via set_border_style().
effective_bg_color() overrides AgtButton’s state palette to
return a neutral surface (no hover/pressed tint, that’s
button-y not checkbox-y). Disabled state still reads visually
via AgtButton’s disabled_color.
on_clicked() toggles checked_ and marks dirty. Combined
with set_checked(bool) for programmatic state changes
(doesn’t emit SEL_COMMAND — only click-driven transitions
fire commands, matching FOX FXCheckButton’s contract).
Default indicator size: 14 px square, sized for a 16 px font
line height. set_indicator_size, set_indicator_color,
set_check_color cover theming.
AgtProgressBar — proportional value-fill display
AgtProgressBar is a non-interactive, AgtFrame-derived widget
that paints a proportional fill rectangle inside the inner rect.
The fill width (HORIZONTAL) or height (VERTICAL) tracks
(value - min) / (max - min); horizontal fills left-to-right,
vertical fills bottom-to-top — matching FOX FXProgressBar
and Win32 progress bar conventions.
No AGT_SEL_COMMAND emission, no input handlers; drive via
set_value from whoever owns the underlying state (a long-
running task, a stream reader, a download manager).
set_value clamps to [min, max] so callers can pass raw
streaming values without their own clamp.
Defaults
value = 0,min = 0,max = 100— reads as a percentage gauge out of the box.Orientation defaults to
AGT_ORIENT_HORIZONTAL.Border defaults to
AGT_FRAME_SUNKENwithborder_width = 1— matches Win32 / FOX where the progress bar sits in a sunken well so the filled portion reads as content inside a recess.Fill color defaults to
AXL_GFX_RGB(0x40, 0x90, 0x40)(green that reads as progress over the SUNKEN bg). Override viaset_fill_color.
Range degeneracy
Both max <= min and value == min emit no fill rectangle —
only the AgtFrame chrome paints. This is deliberate: a
misconfigured range (someone passed min and max in the wrong
order) reads as “no progress” rather than crashing or wrapping
around with negative widths. set_range(min > max) is rejected
outright — the range stays unchanged so a fix-up at the caller
isn’t masked by silently swapping.
Overflow safety
The proportional-fill math is done in 64-bit:
(value - min) * inner_w / (max - min). A 32-bit multiply would
overflow for wide ranges (e.g. max = INT32_MAX,
value = INT32_MAX / 2); the explicit int64_t widens before
the multiply so the proportional fill is correct at the
boundaries of the int range.
AgtSlider — draggable thumb on a track
AgtSlider is the interactive sibling of AgtProgressBar. Same
FOX-shape inheritance off AgtFrame for the bg + border + padding,
plus a draggable thumb fill rectangle that the user can grab and
move along the inner rect. HORIZONTAL slides the thumb left-
to-right with value increasing along the way; VERTICAL slides
top-to-bottom with value increasing toward the TOP (FOX FXSlider
convention).
Drag model
Pressing inside the widget snaps the thumb to the click pixel (matching FOX / Win32 trackbar shape — clicking the bare track relocates the thumb immediately, not just clicks-to-start-drag). Subsequent motion updates the value proportionally; release ends the drag.
The slider calls the owning AgtWindow’s capture_mouse while
dragging, so the pointer wandering off-bounds still delivers
motion + release events to the slider. A detached slider (no
window ancestor) skips the capture call and the drag stays
contained inside the slider’s own bounds — useful for unit-test
fixtures.
Commands
AGT_SEL_COMMAND fires on every value change during the drag —
FOX semantics, giving the handler real-time feedback for live
previews (the widgets-demo wires a slider’s SEL_COMMAND to a
paired AgtProgressBar::set_value). Drag motion that doesn’t
quantize to a new integer value emits nothing.
set_value (programmatic) does NOT emit SEL_COMMAND — only
user-driven changes dispatch, mirroring FOX FXSlider’s contract.
Defaults
value=0, min=0, max=100.
Orientation defaults to
AGT_ORIENT_HORIZONTAL.Border defaults to
AGT_FRAME_RAISEDwithborder_width=1(matches AgtButton — reads as interactive).Thumb extent along the orient axis defaults to 20 pixels;
set_thumb_sizeclamps at the lower edge to 4 px (anything narrower stops reading as a thumb) and at the upper edge to the inner extent at draw time.Thumb color defaults to
AXL_GFX_RGB(0xC0, 0xC0, 0xC0)(a neutral light grey that reads over the AgtFrame bg).
Disabled mid-drag
set_enabled(false) while a drag is in progress clears the
dragging flag AND releases the mouse capture — without this,
re-enabling later would leave the slider thinking it still owns
the mouse.
AgtEditField — single-line text input
AgtEditField is the first widget that consumes keyboard
focus. It owns a fixed-size 256-byte text buffer (UTF-8), a
byte-offset cursor, and an anchor byte-offset for click-drag
selection. Inherits AgtFrame for the chrome (sunken border
default, matching Win32 / Motif input-field shape).
Interaction
Click anywhere inside the widget grabs the keyboard focus (
AgtWindow::set_focus(this)) and positions the cursor at the clicked pixel, snapped to the nearest UTF-8 codepoint boundary. The pixel-to-byte binary search usesaxl_ttf_measure_prefixfor O(log n · measure) without materializing per-codepoint advance arrays.Click + drag selects a range. The press grabs the mouse capture (
AgtWindow::capture_mouse(this)) so the pointer leaving the widget bounds during a drag-select doesn’t abort the selection.Backspace deletes one codepoint before the cursor (or the selection if any). Delete removes one codepoint after the cursor. Both step in full UTF-8 codepoints — never slicing a multi-byte sequence in half.
Left / Right arrows move the cursor one codepoint at a time, clearing the selection.
Printable Unicode characters insert at the cursor, replacing the selection if any. Unicode arrives via axl-input’s
unicodefield (UCS-2 codepoint); the widget encodes back to UTF-8 before insertion.Enter (CR or LF unicode) emits
AGT_SEL_COMMAND— matches FOXFXTextField’s “user finished editing” event. After the emit,thismay be destroyed by the target’s handler (same UAF guard convention as AgtButton / AgtSlider).
Not in v0.1: clipboard, Home / End, Shift+arrow selection, word-by-word navigation, multi-line. These slot in cleanly later — the surface is deliberately minimal so the primary use case (entering device names, IP addresses, passwords in pre-boot diagnostics) ships without expanding the test surface beyond what’s strictly justified.
State
text()/length()— current buffer contents.cursor()/anchor()— byte offsets.has_selection()isanchor() != cursor();selection_start()/selection_end()return the low / high bounds regardless of which side anchored first.set_cursor(byte_offset)/set_selection(anchor, cursor)— programmatic positioning. Each clamps to[0, length]and snaps DOWN to the nearest UTF-8 boundary, defending against callers passing mid-codepoint offsets.focused()— true between FOCUSIN and FOCUSOUT. The cursor paints only while focused; the selection highlight paints regardless of focus state (matches Win32 — you can see what’s selected even while another widget has the focus).
Defaults
value =
""(empty buffer).Border
AGT_FRAME_SUNKEN, border_width = 1.Background
AXL_GFX_RGB(0x20, 0x20, 0x28)(dark slate that reads white text + blue selection clearly).Text color
AXL_GFX_WHITE; selection bgAXL_GFX_RGB(0x40, 0x60, 0x90)(muted blue); cursor colorAXL_GFX_WHITE. Override viaset_text_color,set_selection_bg_color,set_cursor_color.MAX_TEXT_LEN = 256bytes. Insertions that would overflow are rejected at the edge;set_texttruncates with a codepoint-boundary snap so a multi-byte glyph never gets sliced.
AgtImage — decoded pixmap display
AgtImage is a non-interactive AgtFrame-derived widget that
decodes a PNG / JPEG / GIF / BMP byte buffer via axl-sdk’s
axl_pixmap_decode and renders the result centered inside the
frame’s inner rect. No input handlers; drive via set_image
when the underlying bytes change (e.g. a remote logo arrives
mid-session).
Ownership
The widget owns the decoded AxlGfxBuffer * for its lifetime
and frees it via axl_gfx_buffer_free in the destructor.
Input bytes are NOT referenced after the ctor / set_image
call — axl_pixmap_decode copies the decoded pixels into a
fresh buffer. Callers can free the source bytes immediately.
Failure handling
If axl_pixmap_decode returns NULL (bad bytes, unsupported
format, allocation failure), the widget stays in the “empty
placeholder” state: image_buffer() returns NULL and draw
paints only the frame chrome. No exception; no abort. A
failed set_image replacement always frees the OLD buffer
first, so there’s no partial state where stale pixels keep
rendering after a failed replace.
Centering, not scaling
Images smaller than the inner rect render centered (integer
math: (inner_w - image_w) / 2). Images larger than the
inner rect are CLIPPED — a push_clip rect matching inner
bounds restricts the blit, and the centered position becomes
negative so the visible portion is the image’s middle.
Scaling is deferred until a consumer asks; pre-boot UI use
cases (vendor logos at fixed asset sizes, small status icons)
don’t need it.
Draw trace shape
[0] FillRect (AgtFrame chrome bg)
[1..N] FillRect (AgtFrame border strips if border_width > 0)
[N+1] PushClip (inner rect)
[N+2] Blit (image pixels at centered position)
[N+3] PopClip
When the widget is empty (no decoded buffer), only the AgtFrame chrome paints — no PushClip, no Blit, no PopClip.
See the API Reference section for the full surface.
API Reference
AgtFrame
-
class AgtFrame : public AgtWidget
Subclassed by AgtAnimatedImage, AgtCanvas, AgtChart, AgtComboBox, AgtDial, AgtEditBox, AgtEditField, AgtExpander, AgtFormBrowser, AgtGrid, AgtGroupBox, AgtHBox, AgtHexBox, AgtHexDataPanel, AgtIcon, AgtImage, AgtLabel, AgtListBox, AgtLogView, AgtMenu, AgtPaned, AgtProgressBar, AgtScale, AgtScrollBar, AgtScrollFrame, AgtSlider, AgtSpinBox, AgtSprite, AgtStatusBar, AgtTabView, AgtTableBase, AgtTerminal, AgtTooltip, AgtTreeView, AgtVBox
Public Types
-
enum BorderStyle
Border decoration style. Values are stable — new variants (THICK / GROOVE / RIDGE) append at the end so existing callers stay binary-compatible.
Values:
-
enumerator AGT_FRAME_NONE
no border drawn
-
enumerator AGT_FRAME_LINE
single-color rectangular outline
-
enumerator AGT_FRAME_RAISED
2D bevel: hilite TL, shadow BR
-
enumerator AGT_FRAME_SUNKEN
inverted bevel: shadow TL, hilite BR
-
enumerator AGT_FRAME_ROUNDED
Rounded-corner fill via
ctx.fill_rounded_rect. Border stroke for ROUNDED is deferred (RAISED/SUNKEN bevels don’t compose with rounded corners in this batch — fill- only is the v0.1 shape). Useset_corner_radiusto control the corner radius; default 0 produces a plain rect (same as AGT_FRAME_NONE visually, but still routed throughaxl_gfx_fill_rounded_rect).
-
enumerator AGT_FRAME_NONE
Public Functions
-
AgtFrame(AgtWidget *parent, int x, int y, int w, int h, BorderStyle border = AGT_FRAME_NONE, int border_width = 1) noexcept
Construct a frame at the given parent-local bounds.
borderdefaults toAGT_FRAME_NONEso a bare AgtFrame is just a colored rectangle until the caller opts in.
-
inline BorderStyle border_style() const noexcept
-
void set_border_style(BorderStyle s) noexcept
-
inline int border_width() const noexcept
-
void set_border_width(int w) noexcept
-
inline int padding_top() const noexcept
-
inline int padding_right() const noexcept
-
inline int padding_bottom() const noexcept
-
inline int padding_left() const noexcept
-
void set_padding(int top, int right, int bottom, int left) noexcept
Set all four paddings. Argument order matches CSS shorthand: top, right, bottom, left. Marks dirty if any value changed.
-
inline void set_padding(int all) noexcept
Convenience: same value for all four sides.
-
inline int inner_offset_x() const noexcept
Interior content area in widget-local coordinates.
offset_*is the inset from the widget’s (x, y) — i.e. add it toctx.origin_x() / origin_y()at draw time to get the absolute content top-left.inner_width/inner_heightare the content dimensions, clamped to 0 (never negative) when the frame is too small to hold any inner area.corner_radiusdoes NOT shrink the inner rect — rounded corners only affect the visible bg silhouette, not the usable interior bounds. Subclasses (AgtLabel) lay out content inside the same rect regardless of border_style.
-
inline int inner_offset_y() const noexcept
-
int inner_width() const noexcept
-
int inner_height() const noexcept
-
inline float corner_radius() const noexcept
Corner radius for
AGT_FRAME_ROUNDED. Ignored by other border styles. Clamped by axl-gfx tomin(w, h) / 2at draw time, so values larger than half the smaller side produce a pill (capsule) shape. Default 0.
-
void set_corner_radius(float r) noexcept
-
inline AxlGfxPixel bg_color() const noexcept
-
inline AxlGfxPixel hilite_color() const noexcept
-
inline AxlGfxPixel shadow_color() const noexcept
-
inline AxlGfxPixel border_color() const noexcept
-
void set_bg_color(AxlGfxPixel c) noexcept
Change the background color and (unless the caller has already overridden them individually) recompute the hilite / shadow / border accents from it. To customize accents: set bg first, then set each accent individually.
-
void set_themed_bg(AxlGfxPixel AgtPalette::* role) noexcept
Set the widget’s THEMED-default background by palette role (a pointer-to-
AgtPalette-member, e.g.&AgtPalette::well_bg) rather than a fixed color. Unlikeset_bg_color, this is NOT a consumer pin:restyle()re-reads the live palette through the role on a theme swap, so a widget that picks its surface token this way recolors live. Widgets call this in their constructor instead ofset_bg_color(AgtPalette::current().token); accents derive from the resolved color exactly asset_bg_color.
-
void set_hilite_color(AxlGfxPixel c) noexcept
-
void set_shadow_color(AxlGfxPixel c) noexcept
-
void set_border_color(AxlGfxPixel c) noexcept
-
virtual AxlGfxPixel effective_bg_color() const noexcept
Color used for
draw()’s background fill_rect. Default returnsbg_color(); subclasses (notablyAgtButton) override to swap palettes based on state — letting AgtFrame stay agnostic about WHY the color is what it is, just painting whatever the subclass declares.
-
void set_bg_gradient(AxlGfxPixel top, AxlGfxPixel bottom) noexcept
Fill the background with a vertical gradient (top at the top edge → bottom at the bottom) instead of the flat
effective_bg_color(). A glossy/raised look for buttons, panels, etc.Overrides state coloring: the gradient is drawn as-is in every state, so a subclass whose
effective_bg_color()varies by state (e.g.AgtButton’s normal/hover/pressed) loses that feedback while a gradient is set. Honored by both the square andAGT_FRAME_ROUNDEDfills (the rounded path uses the AA rounded-gradient primitive).
-
void set_bg_gradient_auto(bool on) noexcept
Enable a STATE-AWARE background gradient: at draw time the top is
effective_bg_color()(so it tracks normal/hover/pressed) and the bottom is that color darkened byAgtPalette::button.gradient_sheen. The glossy default for buttons; unlikeset_bg_gradientit doesn’t freeze the state coloring.
-
void clear_bg_gradient() noexcept
Drop the background gradient (explicit or auto) — flat fill again.
-
inline bool has_bg_gradient() const noexcept
True while a background gradient is active.
-
inline bool bg_gradient_is_auto() const noexcept
Gradient introspection for the renderer (
AgtStyle::draw_frame). In AUTO mode the endpoints are derived at draw time from the liveeffective_bg_color()+ the themed sheen; in explicit mode they are the storedset_bg_gradientcolors.
-
inline AxlGfxPixel bg_gradient_top() const noexcept
-
inline AxlGfxPixel bg_gradient_bottom() const noexcept
-
void draw(AgtDrawContext &ctx) override
Paints background then border on top. Override only if the whole compositing order needs to change; subclasses that just want to paint content inside the inner rect should call
AgtFrame::draw(ctx)then do their own work.
-
void restyle() noexcept override
Re-snapshot the background + derived accents from the live
palette()(QtchangeEventshape) unless the consumer pinned them viaset_bg_color/set_*_color. Called byrestyle_tree()after a palette swap.
Public Static Functions
-
static AxlGfxPixel shade(AxlGfxPixel c, int delta) noexcept
Channel-wise lighten (+delta) / darken (−delta) with saturation clamping; alpha preserved. The shared bevel/gloss shading helper — used by
AgtFrame’s accent derivation and the renderer’s auto-gradient ramp.
-
enum BorderStyle
AgtLabel
-
class AgtLabel : public AgtFrame
Subclassed by AgtButton, AgtLight
Public Types
-
enum TextAlign
Horizontal alignment of the label within the inner rect. Vertical alignment is always center. Stable enum values (CENTER == 0 = default) so callers using the default don’t need to import the enum just to construct an AgtLabel.
Values:
-
enumerator AGT_ALIGN_CENTER
-
enumerator AGT_ALIGN_LEFT
-
enumerator AGT_ALIGN_RIGHT
-
enumerator AGT_ALIGN_CENTER
Public Functions
-
AgtLabel(AgtWidget *parent, int x, int y, int w, int h, const char *label, BorderStyle border = AGT_FRAME_NONE, int border_width = 0) noexcept
Construct a label.
borderandborder_widthdefault to NONE / 0 — a bare AgtLabel renders text on a solid bg rectangle with no border, matching the “just a piece of
text” use case. Bordered labels (status panels, group headers) opt in by passing a non-NONE style.
Deliberate divergence from AgtFrame’s default
border_width = 1: pairing AGT_FRAME_NONE withborder_width = 1would insetinner_offset_xby a wasted pixel even though no border is drawn. AgtLabel’s border-disabled default mirrors that visually.
-
AgtLabel(AgtWidget *parent, const char *label, BorderStyle border = AGT_FRAME_NONE, int border_width = 0) noexcept
Geometry-free ctor (FOX
new FXLabel(p,"text")): no x/y/w/h — the label reports its measured text size vianatural_*()and a layout container sizes/places it. Both axes start AUTO (un-pinned); a laterset_bounds/set_fixed_*pins them.
-
int natural_width() const noexcept override
Natural size = measured text + the frame’s border/padding chrome. With
wrap()ON, the natural size measures the **explicit-newline (\n) block** — the widest\n-delimited line for the width, the line count for the height — which is width-INDEPENDENT, so a multi-line caption (andAgtButton, which inherits this) auto-sizes to its block. (Pure word-wrap to a narrower width than the natural block still needs a fixed width — that wrap target the single-pass box layout can’t negotiate.)
-
int natural_height() const noexcept override
-
inline const char *label() const noexcept
-
void set_label(const char *label) noexcept
-
inline int mnemonic_index() const noexcept
Index (into
label()) of a single character to underline — the keyboard MNEMONIC cue (e.g. the “F” of “File”). -1 (default) draws no underline. Honored only on the single-line caption path; the wrapped path ignores it.AgtMenuItem::set_mnemonicderives this from a letter; most widgets never set it.
-
void set_mnemonic_index(int index) noexcept
-
inline AxlGfxPixel label_color() const noexcept
-
inline AxlGfxPixel disabled_label_color() const noexcept
-
void set_label_color(AxlGfxPixel c) noexcept
-
void set_disabled_label_color(AxlGfxPixel c) noexcept
-
inline float text_size() const noexcept
Font pixel height passed to
axl_ttf_draw/axl_ttf_measure. Default 16.0f — close to the bitmap LaffStd height the pre-TTF AgtLabel used, so a label that fits in its inner rect at the bitmap path keeps fitting after TTF adoption. Subclasses (AgtCheckBox / AgtRadioButton) inherit and reuse this setter for their own label rendering.
-
void set_text_size(float px_size) noexcept
-
inline bool wrap() const noexcept
Word-wrap mode. Default OFF — the label renders a single line (vertically centered), the original behavior. When ON, the text greedily wraps to the inner width on word (space) boundaries, honoring embedded
\nas forced breaks; the wrapped block is vertically centered in the inner rect and each line is horizontally aligned pertext_align(). A single word wider than the inner rect overflows on its own line rather than being split mid-word. Used byAgtMessageBoxfor multi-line message bodies; reusable for any flowed text (help blurbs, hints).
-
void set_wrap(bool on) noexcept
-
int wrapped_height(int avail_width) const noexcept
Pixel height needed to render the current label wrapped to avail_width (the content width, i.e. what
inner_width()would be). Returns one line-height for empty / NULL text. Lets a container (e.g.AgtMessageBox) size itself to fit the wrapped body before laying out. Independent of thewrap()flag — it always measures as if wrapping.
-
void draw(AgtDrawContext &ctx) override
Delegates to the renderer (
AgtStyle::draw_label): bg + border then the caption. Suppressed for NULL / empty labels — the frame still paints.
-
void draw_caption(AgtDrawContext &ctx) const
Paint just the caption (single-line aligned, or wrapped) inside the inner rect — the text half of the label, with the frame already painted. Called by
AgtStyle::draw_labelafter the frame chrome; the intricate wrap layout stays widget-owned (Qt keeps complex text layout in the widget, not the style).
-
void restyle() noexcept override
Re-snapshot the label/disabled-label colors + text size from the live palette after a theme swap.
Public Static Functions
-
enum TextAlign
AgtCheckBox
-
class AgtCheckBox : public AgtButton
Subclassed by AgtSwitch
Public Types
Public Functions
-
AgtCheckBox(AgtWidget *parent, int x, int y, int w, int h, const char *label, AgtObject *target = nullptr, uint16_t target_id = 0, bool checked = false) noexcept
-
AgtCheckBox(AgtWidget *parent, const char *label, AgtObject *target = nullptr, uint16_t target_id = 0, bool checked = false) noexcept
Geometry-free ctor (FOX
new FXCheckButton(p,"label")): no x/y/w/h — the checkbox sizes to indicator + gap + label vianatural_*()and a layout container places it. Both axes start AUTO.
-
int natural_width() const noexcept override
Natural size = indicator + gap + label (not the button-face padding AgtButton uses), tall enough for the larger of indicator / text.
-
int natural_height() const noexcept override
-
inline bool checked() const noexcept
-
void set_checked(bool c) noexcept
Set checked state and mark dirty. No-op when unchanged. Does NOT emit SEL_COMMAND — only click-driven transitions fire commands (matches FOX FXCheckButton’s contract).
-
inline int indicator_size() const noexcept
Indicator size in pixels (square outline + inner check when checked). Default 14; sized for a 16px label.
-
void set_indicator_size(int px) noexcept
-
inline AxlGfxPixel indicator_color() const noexcept
Indicator outline color. Default WHITE.
-
void set_indicator_color(AxlGfxPixel c) noexcept
-
inline AxlGfxPixel check_color() const noexcept
Inner fill color when checked. Default WHITE.
-
void set_check_color(AxlGfxPixel c) noexcept
-
AxlGfxPixel effective_bg_color() const noexcept override
Neutral surface color — no hover/pressed tint (that’s button-y). Returns
disabled_color()when!enabled()so disabled state still reads visually; otherwise the inherited AgtFramebg_color().
-
void on_clicked() noexcept override
Toggle
checked_and mark dirty. Called fromAgtButton::on_left_button_releasejust before the SEL_COMMAND emit, so the target’s handler sees the new state viasender->checked().
-
void draw(AgtDrawContext &ctx) override
Delegates to the renderer (
AgtStyle::draw_checkbox): bg, the indicator (outline + optional inner check), then the trailing label.
-
void restyle() noexcept override
Re-snapshot indicator/check colors + size and re-assert the flat, borderless surface after a theme swap.
-
uint32_t state_flags() const noexcept override
Adds CHECKED when ticked.
-
AgtCheckBox(AgtWidget *parent, int x, int y, int w, int h, const char *label, AgtObject *target = nullptr, uint16_t target_id = 0, bool checked = false) noexcept
AgtProgressBar
-
class AgtProgressBar : public AgtFrame
Public Types
Public Functions
-
AgtProgressBar(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
Construct a progress bar at x, y of size (w, h). value is clamped to [min, max] at construction; if max <= min the range is degenerate and the fill stays zero-width regardless of value (so a misconfigured range reads as “no progress” rather than crashing or wrapping). Default border is
AGT_FRAME_SUNKENwithborder_width = 1— matches Win32 / FOX where progress bars sit in a sunken well so the filled portion reads as content inside a recess.
-
inline int value() const noexcept
Current value, clamped to [min, max].
-
void set_value(int v) noexcept
Set the current value, clamped to [min, max]. Mark-dirties only on actual change (no spurious redraw for set-to-same). Caller does not need to clamp themselves — pass a raw streaming value and the widget tames it.
-
inline int min() const noexcept
-
inline int max() const noexcept
-
void set_range(int min, int max) noexcept
Replace the range. Rejects min > max (range stays unchanged in that case — same pattern as
AgtLabel::set_text_sizerejecting non-positive sizes). Re-clamps the current value to the new range.
-
inline Orientation orientation() const noexcept
-
void set_orientation(Orientation o) noexcept
-
inline AxlGfxPixel fill_color() const noexcept
Color of the proportional fill. Default
AXL_GFX_RGB(0x40, 0x90, 0x40)— a green that reads as progress over the default sunken AgtFrame bg. Override to theme.
-
void set_fill_color(AxlGfxPixel c) noexcept
-
void set_fill_gradient(AxlGfxPixel top, AxlGfxPixel bottom) noexcept
Fill the progress bar with a vertical gradient (top → bottom) instead of the flat
fill_color()— a glossy bar.
-
void clear_fill_gradient() noexcept
Drop the fill gradient, back to a flat
fill_color().
-
inline bool has_fill_gradient() const noexcept
-
inline AxlGfxPixel fill_gradient_top() const noexcept
Fill-gradient endpoints (valid when
has_fill_gradient()) — read by the renderer (AgtStyle::draw_progress).
-
inline AxlGfxPixel fill_gradient_bottom() const noexcept
-
void draw(AgtDrawContext &ctx) override
Paints AgtFrame::draw (bg + border) then the proportional fill rectangle inside the inner rect. Degenerate ranges (max <= min) or zero progress (value == min) emit no fill — only the AgtFrame chrome. Full progress (value == max) fills the entire inner rect.
-
void restyle() noexcept override
Re-snapshot the fill color from the live palette on a theme swap.
Public Static Functions
-
AgtProgressBar(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
AgtScale
-
class AgtScale : public AgtFrame
Public Types
Public Functions
-
AgtScale(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
Construct a scale at x, y of size (w, h). value is clamped to [min, max]; a degenerate range (max <= min) reads as “at min”. Default border is
AGT_FRAME_SUNKENwidth 1 — the track sits in a recessed well (matching AgtProgressBar).
-
inline int value() const noexcept
-
void set_value(int v) noexcept
Set the value, clamped to [min, max]. Mark-dirties only on change.
-
inline int min() const noexcept
-
inline int max() const noexcept
-
void set_range(int min, int max) noexcept
Replace the range (rejects min > max; re-clamps the value).
-
inline Orientation orientation() const noexcept
-
void set_orientation(Orientation o) noexcept
-
inline int tick_interval() const noexcept
Major tick spacing in value units (0 = no ticks).
-
inline int minor_divisions() const noexcept
Sub-divisions drawn between each major tick (1 = none).
-
void set_ticks(int major_step, int minor_div = 1) noexcept
Set the major tick spacing (value units) and the minor sub-division count per major interval. major_step <= 0 disables ticks; minor_div is clamped to >= 1.
-
inline int band_count() const noexcept
-
void set_bands(const Band *bands, int count) noexcept
Copy up to
MAX_BANDSbands (extra are dropped). Marks dirty.
-
void clear_bands() noexcept
-
int band_at(int v) const noexcept
Index of the first band whose
[lo, hi]contains v, or -1.
-
inline AxlGfxPixel fill_color() const noexcept
-
inline AxlGfxPixel tick_color() const noexcept
-
inline AxlGfxPixel needle_color() const noexcept
-
void set_fill_color(AxlGfxPixel c) noexcept
Pin a color (consumer override that survives a theme swap).
-
void set_tick_color(AxlGfxPixel c) noexcept
-
void set_needle_color(AxlGfxPixel c) noexcept
-
AxlGfxPixel active_fill_color() const noexcept
The fill color used RIGHT NOW: the color of the band containing the current value (FILL mode’s zone coloring), or
fill_color()when no band applies. The renderer reads this so band-coloring stays widget-owned.
-
int track_length() const noexcept
Length of the track in pixels along the orient axis (inner width for horizontal, inner height for vertical).
-
int value_position(int v) const noexcept
Pixel offset from the MIN end of the track for value v (0 at min,
track_length()at max). v is clamped to the range; a degenerate range maps to 0. Orientation-independent — the renderer maps the offset to the correct physical end.
-
void draw(AgtDrawContext &ctx) override
Paints the well chrome then the bands / indicator / ticks.
-
void restyle() noexcept override
Re-snapshot the fill / tick / needle colors from the live palette, unless a consumer pinned them.
Public Static Functions
Public Static Attributes
-
static constexpr int MAX_BANDS = 8
Maximum threshold bands stored (copied, fixed array — no alloc).
-
struct Band
A colored threshold zone over
[lo, hi](inclusive), in value units. Bands are app-specific (safe/warn/critical limits), so the color is given explicitly rather than themed.
-
AgtScale(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
AgtDial
-
class AgtDial : public AgtFrame
Public Functions
-
AgtDial(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100) noexcept
Construct a dial at x, y of size (w, h). value is clamped to [min, max]; a degenerate range (max <= min) parks the needle at
min.
-
inline int value() const noexcept
-
void set_value(int v) noexcept
-
inline int min() const noexcept
-
inline int max() const noexcept
-
void set_range(int min, int max) noexcept
-
inline double sweep_deg() const noexcept
Total angular sweep in degrees (the arc the needle travels from
mintomax). Default 270. Clamped to (0, 360]. At a full 360° sweepminandmaxland on the SAME point (bottom / 6 o’clock), so a tick at each coincides — expected for a full-circle gauge.
-
void set_sweep_deg(double deg) noexcept
-
double value_angle(int v) const noexcept
Compass angle (degrees, 0 = up, clockwise) the needle points at for value v (clamped to the range). Monotonic in v — not wrapped to [0, 360) — so a 270° gauge yields
min=225°, mid=360°,max=495°.
-
inline double start_angle() const noexcept
Needle angle at
min(=360 - sweep/2) and atmax(= start+sweep).
-
inline double end_angle() const noexcept
-
inline int tick_interval() const noexcept
-
inline int minor_divisions() const noexcept
-
void set_ticks(int major_step, int minor_div = 1) noexcept
Major tick spacing (value units; 0 = none) + minor sub-divisions per major interval (1 = none).
-
inline AxlGfxPixel needle_color() const noexcept
-
inline AxlGfxPixel tick_color() const noexcept
-
void set_needle_color(AxlGfxPixel c) noexcept
-
void set_tick_color(AxlGfxPixel c) noexcept
-
void draw(AgtDrawContext &ctx) override
Paints the face, tick marks, the needle, and the hub.
-
void restyle() noexcept override
Re-snapshot the needle / tick colors from the live palette unless a consumer pinned them.
Public Static Functions
-
AgtDial(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100) noexcept
AgtChart
-
class AgtChart : public AgtFrame
Public Functions
-
AgtChart(AgtWidget *parent, int x, int y, int w, int h, int capacity = DEFAULT_CAPACITY) noexcept
Construct a chart. capacity is the ring-buffer size (clamped to [1, MAX_CAPACITY]). Default border is
AGT_FRAME_SUNKENwidth 1 — the plot sits in a recessed well (matching AgtProgressBar / AgtScale).
-
inline int capacity() const noexcept
-
inline int count() const noexcept
-
double sample(int i) const noexcept
Sample at index i in
[0, count())— 0 is the OLDEST,count()-1the newest. Out-of-range returns 0.
-
void push(double v) noexcept
Append a sample; once full, the oldest is dropped (scroll). Marks dirty.
-
void clear() noexcept
Drop all samples. Marks dirty.
-
inline bool auto_range() const noexcept
-
void set_auto_range(bool on) noexcept
Turn auto-ranging on (range tracks the data min/max) or off (keeps the last
set_y_range).
-
void set_y_range(double lo, double hi) noexcept
Pin a fixed value range (turns auto-ranging OFF). Rejects lo >= hi.
-
double active_y_min() const noexcept
The value range currently in effect: the fixed range, or — in auto mode — the data’s min/max (a unit window around a single level, or [0, 1] when empty).
-
double active_y_max() const noexcept
-
inline int grid_divisions() const noexcept
-
void set_grid_divisions(int n) noexcept
Number of horizontal grid INTERVALS (0 = no gridlines); draws
grid_divisions + 1lines spanning the plot. Clamped to >= 0.
-
int sample_x(int i) const noexcept
Widget-local x pixel for sample index i (oldest at the left edge, newest at the right). A single sample sits at the left.
-
int value_y(double v) const noexcept
Widget-local y pixel for value v through the active range (clamped; larger values map UP, i.e. to a smaller y).
-
inline AxlGfxPixel line_color() const noexcept
-
inline AxlGfxPixel grid_color() const noexcept
-
void set_line_color(AxlGfxPixel c) noexcept
-
void set_grid_color(AxlGfxPixel c) noexcept
-
void draw(AgtDrawContext &ctx) override
Paints the well chrome, the gridlines, then the series polyline.
-
void restyle() noexcept override
Re-snapshot the line / grid colors from the live palette unless pinned.
Public Static Functions
-
AgtChart(AgtWidget *parent, int x, int y, int w, int h, int capacity = DEFAULT_CAPACITY) noexcept
AgtSlider
-
class AgtSlider : public AgtFrame
Public Types
Public Functions
-
AgtSlider(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL, AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
-
inline int value() const noexcept
-
void set_value(int v) noexcept
Set the value programmatically. Clamps to [min, max]; no SEL_COMMAND is emitted (only drag-driven changes dispatch — matches FOX FXSlider’s
setValuecontract).
-
inline int min() const noexcept
-
inline int max() const noexcept
-
void set_range(int min, int max) noexcept
Rejects min > max; re-clamps current value.
-
inline Orientation orientation() const noexcept
-
void set_orientation(Orientation o) noexcept
-
inline int thumb_size() const noexcept
Thumb extent along the orient axis, in pixels. Default 20. Clamped at the lower edge to 4 px (any narrower stops reading as a thumb); upper bound is enforced at draw time against the inner rect.
-
void set_thumb_size(int s) noexcept
-
inline AxlGfxPixel thumb_color() const noexcept
-
void set_thumb_color(AxlGfxPixel c) noexcept
-
int thumb_origin() const noexcept
Thumb’s widget-local top-left along the orient axis (local x for HORIZONTAL, local y for VERTICAL) — the value-to-pixel mapping the renderer (
AgtStyle::draw_slider) needs to place the thumb.
-
inline uint16_t target_id() const noexcept
-
void set_enabled(bool enabled) noexcept override
Override AgtWidget::set_enabled to also clear dragging_ on a disable transition — a slider disabled mid-drag would otherwise keep capturing the mouse silently.
-
inline bool dragging() const noexcept
Inspection (for tests). True between a successful press and the matching release (clearing on either release or
set_enabled(false)).
-
inline uint32_t focus_policy() const noexcept override
Sliders accept keyboard focus so future arrow-key adjustment lands cleanly; currently they only emit on drag, but the focus inclusion is the right shape.
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot the thumb color / size from the live palette on a theme swap.
Public Static Functions
-
AgtSlider(AgtWidget *parent, int x, int y, int w, int h, int value = 0, int min = 0, int max = 100, Orientation orient = AGT_ORIENT_HORIZONTAL, AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
AgtEditField
-
class AgtEditField : public AgtFrame
Subclassed by AgtPasswordField, AgtSearchEntry
Public Types
-
enum EchoMode
How the buffer is DISPLAYED (the value is always stored in full and readable via
text()). The FOXTEXTFIELD_PASSWD/ QtQLineEdit::EchoModeshape — a property, not a separate widget, soAgtPasswordFieldand the forms framework reuse the same field.Values:
-
enumerator AGT_ECHO_NORMAL
show the real glyphs (default)
-
enumerator AGT_ECHO_PASSWORD
one masking dot per codepoint
-
enumerator AGT_ECHO_NO_ECHO
draw nothing (PIN / sudo style)
-
enumerator AGT_ECHO_NORMAL
Public Functions
-
AgtEditField(AgtWidget *parent, int x, int y, int w, int h, const char *text = "", AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
-
AgtEditField(AgtWidget *parent, const char *text = "", AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
Geometry-free ctor (FOX
new FXTextField(p, ncols)): no x/y/w/h — the field takes a default visible width (NATURAL_COLUMNS) + text height vianatural_*()and a layout container places it. Both axes AUTO.
-
int natural_width() const noexcept override
Natural size:
NATURAL_COLUMNSdigit-widths + text inset, one text line + a little vertical breathing room, plus the frame chrome.
-
int natural_height() const noexcept override
-
inline const char *text() const noexcept
Current buffer (NUL-terminated UTF-8). The pointer stays valid until the next
set_textor edit operation.
-
inline int length() const noexcept
-
void set_text(const char *text) noexcept
Replace the buffer contents. Truncates at MAX_TEXT_LEN (at a UTF-8 codepoint boundary — won’t slice a multi-byte glyph in half). Resets cursor to the end, clears selection, marks dirty. Emits no
AGT_SEL_COMMAND(programmatic set; only user-driven Enter dispatches).
-
inline int cursor() const noexcept
Cursor byte offset into the buffer. Always falls on a UTF-8 codepoint boundary (the setters enforce this).
-
inline int anchor() const noexcept
Anchor byte offset. Equal to cursor when there’s no selection; otherwise the selection spans
[min(anchor, cursor), max(anchor, cursor)).
-
inline int selection_start() const noexcept
-
inline int selection_end() const noexcept
-
inline bool has_selection() const noexcept
-
void set_cursor(int byte_offset) noexcept
Move the cursor to byte_offset (clamped to
[0, length], then snapped DOWN to the nearest codepoint boundary). Clears any selection.
-
void set_selection(int anchor, int cursor) noexcept
Set both anchor and cursor directly. Each is independently clamped + boundary-snapped. Anchor != cursor produces a selection.
-
void select_word_at(int byte_offset) noexcept
Select the run of like-classed characters (word chars, whitespace, or other punctuation) containing the byte at byte_offset — the double-click gesture, and a menu-callable “Select Word”. At a word/non-word boundary the word side wins.
-
void select_all() noexcept
Select the whole field (anchor 0, cursor at the end) — the triple-click gesture / “Select All”.
-
void copy() noexcept
Copy the current selection to the process clipboard as UTF-8 text (
axl_clipboard_set). No-op (clipboard untouched) with no selection.
-
void cut() noexcept
Copy the selection, then delete it — as one action. No-op with no selection; the delete only runs if the copy succeeded (a failed capture never loses the text).
-
void paste() noexcept
Insert the clipboard’s text at the cursor, replacing any selection. A non-text payload or empty clipboard is ignored. Single-line: pasted text is truncated at the first line break.
-
void set_echo_mode(EchoMode m) noexcept
Set how the buffer is displayed. The stored value is unchanged and still readable via
text(); only the rendering + clipboard policy change. Marks dirty. In a masked mode (PASSWORD/NO_ECHO)copy()/cut()are suppressed so the secret can’t be exfiltrated to the clipboard (paste()still works — you can paste a secret in).
-
inline bool echo_masked() const noexcept
True while the displayed text is masked (echo mode != NORMAL).
-
inline uint32_t password_char() const noexcept
Codepoint drawn (as a filled dot) per character in
PASSWORDmode. Stored as a Unicode scalar but RENDERED as a procedural disc, so the value is font-independent — it exists mainly so a consumer/theme can reason about the mask; the default is U+00B7 MIDDLE DOT.
-
void set_password_char(uint32_t codepoint) noexcept
-
inline bool cursor_blink() const noexcept
Whether the cursor blinks while focused (default true). Pauses solid for one interval after cursor activity. Disable for a steady cursor (accessibility, or deterministic screenshots).
-
inline void set_cursor_blink(bool on) noexcept
-
inline uint32_t cursor_blink_interval() const noexcept
-
inline void set_cursor_blink_interval(uint32_t ms) noexcept
-
inline bool cursor_blink_visible() const noexcept
True when the blink phase shows the cursor now (always true while disabled). The draw gate ANDs this with focus.
-
inline void blink_tick() noexcept
One blink half-cycle (the loop-timer trampoline + direct testing).
-
inline AxlGfxPixel text_color() const noexcept
-
inline AxlGfxPixel selection_bg_color() const noexcept
-
inline AxlGfxPixel cursor_color() const noexcept
-
void set_text_color(AxlGfxPixel c) noexcept
-
void set_selection_bg_color(AxlGfxPixel c) noexcept
-
void set_cursor_color(AxlGfxPixel c) noexcept
-
inline float text_size() const noexcept
TTF text height (px). Defaults from
AgtPalette::current().text_size.
-
void set_text_size(float px) noexcept
-
inline uint16_t target_id() const noexcept
-
inline bool focused() const noexcept
True between AGT_SEL_FOCUSIN and AGT_SEL_FOCUSOUT. The cursor only paints while focused; the selection highlight paints regardless (matches Win32 — losing focus keeps the selection visible so you can see what was selected).
-
inline uint32_t focus_policy() const noexcept override
Editable text fields are always Tab-cycle focusable.
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot text/selection/cursor colors + size + edit bg on a theme swap.
Public Static Functions
Public Static Attributes
-
static constexpr int MAX_TEXT_LEN = 256
Inline buffer length. 256 bytes covers most practical inputs (path component, device name, URL fragment) plus some Unicode headroom. Inputs longer than this are rejected at the insertion edge — the field never truncates after the fact.
-
static constexpr uint16_t ID_LAST = AgtFrame::ID_LAST
FOX-style message-ID chain (see
AgtFrame::ID_LAST).
-
static constexpr int NATURAL_COLUMNS = 12
Default visible width in “0”-glyph columns when auto-sized (FOX ncols).
-
enum EchoMode
AgtImage
-
class AgtImage : public AgtFrame
Public Types
-
enum ScaleMode
How the decoded image is fitted into the inner rect.
Values:
-
enumerator AGT_IMAGE_CENTER
1:1 pixels, centered; an image larger than the inner rect is clipped. The default — no resampling, exact pixels (right for fixed-size logos / icons).
-
enumerator AGT_IMAGE_FIT
Scale preserving aspect ratio to the largest size that fits inside the inner rect, then center. Nearest- neighbor resample (cached).
-
enumerator AGT_IMAGE_STRETCH
Stretch to fill the inner rect exactly, ignoring aspect ratio. Nearest-neighbor resample (cached).
-
enumerator AGT_IMAGE_CENTER
Public Functions
-
AgtImage(AgtWidget *parent, int x, int y, int w, int h, const uint8_t *bytes = nullptr, size_t len = 0) noexcept
Construct an image widget and decode bytes immediately. Pass
NULL/0for an empty placeholder (just the frame chrome; set image later viaset_image).
-
~AgtImage() noexcept override
Free the decoded buffer. Cascades through AgtFrame’s children (this widget has none of its own).
-
void set_image(const uint8_t *bytes, size_t len) noexcept
Replace the current image. Frees the previous decoded buffer, decodes bytes via
axl_pixmap_decode. PassNULL/0to clear back to the empty placeholder state. On decode failure, the widget ends up in the empty state (previous image still freed — no half-state). Mark-dirty fires either way so the consumer’s next redraw paints the new state.
-
inline AxlGfxBuffer *image_buffer() const noexcept
Decoded buffer or NULL. Pointer is stable until the next
set_imageor destruction. Exposed for diagnostics + tests; production code shouldn’t need direct access. Returned non-const becauseaxl_gfx_buffer_pixels/axl_gfx_buffer_get_infotake non-const buffer handles — holding the const-correctness line here would force aconst_castat every consumer.
-
inline int image_width() const noexcept
Decoded image dimensions in pixels. Both report 0 when the widget is in the empty state (no buffer). Stable for the lifetime of the current buffer.
-
inline int image_height() const noexcept
-
inline ScaleMode scale_mode() const noexcept
Fit mode (default
AGT_IMAGE_CENTER). FIT / STRETCH resample via nearest-neighbor into a cached scaled buffer that is rebuilt only when the target size or source image changes — redraws at a steady size pay no resample cost.
-
void draw(AgtDrawContext &ctx) override
Public Static Functions
-
enum ScaleMode
AgtScrollBar
-
class AgtScrollBar : public AgtFrame
Public Types
Public Functions
-
AgtScrollBar(AgtWidget *parent, int x, int y, int w, int h, Orientation orient = AGT_ORIENT_VERTICAL, AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
-
inline int total() const noexcept
-
inline int page() const noexcept
-
void set_range(int total, int page) noexcept
Set the content extent + visible page (both clamped to >= 0). Re-clamps
positioninto the new[0, total - page]range. No SEL_COMMAND (programmatic).
-
inline int position() const noexcept
-
int max_position() const noexcept
The largest valid position,
max(0, total - page).
-
void set_position(int p) noexcept
Set the scroll position programmatically; clamps to
[0, max_position()]. No SEL_COMMAND (matchesAgtSlider::set_value— only user drag/paging dispatches).
-
inline Orientation orientation() const noexcept
-
void set_orientation(Orientation o) noexcept
-
inline int min_thumb() const noexcept
Minimum thumb extent along the orient axis, in pixels — the thumb never shrinks below this however small
page / totalgets, so it stays grabbable. Default 16.
-
void set_min_thumb(int px) noexcept
-
inline AxlGfxPixel thumb_color() const noexcept
-
void set_thumb_color(AxlGfxPixel c) noexcept
-
inline uint16_t target_id() const noexcept
-
void set_enabled(bool enabled) noexcept override
Clears an in-flight drag (+ releases capture) on a disable transition — same guard as AgtSlider.
-
inline bool dragging() const noexcept
True between a successful thumb press and its release.
-
inline uint32_t focus_policy() const noexcept override
A scrollbar is not a Tab-focus target — the widget it scrolls (listbox, scrollframe) owns the keyboard; the bar is a mouse affordance. (The default is already
AGT_FOCUS_NONE; stated explicitly for intent.)
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot thumb color/metrics + well bg on a theme swap.
-
int thumb_extent() const noexcept
Thumb extent along the orient axis, in pixels (proportional to
page / total, clamped to[min_thumb, track]).
-
int thumb_offset() const noexcept
Thumb top-left offset along the orient axis, in pixels measured from the inner-rect start (
inner_offset_*). 0 at position 0.
Public Static Functions
-
AgtScrollBar(AgtWidget *parent, int x, int y, int w, int h, Orientation orient = AGT_ORIENT_VERTICAL, AgtObject *target = nullptr, uint16_t target_id = 0) noexcept
AgtListBox
-
class AgtListBox : public AgtFrame
Public Types
Message-ID chain. ID_SCROLLBAR is the id the owned scrollbar targets the list with (internal); consumer command ids start at ID_LAST.
Values:
-
enumerator ID_SCROLLBAR
-
enumerator ID_LAST
-
enumerator ID_SCROLLBAR
-
enum Orientation
Layout axis. VERTICAL (default) stacks rows top-to-bottom with a right-edge scrollbar; HORIZONTAL lays items left-to-right — a filmstrip / strip of choices — with a bottom-edge scrollbar. The item model, selection, and command wiring are identical either way; only the layout
scrollbar axis flip.
Values:
-
enumerator AGT_ORIENT_VERTICAL
-
enumerator AGT_ORIENT_HORIZONTAL
Public Functions
-
AgtListBox(AgtWidget *parent, int x, int y, int w, int h, AgtObject *target = nullptr, uint16_t target_id = 0, Orientation orient = AGT_ORIENT_VERTICAL) noexcept
-
~AgtListBox() noexcept override
-
int add_item(const char *text) noexcept
Append a row (the text is copied). Returns the new row index, or -1 on allocation failure / NULL text.
-
int add_item(const char *text, AgtStyle::StockIcon icon) noexcept
Append a row with a leading built-in stock icon (drawn left of the text in the row color). Same copy/return contract as
add_item.
-
void clear() noexcept
Remove all rows, freeing their text. Resets selection + scroll.
-
int item_count() const noexcept
-
const char *item_text(int index) const noexcept
Row text at index, or NULL if out of range. Borrowed — the list owns it.
-
bool item_has_icon(int index) const noexcept
Whether row index carries a leading stock icon.
-
AgtStyle::StockIcon item_icon(int index) const noexcept
Row index’s stock icon (meaningful only when
item_has_icon).
-
inline int current() const noexcept
-
void set_current(int index) noexcept
Set the selection programmatically (clamped to [-1, count-1]; -1 clears). Scrolls it into view. No SEL_COMMAND.
-
inline Orientation orientation() const noexcept
Layout axis (default VERTICAL).
-
void set_orientation(Orientation o) noexcept
Switch the layout axis: moves the scrollbar to the right (VERTICAL) or bottom (HORIZONTAL) edge, re-lays out, and re-clamps the scroll.
-
inline int item_width() const noexcept
Per-item extent along the MAIN axis:
row_height()is the height of a row in VERTICAL mode;item_width()is the width of an item cell in HORIZONTAL mode. Each is used only in its own orientation.
-
void set_item_width(int px) noexcept
-
inline int top() const noexcept
First visible item index (scroll position in item units).
-
int visible_rows() const noexcept
Number of fully-visible items in the content area — rows in VERTICAL mode, columns in HORIZONTAL mode.
-
void ensure_visible(int index) noexcept
Scroll index into view (unconditionally — unlike
set_current, which short-circuits when the selection is unchanged). Needed after a resize when the selection already equals index but the new viewport height changed which rows are visible (e.g. a combo dropdown opening at its computed height). No SEL_COMMAND.
-
inline int row_height() const noexcept
-
void set_row_height(int px) noexcept
-
inline float text_size() const noexcept
Row TTF text height (px). Defaults from
AgtPalette::current().text_size.
-
void set_text_size(float px) noexcept
-
inline AxlGfxPixel text_color() const noexcept
-
void set_text_color(AxlGfxPixel c) noexcept
-
void set_selection_colors(AxlGfxPixel bg, AxlGfxPixel text) noexcept
-
inline uint16_t target_id() const noexcept
-
inline void set_activate_command(uint16_t id) noexcept
Activation command (FOX
SEL_DOUBLECLICKED/ Qtactivated): a SEL_COMMAND with this id fires on double-click or Enter — distinct from the selection-changedtarget_idof a single click / arrow nav. Sent to the sametarget. Default 0 = no activation signal (double-click then behaves like a single click). A file list wires this to “open the row” (enter a folder / pick a file).
-
inline uint16_t activate_command() const noexcept
-
inline uint32_t focus_policy() const noexcept override
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot row/text/selection colors + metrics + well bg on a theme swap.
AgtSeparator
-
class AgtSeparator : public AgtWidget
Public Types
Public Functions
-
AgtSeparator(AgtWidget *parent, int x, int y, int w, int h, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
-
inline Orientation orientation() const noexcept
-
void set_orientation(Orientation o) noexcept
-
inline int thickness() const noexcept
Line thickness in pixels along the minor axis (default 1).
-
void set_thickness(int px) noexcept
-
inline AxlGfxPixel color() const noexcept
-
void set_color(AxlGfxPixel c) noexcept
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot the line color from the live palette on a theme swap.
Public Static Functions
-
AgtSeparator(AgtWidget *parent, int x, int y, int w, int h, Orientation orient = AGT_ORIENT_HORIZONTAL) noexcept
AgtLogView
-
class AgtLogView : public AgtFrame
Public Types
Public Functions
-
AgtLogView(AgtWidget *parent, int x, int y, int w, int h, int scrollback = DEFAULT_SCROLLBACK) noexcept
-
~AgtLogView() noexcept override
-
void append(const char *text) noexcept
Append a byte stream (interpreting
\n/\r/\tas above). NULL is ignored. Follow-tail keeps the newest output in view.
-
void append_line(const char *text) noexcept
Append text followed by a newline (the common “log a line” call).
-
void clear() noexcept
Drop all lines (ring + current), reset the scroll, and re-engage follow-tail — a cleared console behaves like a fresh one.
-
int line_count() const noexcept
Number of DISPLAYED lines — completed ring lines plus the in-progress current line when it is non-empty.
-
const char *line_text(int i) const noexcept
Text of displayed line i (borrowed; NULL if out of range). The log view owns ring lines; the current line points at the inline buffer.
-
inline int scrollback() const noexcept
Scrollback capacity (completed lines).
set_scrollbackevicts the oldest lines if the new cap is below the current line count.
-
void set_scrollback(int lines) noexcept
-
inline bool follow_tail() const noexcept
-
void set_follow_tail(bool on) noexcept
Enable/disable auto-scroll to the newest line. Enabling snaps the view to the bottom immediately.
-
inline int top() const noexcept
First visible line index (scroll position in line units).
-
int visible_rows() const noexcept
Number of fully-visible text rows in the content area.
-
void scroll_to(int top_line) noexcept
Scroll so top_line is the first visible line (clamped). Re-evaluates follow-tail (engaged only when scrolled to the very bottom).
-
inline int row_height() const noexcept
Line-row height (px). Independent of
text_size(matches AgtListBox): shrinking the text does NOT shrink the row, and a larger text may need a matchingset_row_height. Defaults fromAgtPalette::list_row_height.
-
void set_row_height(int px) noexcept
-
inline float text_size() const noexcept
Monospace text height (px). Defaults from
AgtPalette::current().text_size. Does not changerow_height()— set that too for very large text.
-
void set_text_size(float px) noexcept
-
inline AxlGfxPixel text_color() const noexcept
-
void set_text_color(AxlGfxPixel c) noexcept
-
inline uint32_t focus_policy() const noexcept override
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot text color + metrics + well bg on a theme swap.
Public Static Functions
-
AgtLogView(AgtWidget *parent, int x, int y, int w, int h, int scrollback = DEFAULT_SCROLLBACK) noexcept
AgtTerminal
-
class AgtTerminal : public AgtFrame
Public Types
ID_SCROLLBAR is the id the owned scrollbar targets the terminal with; consumer command ids start at ID_LAST.
Values:
-
enumerator ID_SCROLLBAR
-
enumerator ID_LAST
-
enumerator ID_SCROLLBAR
-
enum Attr
Cell attribute bits (
Cell::attr).Values:
-
enumerator AGT_TERM_BOLD
-
enumerator AGT_TERM_UNDERLINE
-
enumerator AGT_TERM_INVERSE
-
enumerator AGT_TERM_BOLD
-
using InputFn = void (*)(void *user, const char *bytes, int len)
Sink for bytes the terminal emits from keystrokes (the WRITE side).
Public Functions
-
AgtTerminal(AgtWidget *parent, int x, int y, int w, int h, int cols = DEFAULT_COLS, int rows = DEFAULT_ROWS) noexcept
-
~AgtTerminal() noexcept override
-
inline int cols() const noexcept
-
inline int rows() const noexcept
-
inline int cursor_row() const noexcept
-
inline int cursor_col() const noexcept
-
const Cell &cell_at(int row, int col) const noexcept
The visible-grid cell at (row, col). Out-of-range returns a reference to a static blank cell (never a bad read).
-
int scrollback_len() const noexcept
Lines currently held in the scrollback ring (0 .. scrollback cap).
-
const Cell &scrollback_cell(int n, int col) const noexcept
A scrollback line, n counted from the OLDEST (0) toward the newest.
colindexes within the line. Out-of-range returns the blank cell.
-
void feed(const char *bytes, int len) noexcept
Feed len bytes of terminal output through the escape parser.
-
void feed_str(const char *s) noexcept
Convenience: feed a NUL-terminated string.
-
void reset() noexcept
Clear the grid + scrollback, home the cursor, reset the pen (the
ESC ceffect).
-
void set_grid_size(int cols, int rows) noexcept
Resize the grid (clamped to [1, MAX]). Clears the grid + scrollback and homes the cursor (no reflow in v0.1).
-
inline int scrollback_cap() const noexcept
-
void set_scrollback_cap(int lines) noexcept
-
inline void set_on_input(InputFn fn, void *user) noexcept
Install the sink for emitted input bytes (replaces any previous).
-
bool emit_key(const AgtEvent &ev) noexcept
Translate one key event to bytes and emit them via
on_input_. Public for direct testing. Returns whether anything was emitted.
-
inline AxlGfxPixel default_fg() const noexcept
-
inline AxlGfxPixel default_bg() const noexcept
-
void set_default_colors(AxlGfxPixel fg, AxlGfxPixel bg) noexcept
Colors for cells whose fg/bg is
COLOR_DEFAULT(the terminal’s own foreground / background). Default: a light-grey-on-near-black console.
-
inline float text_size() const noexcept
-
void set_text_size(float px) noexcept
-
inline int top_line() const noexcept
First visible content line (0 = oldest scrollback line). The viewport shows
rows()lines from[scrollback ++ live grid].
-
inline bool follow_tail() const noexcept
When true (default) new output snaps the view to the bottom (the live grid); scrolling up releases the glue, scrolling back re-engages it.
-
void set_follow_tail(bool on) noexcept
-
inline uint32_t focus_policy() const noexcept override
-
inline bool focused() const noexcept
-
void draw(AgtDrawContext &ctx) override
Public Static Functions
-
static inline AgtTerminalBuilder build(AgtWidget *parent) noexcept
Fluent builder: see agt-builder.hpp.
-
static AxlGfxPixel ansi_pixel(uint8_t index) noexcept
Map an ANSI/256 color index to a pixel (0–15 base + bright, 16–231 the 6×6×6 cube, 232–255 the grayscale ramp).
COLOR_DEFAULTis NOT valid here — callers resolve that todefault_fg/bgfirst.
Public Static Attributes
-
static constexpr int MAX_COLS = 256
Hard bounds on the grid (a cell is 8 bytes; 256×128 caps one terminal’s grid at ~256 KB).
set_grid_sizeclamps to these.
-
static constexpr int MAX_ROWS = 128
-
static constexpr int DEFAULT_COLS = 80
-
static constexpr int DEFAULT_ROWS = 24
-
static constexpr int DEFAULT_SCROLLBACK = 1000
Lines retained above the top of the screen (bounded ring).
-
struct Cell
One screen cell.
cpis a Unicode scalar ( ‘` for blank).
AgtSpacer
AgtGroupBox
-
class AgtGroupBox : public AgtFrame
Public Functions
-
inline const char *title() const noexcept
-
void set_title(const char *title) noexcept
-
inline AxlGfxPixel title_color() const noexcept
-
void set_title_color(AxlGfxPixel c) noexcept
-
inline float title_size() const noexcept
-
void set_title_size(float px) noexcept
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot title color/size + surface bg on a theme swap.
Public Static Functions
-
inline const char *title() const noexcept
AgtDialog
-
class AgtDialog : public AgtWindow
Subclassed by AgtFileDialog, AgtMessageBox, AgtProgressDialog, AgtPromptDialog, AgtThemeDialog
Public Functions
-
AgtDialog() noexcept
-
~AgtDialog() noexcept override
-
int run(AgtApp *app) noexcept
Block until
dismiss()is called. Pushes self onto the app’s modal stack, saves the currently-focused widget, then drivesaxl_loop_iterate_untiluntil dismissed. On return, pops the modal and restores focus.- Returns:
result code set by
dismiss(), orRESULT_RUN_FAILEDif the app’s modal stack was already full.
-
void dismiss(int result_code) noexcept
Signal the dialog to dismiss with result_code. For a MODAL dialog (
run()) this signals the nested loop to exit; for a MODELESS dialog (show()) it routes toclose()— non-blocking teardown + the on-close command. Safe to call from any AGT handler dispatched while the dialog is up (button click, key press, etc.); the OK/Cancel buttons and the Enter/Escape shortcuts all funnel here, so they close a modeless dialog exactly as they dismiss a modal one.
-
void show(AgtApp *app) noexcept
Show the dialog modelessly (non-blocking). Hosts a transparent fullscreen child surface of app’s window, clips its input region to the card, gives the dialog keyboard focus, presents, and returns immediately. No-op if already open or app has no window. The dialog must outlive this call (see the lifetime note above).
-
void close(int result_code) noexcept
Tear down a modeless dialog: destroy its surface, restore keyboard focus + repaint the parent, and emit the on-close command (see
set_on_close) with result_code as the message id. Idempotent — a secondclose()(or aclose()on a never-shown dialog) is a no-op.dismiss()routes here while modeless, so a button/Escape closes too.
-
inline bool is_open() const noexcept
True between
show()andclose()(modeless dialog currently up).
-
inline bool is_modeless() const noexcept
True if this dialog is running modelessly (
show()was used rather thanrun()). Stays set afterclose()so a reused instance keeps its mode until the nextrun()/show().
-
inline void set_on_close(AgtObject *target, uint16_t id) noexcept
Set the completion callback for a modeless dialog: on
close(code)the dialog emitsAGT_SEL_COMMAND(code)to target (itsmessage_id()is the result code; the target readsresult()too). A non-blocking dialog can’t return a code, so this is how the caller learns the outcome. Pass a NULL target to disable. Mirrors the button/target emit pattern.
-
inline int result() const noexcept
Last
dismiss()code, or 0 if never dismissed.
-
void draw(AgtDrawContext &ctx) override
Paint the modal veil (C7 P6): a translucent dark tint written into the surface buffer (raw
axl_gfx_buffer_clear— afill_rectwould force the result opaque and defeat the veil). The dialog renders on a per-pixel-alpha child surface the compositor frosts at composite time (axl_surface_set_backdrop_blur), so the tint blends over the LIVE frosted parent surface beneath — no parent-frame readback. The dialog’s own widgets (the card) render opaque on top via the normal child walk. Headless (no surface buffer) falls back to an opaque dark fill.
-
PresentMode present_mode() const noexcept override
Coalesce PRESENT_DAMAGE up to PRESENT_FULL: the veil is a whole-surface write (
buffer_clearignores the damage clip) and a backdrop-blur surface recomposites its full rect regardless, so a partial present would leave the card stale outside the damage bbox.
-
inline void set_veil_blur(bool on) noexcept
Enable/disable the frosted backdrop blur behind the modal veil for THIS dialog. When off, the veil still dims (the translucent tint) but the parent surface beneath shows through un-blurred. Blur is a per-present full-surface cost, so turning it off is the cheap path on slow targets / when content animates behind the modal. Defaults to the global default (see
set_default_veil_blur).
-
inline bool veil_blur() const noexcept
-
inline void set_default_button(AgtButton *b) noexcept
Set the button that should activate on Enter. Pass NULL to disable the default-button shortcut. AGT_SEL_COMMAND is emitted to the button’s target with its target_id on Enter — the same dispatch the button would emit on click.
-
inline void set_cancel_button(AgtButton *b) noexcept
Set the button that should activate on Escape. Pass NULL to fall back to
dismiss(0)on Escape.
-
inline AxlEvent *done_event() const noexcept
Currently-active dialog event, valid only between
run()entry anddismiss(). Exposed so the parent test infrastructure can short-circuit modals via Scenario’s.dismiss_modal(code)helper.
-
long on_command_dismiss(AgtObject *sender, AgtEvent *ev)
Default
AGT_SEL_COMMANDhandler: dismiss the dialog with the command’smessage_id()as the result code. Dialog composites wire their OK/Cancel buttons to target the dialog itself withtarget_id == result code— so a button click routes here and dismisses, with no per-composite forwarding trampoline. Mapped over the full id range; a dialog with a button that should NOT dismiss simply targets a different object instead ofthis.
Public Static Functions
-
static inline void set_default_veil_blur(bool on) noexcept
Set the GLOBAL default for the modal backdrop blur — the value every subsequently-constructed dialog (including
AgtMessageBox/AgtFileDialog, which are built + run internally and so can’t be configured per-instance) starts with. Default:true(frosted). Call once at startup to opt the whole app out of the blur.
-
static inline bool default_veil_blur() noexcept
Public Static Attributes
-
static constexpr uint16_t ID_CANCEL = 0
dismiss(0) — negative result
Standard dialog result codes (FOX
FXDialogBox::ID_ACCEPT/ID_CANCELshape). A button targeting the dialog with one of these dismissesrun()with that value — wire an OK button to&dlg, AgtDialog::ID_ACCEPT, a Cancel button toAgtDialog::ID_CANCEL, with no per-dialog handler. These are RESULT CODES (the valuerun()returns), not message-map chain ids:on_command_dismissmaps the whole command range and dismisses with the command id AS the result, so it shadows the inheritedAgtWidgetstate commands on a dialog. Values matchAgtMessageBox::RESULT_OK/RESULT_CANCEL(1 / 0).
-
static constexpr uint16_t ID_ACCEPT = 1
dismiss(1) — affirmative
-
static constexpr int RESULT_RUN_FAILED = -1
Sentinel returned by
run()on any non-dismissal failure path — NULL app, allocation failure for the done event, or modal-stack overflow (AgtApp::MODAL_STACK_MAXalready- pushed dialogs). Callers compare against this before inspecting a real result code; the dialog ran no event loop in this case.
-
AgtDialog() noexcept
AgtMovableFrame
-
class AgtMovableFrame : public AgtVBox
Public Functions
-
AgtMovableFrame(AgtWidget *parent, int x, int y, int w, int h, const char *title, int spacing = 8) noexcept
Construct a movable frame. title is shown in the bar (caller owns the storage). spacing is the gap between stacked content children. Defaults to a raised 1px border so it reads as a floating panel.
-
inline const char *title() const noexcept
-
void set_title(const char *title) noexcept
-
inline int title_height() const noexcept
Height of the title-bar grip strip (px). Content stacks below it. Default 30.
-
void set_title_height(int h) noexcept
-
void set_content_padding(int pad) noexcept
Inset applied to the content area on the left / right / bottom (the top inset is the title bar). Re-applied as the underlying frame padding. Default 0.
-
inline AxlGfxPixel title_bg_color() const noexcept
Title-bar colors + text size. Defaults derive from the frame background (a lighter bar over the content).
-
inline AxlGfxPixel title_text_color() const noexcept
-
inline float title_text_size() const noexcept
-
void set_title_bg_color(AxlGfxPixel c) noexcept
-
void set_title_text_color(AxlGfxPixel c) noexcept
-
void set_title_text_size(float px) noexcept
-
inline bool movable() const noexcept
Enable / disable dragging (default enabled). Disabling mid-drag also ends any in-progress drag + releases capture.
-
void set_movable(bool on) noexcept
-
inline bool dragging() const noexcept
True between a title-bar press and its release.
-
void draw(AgtDrawContext &ctx) override
Paint the VBox (bg + border + stacked content) then the title bar strip + title text on top of the bar area.
-
void restyle() noexcept override
Re-snapshot title-bar colors/metrics + surface bg on a theme swap.
-
int dirty_margin() const noexcept override
Over-draw margin covering the drop shadow, so a drag / hide damages the shadowed footprint (no trail on incremental present).
Public Static Functions
-
AgtMovableFrame(AgtWidget *parent, int x, int y, int w, int h, const char *title, int spacing = 8) noexcept
AgtStatusBar
-
class AgtStatusBar : public AgtFrame
Public Functions
-
AgtStatusBar(AgtWidget *parent, int x, int y, int w, int h, BorderStyle border = AGT_FRAME_LINE, int border_width = 1) noexcept
-
~AgtStatusBar() noexcept override
-
void set_text(const char *text)
Set the left status text (copied). NULL clears it.
-
void set_right_text(const char *text)
Set the right-aligned field (copied). NULL clears it.
-
inline const char *text() const noexcept
-
inline const char *right_text() const noexcept
-
void set_segment_text(int index, const char *text) noexcept
-
inline int segment_count() const noexcept
-
int segment_at(int local_x, int local_y) noexcept
Public for direct testing: hit-test a content-local x/y against the laid-out segments; returns the segment index hit, or -1.
-
inline AxlGfxPixel text_color() const noexcept
-
inline float text_size() const noexcept
-
void set_text_color(AxlGfxPixel c) noexcept
-
void set_text_size(float px_size) noexcept
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot text color/size + title-bar bg on a theme swap.
Public Static Functions
Public Static Attributes
-
static constexpr int MAX_SEGMENTS = 4
Right-aligned clickable segments (cells), laid out left-to-right in add order with the group flush to the right edge. A left-click on a cell emits
AGT_SEL_COMMAND(its id) to target — e.g. an editor’s encoding / line-ending indicators that cycle on click. Returns the segment index, or -1 if full (MAX_SEGMENTS). Segments own the right side; don’t also useset_right_textwhen segments are present.
-
AgtStatusBar(AgtWidget *parent, int x, int y, int w, int h, BorderStyle border = AGT_FRAME_LINE, int border_width = 1) noexcept
AgtSwitch
-
class AgtSwitch : public AgtCheckBox
Public Functions
-
AgtSwitch(AgtWidget *parent, int x, int y, int w, int h, const char *label = "", AgtObject *target = nullptr, uint16_t target_id = 0, bool checked = false) noexcept
-
inline AxlGfxPixel on_color() const noexcept
-
void set_on_color(AxlGfxPixel c) noexcept
-
inline AxlGfxPixel off_color() const noexcept
-
void set_off_color(AxlGfxPixel c) noexcept
-
inline AxlGfxPixel knob_color() const noexcept
-
void set_knob_color(AxlGfxPixel c) noexcept
-
inline int track_width() const noexcept
-
inline int track_height() const noexcept
-
void set_track_size(int w, int h) noexcept
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot on/off/knob colors on a theme swap.
Public Static Functions
Public Static Attributes
-
static constexpr uint16_t ID_LAST = AgtCheckBox::ID_LAST
-
static constexpr int DEFAULT_TRACK_WIDTH = 44
-
static constexpr int DEFAULT_TRACK_HEIGHT = 20
-
AgtSwitch(AgtWidget *parent, int x, int y, int w, int h, const char *label = "", AgtObject *target = nullptr, uint16_t target_id = 0, bool checked = false) noexcept
AgtIcon
-
class AgtIcon : public AgtFrame
Public Functions
-
AgtIcon(AgtWidget *parent, int x, int y, int w = 0, int h = 0, const uint8_t *bytes = nullptr, size_t len = 0) noexcept
Construct an icon. Argument order matches
AgtImage(parent, x, y, w, h, bytes, len) so the sister widgets read the same. w / hdefault to 0 = “size to the decoded
image” per axis (see “Natural sizing”); pass explicit extents to fix the box.
bytes / len default to empty (set the glyph later viaset_icon).
-
~AgtIcon() noexcept override = default
Decoded buffer is freed by the
AgtPixmapmember; AgtFrame’s dtor cascades into children (this widget has none of its own).
-
void set_icon(const uint8_t *bytes, size_t len) noexcept
Replace the current glyph. Frees the previous decoded buffer, decodes bytes. Pass
NULL/0to clear back to the empty state. Does NOT resize the widget (the box layout gave it is kept). Marks dirty either way.
-
inline AxlGfxBuffer *icon_buffer() const noexcept
Decoded buffer or NULL. Non-const for the same reason as
AgtPixmap::buffer(the axl-gfx pixel/info accessors take a non-const handle).
-
inline int icon_width() const noexcept
Decoded glyph dimensions in pixels; both 0 in the empty state.
-
inline int icon_height() const noexcept
-
void draw(AgtDrawContext &ctx) override
Public Static Functions
-
AgtIcon(AgtWidget *parent, int x, int y, int w = 0, int h = 0, const uint8_t *bytes = nullptr, size_t len = 0) noexcept
AgtSpinner
-
class AgtSpinner : public AgtWidget
Public Functions
-
AgtSpinner(AgtWidget *parent, int x, int y, int w, int h, int steps = DEFAULT_STEPS) noexcept
Construct a spinner. steps is the dot count (clamped to a minimum of 2). Starts stopped at phase 0; call
start()to self-animate or driveadvance()from your own clock.
-
~AgtSpinner() noexcept override
Stops the animation timer (if any) before teardown.
-
inline int steps() const noexcept
-
inline int phase() const noexcept
Index of the brightest dot, in
[0, steps()).
-
void set_phase(int p) noexcept
Set the brightest dot (wrapped into range). Marks dirty.
-
void advance() noexcept
Advance the brightest dot by one (wraps). This is one animation tick; the self-running timer calls it.
-
inline AxlGfxPixel active_color() const noexcept
Brightest-dot color and the color the trail fades toward.
-
inline AxlGfxPixel trail_color() const noexcept
-
void set_active_color(AxlGfxPixel c) noexcept
-
void set_trail_color(AxlGfxPixel c) noexcept
-
inline uint32_t interval_ms() const noexcept
Per-tick interval for the self-running animation. Takes effect immediately if already running.
-
void set_interval_ms(uint32_t ms) noexcept
-
inline bool running() const noexcept
True while the self-running timer is armed.
-
void start() noexcept
Begin self-animating: arm a repeating timer on the window’s event loop that calls
advance()+ redraws each tick. Means “ensure armed” — calling it when already armed is a no-op, and calling it again after the spinner is attached to a window (having first been started while detached) arms the timer then. With no window/loop bound (the headless test harness) it flipsrunning()but arms no timer — driveadvance()directly there. The boundAxlLoopmust outlive the spinner (declareAgtAppbefore the window so the loop tears down last).
-
void stop() noexcept
Stop self-animating and remove the timer. Safe if not running.
-
void draw(AgtDrawContext &ctx) override
Paint the ring of dots for the current phase.
-
void restyle() noexcept override
Re-snapshot the active / trail dot colors on a theme swap.
Public Static Functions
Public Static Attributes
-
static constexpr uint16_t ID_LAST = AgtWidget::ID_LAST
FOX-style message-ID chain (see
AgtWidget::ID_LAST).
-
static constexpr int DEFAULT_STEPS = 12
Dots around the ring by default.
-
static constexpr uint32_t DEFAULT_INTERVAL_MS = 80
Default per-tick interval when self-animating (~12.5 fps).
-
AgtSpinner(AgtWidget *parent, int x, int y, int w, int h, int steps = DEFAULT_STEPS) noexcept
AgtLight
-
class AgtLight : public AgtLabel
Public Types
-
enum State
Discrete indicator state. Stable values (OFF == 0 = default) so a caller using the default doesn’t need to import the enum. Indexes the per-state color table, so new states append at the end.
Values:
-
enumerator OFF
neutral / unlit
-
enumerator OK
green — pass / healthy
-
enumerator WARN
amber — caution
-
enumerator ERROR
red — fail
-
enumerator BUSY
blue — running / in progress
-
enumerator OFF
Public Functions
-
AgtLight(AgtWidget *parent, int x, int y, int w, int h, const char *label = "", State state = OFF) noexcept
Construct a light at fixed parent-local bounds. label defaults to “” (a caption-less disc); state defaults to OFF.
-
AgtLight(AgtWidget *parent, const char *label = "", State state = OFF) noexcept
Geometry-free ctor (FOX
new FXLabel(p,"text")shape): no x/y/w/h — the light sizes to disc + gap + caption vianatural_*()and a layout container places it.
-
~AgtLight() noexcept override
Stops the blink timer (if any) before teardown.
-
int natural_width() const noexcept override
Natural size = disc + gap + caption (or just the disc when there is no caption), tall enough for the larger of disc / text.
-
int natural_height() const noexcept override
-
inline bool blinking() const noexcept
True when blinking is enabled (whether or not its timer is armed).
-
void set_blink(bool on) noexcept
Enable / disable the pulse. Disabling seats the phase lit (steady). Does NOT arm the timer — call
start()once the window loop is bound (the spinner shape); a layout/test can driveadvance_blink().
-
inline bool blink_phase() const noexcept
Current blink phase: true = lit half, false = dim half. Pure state, like
AgtSpinner::phase()— pin it for a deterministic baseline.
-
void set_blink_phase(bool lit) noexcept
-
void advance_blink() noexcept
Flip the blink phase (one animation tick). The self-running timer calls this; drive it directly in a headless layout/test.
-
void start() noexcept
Begin self-animating: arm a repeating timer on the window’s loop that flips the phase + redraws each half-period. “Ensure armed” — a second
start()is a no-op. With no window/loop bound (headless) it flipsrunning()but arms no timer. Safe to call when not blinking (the tick is a no-op untilset_blink(true)).
-
void stop() noexcept
Stop self-animating and remove the timer. Safe if not running.
-
inline bool running() const noexcept
True while the self-running timer is armed.
-
inline uint32_t blink_interval_ms() const noexcept
-
void set_blink_interval_ms(uint32_t ms) noexcept
Per-half-period interval (ms). Takes effect immediately if running.
-
inline int indicator_size() const noexcept
Disc diameter in pixels. Default seeds from
AgtPalette::indicator_sizeand tracks the live palette metric; pinning a size here makes it a consumer override that survives a theme swap (theAgtFrameexplicit-color shape). Clamped to >= 0.
-
void set_indicator_size(int px) noexcept
-
AxlGfxPixel state_color(State state) const noexcept
Base color for state — the per-instance override if one was set via
set_state_color, otherwise the liveAgtPalette::lighttoken.
-
void set_state_color(State state, AxlGfxPixel c) noexcept
Pin a per-state color override (mark dirty). Survives a palette swap; pass states you never override to keep tracking the theme.
-
AxlGfxPixel indicator_color() const noexcept
The color the disc renders with RIGHT NOW:
state_color(state()), darkened while blinking and in the dim phase. The renderer reads this so the blink presentation stays widget-owned.
-
void draw(AgtDrawContext &ctx) override
Delegates to the renderer (
AgtStyle::draw_light): flat surface + bezelled disc inindicator_color()+ the trailing caption.
-
void restyle() noexcept override
Re-snapshot the indicator size from the live palette on a theme swap (colors resolve live through
state_color).
Public Static Functions
-
enum State
AgtCanvas
-
class AgtCanvas : public AgtFrame
Public Types
-
using PaintFn = void (*)(void *user, AgtDrawContext &ctx, int width, int height)
Per-frame paint callback. ctx is clipped + translated to the inner content rect, so paint in local coordinates from
(0, 0)to (width, height). user is the context registered with the callback. NULL is allowed (the canvas then shows only its frame chrome).
Public Functions
-
AgtCanvas(AgtWidget *parent, int x, int y, int w, int h, PaintFn paint = nullptr, void *user = nullptr) noexcept
Construct a canvas. Same
(parent, x, y, w, h)shape as every widget; paint / user wire the draw callback (settable later too).
-
void set_paint(PaintFn fn, void *user) noexcept
Set (or clear, with NULL) the paint callback + its borrowed context. Marks the canvas dirty so the next present repaints.
-
inline void *paint_user() const noexcept
-
void draw(AgtDrawContext &ctx) override
Paint the frame chrome (
AgtFrame::draw), then invoke the callback clipped + translated to the inner content rect. No callback → chrome only.
Public Static Functions
-
using PaintFn = void (*)(void *user, AgtDrawContext &ctx, int width, int height)
AgtSprite
-
class AgtSprite : public AgtFrame
Public Functions
-
~AgtSprite() noexcept override
Stops the animation timer (if any) before teardown.
-
void set_sheet(const AxlGfxPixel *pixels, int sheet_w, int sheet_h, int cell_w, int cell_h, int cols, int frame_count) noexcept
Bind the sprite sheet (BORROWED): pixels is a row-major BGRX image sheet_w × sheet_h pixels, laid out as a grid of cell_w × cell_h cells, cols cells per row, frame_count cells total (left-to-right, top-to-bottom). Resets to frame 0. Pass
pixels = NULLto clear. No-op on a malformed grid (non-positive dims orcols< 1).
-
inline int frame() const noexcept
-
inline int frame_count() const noexcept
-
inline int cell_width() const noexcept
-
inline int cell_height() const noexcept
-
void set_frame(int f) noexcept
Set the visible cell (wrapped into
[0, frame_count())). Marks dirty.
-
void advance() noexcept
Advance the cell by one (wraps). One animation tick.
-
inline uint32_t interval_ms() const noexcept
-
void set_interval_ms(uint32_t ms) noexcept
-
inline bool running() const noexcept
-
void start() noexcept
Begin self-animating: arm a repeating timer on the window’s loop that
advance()s + redraws each tick. “Ensure armed” (idempotent). With no window/loop bound (headless) it flipsrunning()but arms nothing — driveadvance()directly there. The boundAxlLoopmust outlive the sprite.
-
void stop() noexcept
Stop self-animating + remove the timer. Safe if not running.
-
void draw(AgtDrawContext &ctx) override
Blit the current cell, centered + clipped to the inner content rect.
Public Static Functions
-
~AgtSprite() noexcept override
AgtAnimatedImage
-
class AgtAnimatedImage : public AgtFrame
Public Functions
-
~AgtAnimatedImage() noexcept override
Stops the animation timer (if any) before teardown.
-
void set_frames(const AxlGfxPixel *const *frames, int frame_count, int frame_w, int frame_h) noexcept
Bind the frame list (BORROWED): frames is an array of frame_count pointers, each a row-major BGRX image frame_w × frame_h pixels. Both the array and the pixels are borrowed — the caller keeps them alive for the widget’s lifetime. Resets to frame 0. Pass
frames = NULLor a non-positive count/size to clear.
-
inline int frame() const noexcept
-
inline int frame_count() const noexcept
-
inline int frame_width() const noexcept
-
inline int frame_height() const noexcept
-
void set_frame(int f) noexcept
Set the visible frame (wrapped into
[0, frame_count())). Marks dirty.
-
void advance() noexcept
Advance the frame by one (wraps). One animation tick.
-
inline uint32_t interval_ms() const noexcept
-
void set_interval_ms(uint32_t ms) noexcept
-
inline bool running() const noexcept
-
void start() noexcept
Begin self-animating: arm a repeating timer on the window’s loop that
advance()s + redraws each tick. “Ensure armed” (idempotent). With no window/loop bound (headless) it flipsrunning()but arms nothing — driveadvance()directly there. The boundAxlLoopmust outlive the widget.
-
void stop() noexcept
Stop self-animating + remove the timer. Safe if not running.
-
void draw(AgtDrawContext &ctx) override
Blit the current frame, centered + clipped to the inner content rect.
Public Static Functions
-
~AgtAnimatedImage() noexcept override
AgtEditBox
-
class AgtEditBox : public AgtFrame
Public Types
Public Functions
-
~AgtEditBox() noexcept override
-
AgtEditBox(const AgtEditBox&) = delete
-
AgtEditBox(AgtEditBox&&) = delete
-
AgtEditBox &operator=(const AgtEditBox&) = delete
-
AgtEditBox &operator=(AgtEditBox&&) = delete
-
inline const char *text() const noexcept
-
inline int length() const noexcept
-
inline uint64_t revision() const noexcept
Monotonic content revision (bumps on every edit) — a cheap “did the
text change?” signal for content-derived caches like highlighting.
-
inline AxlPieceTree *tree() const noexcept
The buffer’s backing
AxlPieceTree(borrowed; NULL only on a degenerate doc) — for a shared-tree hex view (AgtPieceTreeHexSource::attach) that reads the SAME bytes, including the editor’s unsaved edits.
-
void set_text(const char *text) noexcept
Replace the contents. Cursor to end, selection cleared, scroll reset.
-
bool load_file(const char *path) noexcept
Load the file at path into the buffer (encoding + EOL detected; large UTF-8 files stay out-of-core). Resets the view + cursor to the top; returns false (contents unchanged) on failure.
-
bool save_file(const char *path) noexcept
Write the buffer to path (current encoding / EOL; a save over the out-of-core backing file rebases — see
AgtTextDoc::save_file). Returns false on failure.
-
void set_page_cache(AxlPageCache *cache) noexcept
Borrow a shared
AxlPageCacheso several editors’ out-of-core loads share ONE bounded frame budget (a multi-buffer editor — call beforeload_file). Caller-owns the cache; it must outlive every editor that borrows it. Forwards toAgtTextDoc::set_page_cache.
-
const char *path() const noexcept
The buffer’s associated file (”” when untitled) and whether it has unsaved edits — for the app’s title / status bar.
-
bool modified() const noexcept
-
AxlEncoding encoding() const noexcept
Detected/loaded text encoding + line-ending style (for the status bar; default UTF-8 / LF on an untitled buffer).
-
AxlEol eol() const noexcept
-
void set_encoding(AxlEncoding enc, bool bom) noexcept
Change the save encoding / line-ending style (status-bar “switch
modes”). set_eol rewrites the buffer’s line endings; set_encoding only changes the on-disk codec. Both mark the buffer modified and repaint.
-
void set_eol(AxlEol eol) noexcept
-
int cursor_line() const noexcept
Cursor position as a 0-based logical line and a 0-based column counted in UTF-8 codepoints from the line start (the status bar shows these +1).
-
int cursor_col() const noexcept
-
inline int cursor() const noexcept
-
inline int anchor() const noexcept
-
inline int selection_start() const noexcept
-
inline int selection_end() const noexcept
-
inline bool has_selection() const noexcept
-
void set_cursor(int byte_offset) noexcept
Move the cursor (clears selection) and scroll it into view.
-
void set_selection(int anchor, int cursor) noexcept
Set anchor + cursor directly; scrolls the cursor into view.
-
void go_to_line(int line) noexcept
Place the cursor at the start of (0-based) logical line, clamped to the document, and scroll it into view. For the editor’s Go to Line.
-
void select_word_at(int byte_offset) noexcept
Select the run of like-classed characters (word chars, whitespace, or other punctuation) containing the byte at byte_offset, clamped to that character’s line so a selection never crosses a newline. An empty line just places the cursor. This is the double-click gesture and a menu-callable “Select Word”.
-
void select_line_at(int byte_offset) noexcept
Select the text of the line containing byte_offset, excluding the line terminator. The triple-click gesture / “Select Line”.
-
void undo() noexcept
-
void redo() noexcept
-
inline bool can_undo() const noexcept
-
inline bool can_redo() const noexcept
-
void cut() noexcept
Cut the selection to the clipboard: copy, then delete, as one atomic undo step. A no-op with no selection; a failed copy (OOM) aborts without deleting, so text it couldn’t capture is never lost.
-
void copy() noexcept
Copy the selection to the clipboard as UTF-8 text. A no-op (the clipboard is left untouched) when there is no selection.
-
void paste() noexcept
Insert the clipboard’s text at the cursor, replacing any selection, as one atomic undo step. A non-text payload or empty clipboard is ignored.
-
void select_all() noexcept
Select the entire buffer (anchor at 0, cursor at the end).
-
bool find(const char *query, bool forward = true) noexcept
Find the literal substring query and select the next match. Scans from just past the current match (or from the cursor when no selection is active) so repeated calls step through occurrences, and wraps around the document ends. forward = false searches toward the start. On a hit the match is selected (cursor at its end) and scrolled into view, and the method returns true; on no match (or an empty query) the selection is left unchanged and it returns false. Case-sensitive in v0.1.
-
bool find_regex(const char *pattern, bool forward = true) noexcept
Regex find: compile pattern (
AxlRegexsyntax) and select the next/previous match, stepping past the current one and wrapping — the regex counterpart offind. Returns false (selection unchanged) on a malformed pattern or no match. The find-options dialog (Phase 4) toggles between this and literalfind.
-
bool find(const char *query, bool forward, uint32_t flags) noexcept
Find with options.
flags == 0is exactly the plain literalfindabove (case-sensitive, out-of-core). Any flag routes through the regex engine: a non-AGT_FIND_REGEXquery is matched literally (its metacharacters escaped);AGT_FIND_CASELESSfolds ASCII case;AGT_FIND_WHOLE_WORDkeeps only word-delimited matches. Selects the match + scrolls it into view; returns false on no match / malformed regex.
-
int replace_all(const char *query, const char *replacement) noexcept
Replace every literal match of query with replacement across the buffer, as ONE atomic undo step; returns the replacement count. Scrolls the (collapsed) cursor into view + repaints when any match was replaced.
-
int replace_all_regex(const char *pattern, const char *replacement) noexcept
Regex replace-all: compile pattern and replace every match with replacement, expanding
\0..\9capture groups and\\, as ONE atomic undo step; returns the count (0 on a malformed pattern, no match, or error).
-
int replace_all(const char *query, const char *replacement, uint32_t flags) noexcept
Replace-all with the same option flags as the unified
find.flags == 0is the plain literalreplace_allabove (the replacement is inserted verbatim). WithAGT_FIND_REGEXthe replacement expands\0..\9capture groups +\\; for a literal (non-regex) query the replacement stays verbatim even under CASELESS / WHOLE_WORD. Returns the replacement count.
-
void replace_selection(const char *text) noexcept
Replace the current selection with text as ONE atomic undo step (inserts at the cursor when nothing is selected; an empty text deletes the selection). No-op when read-only or text is NULL. The find bar’s single Replace uses this on the current match.
-
int set_filter(const char *query, uint32_t flags) noexcept
Enter “filter mode”: render ONLY the logical lines that match query (option flags as for
find— regex / caseless / whole-word), as a live grep over a log. The document is NOT copied — a per-match line INDEX is built over the out-of-core doc (one line number per matching line, de-duped when a line matches more than once), and the view, the scrollbar, Up/Down and clicks all map through it (so a match stays clickable back to its source line). Filter mode is read-only and pins soft-wrap off (one match = one row). The caret parks on the first match. Returns the number of matching lines; an empty query or NO matches leaves the full view unchanged and returns 0 (never shows a blank filtered screen). Re-applying replaces the active filter.
-
void clear_filter() noexcept
Leave filter mode: restore the full view (and the pre-filter wrap / read-only state), keeping the caret on its current source line — so
Escafter browsing matches drops you onto that line in the full document. A no-op when not filtering.
-
inline bool filtering() const noexcept
Whether filter mode is active.
-
int filter_match_count() const noexcept
Number of matching lines in the active filter (0 when not filtering).
-
int filter_source_line(int view_row) const noexcept
Source (full-document) line number shown at filtered view-row view_row, or -1 when not filtering / out of range. The click-to- source map; public for tests.
-
int line_count() const noexcept
Number of logical lines (
\n-delimited; always >= 1).
-
int line_text(int line, char *out, int cap, int *start) const noexcept
Copy logical line line’s content (excluding the terminator) into out (NUL-terminated within cap); returns the byte count and, if start is non-NULL, the line’s start byte offset. The syntax-highlight engine reads visible lines through this.
-
inline int top_line() const noexcept
First visible line (vertical scroll position, in line units).
-
inline int left_offset() const noexcept
Horizontal scroll position in pixels (0 = line start at the left inset; grows as a long line scrolls left).
-
int visible_lines() const noexcept
Number of fully-visible text lines in the content area.
-
inline int line_height() const noexcept
-
void set_line_height(int px) noexcept
-
inline AxlGfxPixel text_color() const noexcept
-
inline AxlGfxPixel selection_bg_color() const noexcept
-
inline AxlGfxPixel cursor_color() const noexcept
-
void set_text_color(AxlGfxPixel c) noexcept
-
void set_selection_bg_color(AxlGfxPixel c) noexcept
-
void set_cursor_color(AxlGfxPixel c) noexcept
-
inline float text_size() const noexcept
TTF text height (px). Defaults from
AgtPalette::current().text_size.
-
void set_text_size(float px) noexcept
-
inline AxlTtf *font() const noexcept
Text face. NULL (the default) renders with
axl_ttf_default()(the proportional UI font); pass a fixed-width face such asaxl_ttf_mono_default()for a code editor. Borrowed — the caller keeps it alive for the widget’s lifetime; changing it reflows.
-
void set_font(AxlTtf *ttf) noexcept
-
inline bool zoomable() const noexcept
When enabled, Ctrl+wheel and Ctrl+
+/-(and Ctrl+0to reset) zoom the text size in-place (set_text_size, clamped to [6, 72] px), keeping the caret in view. Off by default — a plain text input keeps Ctrl+wheel as ordinary scroll.
-
inline void set_zoomable(bool on) noexcept
-
void zoom_in() noexcept
grow the text by one step
Programmatic zoom (clamped to [6, 72] px), independent of
zoomable_(which gates only the Ctrl+wheel/key shortcuts) — wire these to toolbar or menu commands. Each keeps the caret in view.
-
void zoom_out() noexcept
shrink the text by one step
-
void zoom_reset() noexcept
back to the construction-time size
-
inline int tab_width() const noexcept
Tab stop width in columns (one column = the advance of a space at the current
text_size); a\trenders by advancing to the next stop. Default 4. Render-only — the buffer keeps the literal tab.
-
void set_tab_width(int columns) noexcept
-
inline bool line_numbers() const noexcept
Whether a left-column line-number gutter is shown (default off). The gutter displays each logical line’s 1-based number (the SOURCE line when filtering; blank on soft-wrap continuation rows), right-aligned and dimmed with the cursor’s line emphasized. It narrows the usable text column (so wrap / h-scroll / click mapping all account for it); a click inside the gutter places the caret at that line’s start. A persisted editor preference — see
docs/AGT-Settings-Design.md.
-
void set_line_numbers(bool on) noexcept
-
inline bool word_wrap() const noexcept
When on, long logical lines wrap to the content width across multiple visual rows and the horizontal scrollbar is suppressed; when off (default), a long line is clipped and the h-scrollbar appears. (This commit lands the wrap-layout engine + the toggle; the wrapped render + caret / click / Up-Down remapping are follow-on commits.)
-
void set_word_wrap(bool on) noexcept
-
int wrap_line(int line, int width, int *breaks, int maxbreaks) const noexcept
Wrap-layout query: split logical line line into the visual rows that fit width px — tab-aware, greedy word-break, an over-long word hard-breaking at a codepoint boundary. Fills breaks with line-relative byte offsets (
breaks[0] == 0,breaks[rows] == line length; visual rowris[breaks[r], breaks[r+1])) and returns the row count (always >= 1, capped at maxbreaks - 1 rows). A line longer than the internal scratch is wrapped up to that bound (the same cap the renderer uses). Public for the renderer + tests.
-
inline bool focused() const noexcept
-
inline uint32_t focus_policy() const noexcept override
-
inline bool cursor_blink() const noexcept
Whether the text cursor blinks while the box is focused (default true). The blink pauses — cursor solid — for one full interval after any cursor activity (typing / move / click), the standard editor feel. Disable for a steady cursor: an accessibility preference, or deterministic screenshots. The blink is driven by a repeating timer on the window’s event loop, so it only ticks once attached + focused.
-
inline void set_cursor_blink(bool on) noexcept
-
inline uint32_t cursor_blink_interval() const noexcept
Blink half-period in ms (default 530, ~ the Win32 default).
-
inline void set_cursor_blink_interval(uint32_t ms) noexcept
-
inline bool cursor_blink_visible() const noexcept
True when the blink phase currently shows the cursor (always true while blink is disabled). The draw gate ANDs this with focus.
-
inline void blink_tick() noexcept
One blink half-cycle: flip the phase and repaint. Called by the repeating loop timer; public for the trampoline + direct testing.
-
inline bool overwrite() const noexcept
Whether typing overwrites the character under the cursor instead of inserting (default false = insert). The Insert key toggles it. In overwrite mode the cursor renders as a char-wide underline; at a line end (or with an active selection) typing still inserts / replaces the selection, so the newline is never consumed.
-
void set_overwrite(bool on) noexcept
-
inline bool read_only() const noexcept
Whether the buffer rejects edits (default false). A read-only box still moves the caret, extends + copies selections, finds, scrolls, and zooms — only the mutating paths (typing, Enter/Tab, Backspace/ Delete, cut, paste, undo, redo) become no-ops. For a diagnostics viewer that opens a log / dump without risking accidental edits.
-
inline void set_read_only(bool on) noexcept
-
void set_hilite_styles(const AgtHiliteStyle *styles, int count) noexcept
Set the style palette (BORROWED — must outlive the widget). Style index 0 is the default (drawn in
text_color()); indexiin[1, count]maps tostyles[i-1]. NULL / count 0 drops it.
-
void set_style(int pos, int len, uint8_t idx) noexcept
Mark bytes
[pos, pos+len)with style indexidx. Runs accumulate in document order (the engine clears, then pushes left-to-right); index 0 leaves the span default. Empty / out-of-range spans ignored.
-
void clear_styles() noexcept
Drop all style runs (the engine calls this before re-highlighting).
-
uint8_t style_at(int pos) const noexcept
Style index covering byte
pos(0 if none) — for the renderer + tests.
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
-
~AgtEditBox() noexcept override
AgtHexBox
-
class AgtHexBox : public AgtFrame
Public Types
-
enum class CopyFormat
Clipboard copy formats (H6).
HEX_TEXTis the defaultCtrl+Cformat; the others are menu-driven.RAWpastes back verbatim (round-trips withpaste()).Values:
-
enumerator HEX_TEXT
“DE AD BE EF” — uppercase, space-separated (text/plain)
-
enumerator C_ARRAY
“0xDE, 0xAD, 0xBE, 0xEF” — C initializer (text/plain)
-
enumerator RAW
the literal bytes (application/octet-stream)
-
enumerator HEX_TEXT
Public Functions
-
~AgtHexBox() noexcept override
-
void set_source(AgtHexSource *src) noexcept
Set the byte source (BORROWED — the caller owns it and keeps it alive for as long as the box references it). NULL shows an empty view. Resets the cursor + scroll to the top.
-
inline AgtHexSource *source() const noexcept
-
inline int64_t cursor() const noexcept
Selected byte offset (0-based).
set_cursorclamps to the source and scrolls it into view.
-
void set_cursor(int64_t off) noexcept
-
inline int64_t anchor() const noexcept
-
inline bool has_selection() const noexcept
-
inline int64_t selection_start() const noexcept
Inclusive selection bounds (== cursor when there is no selection).
-
inline int64_t selection_end() const noexcept
-
void set_selection(int64_t anchor, int64_t cursor) noexcept
Set anchor + cursor directly (both clamped); scrolls the cursor in view.
-
void select_all() noexcept
Select every byte (anchor 0 .. cursor size()-1).
-
int copy(CopyFormat fmt = CopyFormat::HEX_TEXT) noexcept
Copy the selection — or the single cursor byte when none — to the clipboard in fmt. Works in a viewer (read-only). Returns the number of bytes copied (0 = nothing / failure); a huge selection is capped.
-
int paste() noexcept
Paste over the caret. A
text/*clipboard is parsed as hex bytes (“DE AD BE EF”, any whitespace / separators ignored); anapplication/octet-streamclipboard (aRAWcopy) is taken verbatim. Either way the bytes OVERWRITE at the caret (does not grow the view; a span past the end is truncated). Editable sources only; one undo step. Returns the number of bytes written.
-
inline void set_caret_target(AgtObject *target, uint16_t id) noexcept
Emit
AGT_SEL_COMMAND(@a id)to target whenever the bytes a reader at the caret would see change — the caret MOVES (nav / click / find) or the byte(s) under it are EDITED in place / undone without the caret moving — so a data-interpreter panel can re-readcursor(). NULL target detaches.
-
inline bool read_only() const noexcept
Viewer mode: when true (or the source is not
writable()), typing is inert and the cursor renders as a plain selection. Default false (an editor): hex digits overwrite the active nibble, the ASCII pane types whole bytes, Tab switches panes, Ctrl+Z / Ctrl+Y undo / redo.
-
void set_read_only(bool on) noexcept
-
void set_enabled(bool enabled) noexcept override
Whether typing currently edits (an editable widget over a writable source). Disabling mid-drag drops the mouse grab cleanly (so a re-enable doesn’t resume from a stale drag) — mirrors AgtSlider.
-
bool editable() const noexcept
-
bool can_resize() const noexcept
Whether insert/delete editing is available (editable over a
resizablesource — a file, not memory / I/O). Gates the Insert-key toggle and Backspace / Delete, and lets the caret reach the append (EOF) cell.
-
inline bool ascii_pane() const noexcept
Which pane the caret edits — false = hex, true = ASCII (Tab toggles).
-
inline int nibble() const noexcept
Active hex nibble at the caret: 0 = high, 1 = low (hex pane only).
-
inline bool overwrite_mode() const noexcept
Typing mode (H3b): true (default) overwrites the byte under the caret; false inserts new bytes before it (the view grows). The Insert key toggles it when
can_resize(). At the append (EOF) cell typing always inserts regardless of this flag. Inert on a non-resizable source.
-
void set_overwrite_mode(bool on) noexcept
-
void undo() noexcept
Ctrl+Z — revert the last edit (delegates to the source)
-
void redo() noexcept
Ctrl+Y — re-apply the last undone edit.
-
bool find(const char *query, bool hex_mode, bool caseless, bool backward, bool wrap, bool regex = false) noexcept
Search for query and move the cursor to the match, highlighting it (out-of-core: scans
source()read-windows, so it works over a file, memory, or I/O source). hex_mode parses query as a hex byte pattern with nibble wildcards (DE AD ?? EF;D?= byte 0xD0, mask 0xF0); otherwise query’s literal bytes are matched (caseless = ASCII case-insensitive). Repeating the same query + mode steps to the next (backward = previous) match; wrap continues past the start / end. Returns whether a match was found (the caret + highlight only move on success).regex (mutually exclusive with hex_mode) treats query as an
AxlRegexpattern matched over the raw byte stream (so it spans binary too); caseless maps toAXL_REGEX_CASELESS. The match is variable-length (match_length()reflects it).^/$anchor to the true source boundaries (the windowing passesNOTBOL/NOTEOLon mid-stream windows); an empty match (a*,x?) is skipped (a pattern that only ever matches empty re-reads a window per byte — fine for files, pathological for a multi-GB source, but degenerate for a find). Out-of-core caveat: a regex match is found only if it fits within one search window (FIND_WINDOWbytes) — longer matches (e.g. an unbounded.*run) are skipped; literal / hex / bounded patterns are unaffected.
-
inline int64_t match_offset() const noexcept
The active find-match highlight range;
match_length() == 0when there is none (any manual caret move / edit clears it).
-
inline int match_length() const noexcept
-
bool replace_match(const char *replacement, bool hex_mode) noexcept
Replace the current find-match (the
match_offset()/match_length()highlight) with replacement. hex_mode parses replacement as concrete hex byte pairs (DE AD), otherwise its literal text bytes; wildcards are not allowed in a replacement (??/D?→ no-op). Equal length overwrites in place (any writable source); a different length splices (delete + insert) and so needs aresizable()source — on a fixed memory / I/O source an unequal-length replace is refused. One undo step. On success the match highlight clears and the caret sits just after the replacement. Pure replace — it does NOT auto-find the next match (a “Replace” UI follows it withfind(..., forward)). An EMPTY replacement is rejected (no-op) — delete-the-match is not a replace in v0.1 (mirrorsfind’s empty-query rejection). Returns whether a replacement was written.
-
int replace_all(const char *query, bool hex_mode, bool caseless, bool regex, const char *replacement) noexcept
Replace EVERY match of query (parsed exactly as in
find) from the start of the source with replacement, as ONE undo group. regex matches replace with the literal replacement bytes (no capture-group back-references in v0.1). Stops early (and leaves the prior replacements) if an unequal-length replace hits a fixed source. Returns the number of replacements made.
-
int add_region(int64_t start, int64_t len, AxlGfxPixel color, const char *label = nullptr) noexcept
Add a colored byte range
[start, start + len)with an optional label (copied; NULL = none). Regions paint as the LOWEST background layer — the find-match highlight, the selection, and the cursor draw on top. Where ranges overlap, the FIRST-added region wins. Returns the region index, or -1 (bad args / allocation failure). Out-of-core safe: only the visible window is consulted at paint time, so thousands of regions over a multi-GB source stay cheap to store; a page paints in O(visible-bytes x regions).
-
void clear_regions() noexcept
Remove every region.
-
int region_count() const noexcept
-
int region_at(int64_t off) const noexcept
Index of the FIRST region containing off, or -1 — drives a “field under the caret” status readout.
-
const char *region_label(int idx) const noexcept
-
AxlGfxPixel region_color(int idx) const noexcept
-
int64_t region_start(int idx) const noexcept
-
int64_t region_length(int idx) const noexcept
-
int64_t size() const noexcept
Total bytes (0 when no source).
-
int bytes_per_row() const noexcept
Bytes shown per row. Default 0 = responsive (the largest of 8/16/32 that fits the content width); a non-zero value FIXES it (clamped to
[1, 32]).bytes_per_row()returns the effective count either way.
-
void set_bytes_per_row(int n) noexcept
-
int offset_digits() const noexcept
Hex digits in the offset gutter (enough for
size(), min 8).
-
inline int top_row() const noexcept
First visible row (vertical scroll position, in rows).
-
int total_rows() const noexcept
Total rows = ceil(size / bytes_per_row) (>= 0; 0 when empty).
-
int visible_rows() const noexcept
Fully-visible rows in the content area.
-
int64_t byte_at_point(int lx, int ly) const noexcept
Byte offset under a widget-local point (the hex OR ASCII pane), or -1 when the point is outside any byte cell. Public for tests + click.
-
inline int line_height() const noexcept
-
void set_line_height(int px) noexcept
-
inline uint32_t focus_policy() const noexcept override
-
inline bool focused() const noexcept
-
void draw(AgtDrawContext &ctx) override
-
void restyle() noexcept override
Re-snapshot the pane colors + metrics on a theme swap (
restyle_tree), so a live light/dark switch re-skins the hex view.
Public Static Functions
Public Static Attributes
-
static constexpr int FIND_MAX_PATTERN = 256
Max search-pattern length, in bytes (hex or text), for
find.
-
enum class CopyFormat
AgtHexDataPanel
-
class AgtHexDataPanel : public AgtFrame
Public Functions
-
~AgtHexDataPanel() noexcept override
-
AgtHexDataPanel(const AgtHexDataPanel&) = delete
-
AgtHexDataPanel &operator=(const AgtHexDataPanel&) = delete
-
void set_source(AgtHexSource *src) noexcept
Byte source to decode (BORROWED — caller keeps it alive). NULL = empty.
-
void set_offset(int64_t off) noexcept
The offset whose bytes are interpreted (the hex caret). Clamped >= 0.
-
inline int64_t offset() const noexcept
-
inline bool little_endian() const noexcept
Endianness of multi-byte decodes (default little-endian, x86-native).
-
void set_little_endian(bool le) noexcept
-
inline void toggle_endian() noexcept
-
int read_cursor_bytes(uint8_t *out8) const noexcept
Read up to 8 bytes at
offset()into out8 (caller-sized >= 8), honouring the source’saccess_width()alignment: width>1 register sources (whoseread()refuses an unaligned offset) are read at an aligned base and the caret’s byte is shifted toout8[0]. Returns the number of bytes available fromoffset()(0..8). Public for tests + reuse;draw()decodes from exactly these bytes.
-
void draw(AgtDrawContext &ctx) override
-
inline int line_height() const noexcept
-
void set_line_height(int px) noexcept
-
~AgtHexDataPanel() noexcept override
AgtHexSource
-
class AgtHexSource
Subclassed by AgtPieceTreeHexSource, AgtRangeHexSource
Public Functions
-
virtual ~AgtHexSource() noexcept = default
-
virtual int64_t size() const noexcept = 0
Total addressable bytes (0 when closed / empty).
-
virtual int read(int64_t off, int len, uint8_t *buf) const noexcept = 0
Copy
[off, off+len)into buf; returns the number of bytes actually read — clamped tosize()(0 when off is past the end, len <= 0, or buf is NULL). Reads ONLY the requested span (out-of-core).
-
inline virtual bool writable() const noexcept
Whether bytes can be written at all (overwrite). False = a viewer.
-
inline virtual bool resizable() const noexcept
Whether bytes can be inserted / removed (length changes). Memory is fixed-size (false); a file is resizable (true). Only meaningful when
writable().
-
inline virtual bool is_volatile() const noexcept
Whether the bytes can change underneath us (live memory) — the widget re-reads the visible window every repaint instead of caching it.
-
inline virtual uint32_t access_width() const noexcept
Read/write granularity in bytes (1 for a byte-addressable file or RAM; 2/4/8 for a width-N register space).
read()offsets and lengths must be multiples of this, so windowed scanners (find) align to it.
-
inline virtual bool overwrite(int64_t, const uint8_t*, int) noexcept
Overwrite
nbytes at off in place (no length change). All writable sources support this.
-
inline virtual bool insert(int64_t, const uint8_t*, int) noexcept
Insert
nbytes at off (grows the source). Resizable sources only.
-
inline virtual bool remove(int64_t, int) noexcept
Remove
nbytes at off (shrinks the source). Resizable sources only.
-
inline virtual bool can_undo() const noexcept
-
inline virtual bool can_redo() const noexcept
-
inline virtual bool undo() noexcept
-
inline virtual bool redo() noexcept
-
inline virtual void begin_edit_group() noexcept
Open / close an atomic undo group: every mutation between a
begin_edit_group()and its matchingend_edit_group()undoes as ONE step. Nestable (depth-counted) — the widget brackets a two-nibble hex byte so it is a single undo step even though it overwrites/inserts twice. Default no-ops; a source with undo (the file) maps them to its history. Calls must be balanced.
-
inline virtual void end_edit_group() noexcept
-
inline virtual const char *label() const noexcept
A short human label for the status bar (a file basename, or a memory region descriptor like “RAM 0x…”). Never NULL; “” when unknown.
-
virtual ~AgtHexSource() noexcept = default
AgtRangeHexSource
-
class AgtRangeHexSource : public AgtHexSource
Subclassed by AgtIoHexSource, AgtMemoryHexSource
Public Functions
-
AgtRangeHexSource() noexcept = default
-
void set_window(uintptr_t base, uint64_t len, uint32_t access_width = 1) noexcept
View
[base, base+len)of the address space at access_width-byte granularity (1/2/4/8, clamped to 1 on a bad value). base should be aligned to access_width. Rebuilds the label from the region.
-
inline uintptr_t base() const noexcept
-
inline uint32_t access_width() const noexcept override
-
inline int64_t size() const noexcept override
-
int read(int64_t off, int len, uint8_t *buf) const noexcept override
-
inline bool resizable() const noexcept override
-
inline bool is_volatile() const noexcept override
-
bool writable() const noexcept override
-
bool overwrite(int64_t off, const uint8_t *bytes, int n) noexcept override
-
inline const char *label() const noexcept override
-
AgtRangeHexSource() noexcept = default
AgtMemoryHexSource
-
class AgtMemoryHexSource : public AgtRangeHexSource
AgtIoHexSource
-
class AgtIoHexSource : public AgtRangeHexSource
AgtPieceTreeHexSource
-
class AgtPieceTreeHexSource : public AgtHexSource
Public Functions
-
AgtPieceTreeHexSource() noexcept = default
-
~AgtPieceTreeHexSource() noexcept override
-
AgtPieceTreeHexSource(const AgtPieceTreeHexSource&) = delete
-
AgtPieceTreeHexSource &operator=(const AgtPieceTreeHexSource&) = delete
-
bool open(const char *path, AxlPageCache *cache = nullptr) noexcept
Open path raw + out-of-core, replacing any currently-open file. When cache is non-NULL the file view borrows that shared page-cache frame budget (an editor with several open buffers); NULL gives the source its own frames. Returns false (source left closed) on failure.
-
void attach(AxlPieceTree *tree, const char *label = nullptr) noexcept
Read an EXISTING (BORROWED) piece tree — the bytes another widget owns, e.g. an
AgtEditBox’sAgtTextDoctree, for a shared-tree text↔hex view (no reload, no second copy; the hex view even reflects the text view’s unsaved edits). The source does NOT own / free tree, and a borrowed tree is read-only via this source (writable()is false) so a hex edit can never bypass the owner’s caches. Replaces any currently-open file (freeing it). label is the status-bar label (NULL = “”). NULL tree leaves the source empty.
-
int64_t size() const noexcept override
-
int read(int64_t off, int len, uint8_t *buf) const noexcept override
-
inline bool writable() const noexcept override
-
inline bool resizable() const noexcept override
-
bool overwrite(int64_t off, const uint8_t *bytes, int n) noexcept override
Overwrite n bytes at off in place (fixed length — refuses a span past the end), as ONE undo step. Returns whether it applied.
-
bool insert(int64_t off, const uint8_t *bytes, int n) noexcept override
Insert n bytes at off (grows the file); off == size() appends. One undo step. Refused on a borrowed tree. Returns whether it applied.
-
bool remove(int64_t off, int n) noexcept override
Remove n bytes at off (shrinks the file), clamped to the tail. One undo step. Refused on a borrowed tree. Returns whether it applied.
-
bool can_undo() const noexcept override
-
bool can_redo() const noexcept override
-
bool undo() noexcept override
-
bool redo() noexcept override
-
void begin_edit_group() noexcept override
-
void end_edit_group() noexcept override
-
inline const char *label() const noexcept override
-
inline AxlPieceTree *tree() const noexcept
The backing tree (borrowed) — for the future shared-tree text↔hex toggle + the H3 editing surface. NULL when closed.
-
AgtPieceTreeHexSource() noexcept = default