diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ce98dbd7795cb189b757d4db8ceb5c7e096682ed..7cc7c32af2e2da232b02b1444bceab1f636b662b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -39,4 +39,4 @@ jobs: - name: Run fmt check run: cargo fmt --all -- --check - name: Run clippy - run: cargo clippy --workspace --all-targets --all-features --features "bevy/x11" + run: cargo clippy --workspace --all-targets --all-features --features "bevy/x11" -- --deny warnings diff --git a/examples/svg.rs b/examples/svg.rs index 480c558b8dd5d90557b21896cd8aa5c8695e670c..e00666f8a39b4411f1efe0240d81600e8730151a 100644 --- a/examples/svg.rs +++ b/examples/svg.rs @@ -23,8 +23,8 @@ fn startup( <ElementBundle styles={KStyle { position_type: StyleProp::Value(KPositionType::SelfDirected), - left: StyleProp::Value(Units::Pixels(-34.545261 * 7.6)), - top: StyleProp::Value(Units::Pixels(10.0 - 95.557219 * 7.6)), + left: StyleProp::Value(Units::Pixels(-34.545 * 7.6)), + top: StyleProp::Value(Units::Pixels(10.0 - 95.557 * 7.6)), ..Default::default() }} > diff --git a/src/context.rs b/src/context.rs index edc6b01317d22052d5a6f23b75bc1b5b6a06e8ae..3baca230b4d1f0ca32885fd94ce74e6933fafed8 100644 --- a/src/context.rs +++ b/src/context.rs @@ -86,7 +86,7 @@ type WidgetSystems = HashMap< pub struct KayakRootContext { pub tree: Arc<RwLock<Tree>>, pub(crate) layout_cache: Arc<RwLock<LayoutCache>>, - pub(crate) focus_tree: Arc<RwLock<FocusTree>>, + pub(crate) focus_tree: FocusTree, systems: WidgetSystems, pub(crate) current_z: f32, pub(crate) context_entities: ContextEntities, @@ -140,14 +140,6 @@ impl KayakRootContext { plugin.build(self) } - /// Retreives the current entity that has focus or None if nothing is focused. - pub fn get_current_focus(&self) -> Option<Entity> { - if let Ok(tree) = self.focus_tree.try_read() { - return tree.current().map(|a| a.0); - } - None - } - /// Get's the layout for th given widget index. pub(crate) fn get_layout(&self, id: &WrappedIndex) -> Option<Rect> { if let Ok(cache) = self.layout_cache.try_read() { @@ -245,10 +237,10 @@ impl KayakRootContext { /// widget_context.add_widget(None, root_entity); /// } ///``` - pub fn spawn_widget<'a>( + pub fn spawn_widget( &self, commands: &mut Commands, - key: Option<&'a str>, + key: Option<&str>, parent_id: Option<Entity>, ) -> Entity { let mut entity = None; @@ -647,18 +639,16 @@ pub fn update_widgets_sys(world: &mut World) { // let change_tick = world.increment_change_tick(); - let old_focus = if let Ok(mut focus_tree) = context.focus_tree.try_write() { - let current = focus_tree.current(); - focus_tree.clear(); - if let Ok(tree) = context.tree.read() { - if let Some(root_node) = tree.root_node { - focus_tree.add(root_node, &tree); - } - } - current - } else { - None - }; + // let old_focus = { + // let current = context.focus_tree.current(); + // context.focus_tree.clear(); + // if let Ok(tree) = context.tree.read() { + // if let Some(root_node) = tree.root_node { + // context.focus_tree.add(root_node, &tree); + // } + // } + // current + // }; let mut new_ticks = HashMap::new(); @@ -681,13 +671,11 @@ pub fn update_widgets_sys(world: &mut World) { &context.unique_ids_parents, ); - if let Some(old_focus) = old_focus { - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - if focus_tree.contains(old_focus) { - focus_tree.focus(old_focus); - } - } - } + // if let Some(old_focus) = old_focus { + // if context.focus_tree.contains(old_focus) { + // context.focus_tree.focus(old_focus); + // } + // } let tick = world.read_change_tick(); @@ -718,7 +706,7 @@ fn update_widgets( systems: &mut WidgetSystems, widgets: Vec<WrappedIndex>, context_entities: &ContextEntities, - focus_tree: &Arc<RwLock<FocusTree>>, + focus_tree: &FocusTree, clone_systems: &Arc<RwLock<EntityCloneSystems>>, cloned_widget_entities: &Arc<RwLock<HashMap<Entity, Entity>>>, widget_state: &WidgetState, @@ -754,6 +742,7 @@ fn update_widgets( let (widget_context, should_update_children) = update_widget( systems, tree, + focus_tree, world, *entity, widget_type.0.clone(), @@ -1145,9 +1134,7 @@ fn update_widgets( if let Some(entity_ref) = world.get_entity(entity.0) { if entity_ref.contains::<Focusable>() { if let Ok(tree) = tree.try_read() { - if let Ok(mut focus_tree) = focus_tree.try_write() { - focus_tree.add(*entity, &tree); - } + focus_tree.add(*entity, &tree); } } } @@ -1157,6 +1144,7 @@ fn update_widgets( fn update_widget( systems: &mut WidgetSystems, tree: &Arc<RwLock<Tree>>, + focus_tree: &FocusTree, world: &mut World, entity: WrappedIndex, widget_type: String, @@ -1311,12 +1299,14 @@ fn update_widget( let widget_render_system = &mut systems.get_mut(&widget_type).unwrap().1; let old_tick = widget_render_system.get_last_change_tick(); world.insert_resource(widget_context.clone()); + world.insert_resource(focus_tree.clone()); should_update_children = widget_render_system.run(entity.0, world); let new_tick = widget_render_system.get_last_change_tick(); new_ticks.insert(widget_type.clone(), new_tick); widget_render_system.set_last_change_tick(old_tick); widget_render_system.apply_buffers(world); world.remove_resource::<KayakWidgetContext>(); + world.remove_resource::<FocusTree>(); if let Ok(mut indices) = widget_context.index.try_write() { indices.insert(entity.0, 0); diff --git a/src/event_dispatcher.rs b/src/event_dispatcher.rs index f08bbf4b5cd0f78b278d018f5408bbda3309c836..4c9f4bb93e1759be710b8a0ba8666894c86bbac8 100644 --- a/src/event_dispatcher.rs +++ b/src/event_dispatcher.rs @@ -229,6 +229,7 @@ impl EventDispatcher { (event_dispatcher_context, node_event) = on_event.try_call( event_dispatcher_context, context.widget_state.clone(), + context.focus_tree.clone(), index.0, node_event, world, @@ -437,67 +438,67 @@ impl EventDispatcher { } } - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - // === Keyboard Events === // - for input_event in input_events { - // Keyboard events only care about the currently focused widget so we don't need to run this over every node in the tree - let events = - self.process_keyboard_events(input_event, &mut states, &focus_tree); - event_stream.extend(events); - } + // === Keyboard Events === // + for input_event in input_events { + // Keyboard events only care about the currently focused widget so we don't need to run this over every node in the tree + let events = + self.process_keyboard_events(input_event, &mut states, &context.focus_tree); + event_stream.extend(events); + } - // === Additional Events === // - let mut had_focus_event = false; - - // These events are ones that require a specific target and need the tree to be evaluated before selecting the best match - for (event_type, state) in states { - if let Some(node) = state.best_match { - event_stream.push(KEvent::new(node.0, event_type)); - - match event_type { - EventType::Focus => { - had_focus_event = true; - if let Some(current_focus) = focus_tree.current() { - if current_focus != node { - event_stream - .push(KEvent::new(current_focus.0, EventType::Blur)); - } + // === Additional Events === // + let mut had_focus_event = false; + + // These events are ones that require a specific target and need the tree to be evaluated before selecting the best match + for (event_type, state) in states { + if let Some(node) = state.best_match { + event_stream.push(KEvent::new(node.0, event_type)); + + match event_type { + EventType::Focus => { + had_focus_event = true; + if let Some(current_focus) = + context.focus_tree.current().map(WrappedIndex) + { + if current_focus != node { + event_stream + .push(KEvent::new(current_focus.0, EventType::Blur)); } - focus_tree.focus(node); - } - EventType::Hover(..) => { - self.hovered = Some(node); } - _ => {} + context.focus_tree.focus(node.0); + } + EventType::Hover(..) => { + self.hovered = Some(node); } + _ => {} } } + } - // --- Blur Event --- // - if !had_focus_event && input_events.contains(&InputEvent::MouseLeftPress) { - // A mouse press didn't contain a focus event -> blur - if let Some(current_focus) = focus_tree.current() { - event_stream.push(KEvent::new(current_focus.0, EventType::Blur)); - focus_tree.blur(); - } + // --- Blur Event --- // + if !had_focus_event && input_events.contains(&InputEvent::MouseLeftPress) { + // A mouse press didn't contain a focus event -> blur + if let Some(current_focus) = context.focus_tree.current() { + event_stream.push(KEvent::new(current_focus, EventType::Blur)); + context.focus_tree.blur(); } + } - // === Process Cursor States === // - self.current_mouse_position = self.next_mouse_position; - self.is_mouse_pressed = self.next_mouse_pressed; + // === Process Cursor States === // + self.current_mouse_position = self.next_mouse_position; + self.is_mouse_pressed = self.next_mouse_pressed; - if self.hovered.is_none() { - // No change -> revert - self.hovered = old_hovered; - } - if self.contains_cursor.is_none() { - // No change -> revert - self.contains_cursor = old_contains_cursor; - } - if self.wants_cursor.is_none() { - // No change -> revert - self.wants_cursor = old_wants_cursor; - } + if self.hovered.is_none() { + // No change -> revert + self.hovered = old_hovered; + } + if self.contains_cursor.is_none() { + // No change -> revert + self.contains_cursor = old_contains_cursor; + } + if self.wants_cursor.is_none() { + // No change -> revert + self.wants_cursor = old_wants_cursor; } } @@ -694,7 +695,7 @@ impl EventDispatcher { if let Some(current_focus) = focus_tree.current() { match input_event { InputEvent::CharEvent { c } => { - event_stream.push(KEvent::new(current_focus.0, EventType::CharInput { c: *c })) + event_stream.push(KEvent::new(current_focus, EventType::CharInput { c: *c })) } InputEvent::Keyboard { key, is_pressed } => { // === Modifers === // @@ -717,12 +718,12 @@ impl EventDispatcher { // === Event === // if *is_pressed { event_stream.push(KEvent::new( - current_focus.0, + current_focus, EventType::KeyDown(KeyboardEvent::new(*key, self.keyboard_modifiers)), )) } else { event_stream.push(KEvent::new( - current_focus.0, + current_focus, EventType::KeyUp(KeyboardEvent::new(*key, self.keyboard_modifiers)), )) } @@ -798,30 +799,25 @@ impl EventDispatcher { ) { if let EventType::KeyDown(evt) = event.event_type { if let KeyCode::Tab = evt.key() { - let (index, current_focus) = - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - let current_focus = focus_tree.current(); + let (index, current_focus) = { + let current_focus = context.focus_tree.current(); - let index = if evt.is_shift_pressed() { - focus_tree.prev() - } else { - focus_tree.next() - }; - (index, current_focus) + let index = if evt.is_shift_pressed() { + context.focus_tree.prev() } else { - (None, None) + context.focus_tree.next() }; + (index, current_focus) + }; if let Some(index) = index { - let mut events = vec![KEvent::new(index.0, EventType::Focus)]; + let mut events = vec![KEvent::new(index, EventType::Focus)]; if let Some(current_focus) = current_focus { if current_focus != index { - events.push(KEvent::new(current_focus.0, EventType::Blur)); + events.push(KEvent::new(current_focus, EventType::Blur)); } } - if let Ok(mut focus_tree) = context.focus_tree.try_write() { - focus_tree.focus(index); - } + context.focus_tree.focus(index); self.dispatch_events(events, context, world); } } diff --git a/src/focus_tree.rs b/src/focus_tree.rs index b3dfbc066679cd5026d51183506b7e6cfc25dfc1..826beeb5e79569cb4a3f1a1620f42823b7f73037 100644 --- a/src/focus_tree.rs +++ b/src/focus_tree.rs @@ -1,5 +1,7 @@ +use std::sync::{Arc, RwLock}; + use bevy::{ - prelude::{Component, Reflect, ReflectComponent}, + prelude::{Component, Entity, Reflect, ReflectComponent, Resource}, utils::HashMap, }; @@ -9,10 +11,10 @@ use crate::{node::WrappedIndex, prelude::Tree}; #[reflect(Component)] pub struct Focusable; -#[derive(Debug, Default, PartialEq, Eq)] +#[derive(Resource, Debug, Clone, Default)] pub struct FocusTree { - tree: Tree, - current_focus: Option<WrappedIndex>, + tree: Arc<RwLock<Tree>>, + current_focus: Arc<RwLock<Option<WrappedIndex>>>, } /// A struct used to track and calculate widget focusability, based on the following rule: @@ -28,140 +30,174 @@ pub(crate) struct FocusTracker { impl FocusTree { /// Add the given focusable index to the tree - pub fn add(&mut self, index: WrappedIndex, widget_context: &Tree) { + pub(crate) fn add(&self, index: WrappedIndex, widget_context: &Tree) { // Cases to handle: // 1. Tree empty -> insert root node // 2. Tree not empty // a. Contains parent -> insert child node // b. Not contains parent -> demote and replace root node - - let mut current_index = index; - while let Some(parent) = widget_context.get_parent(current_index) { - current_index = parent; - if self.contains(parent) { - self.tree.add(index, Some(parent)); - return; + if let Ok(mut tree) = self.tree.try_write() { + let mut current_index = index; + while let Some(parent) = widget_context.get_parent(current_index) { + current_index = parent; + if tree.contains(parent) { + tree.add(index, Some(parent)); + return; + } } - } - if self.tree.root_node.is_none() { - // Set root node - self.tree.add(index, None); - self.focus(index); + if tree.root_node.is_none() { + // Set root node + tree.add(index, None); + self.focus(index.0); + } } } /// Remove the given focusable index from the tree - pub fn remove(&mut self, index: WrappedIndex) { - if self.current_focus == Some(index) { - self.blur(); - } + pub(crate) fn remove(&self, index: WrappedIndex) { + if let (Ok(mut tree), Ok(mut current_focus)) = + (self.tree.try_write(), self.current_focus.try_write()) + { + if *current_focus == Some(index) { + // Blur + *current_focus = tree.root_node; + } - if self.tree.root_node == Some(index) { - self.tree.remove(index); - } else { - self.tree.remove_and_reparent(index); + if tree.root_node == Some(index) { + tree.remove(index); + } else { + tree.remove_and_reparent(index); + } } } /// Checks if the given index is present in the tree - pub fn contains(&self, index: WrappedIndex) -> bool { - self.tree.contains(index) + pub fn contains(&self, index: Entity) -> bool { + if let Ok(tree) = self.tree.try_read() { + tree.contains(WrappedIndex(index)) + } else { + false + } } /// Clear the tree and remove the current focus - pub fn clear(&mut self) { - self.tree = Tree::default(); - self.blur(); + pub(crate) fn clear(&mut self) { + if let Ok(mut tree) = self.tree.try_write() { + *tree = Tree::default(); + self.blur(); + } } /// Set the current focus - pub fn focus(&mut self, index: WrappedIndex) { - self.current_focus = Some(index); + pub fn focus(&self, index: Entity) { + if let Ok(mut current_focus) = self.current_focus.try_write() { + *current_focus = Some(WrappedIndex(index)); + } } /// Remove the current focus /// /// This returns focus to the root node - pub fn blur(&mut self) { - self.current_focus = self.tree.root_node; + pub fn blur(&self) { + if let (Ok(tree), Ok(mut current_focus)) = + (self.tree.try_read(), self.current_focus.try_write()) + { + *current_focus = tree.root_node; + } } /// Get the currently focused index - pub fn current(&self) -> Option<WrappedIndex> { - self.current_focus + pub fn current(&self) -> Option<Entity> { + if let Ok(current_focus) = self.current_focus.try_read() { + current_focus.map(|i| i.0) + } else { + None + } } /// Change focus to the next focusable index - pub fn next(&mut self) -> Option<WrappedIndex> { - self.current_focus = self.peek_next(); - self.current_focus + pub fn next(&self) -> Option<Entity> { + if let Ok(mut current_focus) = self.current_focus.try_write() { + *current_focus = self.peek_next(*current_focus); + current_focus.map(|i| i.0) + } else { + None + } } /// Change focus to the previous focusable index - pub fn prev(&mut self) -> Option<WrappedIndex> { - self.current_focus = self.peek_prev(); - self.current_focus + pub fn prev(&self) -> Option<Entity> { + if let Ok(mut current_focus) = self.current_focus.try_write() { + *current_focus = self.peek_prev(*current_focus); + current_focus.map(|i| i.0) + } else { + None + } } /// Peek the next focusable index without actually changing focus - pub fn peek_next(&self) -> Option<WrappedIndex> { - if let Some(index) = self.current_focus { - // === Enter Children === // - if let Some(child) = self.tree.get_first_child(index) { - return Some(child); - } + pub fn peek_next(&self, current_focus: Option<WrappedIndex>) -> Option<WrappedIndex> { + if let Ok(tree) = self.tree.try_read() { + if let Some(index) = current_focus { + // === Enter Children === // + if let Some(child) = tree.get_first_child(index) { + return Some(child); + } - // === Enter Siblings === // - if let Some(sibling) = self.tree.get_next_sibling(index) { - return Some(sibling); - } + // === Enter Siblings === // + if let Some(sibling) = tree.get_next_sibling(index) { + return Some(sibling); + } - // === Go Back Up === // - let mut next = index; - while let Some(parent) = self.tree.get_parent(next) { - if let Some(uncle) = self.tree.get_next_sibling(parent) { - return Some(uncle); + // === Go Back Up === // + let mut next = index; + while let Some(parent) = tree.get_parent(next) { + if let Some(uncle) = tree.get_next_sibling(parent) { + return Some(uncle); + } + next = parent; } - next = parent; } - } - // Default to root node to begin the cycle again - self.tree.root_node + // Default to root node to begin the cycle again + tree.root_node + } else { + None + } } /// Peek the previous focusable index without actually changing focus - pub fn peek_prev(&self) -> Option<WrappedIndex> { - if let Some(index) = self.current_focus { - // === Enter Siblings === // - if let Some(sibling) = self.tree.get_prev_sibling(index) { - let mut next = sibling; - while let Some(child) = self.tree.get_last_child(next) { - next = child; + pub fn peek_prev(&self, current_focus: Option<WrappedIndex>) -> Option<WrappedIndex> { + if let Ok(tree) = self.tree.try_read() { + if let Some(index) = current_focus { + // === Enter Siblings === // + if let Some(sibling) = tree.get_prev_sibling(index) { + let mut next = sibling; + while let Some(child) = tree.get_last_child(next) { + next = child; + } + return Some(next); } - return Some(next); - } - // === Enter Parent === // - if let Some(parent) = self.tree.get_parent(index) { - return Some(parent); - } + // === Enter Parent === // + if let Some(parent) = tree.get_parent(index) { + return Some(parent); + } - // === Go Back Down === // - let mut next = index; - while let Some(child) = self.tree.get_last_child(next) { - next = child; + // === Go Back Down === // + let mut next = index; + while let Some(child) = tree.get_last_child(next) { + next = child; + } + + return Some(next); } - return Some(next); + tree.root_node + } else { + None } - - self.tree.root_node - } - - pub fn tree(&self) -> &Tree { - &self.tree } } @@ -227,7 +263,7 @@ mod tests { #[test] fn next_should_cycle() { - let mut focus_tree = FocusTree::default(); + let focus_tree = FocusTree::default(); let mut tree = Tree::default(); let a = WrappedIndex(Entity::from_raw(0)); @@ -253,23 +289,25 @@ mod tests { focus_tree.add(a_a_a_b, &tree); focus_tree.add(a_b_a, &tree); - assert_eq!(Some(a), focus_tree.current_focus); - assert_eq!(Some(a_a), focus_tree.next()); - assert_eq!(Some(a_a_a), focus_tree.next()); - assert_eq!(Some(a_a_a_a), focus_tree.next()); - assert_eq!(Some(a_a_a_b), focus_tree.next()); - assert_eq!(Some(a_b), focus_tree.next()); - assert_eq!(Some(a_b_a), focus_tree.next()); + dbg!(&focus_tree); + + assert_eq!(Some(a.0), focus_tree.current()); + assert_eq!(Some(a_a.0), focus_tree.next()); + assert_eq!(Some(a_a_a.0), focus_tree.next()); + assert_eq!(Some(a_a_a_a.0), focus_tree.next()); + assert_eq!(Some(a_a_a_b.0), focus_tree.next()); + assert_eq!(Some(a_b.0), focus_tree.next()); + assert_eq!(Some(a_b_a.0), focus_tree.next()); - assert_eq!(Some(a), focus_tree.next()); - assert_eq!(Some(a_a), focus_tree.next()); + assert_eq!(Some(a.0), focus_tree.next()); + assert_eq!(Some(a_a.0), focus_tree.next()); // etc. } #[test] fn prev_should_cycle() { - let mut focus_tree = FocusTree::default(); + let focus_tree = FocusTree::default(); let mut tree = Tree::default(); let a = WrappedIndex(Entity::from_raw(0)); @@ -295,16 +333,16 @@ mod tests { focus_tree.add(a_a_a_b, &tree); focus_tree.add(a_b_a, &tree); - assert_eq!(Some(a), focus_tree.current_focus); - assert_eq!(Some(a_b_a), focus_tree.prev()); - assert_eq!(Some(a_b), focus_tree.prev()); - assert_eq!(Some(a_a_a_b), focus_tree.prev()); - assert_eq!(Some(a_a_a_a), focus_tree.prev()); - assert_eq!(Some(a_a_a), focus_tree.prev()); - assert_eq!(Some(a_a), focus_tree.prev()); + assert_eq!(Some(a.0), focus_tree.current()); + assert_eq!(Some(a_b_a.0), focus_tree.prev()); + assert_eq!(Some(a_b.0), focus_tree.prev()); + assert_eq!(Some(a_a_a_b.0), focus_tree.prev()); + assert_eq!(Some(a_a_a_a.0), focus_tree.prev()); + assert_eq!(Some(a_a_a.0), focus_tree.prev()); + assert_eq!(Some(a_a.0), focus_tree.prev()); - assert_eq!(Some(a), focus_tree.prev()); - assert_eq!(Some(a_b_a), focus_tree.prev()); + assert_eq!(Some(a.0), focus_tree.prev()); + assert_eq!(Some(a_b_a.0), focus_tree.prev()); // etc. } diff --git a/src/lib.rs b/src/lib.rs index c9f81aa22a9cf3d8e8d210c2712f216039546342..f2895fa73d020fef5340682c26c9cd10d9569c22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,7 @@ pub mod prelude { pub use crate::cursor::*; pub use crate::event::*; pub use crate::event_dispatcher::{EventDispatcher, EventDispatcherContext}; - pub use crate::focus_tree::Focusable; + pub use crate::focus_tree::{FocusTree, Focusable}; pub use crate::input_event::*; pub use crate::keyboard_event::*; pub use crate::layout::*; diff --git a/src/on_event.rs b/src/on_event.rs index 4b8014c7388041085d16a97cdebd8f98e7a5ce40..6fd441a92c5c3a611317db72e627b5f38f95266f 100644 --- a/src/on_event.rs +++ b/src/on_event.rs @@ -4,6 +4,7 @@ use std::sync::{Arc, RwLock}; use crate::event::KEvent; use crate::event_dispatcher::EventDispatcherContext; +use crate::focus_tree::FocusTree; use crate::widget_state::WidgetState; /// A container for a function that handles events @@ -42,6 +43,7 @@ impl OnEvent { &mut self, mut event_dispatcher_context: EventDispatcherContext, widget_state: WidgetState, + focus_tree: FocusTree, entity: Entity, mut event: KEvent, world: &mut World, @@ -57,6 +59,7 @@ impl OnEvent { world.insert_resource(event_dispatcher_context); world.insert_resource(widget_state); world.insert_resource(event); + world.insert_resource(focus_tree); system.run(entity, world); system.apply_buffers(world); @@ -64,6 +67,7 @@ impl OnEvent { event_dispatcher_context = world.remove_resource::<EventDispatcherContext>().unwrap(); event = world.remove_resource::<KEvent>().unwrap(); world.remove_resource::<WidgetState>().unwrap(); + world.remove_resource::<FocusTree>().unwrap(); } (event_dispatcher_context, event) } diff --git a/src/styles/units.rs b/src/styles/units.rs index eab69b5c06676b93eaf48c4db45d1a4c75b06da1..439ab70acb6e1202cf4c5b9d3622e9ef8dba4037 100644 --- a/src/styles/units.rs +++ b/src/styles/units.rs @@ -1,22 +1,17 @@ use bevy::reflect::{FromReflect, Reflect}; /// The layout type determines how nodes will be positioned when directed by the parent -#[derive(Debug, FromReflect, Reflect, Clone, Copy, PartialEq)] +#[derive(Default, Debug, FromReflect, Reflect, Clone, Copy, PartialEq)] pub enum LayoutType { /// Stack child elements horizontally Row, + #[default] /// Stack child elements vertically Column, /// Position child elements into specified rows and columns Grid, } -impl Default for LayoutType { - fn default() -> Self { - LayoutType::Column - } -} - impl From<LayoutType> for morphorm::LayoutType { fn from(val: LayoutType) -> Self { match val { @@ -28,20 +23,15 @@ impl From<LayoutType> for morphorm::LayoutType { } /// The position type determines whether a node will be positioned in-line with its siblings or seperate -#[derive(Debug, Reflect, FromReflect, Clone, Copy, PartialEq)] +#[derive(Default, Debug, Reflect, FromReflect, Clone, Copy, PartialEq)] pub enum KPositionType { /// Node is positioned relative to parent but ignores its siblings SelfDirected, + #[default] /// Node is positioned relative to parent and in-line with siblings ParentDirected, } -impl Default for KPositionType { - fn default() -> Self { - KPositionType::ParentDirected - } -} - impl From<KPositionType> for morphorm::PositionType { fn from(val: KPositionType) -> Self { match val { @@ -52,7 +42,7 @@ impl From<KPositionType> for morphorm::PositionType { } /// Units which describe spacing and size -#[derive(Debug, FromReflect, Reflect, Clone, Copy, PartialEq)] +#[derive(Default, Debug, FromReflect, Reflect, Clone, Copy, PartialEq)] pub enum Units { /// A number of pixels Pixels(f32), @@ -60,16 +50,11 @@ pub enum Units { Percentage(f32), /// A factor of the remaining free space Stretch(f32), + #[default] /// Automatically determine the value Auto, } -impl Default for Units { - fn default() -> Self { - Units::Auto - } -} - impl From<Units> for morphorm::Units { fn from(val: Units) -> Self { match val { diff --git a/src/widgets/scroll/scroll_context.rs b/src/widgets/scroll/scroll_context.rs index 71bbd6071c06e20e08ec9f708d3b927318884853..3e8b645ed5dd55e817de03c1a500383fc67d6852 100644 --- a/src/widgets/scroll/scroll_context.rs +++ b/src/widgets/scroll/scroll_context.rs @@ -26,20 +26,15 @@ pub struct ScrollContext { } #[non_exhaustive] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum ScrollMode { /// Clamps the scroll offset to stay within the scroll range + #[default] Clamped, /// Allows infinite scrolling Infinite, } -impl Default for ScrollMode { - fn default() -> Self { - ScrollMode::Clamped - } -} - impl ScrollContext { /// Get the current x-axis scroll offset pub fn scroll_x(&self) -> f32 {