working events

This commit is contained in:
Daniel Bulant 2023-10-24 12:31:58 +02:00
parent 5d53e10a32
commit c785b36442
5 changed files with 64 additions and 19 deletions

View file

@ -6,6 +6,7 @@ pub use winit::event::{TouchPhase, MouseScrollDelta, DeviceId, ModifiersState, V
use crate::SharedNode;
#[derive(Clone, Debug)]
pub struct NodeEvent {
/// Target node of event.
pub target: SharedNode,
@ -16,6 +17,7 @@ pub struct NodeEvent {
}
/// Different event types that can be sent to a node.
#[derive(Clone, Debug, PartialEq)]
pub enum InnerEvent {
Wheel {
phase: TouchPhase,
@ -56,6 +58,7 @@ pub enum InnerEvent {
KeyUp(KeyboardEvent),
}
#[derive(Clone, Debug, PartialEq)]
pub struct KeyboardEvent {
/// Logical location ("it's effect") of the key
pub key: Option<VirtualKeyCode>,
@ -77,6 +80,7 @@ pub struct KeyboardEvent {
pub device: DeviceId
}
#[derive(Clone, Debug, PartialEq)]
pub struct MouseEvent {
/// The button which fired the event (if any)
pub button: Option<MouseButton>,
@ -214,14 +218,14 @@ impl MouseEvent {
}
}
#[derive(Default)]
#[derive(Copy, Clone, Default, Debug, PartialEq)]
pub(crate) struct MouseValue {
pub last_location: Location,
pub buttons: u8
}
impl MouseValue {
fn update_buttons(&mut self, button: MouseButton, state: ElementState) {
pub(crate) fn update_buttons(&mut self, button: MouseButton, state: ElementState) {
let buttons = MouseEvent::button_to_buttons(button);
match state {
ElementState::Pressed => self.buttons |= buttons,

View file

@ -81,15 +81,14 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
WindowEvent::MouseWheel { device_id, delta, phase, .. } => {},
WindowEvent::CursorMoved { device_id, position, .. } => {
let mouse_value = mouse_values.get(&device_id);
let (movement, location, buttons) = match mouse_value {
let (movement, location, mouse_value) = match mouse_value {
Some(mouse_value) => {
let location = (position.x, position.y).into();
let movement = location - mouse_value.last_location;
mouse_values.insert(device_id, MouseValue {
(movement, location, MouseValue {
last_location: location,
buttons: mouse_value.buttons
});
(movement, location, mouse_value.buttons)
})
},
None => {
let location = (position.x, position.y).into();
@ -98,10 +97,11 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
last_location: location,
buttons: 0
};
mouse_values.insert(device_id, value);
(movement, location, Default::default())
(movement, location, value)
}
};
let buttons = mouse_value.buttons;
mouse_values.insert(device_id, mouse_value);
let path = get_element_at(&root, &context, location);
@ -111,7 +111,7 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
Some(target_layout) => target_layout,
None => { return; }
};
let target_layout = taffy.layout(target_layout.to_owned()).unwrap();
let target_layout = context.taffy.layout(target_layout.to_owned()).unwrap();
let event = NodeEvent {
target: path.last().unwrap().clone(),
path: path.clone(),
@ -125,6 +125,10 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
offset: location - target_layout.location.into()
})
};
for node in path.iter().rev() {
node.write().unwrap().on_event(&event);
}
}
},
WindowEvent::DroppedFile(path) => {},
@ -143,7 +147,7 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
path: strong_focus_path.clone(),
event: if focused { events::InnerEvent::Focus } else { events::InnerEvent::Blur }
};
strong_focus_path.last().unwrap().write().unwrap().on_event(&focus_event.event);
strong_focus_path.last().unwrap().write().unwrap().on_event(&focus_event);
let focus_event = NodeEvent {
target: strong_focus_path.last().unwrap().clone(),
@ -152,7 +156,7 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
};
for node in strong_focus_path.iter().rev() {
node.write().unwrap().on_event(&focus_event.event);
node.write().unwrap().on_event(&focus_event);
}
},
None => {}
@ -162,10 +166,41 @@ pub fn run_event_loop(root_node: SharedNode) -> ! {
WindowEvent::KeyboardInput { device_id, input, is_synthetic } => {},
WindowEvent::MouseInput { device_id, state, button, .. } => {
let mouse_value = mouse_values.get(&device_id);
let mouse_value = match mouse_value {
Some(mouse_value) => mouse_value,
let mut mouse_value = match mouse_value {
Some(mouse_value) => mouse_value.clone(),
None => { return; } // Mouse move should be fired first
};
mouse_value.update_buttons(button, state);
let location = mouse_value.last_location;
let path = get_element_at(&root, &context, location);
match path {
Some(path) => {
let mevent = MouseEvent {
button: Some(button),
buttons: mouse_value.buttons,
client: location,
movement: Location::new(0., 0.),
device: device_id,
modifiers,
offset: Location::new(0., 0.)
};
let event = NodeEvent {
target: path.last().unwrap().clone(),
path: path.clone(),
event: match state {
winit::event::ElementState::Pressed => events::InnerEvent::MouseDown(mevent),
winit::event::ElementState::Released => events::InnerEvent::MouseUp(mevent)
}
};
for node in path.iter().rev() {
node.write().unwrap().on_event(&event);
}
},
None => {}
}
},
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(size) => {

View file

@ -38,4 +38,6 @@ impl Node for Layout {
self.style.layout.size.width = Dimension::Points(width);
self.style.layout.size.height = Dimension::Points(height);
}
fn on_event(&mut self, event: &crate::events::NodeEvent) {}
}

View file

@ -64,19 +64,21 @@ pub trait Node: Debug {
/// Render the node, called after rendering it's children
/// Canvas considers 0, 0 to be top left corner (for location after layouting happens)
fn render_post_children(&self, _context: &mut RenderContext, _layout: Layout) {}
/// Called when an event happens on the node. This is called after the children have been called.
/// Beware! Events include a path and target with [Arc<RwLock<Node>>]s, but you already have a write lock for this node!
/// Remember to check if the node is the same as self, and if it is, use self instead of the node in the path to prevent deadlocks!
fn on_event(&mut self, _event: &crate::events::NodeEvent) {}
/// Called when the size of window changes on the root node. Layouts do implement this.
/// Is an optional function instead of another trait because of missing support for trait upcasting
// TODO: When rust supports trait upcasting, make this a trait
fn resize(&mut self, _width: f32, _height: f32) {}
/// Called when an event happens on the node. This is called after the children have been called.
/// Beware! Events include a path and target with [Arc<RwLock<Node>>]s, but you already have a write lock for this node!
/// Remember to check if the node is the same as self, and if it is, use self instead of the node in the path to prevent deadlocks!
fn on_event(&mut self, _event: &crate::events::InnerEvent) {}
}
pub fn get_element_at(node: &SharedTNode, context: &RenderContext, location: Location) -> Option<Vec<SharedTNode>> {
let children = node.read().unwrap().children();
let node_borrowed = node.read().unwrap();
let children = node_borrowed.children();
let taffy_node = context.node_layout.get(node);
let taffy_node = match taffy_node {
Some(taffy_node) => taffy_node,

View file

@ -40,4 +40,6 @@ impl Node for Rectangle {
&self.fill
);
}
fn on_event(&mut self, event: &crate::events::NodeEvent) {}
}