GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Implement scroll wheel support on sliders and demo app
src/main.rs | 9 +++++++++
src/widget.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/src/main.rs b/src/main.rs
index 48040ca..b93c64e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -421,6 +421,15 @@ impl State {
fn handle_event(&mut self, event: &WindowEvent) -> bool {
match event {
+ WindowEvent::MouseWheel { delta, .. } => {
+ let mut changed = false;
+ for w in &mut self.widgets {
+ if w.mouse_wheel(delta, self.cursor_x, self.cursor_y) {
+ changed = true;
+ }
+ }
+ changed
+ }
WindowEvent::CursorMoved { position, .. } => {
self.cursor_x = position.x as f32 / self.scale as f32;
self.cursor_y = position.y as f32 / self.scale as f32;
diff --git a/src/widget.rs b/src/widget.rs
index 36945e3..7f3390a 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -1,4 +1,4 @@
-use winit::event::{ElementState, KeyEvent, MouseButton};
+use winit::event::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
use winit::keyboard::{Key, NamedKey};
use crate::colors;
@@ -22,6 +22,7 @@ pub trait Widget {
fn cursor_moved(&mut self, _px: f32, _py: f32) -> bool { false }
fn mouse_input(&mut self, _button: MouseButton, _state: ElementState, _px: f32, _py: f32) -> bool { false }
+ fn mouse_wheel(&mut self, _delta: &MouseScrollDelta, _px: f32, _py: f32) -> bool { false }
fn set_hovered(&mut self, _hovered: bool) {}
fn hovered(&self) -> bool { false }
@@ -307,6 +308,32 @@ impl Widget for ParametersBg {
self.dragging_param = None;
}
+ fn mouse_wheel(&mut self, delta: &MouseScrollDelta, px: f32, py: f32) -> bool {
+ let mut changed = false;
+ for (i, p) in self.display_params.iter_mut().enumerate() {
+ if p.2.starts_with("slider") {
+ let row_y = self.y + 30.0 + (i as f32) * 20.0;
+ if py >= row_y - 2.0 && py <= row_y + 18.0 && px >= self.x && px <= self.x + self.w {
+ let val = p.1.parse::<f32>().unwrap_or(0.0);
+ let (min, max) = parse_slider_range(&p.2);
+ let scroll_amount = match delta {
+ MouseScrollDelta::LineDelta(_x, y) => *y,
+ MouseScrollDelta::PixelDelta(pos) => (pos.y as f32) / 120.0,
+ };
+ let step = (max - min) * 0.02;
+ let new_val = (val + scroll_amount * step).clamp(min, max);
+ let old_val = &p.1;
+ let new_val_str = format!("{:.2}", new_val);
+ if *old_val != new_val_str {
+ p.1 = new_val_str;
+ changed = true;
+ }
+ }
+ }
+ }
+ changed
+ }
+
fn extra_quads(&self) -> Vec<(f32, f32, f32, f32, [f32; 4])> {
let mut quads = Vec::new();
for (i, p) in self.display_params.iter().enumerate() {
@@ -1294,6 +1321,23 @@ impl Widget for Slider {
fn drag_end(&mut self) { self.dragging = false; }
+ fn mouse_wheel(&mut self, delta: &MouseScrollDelta, px: f32, py: f32) -> bool {
+ let (sx, sy, sw, sh) = self.rect();
+ if px >= sx && px <= sx + sw && py >= sy && py <= sy + sh {
+ let scroll_amount = match delta {
+ MouseScrollDelta::LineDelta(_x, y) => *y,
+ MouseScrollDelta::PixelDelta(pos) => (pos.y as f32) / 120.0,
+ };
+ let step = 0.02;
+ let new_val = (self.value + scroll_amount * step).clamp(0.0, 1.0);
+ if (new_val - self.value).abs() > 0.0001 {
+ self.value = new_val;
+ return true;
+ }
+ }
+ false
+ }
+
fn extra_quads(&self) -> Vec<(f32, f32, f32, f32, [f32; 4])> {
let thumb_size = self.h * 0.9;
let thumb_x = self.x + self.value * (self.w - thumb_size);