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();
});
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<Option<Entity>>) -> 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"

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 INDIGO_600: &'static str = "#4f46e5";

View file

@ -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<Pointer<Click>>,
click: ManualEventReader<Pointer<Click>>,
mouse_enter: ManualEventReader<Pointer<Over>>,
mouse_exit: ManualEventReader<Pointer<Out>>,
}
impl EventReaders {
pub fn get_dioxus_events(
&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>)> {
let mut events: Vec<(Entity, &'static str, Rc<dyn Any>)> = 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
];
}

View file

@ -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<Q, F>,
world_cell: UnsafeWorldCell<'a>,

View file

@ -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<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