| title | Switch Specs |
|---|
This document captures design and implementation notes for Switch.
Note
For end-user usage and examples, see Switch.
- Status: Implemented
- Primary purpose: A compact toggle switch with optional inline content (label) rendered next to the track.
- Content model:
Switch : ContentVisual(single childContent). - Interaction:
- toggles on
Space/Enterand left click - supports
Left/Rightto force off/on
- toggles on
- Rendering note: Carefully handles RGBA track fills to avoid double-applied alpha blending when drawing the thumb over the track.
Switch : ContentVisual(sealed)
Switch()setsFocusable = true.Switch(Visual content)assignsContent.
IsOn : bool- raises the
Toggledrouted event when it changes
- raises the
IsPressed : bool(read-only public)- set during pointer press/release for pressed styling
Toggled(bubble): raised with old/new boolean values.
- Track width is fixed at 4 cells (
TrackWidth = 4). - If there is content:
- measures content with width reduced by
TrackWidth + SwitchStyle.SpaceBetweenGlyphAndText - desired size is:
width = TrackWidth + gap + contentWidthheight = max(1, contentHeight)
- measures content with width reduced by
- If no content: desired size is
(TrackWidth, 1).
- Content is arranged to the right of the track + gap within
finalRect. - The track itself is drawn in
Renderand is vertically centered within the control’s height.
Track rendering:
- Draws up to
min(TrackWidth, Bounds.Width)cells for the track. - Uses
SwitchStyle.TrackLeft/TrackRightfor the first/last cell glyphs, spaces otherwise. - Resolves per-segment track style with
SwitchStyle.ResolveTrackPart(...):- segments are considered “active” based on
IsOnand thumb position - hovered/pressed/focused variants are applied by the style resolver
- segments are considered “active” based on
Thumb rendering:
- Computes a
thumbIndex:- for full 4-cell track: index is
1(off) or2(on) - for smaller tracks, clamps to the available range
- for full 4-cell track: index is
- Renders
SwitchStyle.ThumbGlyphOn/ThumbGlyphOffover the track. - Avoids double alpha blending:
- if the track background is RGBA, the thumb style is not merged with the track style
- otherwise, merges unspecified style parts from the track into the thumb (
MergeUnspecified)
Space/Enter: toggleLeft: setIsOn = falseRight: setIsOn = true
- left press sets
IsPressed = true - left release clears
IsPressedand togglesIsOnif released within bounds
Key knobs:
- geometry:
SpaceBetweenGlyphAndTextTrackLeft/TrackRightThumbGlyphOn/ThumbGlyphOff(defaults matchRadioButtonStylechecked/unchecked glyphs; seeSwitchStyle.Roundpreset)
- track styles:
TrackOn*,TrackOff*(active/inactive parts)TrackHovered,TrackPressed,TrackFocused,TrackDisabled
- thumb styles:
ThumbOn,ThumbOff,ThumbDisabled
Default resolution uses theme colors like Theme.Primary, Theme.Surface, Theme.SurfaceAlt, Theme.Selection, Theme.FocusBorder.
- Tests:
src/XenoAtom.Terminal.UI.Tests/SwitchTests.cs
- Demo:
- ControlsDemo includes switch examples (with and without inline content).
- Support configurable track width (while keeping a sensible default).
- Add optional “animated” toggling (if/when the framework supports lightweight animations).