Skip to content
Snippets Groups Projects
Commit cbabafc3 authored by MrGVSV's avatar MrGVSV
Browse files

Started integrating focus management

parent ad3f0112
No related branches found
No related tags found
No related merge requests found
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::{Event, EventType, Index, InputEvent, InputEventCategory, KayakContext, PointerEvents}; use crate::{Event, EventType, Index, InputEvent, InputEventCategory, KayakContext, KeyCode, PointerEvents};
use crate::layout_cache::Rect; use crate::layout_cache::Rect;
use crate::widget_manager::WidgetManager; use crate::widget_manager::WidgetManager;
...@@ -59,13 +59,13 @@ impl EventDispatcher { ...@@ -59,13 +59,13 @@ impl EventDispatcher {
/// Process and dispatch an [InputEvent](crate::InputEvent) /// Process and dispatch an [InputEvent](crate::InputEvent)
#[allow(dead_code)] #[allow(dead_code)]
pub fn process_event(&mut self, input_event: InputEvent, context: &mut KayakContext) { pub fn process_event(&mut self, input_event: InputEvent, context: &mut KayakContext) {
let events = self.build_event_stream(&[input_event], &context.widget_manager); let events = self.build_event_stream(&[input_event], &mut context.widget_manager);
self.dispatch_events(events, context); self.dispatch_events(events, context);
} }
/// Process and dispatch a set of [InputEvents](crate::InputEvent) /// Process and dispatch a set of [InputEvents](crate::InputEvent)
pub fn process_events(&mut self, input_events: Vec<InputEvent>, context: &mut KayakContext) { pub fn process_events(&mut self, input_events: Vec<InputEvent>, context: &mut KayakContext) {
let events = self.build_event_stream(&input_events, &context.widget_manager); let events = self.build_event_stream(&input_events, &mut context.widget_manager);
self.dispatch_events(events, context); self.dispatch_events(events, context);
} }
...@@ -79,7 +79,7 @@ impl EventDispatcher { ...@@ -79,7 +79,7 @@ impl EventDispatcher {
pub fn dispatch_events(&mut self, events: Vec<Event>, context: &mut KayakContext) { pub fn dispatch_events(&mut self, events: Vec<Event>, context: &mut KayakContext) {
// === Dispatch Events === // // === Dispatch Events === //
let mut next_events = HashMap::default(); let mut next_events = HashMap::default();
for event in events { for mut event in events {
let mut current_target: Option<Index> = Some(event.target); let mut current_target: Option<Index> = Some(event.target);
while let Some(index) = current_target { while let Some(index) = current_target {
// Create a copy of the event, specific for this node // Create a copy of the event, specific for this node
...@@ -102,6 +102,8 @@ impl EventDispatcher { ...@@ -102,6 +102,8 @@ impl EventDispatcher {
target_widget.on_event(context, &mut node_event); target_widget.on_event(context, &mut node_event);
context.widget_manager.repossess(target_widget); context.widget_manager.repossess(target_widget);
event.default_prevented |= node_event.default_prevented;
// --- Propagate Event --- // // --- Propagate Event --- //
if node_event.should_propagate { if node_event.should_propagate {
current_target = context.widget_manager.node_tree.get_parent(index); current_target = context.widget_manager.node_tree.get_parent(index);
...@@ -109,6 +111,10 @@ impl EventDispatcher { ...@@ -109,6 +111,10 @@ impl EventDispatcher {
current_target = None; current_target = None;
} }
} }
if !event.default_prevented {
self.execute_default(event, context);
}
} }
// === Maintain Events === // // === Maintain Events === //
...@@ -133,7 +139,7 @@ impl EventDispatcher { ...@@ -133,7 +139,7 @@ impl EventDispatcher {
} }
/// Generates a stream of [Events](crate::Event) from a set of [InputEvents](crate::InputEvent) /// Generates a stream of [Events](crate::Event) from a set of [InputEvents](crate::InputEvent)
fn build_event_stream(&mut self, input_events: &[InputEvent], widget_manager: &WidgetManager) -> Vec<Event> { fn build_event_stream(&mut self, input_events: &[InputEvent], widget_manager: &mut WidgetManager) -> Vec<Event> {
let mut event_stream = Vec::<Event>::new(); let mut event_stream = Vec::<Event>::new();
let mut states: HashMap<EventType, EventState> = HashMap::new(); let mut states: HashMap<EventType, EventState> = HashMap::new();
...@@ -208,6 +214,7 @@ impl EventDispatcher { ...@@ -208,6 +214,7 @@ impl EventDispatcher {
event_stream.push(Event::new(current_focus, EventType::Blur)); event_stream.push(Event::new(current_focus, EventType::Blur));
} }
} }
widget_manager.focus_tree.focus(node);
self.current_focus = Some(node); self.current_focus = Some(node);
} }
_ => {} _ => {}
...@@ -220,6 +227,7 @@ impl EventDispatcher { ...@@ -220,6 +227,7 @@ impl EventDispatcher {
// A mouse press didn't contain a focus event -> blur // A mouse press didn't contain a focus event -> blur
if let Some(current_focus) = self.current_focus { if let Some(current_focus) = self.current_focus {
event_stream.push(Event::new(current_focus, EventType::Blur)); event_stream.push(Event::new(current_focus, EventType::Blur));
widget_manager.focus_tree.blur();
self.current_focus = None; self.current_focus = None;
} }
} }
...@@ -344,4 +352,25 @@ impl EventDispatcher { ...@@ -344,4 +352,25 @@ impl EventDispatcher {
let entry = events.entry(*widget_id).or_insert(HashSet::default()); let entry = events.entry(*widget_id).or_insert(HashSet::default());
entry.insert(event_type) entry.insert(event_type)
} }
/// Executes default actions for events
fn execute_default(&mut self, event: Event, context: &mut KayakContext) {
match event.event_type {
EventType::KeyboardInput { key } => {
match key {
KeyCode::Tab => {
if let Some(index) = context.widget_manager.focus_tree.next() {
let mut events = vec![Event::new(index, EventType::Focus)];
if let Some(current_focus) = self.current_focus {
events.push(Event::new(current_focus, EventType::Blur));
}
self.dispatch_events(events, context);
}
}
_ => {}
}
}
_ => {}
}
}
} }
...@@ -10,6 +10,7 @@ use crate::{ ...@@ -10,6 +10,7 @@ use crate::{
render_primitive::RenderPrimitive, render_primitive::RenderPrimitive,
styles::Style, styles::Style,
tree::Tree, tree::Tree,
focus_tree::FocusTree,
Arena, Index, Widget, Arena, Index, Widget,
}; };
use crate::layout_cache::Rect; use crate::layout_cache::Rect;
...@@ -24,6 +25,7 @@ pub struct WidgetManager { ...@@ -24,6 +25,7 @@ pub struct WidgetManager {
pub tree: Tree, pub tree: Tree,
pub node_tree: Tree, pub node_tree: Tree,
pub layout_cache: LayoutCache, pub layout_cache: LayoutCache,
pub focus_tree: FocusTree,
current_z: f32, current_z: f32,
} }
...@@ -37,6 +39,7 @@ impl WidgetManager { ...@@ -37,6 +39,7 @@ impl WidgetManager {
tree: Tree::default(), tree: Tree::default(),
node_tree: Tree::default(), node_tree: Tree::default(),
layout_cache: LayoutCache::default(), layout_cache: LayoutCache::default(),
focus_tree: FocusTree::default(),
current_z: 0.0, current_z: 0.0,
} }
} }
...@@ -74,6 +77,10 @@ impl WidgetManager { ...@@ -74,6 +77,10 @@ impl WidgetManager {
// self.dirty_nodes.remove(index); // self.dirty_nodes.remove(index);
// } // }
if widget.focusable() {
self.focus_tree.add(*widget_id, Some(parent));
}
// TODO: Figure a good way of diffing props passed to children of a widget // TODO: Figure a good way of diffing props passed to children of a widget
// that wont naturally-rerender it's children because of a lack of changes // that wont naturally-rerender it's children because of a lack of changes
// to it's own props. // to it's own props.
...@@ -117,6 +124,8 @@ impl WidgetManager { ...@@ -117,6 +124,8 @@ impl WidgetManager {
self.tree.add(widget_id, parent); self.tree.add(widget_id, parent);
self.layout_cache.add(widget_id); self.layout_cache.add(widget_id);
self.focus_tree.add(widget_id, None);
(true, widget_id) (true, widget_id)
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment