Skip to main content

Module slider

Module slider 

Source
Expand description

Slider — a draggable value selector bound to a Signal<f32>.

The widget owns all input handling: pointer drag (click-to-jump and thumb-drag), the keyboard, and the Increment / Decrement / SetValue accessibility actions. All visual chrome is delegated to a [SliderStyle] implementation; the IntUI default ships out of the box and is also the theme-wide slot override target (theme.style_slots.slider).

§Keyboard

  • ArrowRight / ArrowUp and ArrowLeft / ArrowDown — one step, defaulting to 1 % of the range.
  • PageUp / PageDown — one page_step, defaulting to ten times the step and so to 10 % of the range. That is QAbstractSlider::pageStep, GtkScale’s page increment, and what <input type=range> gives in both WebKit and Blink.
  • Home / End — the minimum and the maximum.
  • A chord holding Ctrl, Alt or Super is not the slider’s and falls through to the application; Shift does not change the step.

The chord table is shared with every other bounded-scalar control; see docs/range-keyboard.md.

§Accessibility

Exposes Role::Slider with numeric value, min, max, step, the page distance as numeric_value_jump, and orientation. Screen readers announce the current value on every change. SetValue accepts a number or a numeric string and snaps it to step, so an assistive technology’s write lands on the same grid a drag does — AT-SPI’s Value.SetCurrentValue is how Orca sets a slider, and macOS gates setAccessibilityValue: settability on the action being advertised. The focus ring follows the :focus-visible heuristic — visible after keyboard interaction, invisible after a pointer tap.

let volume = Signal::new(0.5_f32);
let _w = Slider::new(volume, 0.0, 1.0).step(0.05);

§Value readout and reset

value_tooltip shows the value as text beside the thumb — “-3.0 dB” on an equalizer band — while the pointer is over the slider, while a drag is moving it, and while it has keyboard focus. It is up at once rather than after a hover delay, follows the thumb wherever the slider goes, and changes as the value does. It takes no input: a press or a hover on it belongs to what is under it, and Escape takes it down without keeping the key from the field the user pressed it for. The same text becomes the slider’s accessible value, beside the number, so a reader that speaks a value’s text says “-3.0 dB” rather than “-3”.

value_tooltip_placement moves the readout: Above or Below the thumb, or FollowPointer, which rides the pointer rather than the thumb while a drag moves the value — useful on a stepped slider, whose thumb snaps away from the hand. The default, Auto, is the placement described above. value_tooltip_style paints this slider’s readout with a [TooltipStyle] of its own instead of the theme’s tooltip chrome.

default_value adds a way back: a double-click on the slider, or the “Reset to default” accessibility action, puts the value back to the default, as a user change, so on_change reports it.

let gain = Signal::new(0.0_f32);
let _band = Slider::new(gain, -12.0, 12.0)
    .step(0.5)
    .label(lit!("Low shelf"))
    .value_tooltip(|db| lit!(format!("{db:+.1} dB")))
    .value_tooltip_placement(SliderValueTooltipPlacement::Below)
    .default_value(0.0);

§Clicks, presses and buttons

A click on the track jumps the value to it, on release; a drag moves it from the moment the pointer has travelled far enough to be a drag. Both answer to the primary button only. An application that wants a click of its own on the slider — a secondary-click reset, say — attaches its own on_tap and widens that handler’s mask; the slider’s track click stays on the primary button, and the secondary click is the application’s alone:

let gain = Signal::new(0.0_f32);
let reset = gain.clone();
let _w = Slider::new(gain, -12.0, 12.0)
    .on_tap(move |_, _| reset.set(0.0))
    .accept_tap_buttons(ButtonMask::SECONDARY);

jump_on_press moves the value as soon as a mouse button goes down rather than on release, and a drag carries on from there. A finger’s or a pen’s press still writes nothing until it is a tap or a drag: such a press may yet become a scroll.

§Touch and pen

A slider is a continuous manipulator: the value it produces is the press position, so a finger that lands on it adjusts it — even inside a scrolling form, and from the first movement rather than after a long-press timer. Two separate things deliver that. The press capture the drag takes makes the slider the innermost member of the pointer’s sequence, which is what stops an enclosing scroller winning the gesture. touch_action(NONE) is the declaration on top: it forbids every default touch behaviour on the hit path, which in practice means a two-contact pinch started on the slider never reaches the surface under it. docs/touch-and-pen.md §7.3.

[teksilo_core::widget::Widget::target_regions] reports what the style painted inside the slider’s one node: the whole node as the press surface, and the knob as the grab affordance, sized through the resolved style’s density-aware thumb_diameter_for. Nothing else in the tree can see the knob — it is drawn on the same canvas as the track — so this is the only way a conformance audit or a coarse-press router learns it is there.

Right-to-left. A horizontal slider’s minimum sits at the leading edge, which is the right-hand one in an RTL UI, so both the painted fill and the position→value map mirror. They were previously mirrored in neither, so an RTL slider’s knob moved away from the finger dragging it.

Structs§

Slider
A draggable value selector bound to a Signal<f32> in a continuous or discrete range. Visual chrome is fully delegated to a [SliderStyle] implementation.

Enums§

SliderValueTooltipPlacement
Where Slider::value_tooltip’s readout sits, set with Slider::value_tooltip_placement.
SliderVariantExport

Constants§

SLIDER_PART_BODY
[Widget::target_regions] part id for the whole press surface — the track plus everything either side of it, which is what a tap or a drag acts on.
SLIDER_PART_THUMB
[Widget::target_regions] part id for the knob.