Skip to main content

RangeSlider

Purpose​

Two thumbs on one track, for picking an interval.

Signature​

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

impl RangeSlider {
pub fn new(start: f32, end: f32) -> Self;
}

Example​

Rendered preview of the RangeSlider demo

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

//! `RangeSlider` — two thumbs on one track, for picking an interval (a price range, a
//! time window).

use frus::{Color, RangeSlider, State, StateContext, StatefulWidget, Text, Widget};

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

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

struct RangeDemo;

struct RangeDemoState {
price: (f32, f32),
hours: (f32, f32),
}

impl StatefulWidget for RangeDemo {
type State = RangeDemoState;

fn create_state(&self) -> RangeDemoState {
RangeDemoState {
price: (20.0, 80.0),
hours: (9.0, 17.0),
}
}
}

impl State for RangeDemoState {
type Widget = RangeDemo;

fn build(&self, cx: &StateContext<Self>) -> Box<dyn Widget> {
sections(vec![
// The handler gets both ends at once. `cx.handler` takes one value, so this
// one changes the state through a handle: a closure that returns nothing is
// run when the change is delivered.
Box::new(section(
"Continuous",
RangeSlider::new(self.price.0, self.price.1)
.range(0.0, 100.0)
.width(300.0)
.on_change({
let handle = cx.handle();
move |start, end| handle.set_state(|s| s.price = (start, end))
}),
)),
Box::new(Text::new(format!(
"Price: ${:.0} – ${:.0}",
self.price.0, self.price.1
))),
Box::new(section(
"Whole hours, labelled, custom colour",
RangeSlider::new(self.hours.0, self.hours.1)
.range(0.0, 24.0)
.divisions(24)
.value_label(|v| format!("{v:02.0}:00"))
.active_color(Color::hex("#0891B2"))
.width(300.0)
.on_change({
let handle = cx.handle();
move |start, end| handle.set_state(|s| s.hours = (start, end))
}),
)),
Box::new(Text::new(format!(
"Open {:02.0}:00 to {:02.0}:00",
self.hours.0, self.hours.1
))),
])
}
}

Properties​

MethodArgumentEffect
.range()min: f32, max: f32The travel the two values cover; 0.0..=1.0 by default. Everything the application sees is in these units.
.divisions()n: usizeSplits the travel into n steps: the values snap to them, a tick marks each, and an arrow moves a thumb by one.
.width()width: f32The width, in logical pixels. Unset, the slider takes the width it is offered, and 220 where none can be.
.value_label()label: impl Fn(f32) -> String + 'staticA screen reader hears it too, unless semantic_formatter says otherwise.
.semantic_formatter()format: impl Fn(f32) -> String + 'staticHow a screen reader is told each thumb's value.
.show_value_indicator()when: ShowValueIndicatorWhen the tooltips show. Unset, the theme's, then only on a slider with divisions.
.active_color()color: ColorThe span between the thumbs, and the thumbs; the scheme's primary otherwise.
.inactive_color()color: ColorThe track outside the span; primary at 24 % otherwise.
.thumb_color()color: ColorThe thumbs' fill; the active colour otherwise.
.overlay_color()color: WidgetStateProperty<Color>The halo around a thumb, per state; the active colour at 12 % otherwise.
.thumb_elevation()elevation: f32How far a 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, given both thumbs.
.tick_mark_shape()shape: impl SliderTickMarkShape + 'staticPaints the tick marks with shape.
.thumb_shape()shape: impl SliderThumbShape + 'staticPaints both thumbs with shape.
.overlay_shape()shape: impl SliderOverlayShape + 'staticPaints the halo with shape.
.value_indicator_shape()shape: impl SliderValueIndicatorShape + 'staticPaints the value indicators with shape.
.enabled()enabled: boolWhether the slider can be moved. Disabled it takes no drag, no key and no focus, and still shows its interval.
.on_change()on_change: impl Fn(f32, f32) -> R + 'staticA closure producing a message from the new interval, (start, end), in the slider's units.
.on_change_start()on_start: impl Fn(f32, f32) -> R + 'static—
.on_change_end()on_end: impl Fn(f32, f32) -> R + 'staticSent once when the drag ends, with the interval it settled on.

Behaviour​

Like Slider it takes the width it is offered and is as tall as its halo, its track inset by the halo's radius, running from the right in a right-to-left reading direction.

A press on both, where they meet, waits for the first movement: leftwards takes the start. Each thumb takes the keyboard's focus and tells a screen reader its own value.

See also​

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