diff --git a/examples/tabs/tab.rs b/examples/tabs/tab.rs index 5af1081fc44bf5eb7fc63c285064321c036f15db..dbf598e17bc8f8fa706161f750edf7743fb9cba1 100644 --- a/examples/tabs/tab.rs +++ b/examples/tabs/tab.rs @@ -1,8 +1,9 @@ use kayak_ui::{ core::{ render_command::RenderCommand, + rsx, styles::{LayoutType, Style, StyleProp, Units}, - Bound, EventType, OnEvent, rsx, use_state, widget, + use_state, widget, Bound, EventType, OnEvent, }, widgets::{Background, Text}, }; @@ -28,26 +29,24 @@ pub fn Tab(context: &mut KayakContext, content: String, selected: bool) { _ => {} }; - let event_handler = OnEvent::new(move |_, event| { - match event.event_type { - EventType::Hover => { - if selected { - set_hover_state(TabHoverState::Active); - } else { - set_hover_state(TabHoverState::Inactive); - } + let event_handler = OnEvent::new(move |_, event| match event.event_type { + EventType::Hover => { + if selected { + set_hover_state(TabHoverState::Active); + } else { + set_hover_state(TabHoverState::Inactive); } - EventType::MouseOut => { - set_hover_state(TabHoverState::None); - } - EventType::Focus => { - set_focus_state(true); - } - EventType::Blur => { - set_focus_state(false); - } - _ => {} } + EventType::MouseOut => { + set_hover_state(TabHoverState::None); + } + EventType::Focus => { + set_focus_state(true); + } + EventType::Blur => { + set_focus_state(false); + } + _ => {} }); let tab_color = match hover_state { @@ -108,4 +107,4 @@ pub fn Tab(context: &mut KayakContext, content: String, selected: bool) { </Background> </Background> } -} \ No newline at end of file +} diff --git a/examples/tabs/tab_bar.rs b/examples/tabs/tab_bar.rs index 12608a8544d99a0785fb208d45ac3878db0eb618..6671b3de35a0c21689bb1563cf8b4cd7108ef05b 100644 --- a/examples/tabs/tab_bar.rs +++ b/examples/tabs/tab_bar.rs @@ -1,8 +1,8 @@ use kayak_ui::{ core::{ + constructor, rsx, styles::{LayoutType, Style, StyleProp, Units}, - Bound, constructor, EventType, Handler, KeyCode, OnEvent, - rsx, VecTracker, widget, + widget, Bound, EventType, Handler, KeyCode, OnEvent, VecTracker, }, widgets::Background, }; @@ -12,7 +12,12 @@ use crate::TabTheme; /// A widget displaying a collection of tabs in a horizontal bar #[widget] -pub fn TabBar(context: &mut KayakContext, tabs: Vec<String>, selected: usize, on_select_tab: Handler<usize>) { +pub fn TabBar( + context: &mut KayakContext, + tabs: Vec<String>, + selected: usize, + on_select_tab: Handler<usize>, +) { let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); let tabs = tabs.iter().enumerate().map(|(index, tab)| { @@ -50,4 +55,4 @@ pub fn TabBar(context: &mut KayakContext, tabs: Vec<String>, selected: usize, on <VecTracker data={tabs} /> </Background> } -} \ No newline at end of file +} diff --git a/examples/tabs/tab_box.rs b/examples/tabs/tab_box.rs index 1931c0aaf6cb3a5a9871a53dae8a31b60e7d3a27..fa186e41a4ef4f42e3d35563aa7a743739016113 100644 --- a/examples/tabs/tab_box.rs +++ b/examples/tabs/tab_box.rs @@ -1,15 +1,14 @@ -use std::fmt::Debug; -use kayak_ui::{ - core::{ - render_command::RenderCommand, - styles::{Style, StyleProp}, - Bound, Fragment, Handler, rsx, use_state, widget, - } +use kayak_ui::core::{ + render_command::RenderCommand, + rsx, + styles::{Style, StyleProp}, + use_state, widget, Bound, Fragment, Handler, }; +use std::fmt::Debug; use crate::tab_bar::TabBar; -use crate::TabTheme; use crate::tab_content::TabContent; +use crate::TabTheme; #[derive(Debug, Default, Clone, PartialEq)] pub struct TabData { @@ -27,12 +26,14 @@ pub fn TabBox(context: &mut KayakContext, tabs: Vec<TabData>, initial_tab: usize let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); let (selected, set_selected, ..) = use_state!(initial_tab); - let tab_names = tabs.iter().map(|tab| { - tab.name.clone() - }).collect::<Vec<String>>(); - let tab_content = tabs.iter().map(|tab| { - tab.content.clone() - }).collect::<Vec<_>>(); + let tab_names = tabs + .iter() + .map(|tab| tab.name.clone()) + .collect::<Vec<String>>(); + let tab_content = tabs + .iter() + .map(|tab| tab.content.clone()) + .collect::<Vec<_>>(); let on_select_tab = Handler::<usize>::new(move |index| { set_selected(index); @@ -50,4 +51,4 @@ pub fn TabBox(context: &mut KayakContext, tabs: Vec<TabData>, initial_tab: usize <TabContent tabs={tab_content} selected={selected} /> </> } -} \ No newline at end of file +} diff --git a/examples/tabs/tab_content.rs b/examples/tabs/tab_content.rs index 0dbde71667cb754ed310b928d80061cb1fbf6e91..3348cac2f0d90c7767ca55c983475a356aa92907 100644 --- a/examples/tabs/tab_content.rs +++ b/examples/tabs/tab_content.rs @@ -1,11 +1,10 @@ -use std::ops::Index; -use kayak_ui::{ - core::{ - render_command::RenderCommand, - styles::{Style, StyleProp}, - Bound, Fragment, rsx, VecTracker, widget, - } +use kayak_ui::core::{ + render_command::RenderCommand, + rsx, + styles::{Style, StyleProp}, + widget, Bound, Fragment, VecTracker, }; +use std::ops::Index; use crate::TabTheme; @@ -32,4 +31,4 @@ pub fn TabContent(context: &mut KayakContext, tabs: Vec<Fragment>, selected: usi <VecTracker data={vec![tab.clone()]} /> </> } -} \ No newline at end of file +} diff --git a/examples/tabs/tabs.rs b/examples/tabs/tabs.rs index 5d43a801443825fd051eb82e3a91c781eab358e0..bf3b892d4ab5d5c0d2ea999ff2960317cc1e8bb9 100644 --- a/examples/tabs/tabs.rs +++ b/examples/tabs/tabs.rs @@ -13,20 +13,21 @@ use bevy::{ use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, core::{ + constructor, render, rsx, styles::{Style, StyleProp, Units}, - Children, Color, constructor, Index, render, rsx, widget + widget, Children, Color, Index, }, widgets::{App, Text, Window}, }; +use crate::theming::{ColorState, TabTheme, TabThemeProvider}; use tab_box::TabBox; use tab_box::TabData; -use crate::theming::{ColorState, TabTheme, TabThemeProvider}; +mod tab; mod tab_bar; mod tab_box; mod tab_content; -mod tab; mod theming; #[widget] diff --git a/examples/tabs/theming.rs b/examples/tabs/theming.rs index 118908b1c6287e8316d4bc8b36e497ee2ff937f8..02906902b8fbaa499a957f75eb3a8a4a668460ff 100644 --- a/examples/tabs/theming.rs +++ b/examples/tabs/theming.rs @@ -1,4 +1,4 @@ -use kayak_ui::{core::{Color, rsx, widget}}; +use kayak_ui::core::{rsx, widget, Color}; #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct TabTheme { @@ -9,7 +9,7 @@ pub struct TabTheme { pub text: ColorState, pub active_tab: ColorState, pub inactive_tab: ColorState, - pub tab_height: f32 + pub tab_height: f32, } #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -23,4 +23,4 @@ pub struct ColorState { pub fn TabThemeProvider(initial_theme: TabTheme) { context.create_provider(initial_theme); rsx! { <>{children}</> } -} \ No newline at end of file +} diff --git a/kayak_core/src/event_dispatcher.rs b/kayak_core/src/event_dispatcher.rs index 2012c0f88dcda54d327e34fa49d89a3a423a0203..4d10a67e7ef4954223064c25b6b06ecf2363c135 100644 --- a/kayak_core/src/event_dispatcher.rs +++ b/kayak_core/src/event_dispatcher.rs @@ -414,31 +414,29 @@ impl EventDispatcher { /// Executes default actions for events fn execute_default(&mut self, event: Event, context: &mut KayakContext) { match event.event_type { - EventType::KeyDown(evt) => { - match evt.key() { - KeyCode::Tab => { - let current_focus = context.widget_manager.focus_tree.current(); + EventType::KeyDown(evt) => match evt.key() { + KeyCode::Tab => { + let current_focus = context.widget_manager.focus_tree.current(); - let index = if evt.is_shift_pressed() { - context.widget_manager.focus_tree.prev() - } else { - context.widget_manager.focus_tree.next() - }; - - if let Some(index) = index { - let mut events = vec![Event::new(index, EventType::Focus)]; - if let Some(current_focus) = current_focus { - if current_focus != index { - events.push(Event::new(current_focus, EventType::Blur)); - } + let index = if evt.is_shift_pressed() { + context.widget_manager.focus_tree.prev() + } else { + context.widget_manager.focus_tree.next() + }; + + if let Some(index) = index { + let mut events = vec![Event::new(index, EventType::Focus)]; + if let Some(current_focus) = current_focus { + if current_focus != index { + events.push(Event::new(current_focus, EventType::Blur)); } - context.widget_manager.focus_tree.focus(index); - self.dispatch_events(events, context); } + context.widget_manager.focus_tree.focus(index); + self.dispatch_events(events, context); } - _ => {} } - } + _ => {} + }, _ => {} } } diff --git a/kayak_core/src/focus_tree.rs b/kayak_core/src/focus_tree.rs index 2535a1f6c06da58efb24bde446fd9c14ac6563ed..dbc3a1fc44b24216340ff7302c736b0826901aee 100644 --- a/kayak_core/src/focus_tree.rs +++ b/kayak_core/src/focus_tree.rs @@ -1,5 +1,5 @@ -use std::collections::HashMap; use crate::{Index, Tree}; +use std::collections::HashMap; #[derive(Debug, Default, PartialEq)] pub struct FocusTree { @@ -157,7 +157,6 @@ impl FocusTree { } } - impl FocusTracker { /// Set the focusability of a widget /// @@ -176,7 +175,12 @@ impl FocusTracker { /// * `is_parent_defined`: Does this setting come from the parent or the widget itself? /// /// returns: () - pub fn set_focusability(&mut self, index: Index, focusable: Option<bool>, is_parent_defined: bool) { + pub fn set_focusability( + &mut self, + index: Index, + focusable: Option<bool>, + is_parent_defined: bool, + ) { let map = if is_parent_defined { &mut self.parents } else { @@ -208,7 +212,6 @@ impl FocusTracker { } } - #[cfg(test)] mod tests { use crate::focus_tree::FocusTree; @@ -299,4 +302,4 @@ mod tests { // etc. } -} \ No newline at end of file +} diff --git a/kayak_core/src/lib.rs b/kayak_core/src/lib.rs index f1c8c4161b35613a0babb0d68919484539783ca5..a72b42cde7752e87f314f7f95d938f41b4109e67 100644 --- a/kayak_core/src/lib.rs +++ b/kayak_core/src/lib.rs @@ -30,8 +30,8 @@ pub use color::Color; pub use context::*; pub use cursor::PointerEvents; pub use event::*; -pub use fragment::Fragment; pub use focus_tree::FocusTree; +pub use fragment::Fragment; pub use generational_arena::{Arena, Index}; pub use input_event::*; pub use keyboard::{KeyboardEvent, KeyboardModifiers}; diff --git a/kayak_core/src/tree.rs b/kayak_core/src/tree.rs index a8289b5eb71fbe2f7114deaa63c134d151c0fc59..8291b937c448855a4d2a4ecfdb40d989c9752541 100644 --- a/kayak_core/src/tree.rs +++ b/kayak_core/src/tree.rs @@ -66,7 +66,8 @@ impl Tree { pub fn remove(&mut self, index: Index) -> Vec<Index> { let parent = self.parents.remove(&index); if let Some(parent) = parent { - let children = self.children + let children = self + .children .remove(&index) .unwrap_or_default() .into_iter() @@ -141,7 +142,9 @@ impl Tree { /// Returns true if the given node is in this tree pub fn contains(&self, index: Index) -> bool { - Some(index) == self.root_node || self.parents.contains_key(&index) || self.children.contains_key(&index) + Some(index) == self.root_node + || self.parents.contains_key(&index) + || self.children.contains_key(&index) } /// Get the number of nodes in this tree @@ -212,9 +215,7 @@ impl Tree { pub fn get_last_child(&self, index: Index) -> Option<Index> { self.children.get(&index).map_or(None, |children| { - children - .last() - .map_or(None, |last_child| Some(*last_child)) + children.last().map_or(None, |last_child| Some(*last_child)) }) } @@ -355,8 +356,8 @@ impl Tree { let parent_b = parent_b.unwrap(); parent_a != parent_b || (parent_a == parent_b - && *node != children_a.get(*id).unwrap().1 - && children_a.iter().any(|(_, node_b)| node == node_b)) + && *node != children_a.get(*id).unwrap().1 + && children_a.iter().any(|(_, node_b)| node == node_b)) } else { false }; @@ -477,8 +478,8 @@ impl Tree { let parent_b = parent_b.unwrap(); parent_a != parent_b || (parent_a == parent_b - && *node != tree1.get(*id).unwrap().1 - && tree1.iter().any(|(_, node_b)| node == node_b)) + && *node != tree1.get(*id).unwrap().1 + && tree1.iter().any(|(_, node_b)| node == node_b)) } else { false }; @@ -647,7 +648,7 @@ impl<'a> Iterator for DownwardIterator<'a> { while current_parent.is_some() { if let Some(current_parent) = current_parent { if let Some(next_parent_sibling) = - self.tree.get_next_sibling(current_parent) + self.tree.get_next_sibling(current_parent) { self.current_node = Some(next_parent_sibling); return Some(next_parent_sibling); @@ -845,22 +846,44 @@ mod tests { expected.add(expected_grandchild_b, Some(expected_child_b)); tree.replace(grandchild_b, expected_grandchild_b); - assert!(tree.children.get(&child_b).unwrap().contains(&expected_grandchild_b)); + assert!(tree + .children + .get(&child_b) + .unwrap() + .contains(&expected_grandchild_b)); assert!(!tree.children.get(&child_b).unwrap().contains(&grandchild_b)); tree.replace(grandchild_a, expected_grandchild_a); - assert!(tree.children.get(&child_a).unwrap().contains(&expected_grandchild_a)); + assert!(tree + .children + .get(&child_a) + .unwrap() + .contains(&expected_grandchild_a)); assert!(!tree.children.get(&child_a).unwrap().contains(&grandchild_a)); tree.replace(child_a, expected_child_a); - assert!(tree.children.get(&root).unwrap().contains(&expected_child_a)); + assert!(tree + .children + .get(&root) + .unwrap() + .contains(&expected_child_a)); assert!(!tree.children.get(&root).unwrap().contains(&child_a)); - assert_eq!(expected_child_a, tree.get_parent(expected_grandchild_a).unwrap()); + assert_eq!( + expected_child_a, + tree.get_parent(expected_grandchild_a).unwrap() + ); tree.replace(child_b, expected_child_b); - assert!(tree.children.get(&root).unwrap().contains(&expected_child_b)); + assert!(tree + .children + .get(&root) + .unwrap() + .contains(&expected_child_b)); assert!(!tree.children.get(&root).unwrap().contains(&child_b)); - assert_eq!(expected_child_b, tree.get_parent(expected_grandchild_b).unwrap()); + assert_eq!( + expected_child_b, + tree.get_parent(expected_grandchild_b).unwrap() + ); tree.replace(root, expected_root); assert_eq!(Some(expected_root), tree.root_node); @@ -1004,4 +1027,4 @@ mod tests { tree.add(grandchild, Some(child)); assert_eq!(3, tree.len()); } -} \ No newline at end of file +} diff --git a/kayak_core/src/widget_manager.rs b/kayak_core/src/widget_manager.rs index ef4983116a8b3d45bd99890dc6f71b11b858736c..67c2897df858bd3bc6d21f449c8d9504777fd790 100644 --- a/kayak_core/src/widget_manager.rs +++ b/kayak_core/src/widget_manager.rs @@ -5,14 +5,14 @@ use std::{ use crate::layout_cache::Rect; use crate::{ + focus_tree::FocusTracker, + focus_tree::FocusTree, layout_cache::LayoutCache, node::{Node, NodeBuilder}, render_command::RenderCommand, render_primitive::RenderPrimitive, styles::Style, tree::Tree, - focus_tree::FocusTree, - focus_tree::FocusTracker, Arena, Index, Widget, }; // use as_any::Downcast; @@ -98,7 +98,6 @@ impl WidgetManager { self.set_focusable(widget.focusable(), widget_id, true); } - // 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 // to it's own props. @@ -419,6 +418,7 @@ impl WidgetManager { } pub fn set_focusable(&mut self, focusable: Option<bool>, index: Index, is_parent: bool) { - self.focus_tracker.set_focusability(index, focusable, is_parent); + self.focus_tracker + .set_focusability(index, focusable, is_parent); } } diff --git a/kayak_render_macros/src/function_component.rs b/kayak_render_macros/src/function_component.rs index c66eef4dc80b598dc1eded88369cfc445551b1f2..8bf7a388eb33dc850080c8f20a5cae25fecaec7a 100644 --- a/kayak_render_macros/src/function_component.rs +++ b/kayak_render_macros/src/function_component.rs @@ -122,9 +122,7 @@ pub fn create_function_widget(f: syn::ItemFn, widget_arguments: WidgetArguments) }, ), ( - vec![ - "focusable : Option < bool >", - ], + vec!["focusable : Option < bool >"], quote! { #[derivative(Default(value=#focusable_default))] pub focusable: Option<bool> @@ -139,7 +137,8 @@ pub fn create_function_widget(f: syn::ItemFn, widget_arguments: WidgetArguments) .any(|name| block_name.to_string().contains(name)) }) { input_block_names.push(token); - } else {} + } else { + } } let inputs_block = quote!(