diff --git a/docs/modules/Custom.md b/docs/modules/Custom.md index 05dc5d3..6d33749 100644 --- a/docs/modules/Custom.md +++ b/docs/modules/Custom.md @@ -76,16 +76,17 @@ A draggable slider. Note that `on_change` will provide the **floating point** value as an argument. If your input program requires an integer, you will need to round it. -| Name | Type | Default | Description | -|---------------|----------------------------------------------------|--------------|------------------------------------------------------------------------------| -| `src` | `image` | `null` | Image source. See [here](images) for information on images. | -| `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. | -| `orientation` | `horizontal` or `vertical` (shorthand: `h` or `v`) | `horizontal` | Orientation of the slider. | -| `value` | `Script` | `null` | Script to run to get the slider value. Output must be a valid number. | -| `on_change` | `string [command]` | `null` | Command to execute when the slider changes. More on this [below](#commands). | -| `min` | `float` | `0` | Minimum slider value. | -| `max` | `float` | `100` | Maximum slider value. | -| `length` | `integer` | `null` | Slider length. GTK will automatically size if left unset. | +| Name | Type | Default | Description | +|---------------|----------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------| +| `src` | `image` | `null` | Image source. See [here](images) for information on images. | +| `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. | +| `orientation` | `horizontal` or `vertical` (shorthand: `h` or `v`) | `horizontal` | Orientation of the slider. | +| `value` | `Script` | `null` | Script to run to get the slider value. Output must be a valid number. | +| `on_change` | `string [command]` | `null` | Command to execute when the slider changes. More on this [below](#commands). | +| `min` | `float` | `0` | Minimum slider value. | +| `max` | `float` | `100` | Maximum slider value. | +| `step` | `float` | - | The increment to change when scrolling with the mouse wheel. If left blank, will use the default determined by the environment. | +| `length` | `integer` | `null` | Slider length. GTK will automatically size if left unset. | The example slider widget below shows a volume control for MPC, which updates the server when changed, and polls the server for volume changes to keep the slider in sync. diff --git a/src/modules/custom/slider.rs b/src/modules/custom/slider.rs index 0b2f946..f777b1c 100644 --- a/src/modules/custom/slider.rs +++ b/src/modules/custom/slider.rs @@ -7,6 +7,7 @@ use gtk::prelude::*; use gtk::Scale; use serde::Deserialize; use std::cell::Cell; +use std::ops::Neg; use tokio::spawn; use tracing::error; @@ -21,6 +22,7 @@ pub struct SliderWidget { min: f64, #[serde(default = "default_max")] max: f64, + step: Option, length: Option, } @@ -53,11 +55,26 @@ impl CustomWidget for SliderWidget { if let Some(on_change) = self.on_change { let min = self.min; let max = self.max; + let step = self.step; let tx = context.tx.clone(); // GTK will spam the same value over and over let prev_value = Cell::new(scale.value()); + scale.connect_scroll_event(move |scale, event| { + let value = scale.value(); + let delta = event.delta().1.neg(); + + let delta = match (step, delta.is_sign_positive()) { + (Some(step), true) => step, + (Some(step), false) => -step, + (None, _) => delta, + }; + + scale.set_value(value + delta); + Inhibit(false) + }); + scale.connect_change_value(move |scale, _, val| { // GTK will send values outside min/max range let val = val.clamp(min, max);