Add hover events

This commit is contained in:
JMS55 2023-12-21 21:14:09 -08:00
parent 6d6bad2110
commit fc4720e01e
5 changed files with 42 additions and 11 deletions

View file

@ -49,6 +49,8 @@ fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> El
world.spawn_empty(); world.spawn_empty();
}); });
let (spawn_entity_hovered, enter, exit) = use_hover(cx);
render! { render! {
node { node {
onclick: move |_| selected_entity.set(None), onclick: move |_| selected_entity.set(None),
@ -78,8 +80,10 @@ fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> El
} }
node { node {
onclick: move |_| spawn_entity(), onclick: move |_| spawn_entity(),
onmouse_enter: enter,
onmouse_exit: exit,
padding: "8", padding: "8",
background_color: NEUTRAL_800, background_color: if spawn_entity_hovered { NEUTRAL_600 } else { NEUTRAL_800 },
text { text {
text: "Spawn Entity", text: "Spawn Entity",
text_size: "18" text_size: "18"

View file

@ -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 NEUTRAL_800: &'static str = "#27272a";
pub const INDIGO_600: &'static str = "#4f46e5"; pub const INDIGO_600: &'static str = "#4f46e5";

View file

@ -3,7 +3,7 @@ use bevy::ecs::{
event::{Events, ManualEventReader}, event::{Events, ManualEventReader},
system::Resource, system::Resource,
}; };
use bevy_mod_picking::events::{Click, Pointer}; use bevy_mod_picking::events::{Click, Out, Over, Pointer};
use dioxus::core::ScopeState; use dioxus::core::ScopeState;
use std::{any::Any, rc::Rc}; use std::{any::Any, rc::Rc};
@ -11,32 +11,47 @@ use std::{any::Any, rc::Rc};
#[derive(Resource, Default)] #[derive(Resource, Default)]
pub struct EventReaders { pub struct EventReaders {
clicks: ManualEventReader<Pointer<Click>>, click: ManualEventReader<Pointer<Click>>,
mouse_enter: ManualEventReader<Pointer<Over>>,
mouse_exit: ManualEventReader<Pointer<Out>>,
} }
impl EventReaders { impl EventReaders {
pub fn get_dioxus_events( pub fn get_dioxus_events(
&mut self, &mut self,
clicks: &Events<Pointer<Click>>, click: &Events<Pointer<Click>>,
mouse_enter: &Events<Pointer<Over>>,
mouse_exit: &Events<Pointer<Out>>,
) -> Vec<(Entity, &'static str, Rc<dyn Any>)> { ) -> Vec<(Entity, &'static str, Rc<dyn Any>)> {
let mut events: Vec<(Entity, &'static str, Rc<dyn Any>)> = Vec::new(); let mut events: Vec<(Entity, &'static str, Rc<dyn Any>)> = Vec::new();
for event in self.click.read(click) {
for event in self.clicks.read(clicks) {
events.push((event.target, "click", Rc::new(()))); 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 events
} }
} }
pub fn is_supported_event(event: &str) -> bool { pub fn is_supported_event(event: &str) -> bool {
event == "click" match event {
"click" => true,
"mouse_enter" => true,
"mouse_exit" => true,
_ => false,
}
} }
pub mod events { pub mod events {
super::impl_event! [ super::impl_event! [
(); ();
onclick onclick
onmouse_enter
onmouse_exit
]; ];
} }

View file

@ -9,8 +9,8 @@ use bevy::{
utils::{HashMap, HashSet}, utils::{HashMap, HashSet},
}; };
use dioxus::{ use dioxus::{
core::{ScopeId, ScopeState}, core::{Event, ScopeId, ScopeState},
hooks::use_on_destroy, hooks::{use_on_destroy, use_state},
}; };
#[derive(Default)] #[derive(Default)]
@ -124,6 +124,15 @@ where
.0 .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> { pub struct DioxusUiQuery<'a, Q: ReadOnlyWorldQuery, F: ReadOnlyWorldQuery> {
query_state: QueryState<Q, F>, query_state: QueryState<Q, F>,
world_cell: UnsafeWorldCell<'a>, world_cell: UnsafeWorldCell<'a>,

View file

@ -17,7 +17,7 @@ pub fn tick_dioxus_ui(world: &mut World) {
run_deferred_systems(world); run_deferred_systems(world);
let ui_events = world.resource_scope(|world, mut event_readers: Mut<EventReaders>| { let ui_events = world.resource_scope(|world, mut event_readers: Mut<EventReaders>| {
event_readers.get_dioxus_events(world.resource()) event_readers.get_dioxus_events(world.resource(), world.resource(), world.resource())
}); });
let root_entities: HashMap<Entity, DioxusUiRoot> = world let root_entities: HashMap<Entity, DioxusUiRoot> = world