Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions examples/hover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use dioxus::prelude::*;

fn main() {
dioxus_native::launch(app);
}

fn app() -> Element {
let mut hover_count = use_signal(|| 0);

rsx! {
div {
style: "padding: 20px; background: #eee; cursor: pointer;",
onmouseenter: move |_| hover_count += 1,
"Hover count: {hover_count}"
}
}
}
2 changes: 0 additions & 2 deletions packages/blitz-dom/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,8 +878,6 @@ impl BaseDocument {
return false;
}

println!("Focussed node {}", focus_node_id);

// Remove focus from the old node
if let Some(id) = self.focus_node_id {
self.snapshot_node_and(id, |node| node.blur());
Expand Down
12 changes: 12 additions & 0 deletions packages/blitz-dom/src/events/hover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::BaseDocument;

pub(crate) fn handle_hover(doc: &mut BaseDocument, _target: usize, x: f32, y: f32) {
if let Some(node) = doc.get_node_mut(_target) {
// Toggle hover state on the node
node.hover();

doc.set_focus_to(_target);

doc.set_hover_to(x, y);
}
}
6 changes: 5 additions & 1 deletion packages/blitz-dom/src/events/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
mod hover;
mod ime;
mod keyboard;
mod mouse;

use blitz_traits::{DomEvent, DomEventData};
pub(crate) use hover::handle_hover;
pub(crate) use ime::handle_ime_event;
pub(crate) use keyboard::handle_keypress;
pub(crate) use mouse::handle_click;
Expand All @@ -15,7 +17,9 @@ pub(crate) fn handle_event(doc: &mut BaseDocument, event: DomEvent) {
match event.data {
DomEventData::MouseDown(_) => {}
DomEventData::MouseUp(_) => {}
DomEventData::Hover => {}
DomEventData::Hover(event) => {
handle_hover(doc, target_node_id, event.x, event.y);
}
DomEventData::Click(event) => {
handle_click(doc, target_node_id, event.x, event.y);
}
Expand Down
32 changes: 28 additions & 4 deletions packages/blitz-shell/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::convert_events::{
};
use crate::event::{create_waker, BlitzShellEvent};
use blitz_dom::BaseDocument;
use blitz_traits::{BlitzMouseButtonEvent, ColorScheme, Devtools, Viewport};
use blitz_traits::{BlitzHoverEvent, BlitzMouseButtonEvent, ColorScheme, Devtools, Viewport};
use blitz_traits::{Document, DocumentRenderer, DomEvent, DomEventData};
use winit::keyboard::PhysicalKey;

Expand Down Expand Up @@ -249,12 +249,36 @@ impl<Doc: Document<Doc = D>, Rend: DocumentRenderer<Doc = D>> View<Doc, Rend> {
let dom_x = x + viewport_scroll.x as f32 / self.viewport.zoom();
let dom_y = y + viewport_scroll.y as f32 / self.viewport.zoom();

// println!("Mouse move: ({}, {})", x, y);
// println!("Unscaled: ({}, {})",);
//println!("Mouse move: ({}, {})", x, y);
//println!("Unscaled: ({}, {})",);

self.mouse_pos = (x, y);
self.dom_mouse_pos = (dom_x, dom_y);
self.doc.as_mut().set_hover_to(dom_x, dom_y)

// Get previous and new hover nodes
let previous_hover_node = self.doc.as_ref().get_hover_node_id();
let hover_changed = self.doc.as_mut().set_hover_to(dom_x, dom_y);
let current_hover_node = self.doc.as_ref().get_hover_node_id();

if previous_hover_node != current_hover_node {
// ! No Idea how Handle mouseleave for previous node
// if let Some(prev_node) = previous_hover_node {
// self.doc.handle_event(DomEvent {
// target: prev_node,
// data: DomEventData::Hover(BlitzHoverEvent { x: dom_x, y: dom_y }),
// });
// }

// Handle mouseenter for new node
if let Some(curr_node) = current_hover_node {
self.doc.handle_event(DomEvent {
target: curr_node,
data: DomEventData::Hover(BlitzHoverEvent { x: dom_x, y: dom_y }),
});
}
}

hover_changed
}

pub fn mouse_down(&mut self, _button: &str) {
Expand Down
10 changes: 8 additions & 2 deletions packages/blitz-traits/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub enum DomEventData {
Click(BlitzMouseButtonEvent),
KeyPress(BlitzKeyEvent),
Ime(BlitzImeEvent),
Hover,
Hover(BlitzHoverEvent),
}

impl DomEventData {
Expand All @@ -36,11 +36,17 @@ impl DomEventData {
DomEventData::Click { .. } => "click",
DomEventData::KeyPress { .. } => "keypress",
DomEventData::Ime { .. } => "input",
DomEventData::Hover => "mouseover",
DomEventData::Hover { .. } => "mouseover",
}
}
}

#[derive(Clone, Debug)]
pub struct BlitzHoverEvent {
pub x: f32,
pub y: f32,
}

#[derive(Debug, Clone, Copy)]
pub struct HitResult {
/// The node_id of the node identified as the hit target
Expand Down
4 changes: 2 additions & 2 deletions packages/blitz-traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub mod navigation;

mod events;
pub use events::{
BlitzImeEvent, BlitzKeyEvent, BlitzMouseButtonEvent, DomEvent, DomEventData, EventListener,
HitResult, KeyState,
BlitzHoverEvent, BlitzImeEvent, BlitzKeyEvent, BlitzMouseButtonEvent, DomEvent, DomEventData,
EventListener, HitResult, KeyState,
};

mod document;
Expand Down
40 changes: 39 additions & 1 deletion packages/dioxus-native/src/dioxus_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,45 @@ impl Document for DioxusDocument {
}
// TODO: Implement IME and Hover events handling
DomEventData::Ime(_) => {}
DomEventData::Hover => {}
DomEventData::Hover { .. } => {
let hover_event_data = wrap_event_data(NativeClickData);
println!("HOVER EVENT");

for &DxNodeIds { node_id, dioxus_id } in chain.iter() {
if let Some(id) = dioxus_id {
// Dispatch both mouseenter and mouseover events
let events = ["mouseenter", "mouseover"];
for event_name in events {
let hover_event = Event::new(hover_event_data.clone(), true);
self.vdom
.runtime()
.handle_event(event_name, hover_event.clone(), id);
prevent_default |= !hover_event.default_action_enabled();
stop_propagation |= !hover_event.propagates();
}

// Also dispatch mouseleave when hover ends
if !prevent_default {
let default_event = DomEvent {
target: node_id,
data: renderer_event.data.clone(),
};
self.inner.as_mut().handle_event(default_event.clone());

// Explicit mouseleave event
self.vdom.runtime().handle_event(
"mouseleave",
Event::new(hover_event_data.clone(), true),
id,
);
}
}

if stop_propagation {
break;
}
}
}
}

if !prevent_default {
Expand Down