Skip to main content

Slider

Purpose​

A value picked by dragging along a track, continuous or in steps.

Signature​

pub struct Slider<Msg = crate::callback::Callback> { .. }

impl Slider {
pub fn new(value: f32) -> Self;
}

Example​

Rendered preview of the Slider demo

From frus-examples/widgets/src/features/inputs/widgets/slider.rs:

//! `Slider` — a value picked by dragging along a track: continuous, or in steps with
//! `divisions`, with a bubble showing the value while dragging.

use frus::{
Color, Insets, Padding, ShowValueIndicator, Slider, State, StateContext, StatefulWidget, Text,
Widget,
};

use crate::common::shared::{section, sections};

pub fn example() -> Box<dyn Widget> {
Box::new(SliderDemo.into_widget())
}

struct SliderDemo;

struct SliderDemoState {
volume: f32,
rating: f32,
temperature: f32,
/// Changed only when a drag **ends**: for work too costly to do on every pixel.
committed: f32,
}

impl StatefulWidget for SliderDemo {
type State = SliderDemoState;

fn create_state(&self) -> SliderDemoState {
SliderDemoState {
volume: 0.5,
rating: 3.0,
temperature: 21.0,
committed: 21.0,
}
}
}

impl State for SliderDemoState {
type Widget = SliderDemo;

fn build(&self, cx: &StateContext<Self>) -> Box<dyn Widget> {
sections(vec![
// From 0 to 1 unless told otherwise.
Box::new(section(
"Continuous",
Slider::new(self.volume)
.width(300.0)
.on_change(cx.handler(|s: &mut SliderDemoState, v: f32| s.volume = v)),
)),
Box::new(Text::new(format!("Volume: {:.0}%", self.volume * 100.0))),
// `divisions` snaps to steps; `value_label` writes the bubble, shown here all
// the time (by default only while dragging). The padding is the bubble's room.
Box::new(section(
"Steps with a value label",
Padding::new(
Insets::new(28.0, 0.0, 0.0, 0.0),
Slider::new(self.rating)
.range(1.0, 5.0)
.divisions(4)
.value_label(|v| format!("{v:.0} stars"))
.show_value_indicator(ShowValueIndicator::AlwaysVisible)
.width(300.0)
.on_change(cx.handler(|s: &mut SliderDemoState, v: f32| s.rating = v)),
),
)),
// `on_change_end` fires once, on release.
Box::new(section(
"Custom range, colours and change end",
Slider::new(self.temperature)
.range(10.0, 30.0)
.divisions(40)
.value_label(|v| format!("{v:.1} °C"))
.active_color(Color::hex("#DC2626"))
.inactive_color(Color::hex("#FECACA"))
.thumb_color(Color::hex("#991B1B"))
.width(300.0)
.on_change(cx.handler(|s: &mut SliderDemoState, v: f32| s.temperature = v))
.on_change_end(cx.handler(|s: &mut SliderDemoState, v: f32| s.committed = v)),
)),
Box::new(Text::new(format!(
"Dragging: {:.1} °C · saved: {:.1} °C",
self.temperature, self.committed
))),
// A second, lighter track: how much of a video is buffered, say.
Box::new(section(
"Secondary track, disabled",
Slider::new(0.3)
.secondary_track_value(0.7)
.width(300.0)
.enabled(false),
)),
])
}
}

Properties​

MethodArgumentEffect
.active_color()color: ColorThe travelled part of the track, and the thumb unless thumb_color names it; the scheme's primary otherwise.
.inactive_color()color: ColorThe part of the track still to travel; the scheme's surface_container_highest otherwise.
.secondary_active_color()color: ColorThe part between the value and the secondary value; the scheme's primary at 54 % otherwise.
.thumb_color()color: ColorThe thumb's fill; the active colour otherwise.
.thumb_border_color()color: ColorA ring around the thumb, two pixels wide.
.overlay_color()color: WidgetStateProperty<Color>The halo around the thumb, per state: hovered, focused, dragged. Unset, the theme's, then the active colour at 12 % when one is given, then the scheme's primary at 8 % hovered and 10 % focused or dragged.
.thumb_elevation()elevation: f32How far the thumb sits off the track at rest.
.pressed_thumb_elevation()elevation: f32How far it rises while it is held.
.track_shape()shape: impl SliderTrackShape + 'staticPaints the track with shape.
.tick_mark_shape()shape: impl SliderTickMarkShape + 'staticPaints the tick marks with shape.
.thumb_shape()shape: impl SliderThumbShape + 'staticPaints the thumb with shape.
.overlay_shape()shape: impl SliderOverlayShape + 'staticPaints the halo with shape.
.value_indicator_shape()shape: impl SliderValueIndicatorShape + 'staticPaints the value indicator with shape.
.range()min: f32, max: f32The travel this slider covers; 0.0..=1.0 by default.
.secondary_track_value()value: f32A second value, shown as a lighter part of the track beyond the value: how much of a video is buffered behind where it is playing. It is not dragged.
.divisions()n: usizeSplits the travel into n steps: the value snaps to min + k·(max−min)/n, a tick marks each, and an arrow key moves by one of them. Without this call the travel is continuous and an arrow moves by 5 %.
.value_label()label: impl Fn(f32) -> String + 'staticFormats the value for the value indicator, the drop over the thumb — a percentage, a price, a duration. When it shows is show_value_indicator's to say. A screen reader hears it too, unless semantic_formatter says otherwise.
.allowed_interaction()interaction: SliderInteractionWhat a press and a slide may do.
.show_value_indicator()when: ShowValueIndicatorWhen the value indicator shows.
.semantic_formatter()format: impl Fn(f32) -> String + 'static—
.width()width: f32The width, in logical pixels. Unset, the slider takes the width it is offered, and 220 where none can be offered.
.on_change()on_change: impl Fn(f32) -> R + 'staticA closure producing a message from the new value, in the slider's units.
.on_change_start()on_start: impl Fn(f32) -> R + 'staticSent once, when a drag begins — before the first on_change, with the value the press landed on.
.on_change_end()on_end: impl Fn(f32) -> R + 'staticSent once, when the drag ends — after the last on_change, with the value it settled on.
.enabled()enabled: boolWhether the slider can be moved. Disabled it is inert — it takes no drag and answers no key — and it still shows where it is set.

Behaviour​

The track is inset by the halo's radius at each end, so the thumb reaches both ends without leaving the box. In a right-to-left reading direction it runs from the right.

See also​

Source: crates/frus-widgets/src/slider.rs @ e6fba33f5b42