diff --git a/tcw3/examples/tcw3_widgets.rs b/tcw3/examples/tcw3_widgets.rs index 27a9f647..ad78be2e 100644 --- a/tcw3/examples/tcw3_widgets.rs +++ b/tcw3/examples/tcw3_widgets.rs @@ -155,7 +155,12 @@ fn main() { }); } { - // TODO + let slider_weak = Rc::downgrade(&slider); + slider.set_on_step(move |_, dir| { + let slider = slider_weak.upgrade().unwrap(); + let value = slider.value() + dir as i8 as f64 * 0.2; + slider.set_value(value.max(0.0).min(1.0)); + }); } let slider = { diff --git a/tcw3/src/ui/views/slider.rs b/tcw3/src/ui/views/slider.rs index 776c3570..401bfd0c 100644 --- a/tcw3/src/ui/views/slider.rs +++ b/tcw3/src/ui/views/slider.rs @@ -20,7 +20,9 @@ use crate::{ PropKindFlags, Role, StyledBox, StyledBoxOverride, Widget, }, }, - uicore::{HView, HViewRef, HWndRef, MouseDragListener, UpdateCtx, ViewFlags, ViewListener}, + uicore::{ + HView, HViewRef, HWndRef, KeyEvent, MouseDragListener, UpdateCtx, ViewFlags, ViewListener, + }, utils::resetiter, }; @@ -549,6 +551,33 @@ struct SlViewListener { } impl ViewListener for SlViewListener { + fn key_down(&self, wm: pal::Wm, _: HViewRef<'_>, e: &KeyEvent<'_>) -> bool { + let shared = if let Some(shared) = self.shared.upgrade() { + shared + } else { + return false; + }; + + let is_view_vertical = if shared.vertical { + ACTION_BIT_VERTICAL + } else { + 0 + }; + match e.translate_accel(&ACCEL_TABLE) { + Some(action) if (action & ACTION_BIT_VERTICAL) == is_view_vertical => { + let dir = if (action & ACTION_BIT_INCR) != 0 { + Dir::Incr + } else { + Dir::Decr + }; + + shared.on_step.borrow()(wm, dir); + true + } + _ => false, + } + } + fn mouse_drag( &self, _: pal::Wm, @@ -568,6 +597,20 @@ impl ViewListener for SlViewListener { } } +const ACTION_BIT_VERTICAL: pal::ActionId = 1; +const ACTION_BIT_INCR: pal::ActionId = 1 << 1; +const ACTION_LEFT: pal::ActionId = 0; +const ACTION_RIGHT: pal::ActionId = ACTION_BIT_INCR; +const ACTION_UP: pal::ActionId = ACTION_BIT_VERTICAL; +const ACTION_BOTTOM: pal::ActionId = ACTION_BIT_VERTICAL | ACTION_BIT_INCR; + +static ACCEL_TABLE: pal::AccelTable = pal::accel_table![ + (ACTION_LEFT, windows("Left"), macos("Left"), gtk("Left")), + (ACTION_RIGHT, windows("Right"), macos("Right"), gtk("Right")), + (ACTION_UP, windows("Up"), macos("Up"), gtk("Up")), + (ACTION_BOTTOM, windows("Down"), macos("Down"), gtk("Down")), +]; + /// Implements `MouseDragListener` for `Slider`. struct SlMouseDragListener { shared: Rc,