diff --git a/examples/demo.rs b/examples/demo.rs index 9d93c05..be90917 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -49,6 +49,8 @@ fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState>) -> El world.spawn_empty(); }); + let (spawn_entity_hovered, enter, exit) = use_hover(cx); + render! { node { onclick: move |_| selected_entity.set(None), @@ -78,8 +80,10 @@ fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState>) -> El } node { onclick: move |_| spawn_entity(), + onmouse_enter: enter, + onmouse_exit: exit, padding: "8", - background_color: NEUTRAL_800, + background_color: if spawn_entity_hovered { NEUTRAL_600 } else { NEUTRAL_800 }, text { text: "Spawn Entity", text_size: "18" diff --git a/src/colors.rs b/src/colors.rs index 1ea956b..82647ca 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,3 +1,6 @@ +// Tailwind v3.4.0 https://tailwindcss.com/docs/customizing-colors + +pub const NEUTRAL_600: &'static str = "#525252"; pub const NEUTRAL_800: &'static str = "#27272a"; pub const INDIGO_600: &'static str = "#4f46e5"; diff --git a/src/events.rs b/src/events.rs index 291a611..b672bde 100644 --- a/src/events.rs +++ b/src/events.rs @@ -3,7 +3,7 @@ use bevy::ecs::{ event::{Events, ManualEventReader}, system::Resource, }; -use bevy_mod_picking::events::{Click, Pointer}; +use bevy_mod_picking::events::{Click, Out, Over, Pointer}; use dioxus::core::ScopeState; use std::{any::Any, rc::Rc}; @@ -11,32 +11,47 @@ use std::{any::Any, rc::Rc}; #[derive(Resource, Default)] pub struct EventReaders { - clicks: ManualEventReader>, + click: ManualEventReader>, + mouse_enter: ManualEventReader>, + mouse_exit: ManualEventReader>, } impl EventReaders { pub fn get_dioxus_events( &mut self, - clicks: &Events>, + click: &Events>, + mouse_enter: &Events>, + mouse_exit: &Events>, ) -> Vec<(Entity, &'static str, Rc)> { let mut events: Vec<(Entity, &'static str, Rc)> = Vec::new(); - - for event in self.clicks.read(clicks) { + for event in self.click.read(click) { events.push((event.target, "click", Rc::new(()))); } - + for event in self.mouse_enter.read(mouse_enter) { + events.push((event.target, "mouse_enter", Rc::new(()))); + } + for event in self.mouse_exit.read(mouse_exit) { + events.push((event.target, "mouse_exit", Rc::new(()))); + } events } } pub fn is_supported_event(event: &str) -> bool { - event == "click" + match event { + "click" => true, + "mouse_enter" => true, + "mouse_exit" => true, + _ => false, + } } pub mod events { super::impl_event! [ (); onclick + onmouse_enter + onmouse_exit ]; } diff --git a/src/hooks.rs b/src/hooks.rs index 161dbba..645ee01 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -9,8 +9,8 @@ use bevy::{ utils::{HashMap, HashSet}, }; use dioxus::{ - core::{ScopeId, ScopeState}, - hooks::use_on_destroy, + core::{Event, ScopeId, ScopeState}, + hooks::{use_on_destroy, use_state}, }; #[derive(Default)] @@ -124,6 +124,15 @@ where .0 } +pub fn use_hover<'a>( + cx: &'a ScopeState, +) -> (bool, impl FnMut(Event<()>) + 'a, impl FnMut(Event<()>) + 'a) { + let hovered = use_state(cx, || false); + let on_mouse_enter = |_| hovered.set(true); + let on_mouse_exit = |_| hovered.set(false); + (*hovered.get(), on_mouse_enter, on_mouse_exit) +} + pub struct DioxusUiQuery<'a, Q: ReadOnlyWorldQuery, F: ReadOnlyWorldQuery> { query_state: QueryState, world_cell: UnsafeWorldCell<'a>, diff --git a/src/tick.rs b/src/tick.rs index b7c3623..d4e1a3e 100644 --- a/src/tick.rs +++ b/src/tick.rs @@ -17,7 +17,7 @@ pub fn tick_dioxus_ui(world: &mut World) { run_deferred_systems(world); let ui_events = world.resource_scope(|world, mut event_readers: Mut| { - event_readers.get_dioxus_events(world.resource()) + event_readers.get_dioxus_events(world.resource(), world.resource(), world.resource()) }); let root_entities: HashMap = world