diff --git a/CHANGELOG.md b/CHANGELOG.md index a2bd2fa5a9..2b90822478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ You can find its changes [documented below](#070---2021-01-01). - Scope: expose scoped state using state() and state_mut() ([#2082] by [@rjwittams] - Tabs: allow getting and setting the tab index of a Tabs widget ([#2082] by [@rjwittams] - `RangeSlider` and `Annotated` ([#1979] by [@xarvic]) +- `Slider` widget now scrollable by mouse wheel ([#2104] by [@gordonshieh]) ### Changed diff --git a/druid/src/widget/slider.rs b/druid/src/widget/slider.rs index 7b09afb3f3..fd2b86a8cc 100644 --- a/druid/src/widget/slider.rs +++ b/druid/src/widget/slider.rs @@ -184,6 +184,15 @@ impl Widget for Slider { ctx.set_active(true); } } + if let Event::Wheel(me) = event { + if !self.knob.active { + *data = (*data + self.mapping.calculate_scroll_value(me.wheel_delta.y)) + .max(self.mapping.min) + .min(self.mapping.max); + ctx.request_paint(); + ctx.set_handled(); + } + } } } @@ -359,6 +368,26 @@ impl Widget<(f64, f64)> for RangeSlider { ctx.request_paint(); } } + if let Event::Wheel(me) = event { + if !self.left_knob.is_active() && !self.right_knob.is_active() { + let knob_size = env.get(theme::BASIC_WIDGET_HEIGHT); + let press_value = + self.mapping + .calculate_value(me.pos, knob_size, ctx.size(), 0.0); + + if press_value - data.0 < data.1 - press_value { + data.0 = (data.0 + self.mapping.calculate_scroll_value(me.wheel_delta.y)) + .min(data.1) + .max(self.mapping.min); + } else { + data.1 = (data.1 + self.mapping.calculate_scroll_value(me.wheel_delta.y)) + .min(self.mapping.max) + .max(data.0); + } + ctx.request_paint(); + ctx.set_handled(); + } + } } } @@ -476,6 +505,9 @@ impl> Annotated { self.labels.push(layout); walk += self.labeled_steps; + if self.labeled_steps == 0.0 { + break; + } } } @@ -567,6 +599,9 @@ impl> Widget for Annotated { ctx.stroke(line, &text_color, 1.0); walk += self.unlabeled_steps; + if self.labeled_steps == 0.0 { + return; + } } let mut walk = self.mapping.min; @@ -597,6 +632,9 @@ impl> Widget for Annotated { ); walk += self.labeled_steps; + if self.labeled_steps == 0.0 { + return; + } } self.inner.paint(ctx, data, env); @@ -657,6 +695,20 @@ impl SliderValueMapping { value } + fn calculate_scroll_value(&self, mouse_delta: f64) -> f64 { + let increment = if let Some(step) = self.step { + step + } else { + (self.max - self.min) / 10.0 + }; + + if mouse_delta < 0.0 { + increment + } else { + -increment + } + } + fn get_point(&self, value: f64, knob_size: f64, widget_size: Size) -> Point { let knob_major = (self.axis.major(widget_size) - knob_size) * self.normalize(value) + knob_size / 2.;