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.
