diff --git a/README.md b/README.md index 40f7e9f005981b0c7a9199ffaaea6b6e5cce0d0c..013c40d4d0e6b4866dee90e1d132356ecd4e654d 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Widget's can create their own state and will re-render when that state changes. fn Counter(context: &mut KayakContext) { let (count, set_count, ..) = use_state!(0i32); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_count(count + 1), + EventType::Click(..) => set_count(count + 1), _ => {} }); diff --git a/examples/counter.rs b/examples/counter.rs index f86de9d88de70ef89ba24632b00f4f9e67233900..efa529a3c91e9d272a7367a19b7968321363e6b5 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -31,7 +31,7 @@ fn Counter(context: &mut KayakContext) { let (count, set_count, ..) = use_state!(0i32); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_count(count + 1), + EventType::Click(..) => set_count(count + 1), _ => {} }); diff --git a/examples/fold.rs b/examples/fold.rs index 07463e9e7993dc68c41e4ac9cb51c66964234714..245a4217947f35bef4b88ddbb54ad44bc072b05b 100644 --- a/examples/fold.rs +++ b/examples/fold.rs @@ -63,12 +63,12 @@ fn FolderTree(context: &mut KayakContext) { let (is_b_open, set_b_open, ..) = use_state!(false); let set_close_b = set_b_open.clone(); let close_b = Some(OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_close_b(false), + EventType::Click(..) => set_close_b(false), _ => {} })); let set_open_b = set_b_open.clone(); let open_b = Some(OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_open_b(true), + EventType::Click(..) => set_open_b(true), _ => {} })); diff --git a/examples/full_ui.rs b/examples/full_ui.rs index dd419b629f6130f86136caeae5e161acc225666d..f40962a246239ef598edba533dfe89ce76a6540e 100644 --- a/examples/full_ui.rs +++ b/examples/full_ui.rs @@ -53,10 +53,10 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>) let cloned_current_button_handle = current_button_handle.clone(); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::MouseIn => { + EventType::MouseIn(..) => { cloned_current_button_handle.set(blue_button_hover_handle); } - EventType::MouseOut => { + EventType::MouseOut(..) => { cloned_current_button_handle.set(blue_button_handle); } _ => (), diff --git a/examples/hooks.rs b/examples/hooks.rs index 3f10b788efb0bdf49fb839b493d1e4266fe6d748..9896dbf296444f4e97d9fbc9e3189afa3bc11b2d 100644 --- a/examples/hooks.rs +++ b/examples/hooks.rs @@ -39,7 +39,7 @@ fn StateCounter() { // both implement `Copy`. For other types, you may have to clone the state to pass it into a closure like this. // (You can also clone the setter as well if you need to use it in multiple places.) let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_count(count + 1), + EventType::Click(..) => set_count(count + 1), _ => {} }); @@ -64,7 +64,7 @@ fn EffectCounter() { // the third field in the tuple returned from the `use_state` macro. let (count, set_count, raw_count) = use_state!(0); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => set_count(count + 1), + EventType::Click(..) => set_count(count + 1), _ => {} }); diff --git a/examples/if.rs b/examples/if.rs index f6d1e5ba38a0eebb3b2213d0cc813e111c38bc16..88b0cc959e27c155b8fe5840a727c50e8a13618b 100644 --- a/examples/if.rs +++ b/examples/if.rs @@ -24,7 +24,7 @@ fn Removal(context: &mut KayakContext) { let is_visible = context.create_state(true).unwrap(); let cloned_is_visible = is_visible.clone(); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { cloned_is_visible.set(!cloned_is_visible.get()); } _ => {} diff --git a/examples/provider.rs b/examples/provider.rs index ea7e47531f449ce3676a33055b31dbe72b016f27..d451ddc854770790b8eb4a8b2495b1a10b8de696 100644 --- a/examples/provider.rs +++ b/examples/provider.rs @@ -89,7 +89,7 @@ fn ThemeButton(context: &mut KayakContext, theme: Theme) { let theme_clone = Arc::new(theme); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { // Update the shared state // This will cause the ThemeProvider to re-render along with all of the other consumers consumer.set((*theme_clone).clone()); diff --git a/examples/tabs/tab.rs b/examples/tabs/tab.rs index dbf598e17bc8f8fa706161f750edf7743fb9cba1..1d0eb9a9a4b9061e635e87d45920a5f32f8d00d5 100644 --- a/examples/tabs/tab.rs +++ b/examples/tabs/tab.rs @@ -30,14 +30,14 @@ pub fn Tab(context: &mut KayakContext, content: String, selected: bool) { }; let event_handler = OnEvent::new(move |_, event| match event.event_type { - EventType::Hover => { + EventType::Hover(..) => { if selected { set_hover_state(TabHoverState::Active); } else { set_hover_state(TabHoverState::Inactive); } } - EventType::MouseOut => { + EventType::MouseOut(..) => { set_hover_state(TabHoverState::None); } EventType::Focus => { diff --git a/examples/tabs/tab_bar.rs b/examples/tabs/tab_bar.rs index 6671b3de35a0c21689bb1563cf8b4cd7108ef05b..6c32a16b96e81b012fdc95c730cbf8f9d5a4991d 100644 --- a/examples/tabs/tab_bar.rs +++ b/examples/tabs/tab_bar.rs @@ -24,7 +24,7 @@ pub fn TabBar( let on_select = on_select_tab.clone(); let tab_event_handler = OnEvent::new(move |_, event| { match event.event_type { - EventType::Click => { + EventType::Click(..) => { on_select.call(index); } EventType::KeyDown(evt) => { diff --git a/examples/todo/add_button.rs b/examples/todo/add_button.rs index f32fd32416c0acc8346c7e81fa6a695b1a077847..a3dbdbe32e14dd56dae9dac581e93ffdabc62e97 100644 --- a/examples/todo/add_button.rs +++ b/examples/todo/add_button.rs @@ -29,10 +29,10 @@ pub fn AddButton(children: Children, styles: Option<Style>) { }); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::MouseIn => { + EventType::MouseIn(..) => { set_color(Color::new(0.0791, 0.0998, 0.201, 1.0)); } - EventType::MouseOut => { + EventType::MouseOut(..) => { set_color(Color::new(0.0781, 0.0898, 0.101, 1.0)); } _ => {} diff --git a/examples/todo/card.rs b/examples/todo/card.rs index 78ea8f1e3913be1a5af62c5a3fdadeefecfc5837..7196752c70f1766f27c3450e79e10838c7496c69 100644 --- a/examples/todo/card.rs +++ b/examples/todo/card.rs @@ -24,7 +24,7 @@ pub fn Card(card_id: usize, name: String, on_delete: Handler<usize>) { let on_delete = on_delete.clone(); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { on_delete.call(card_id); } _ => (), diff --git a/examples/todo/delete_button.rs b/examples/todo/delete_button.rs index ac011300d527b1ab5ca43da6e3a8e719f01e65b9..bbe6735b67d26dabdd795c43a3c29e53a15553b8 100644 --- a/examples/todo/delete_button.rs +++ b/examples/todo/delete_button.rs @@ -29,10 +29,10 @@ pub fn DeleteButton(children: Children, styles: Option<Style>) { }); let on_event = OnEvent::new(move |_, event| match event.event_type { - EventType::MouseIn => { + EventType::MouseIn(..) => { set_color(Color::new(0.0791, 0.0998, 0.201, 1.0)); } - EventType::MouseOut => { + EventType::MouseOut(..) => { set_color(Color::new(0.0781, 0.0898, 0.101, 1.0)); } _ => {} diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs index 19221d94ffa79a85e4aed7098251180100dbe4fb..fea3f1e36eebc6f3be6151a5302f6a39b963ccab 100644 --- a/examples/todo/todo.rs +++ b/examples/todo/todo.rs @@ -61,7 +61,7 @@ fn TodoApp() { let mut todos_cloned = todos.clone(); let cloned_set_todos = set_todos.clone(); let add_events = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { if !new_todo_value_cloned.is_empty() { todos_cloned.push(Todo { name: new_todo_value_cloned.clone(), diff --git a/examples/world_interaction.rs b/examples/world_interaction.rs index cf872930dfe9414463ebfeb6dfb7c118961a20e4..916d727f24c7e49c2cb1a3b5298a2d4d32345b93 100644 --- a/examples/world_interaction.rs +++ b/examples/world_interaction.rs @@ -97,7 +97,7 @@ fn ControlPanel() { } let on_change_color = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { // Cycle the color set_color_index((color_index + 1) % COLORS.len()); } diff --git a/kayak_core/src/cursor.rs b/kayak_core/src/cursor.rs index 0fe983dc02135e0ba92baadba3d1a8a01a0e0ec6..44ef8edfa9bfa08f4ffa5d5dd87c8e9e1b362993 100644 --- a/kayak_core/src/cursor.rs +++ b/kayak_core/src/cursor.rs @@ -16,3 +16,11 @@ impl Default for PointerEvents { Self::All } } + +#[derive(Default, Debug, Copy, Clone, PartialEq)] +pub struct CursorEvent { + pub(crate) pressed: bool, + pub(crate) just_pressed: bool, + pub(crate) just_released: bool, + pub(crate) position: (f32, f32) +} \ No newline at end of file diff --git a/kayak_core/src/event.rs b/kayak_core/src/event.rs index b42882bf1fb7d1506295d370a55b8ce0eba796f2..fd32b4b9d877aea4ecaa9821d425dd0de42af4a4 100644 --- a/kayak_core/src/event.rs +++ b/kayak_core/src/event.rs @@ -1,4 +1,6 @@ +use derivative::Derivative; use crate::{Index, KeyboardEvent}; +use crate::cursor::CursorEvent; #[derive(Debug, Clone, Copy, PartialEq)] pub struct Event { @@ -19,7 +21,7 @@ impl Default for Event { Self { target: Default::default(), current_target: Default::default(), - event_type: EventType::Click, + event_type: EventType::Click(CursorEvent::default()), should_propagate: true, default_prevented: false, } @@ -62,19 +64,52 @@ impl Event { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, Derivative)] +#[derivative(PartialEq, Hash, Eq)] pub enum EventType { - Click, - Hover, - MouseIn, - MouseOut, - MouseDown, - MouseUp, + Click( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), + Hover( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), + MouseIn( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), + MouseOut( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), + MouseDown( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), + MouseUp( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + CursorEvent + ), Focus, Blur, CharInput { c: char }, - KeyUp(KeyboardEvent), - KeyDown(KeyboardEvent), + KeyUp( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + KeyboardEvent + ), + KeyDown( + #[derivative(PartialEq = "ignore")] + #[derivative(Hash = "ignore")] + KeyboardEvent + ), } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -92,16 +127,16 @@ impl EventType { pub fn propagates(&self) -> bool { match self { // Propagates - Self::Hover => true, - Self::Click => true, - Self::MouseDown => true, - Self::MouseUp => true, + Self::Hover(..) => true, + Self::Click(..) => true, + Self::MouseDown(..) => true, + Self::MouseUp(..) => true, Self::CharInput { .. } => true, Self::KeyUp(..) => true, Self::KeyDown(..) => true, // Doesn't Propagate - Self::MouseIn => false, - Self::MouseOut => false, + Self::MouseIn(..) => false, + Self::MouseOut(..) => false, Self::Focus => false, Self::Blur => false, } @@ -111,12 +146,12 @@ impl EventType { pub fn event_category(&self) -> EventCategory { match self { // Mouse - Self::Hover => EventCategory::Mouse, - Self::Click => EventCategory::Mouse, - Self::MouseDown => EventCategory::Mouse, - Self::MouseUp => EventCategory::Mouse, - Self::MouseIn => EventCategory::Mouse, - Self::MouseOut => EventCategory::Mouse, + Self::Hover(..) => EventCategory::Mouse, + Self::Click(..) => EventCategory::Mouse, + Self::MouseDown(..) => EventCategory::Mouse, + Self::MouseUp(..) => EventCategory::Mouse, + Self::MouseIn(..) => EventCategory::Mouse, + Self::MouseOut(..) => EventCategory::Mouse, // Keyboard Self::CharInput { .. } => EventCategory::Keyboard, Self::KeyUp(..) => EventCategory::Keyboard, diff --git a/kayak_core/src/event_dispatcher.rs b/kayak_core/src/event_dispatcher.rs index 8abc01221c174d691b413ccc20f272348ed4d952..d5b3637214eada2da652df84a552ed7751931409 100644 --- a/kayak_core/src/event_dispatcher.rs +++ b/kayak_core/src/event_dispatcher.rs @@ -8,6 +8,7 @@ use crate::{ KeyboardModifiers, PointerEvents, Widget, }; use std::collections::{HashMap, HashSet}; +use crate::cursor::CursorEvent; type EventMap = HashMap<Index, HashSet<EventType>>; type TreeNode = ( @@ -37,6 +38,7 @@ impl Default for EventState { #[derive(Debug, Clone)] pub(crate) struct EventDispatcher { is_mouse_pressed: bool, + next_mouse_pressed: bool, current_mouse_position: (f32, f32), next_mouse_position: (f32, f32), previous_events: EventMap, @@ -52,6 +54,7 @@ impl EventDispatcher { Self { last_clicked: Binding::new(Index::default()), is_mouse_pressed: Default::default(), + next_mouse_pressed: Default::default(), current_mouse_position: Default::default(), next_mouse_position: Default::default(), previous_events: Default::default(), @@ -163,17 +166,17 @@ impl EventDispatcher { // Events that need to be maintained without re-firing between event updates should be managed here for (index, events) in &self.previous_events { // Mouse is currently pressed for this node - if self.is_mouse_pressed && events.contains(&EventType::MouseDown) { + if self.is_mouse_pressed && events.contains(&EventType::MouseDown(Default::default())) { // Make sure this event isn't removed while mouse is still held down - Self::insert_event(&mut next_events, index, EventType::MouseDown); + Self::insert_event(&mut next_events, index, EventType::MouseDown(Default::default())); } // Mouse is currently within this node - if events.contains(&EventType::MouseIn) - && !Self::contains_event(&next_events, index, &EventType::MouseOut) + if events.contains(&EventType::MouseIn(Default::default())) + && !Self::contains_event(&next_events, index, &EventType::MouseOut(Default::default())) { // Make sure this event isn't removed while mouse is still within node - Self::insert_event(&mut next_events, index, EventType::MouseIn); + Self::insert_event(&mut next_events, index, EventType::MouseIn(Default::default())); } } @@ -201,6 +204,30 @@ impl EventDispatcher { let old_wants_cursor = self.wants_cursor; self.contains_cursor = None; self.wants_cursor = None; + self.next_mouse_position = self.current_mouse_position; + self.next_mouse_pressed = self.is_mouse_pressed; + + // --- Pre-Process --- // + // We pre-process some events so that we can provide accurate event data (such as if the mouse is pressed) + // This is faster than resolving data after the fact since `input_events` is generally very small + for input_event in input_events { + if let InputEvent::MouseMoved(point) = input_event { + // Reset next global mouse position + self.next_mouse_position = *point; + } + + if matches!(input_event, InputEvent::MouseLeftPress) { + // Reset next global mouse pressed + self.next_mouse_pressed = true; + break; + } else if matches!(input_event, InputEvent::MouseLeftRelease) { + // Reset next global mouse pressed + self.next_mouse_pressed = false; + // Reset global cursor container + self.has_cursor = None; + break; + } + } // === Mouse Events === // let mut stack: Vec<TreeNode> = vec![(root, 0)]; @@ -212,12 +239,7 @@ impl EventDispatcher { // --- Process Event --- // if matches!(input_event.category(), InputEventCategory::Mouse) { // A widget's PointerEvents style will determine how it and its children are processed - let mut pointer_events = PointerEvents::default(); - if let Some(widget) = widget_manager.current_widgets.get(current).unwrap() { - if let Some(styles) = widget.get_styles() { - pointer_events = styles.pointer_events.resolve(); - } - } + let pointer_events = Self::resolve_pointer_events(current, widget_manager); match pointer_events { PointerEvents::All | PointerEvents::SelfOnly => { @@ -226,6 +248,7 @@ impl EventDispatcher { (current, depth), &mut states, widget_manager, + false, ); event_stream.extend(events); @@ -290,6 +313,7 @@ impl EventDispatcher { // === Process Cursor States === // self.current_mouse_position = self.next_mouse_position; + self.is_mouse_pressed = self.next_mouse_pressed; if self.contains_cursor.is_none() { // No change -> revert @@ -309,6 +333,7 @@ impl EventDispatcher { tree_node: TreeNode, states: &mut HashMap<EventType, EventState>, widget_manager: &WidgetManager, + ignore_layout: bool ) -> Vec<Event> { let mut event_stream = Vec::<Event>::new(); let (node, depth) = tree_node; @@ -316,19 +341,20 @@ impl EventDispatcher { match input_event { InputEvent::MouseMoved(point) => { if let Some(layout) = widget_manager.get_layout(&node) { + let cursor_event = self.get_cursor_event(*point); let was_contained = layout.contains(&self.current_mouse_position); let is_contained = layout.contains(point); - if was_contained != is_contained { + if !ignore_layout && was_contained != is_contained { if was_contained { - event_stream.push(Event::new(node, EventType::MouseOut)); + event_stream.push(Event::new(node, EventType::MouseOut(cursor_event))); } else { - event_stream.push(Event::new(node, EventType::MouseIn)); + event_stream.push(Event::new(node, EventType::MouseIn(cursor_event))); } } if self.contains_cursor.is_none() || !self.contains_cursor.unwrap_or_default() { if let Some(widget) = widget_manager.current_widgets.get(node).unwrap() { // Check if the cursor moved onto a widget that qualifies as one that can contain it - if Self::can_contain_cursor(widget) { + if ignore_layout || Self::can_contain_cursor(widget) { self.contains_cursor = Some(is_contained); } } @@ -343,21 +369,16 @@ impl EventDispatcher { } // Check for hover eligibility - if is_contained { - Self::update_state(states, (node, depth), layout, EventType::Hover); + if ignore_layout || is_contained { + Self::update_state(states, (node, depth), layout, EventType::Hover(cursor_event)); } } - - // Reset global mouse position - self.next_mouse_position = *point; } InputEvent::MouseLeftPress => { - // Reset global mouse pressed - self.is_mouse_pressed = true; - if let Some(layout) = widget_manager.get_layout(&node) { - if layout.contains(&self.current_mouse_position) { - event_stream.push(Event::new(node, EventType::MouseDown)); + if ignore_layout || layout.contains(&self.current_mouse_position) { + let cursor_event = self.get_cursor_event(self.current_mouse_position); + event_stream.push(Event::new(node, EventType::MouseDown(cursor_event))); if let Some(focusable) = widget_manager.get_focusable(node) { if focusable { @@ -378,18 +399,15 @@ impl EventDispatcher { } } InputEvent::MouseLeftRelease => { - // Reset global mouse pressed - self.is_mouse_pressed = false; - self.has_cursor = None; - if let Some(layout) = widget_manager.get_layout(&node) { - if layout.contains(&self.current_mouse_position) { - event_stream.push(Event::new(node, EventType::MouseUp)); + if ignore_layout || layout.contains(&self.current_mouse_position) { + let cursor_event = self.get_cursor_event(self.current_mouse_position); + event_stream.push(Event::new(node, EventType::MouseUp(cursor_event))); self.last_clicked.set(node); - if Self::contains_event(&self.previous_events, &node, &EventType::MouseDown) + if Self::contains_event(&self.previous_events, &node, &EventType::MouseDown(cursor_event)) { - Self::update_state(states, (node, depth), layout, EventType::Click); + Self::update_state(states, (node, depth), layout, EventType::Click(cursor_event)); } } } @@ -400,6 +418,27 @@ impl EventDispatcher { event_stream } + fn resolve_pointer_events(index: Index, widget_manager: &WidgetManager) -> PointerEvents { + let mut pointer_events = PointerEvents::default(); + if let Some(widget) = widget_manager.current_widgets.get(index).unwrap() { + if let Some(styles) = widget.get_styles() { + pointer_events = styles.pointer_events.resolve(); + } + } + pointer_events + } + + fn get_cursor_event(&self, position: (f32, f32)) -> CursorEvent { + let change = self.next_mouse_pressed != self.is_mouse_pressed; + let pressed = self.next_mouse_pressed; + CursorEvent { + position, + pressed, + just_pressed: change && pressed, + just_released: change && !pressed, + } + } + fn process_keyboard_events( &mut self, input_event: &InputEvent, diff --git a/kayak_render_macros/src/lib.rs b/kayak_render_macros/src/lib.rs index f04c8488c6e9b6d9826dc41a6425ebcea147ba5a..3459ab222ae9bed1c6dbe94a7f4a83f829e81221 100644 --- a/kayak_render_macros/src/lib.rs +++ b/kayak_render_macros/src/lib.rs @@ -137,7 +137,7 @@ pub fn dyn_partial_eq(_: TokenStream, input: TokenStream) -> TokenStream { /// let (count, set_count, ..) = use_state!(0); /// /// let on_event = OnEvent::new(move |_, event| match event.event_type { -/// EventType::Click => { +/// EventType::Click(..) => { /// set_count(foo + 1); /// } /// _ => {} @@ -215,7 +215,7 @@ pub fn use_state(initial_state: TokenStream) -> TokenStream { /// }, [count_state]); /// /// let on_event = OnEvent::new(move |_, event| match event.event_type { -/// EventType::Click => { +/// EventType::Click(..) => { /// set_count(foo + 1); /// } /// _ => {} diff --git a/src/widgets/fold.rs b/src/widgets/fold.rs index cee810648a77b23f747f750641c5807ff496006d..be10357e7feaf897dbeb54cccdf2aa1668d87d28 100644 --- a/src/widgets/fold.rs +++ b/src/widgets/fold.rs @@ -54,7 +54,7 @@ pub fn Fold( } let handler = OnEvent::new(move |_, event| match event.event_type { - EventType::Click => { + EventType::Click(..) => { if open.is_none() { // This is an internally-managed state set_is_open(!is_open); diff --git a/src/widgets/inspector.rs b/src/widgets/inspector.rs index 9c63447158ec6181413fe76bbb83617c241e9695..8f7b69f0271b57d2118420589e1b3cf00d8cdfb6 100644 --- a/src/widgets/inspector.rs +++ b/src/widgets/inspector.rs @@ -72,7 +72,7 @@ pub fn Inspector() { } let handle_button_events = Some(OnEvent::new(move |_, event| match event.event_type { - EventType::Click => last_clicked.set(parent_id_move.unwrap()), + EventType::Click(..) => last_clicked.set(parent_id_move.unwrap()), _ => {} })); diff --git a/src/widgets/tooltip.rs b/src/widgets/tooltip.rs index 49f5b3e15d120205b5903104c4866ef220fb5d37..9c1108900552e9c51b76f425f240e596d7547a15 100644 --- a/src/widgets/tooltip.rs +++ b/src/widgets/tooltip.rs @@ -185,19 +185,19 @@ pub fn TooltipConsumer( let text = Arc::new(text); self.on_event = Some(OnEvent::new(move |ctx, event| match event.event_type { - EventType::MouseIn => { + EventType::MouseIn(..) => { let mut state = data.get(); state.visible = true; state.text = (*text).clone(); state.size = size; data.set(state); } - EventType::Hover => { + EventType::Hover(..) => { let mut state = data.get(); state.anchor = anchor.unwrap_or(ctx.last_mouse_position()); data.set(state); } - EventType::MouseOut => { + EventType::MouseOut(..) => { let mut state = data.get(); // Set hidden only if the tooltip's text matches this consumer's // Otherwise, it likely got picked up by another widget and should be kept visible