Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make slider scrollable by mouse wheel #2104

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the links aren't automatically generated. Please manually define both [#2104] and [@gordonshieh] at the bottom of the file.


### Changed

Expand Down
52 changes: 52 additions & 0 deletions druid/src/widget/slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ impl Widget<f64> 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();
}
}
}
}

Expand Down Expand Up @@ -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 {
Copy link
Collaborator

@xarvic xarvic Jan 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to remember which knob was scrolled last

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();
}
}
}
}

Expand Down Expand Up @@ -476,6 +505,9 @@ impl<T, W: Widget<T>> Annotated<T, W> {
self.labels.push(layout);

walk += self.labeled_steps;
if self.labeled_steps == 0.0 {
break;
}
}
}

Expand Down Expand Up @@ -567,6 +599,9 @@ impl<T: Data, W: Widget<T>> Widget<T> for Annotated<T, W> {

ctx.stroke(line, &text_color, 1.0);
walk += self.unlabeled_steps;
if self.labeled_steps == 0.0 {
return;
}
}

let mut walk = self.mapping.min;
Expand Down Expand Up @@ -597,6 +632,9 @@ impl<T: Data, W: Widget<T>> Widget<T> for Annotated<T, W> {
);

walk += self.labeled_steps;
if self.labeled_steps == 0.0 {
return;
}
}

self.inner.paint(ctx, data, env);
Expand Down Expand Up @@ -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.;
Expand Down