Control class Core

One interactive part of the drawn UI — the atom of the control-tree concept (docs/control-baum-konzept.md). A control owns its capabilities INHERENTLY: bounds (set by layout — the one geometry source), state (hover/pressed/focus — written only by the ControlHost), behaviour (pointer/keys/text), rendering (reads its own state), spoken label and cursor shape. A pane COMPOSES controls; it no longer implements input, hover, focus or hit-testing itself — which is exactly why a new control cannot get those wrong.

public abstract class Control
Namespace
ArionUI.Presentation.Controls
Package
ArionUI.Presentation · dotnet add package ArionUI.Presentation --prerelease

Constructors

Control

protected Control();

Properties

AccessibleName

public Func<string>? AccessibleName { get; init; }

What assistive technology calls this control, asked each time; null leaves it to Control.SpokenLabel. On a board tile that holds several controls it names the tile's group and wins over the caption the tile opens with.

AccessibleRange

public virtual AccessibleRange? AccessibleRange { get; }

The range of a part that picks a value along one (a slider); null otherwise.

AccessibleValue

public virtual string? AccessibleValue { get; }

The text of a text part; null when the part carries no value.

Bounds

public LogRect Bounds { get; protected internal set; }

Where this control IS — written by Control.Arrange, read by rendering, hit-testing and the focus ring alike. One source, so they can never drift apart again.

CanTakeFocus

public bool CanTakeFocus { get; }

Focusable, enabled and Control.Shown: a button in a hidden panel is no tab stop.

CaretRect

public virtual LogRect? CaretRect { get; }

Where the caret of a text sink stands, absolute like Control.Bounds and as last drawn; null for a control without a caret or before it was drawn. The host anchors the input method's candidate window here.

ChildClip

public virtual LogRect? ChildClip { get; }

The box this control shows its children in (a scrolling panel's viewport); null when it does not clip them. Parts outside it are offscreen to a reader.

Children

public virtual IEnumerable<Control> Children { get; }

The controls inside this one, in tree order (visual order, tab order). A host keeps the tree it adopted: a control whose children change once it is adopted says so with Control.TreeChanged (on a shown board inside Board.Mutate), or its new children get no host and Tab, ticks and the wheel do not find them.

Classes

public IReadOnlyList<string> Classes { get; set; }

The control's style classes, which the rules of the style sheets select (Select.Type<Button>().Class("primary")) - CSS's class attribute. On a shown board change them inside Board.Mutate.

Cursor

public virtual GridCursor Cursor { get; }

DrawsOwnFocus

public virtual bool DrawsOwnFocus { get; }

The control shows its focus itself (accent border, hover row, ring parameter). False = the host draws the shared default ring around Control.Bounds.

Enabled

public bool Enabled { get; }

EnabledWhen

public Func<bool>? EnabledWhen { get; init; }

Live availability probe (a row whose command has nothing to do, an empty list). Null = always enabled.

Focusable

public virtual bool Focusable { get; }

Can this KIND of control hold the keyboard focus? Combined with the live probes in Control.CanTakeFocus.

ForcedStates

public TileStates ForcedStates { get; set; }

States the control shows whatever the pointer and the focus do - the "force state" of a browser's developer tools, for a style guide that shows a button hovered and pressed side by side. Only the look follows; the control behaves as before. On a board the control's tile shows them too. Change it on the UI thread (inside Board.Mutate on a shown board).

Host

public ControlHost? Host { get; }

Id

public string Id { get; init; }

Identity for targeted focus, tests and (later) automation peers.

IsFocused

public bool IsFocused { get; }

Derived, never stored — there cannot be two focused controls.

IsHovered

public bool IsHovered { get; }

IsPressed

public bool IsPressed { get; }

Armed: the pointer went down on this control and has not been released yet. Acting on release-over-the-same-control is the host's capture rule.

Role

public virtual ControlRole Role { get; }

What KIND of part this is for assistive technology — the automation peers translate it into their host's control type.

ToggleState

public virtual bool? ToggleState { get; }

The checked state of a toggle part; null when the part does not toggle.

Visible

public bool Visible { get; }

VisibleWhen

public Func<bool>? VisibleWhen { get; init; }

WantsText

public virtual bool WantsText { get; }

Is this control a text sink? The host routes typing to the focused text control, or — the Excel rule — jumps to the FIRST one in the tree.

WantsTick

public virtual bool WantsTick { get; }

The control animates and wants Control.Tick on every frame.

Methods

Announce

protected void Announce(string text);

Arrange

public virtual void Arrange(LogRect bounds);

ExplainStyle

public IReadOnlyList<StyleDeclaration> ExplainStyle(TileStates states);

Every declaration the cascade weighs for this control in states, under the sheets its look was resolved from (its board's chain, or the theme's alone) - what StyleSheet.ExplainControl tells, the Styles pane of a browser.

HitTest

public virtual Control? HitTest(LogPoint p);

The control under an ABSOLUTE point, or null. Containers recurse; leaves answer for themselves. Same bounds the render pass used.

Invalidate

protected void Invalidate();

This control's look changed: repaint its bounds (and the focus ring or glow around them). A host that only repaints whole is told to do that.

Invalidate

protected void Invalidate(LogRect area);

Repaint area (absolute, like Control.Bounds) - for a control whose look reaches beyond its own bounds.

Invoke

public virtual bool Invoke();

Act like a click on the part (a button fires, a checkbox flips, a menu row runs, a dropdown opens). False when the part has no action or is disabled.

Measure

public virtual LogSize Measure(LogSize available);

Desired size given the space available (layout containers sum this).

OnAttached

protected internal virtual void OnAttached();

A host shows the tree this control is in: it joined a shown board, or the board's view was attached. UI thread, under the render gate; the render pass may be running on the UI thread, so ask for frames here (Control.RequestTick), not for a repaint.

OnDetached

protected internal virtual void OnDetached();

The control is no longer shown: it left the tree, or the host let the tree go. Release what only a shown control needs - GPU resources, subscriptions.

OnFocusChanged

public virtual void OnFocusChanged();

Focus arrived at or left this control (read Control.IsFocused). For side effects the host cannot know — a list syncing its hover row.

OnKey

public virtual bool OnKey(ArionKey key, ArionModifiers mods);

Keys while focused. Return false to let the pane's fallback see the key.

OnPointerLeft

public virtual void OnPointerLeft();

The pointer stopped hovering this control (moved on or left the pane).

OnPointerMoved

public virtual void OnPointerMoved(LogPoint p, bool buttonDown);

OnPointerPressed

public virtual void OnPointerPressed(LogPoint p, ArionModifiers mods, int clickCount);

OnPointerReleased

public virtual void OnPointerReleased(LogPoint p);

OnText

public virtual void OnText(string text);

OnWheel

public virtual bool OnWheel(LogPoint p, double delta);

Render

public abstract void Render(IRenderSurface s, ControlFrame frame);

RequestTick

protected void RequestTick();

Asks the host for frame ticks: from the next one on, Control.WantsTick is asked again. For a control that starts animating outside an input the host delivers - data arriving, a timer. Any thread.

SetAccessibleRangeValue

public virtual bool SetAccessibleRangeValue(double value);

Set the value of a range part, as the user could. False when the part has no range or is disabled.

SetAccessibleValue

public virtual bool SetAccessibleValue(string value);

Replace the text of a text part. False when the part carries no value.

SpokenLabel

public virtual string? SpokenLabel();

What a screen reader speaks when this control receives the focus. A control that cannot take the focus but answers here is READ: it becomes a text part.

StatesIn

protected TileStates StatesIn(ControlFrame frame);

The states the control is in for this frame: the pointer's, the focus while the frame holds the keyboard, disabled, and the Control.ForcedStates.

StyleIn

protected ComputedStyle StyleIn(TileStates states);

The control's style in states, resolved against the current theme - what a control draws its face with. A look-up, no cascade.

Tick

public virtual void Tick(double dtMs);

One frame of the animation. What it changes on screen it marks itself (Control.Invalidate): on a board only the marked area is drawn again.