From 1feae160bd184dcea618415c0e9e55289ca8b68a Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 25 Jan 2026 10:10:24 +0000 Subject: factors out navigable trait --- .../src/gui/components/navigation.rs | 1 + .../components/navigation/navigate_navigation.rs | 45 ++++++++++++++++++++++ .../gui/components/navigation/update_navigation.rs | 43 +++++---------------- schist_desktop_gui/src/traits.rs | 2 + schist_desktop_gui/src/traits/navigable.rs | 9 +++++ 5 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 schist_desktop_gui/src/gui/components/navigation/navigate_navigation.rs create mode 100644 schist_desktop_gui/src/traits/navigable.rs diff --git a/schist_desktop_gui/src/gui/components/navigation.rs b/schist_desktop_gui/src/gui/components/navigation.rs index 6dbe622..d1f7938 100644 --- a/schist_desktop_gui/src/gui/components/navigation.rs +++ b/schist_desktop_gui/src/gui/components/navigation.rs @@ -1,3 +1,4 @@ +mod navigate_navigation; mod update_navigation; mod view_navigation; mod view_navigation_button; diff --git a/schist_desktop_gui/src/gui/components/navigation/navigate_navigation.rs b/schist_desktop_gui/src/gui/components/navigation/navigate_navigation.rs new file mode 100644 index 0000000..f399cd0 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/navigation/navigate_navigation.rs @@ -0,0 +1,45 @@ +use iced::Element; + +use crate::traits::{Navigable, NavigationResult}; + +use super::{Message, Navigation}; + +impl<'a, TOption> Navigable for Navigation +where + TOption: Clone + PartialEq + 'a, + Element<'a, Message>: From<&'a TOption>, +{ + fn move_next(&mut self) -> NavigationResult { + if let Some(next) = self.options_after_active.clone().first() { + self.options_before_active = vec![ + self.options_before_active.clone(), + self.active_option.clone().map_or(vec![], |o| vec![o]), + ] + .concat(); + self.active_option = Some(next.clone()); + self.options_after_active = self.options_after_active.split_at(1).1.to_vec(); + NavigationResult::Moved(next.clone()) + } else { + NavigationResult::LastOption + } + } + + fn move_prev(&mut self) -> NavigationResult { + if let Some(prev) = self.options_before_active.clone().last() { + self.options_after_active = vec![ + self.active_option.clone().map_or(vec![], |o| vec![o]), + self.options_after_active.clone(), + ] + .concat(); + self.active_option = Some(prev.clone()); + self.options_before_active = self + .options_before_active + .split_last() + .map(|split| split.1.to_vec()) + .unwrap_or_else(Vec::new); + NavigationResult::Moved(prev.clone()) + } else { + NavigationResult::LastOption + } + } +} diff --git a/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs b/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs index c44ddd8..15321b7 100644 --- a/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs +++ b/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs @@ -1,6 +1,6 @@ use iced::Element; -use crate::traits::Component; +use crate::traits::{Component, Navigable, NavigationResult}; use super::{Action, Message, Navigation}; @@ -93,39 +93,14 @@ where .map_or(Action::None, Action::SelectOption) } } - Message::SelectNext => { - if let Some(next) = navigation.options_after_active.clone().first() { - navigation.options_before_active = vec![ - navigation.options_before_active.clone(), - navigation.active_option.clone().map_or(vec![], |o| vec![o]), - ] - .concat(); - navigation.active_option = Some(next.clone()); - navigation.options_after_active = - navigation.options_after_active.split_at(1).1.to_vec(); - Action::SelectOption(next.clone()) - } else { - Action::None - } - } - Message::SelectPrev => { - if let Some(prev) = navigation.options_before_active.clone().last() { - navigation.options_after_active = vec![ - navigation.active_option.clone().map_or(vec![], |o| vec![o]), - navigation.options_after_active.clone(), - ] - .concat(); - navigation.active_option = Some(prev.clone()); - navigation.options_before_active = navigation - .options_before_active - .split_last() - .map(|split| split.1.to_vec()) - .unwrap_or_else(Vec::new); - Action::SelectOption(prev.clone()) - } else { - Action::None - } - } + Message::SelectNext => match self.move_next() { + NavigationResult::Moved(option) => Action::SelectOption(option), + NavigationResult::LastOption => Action::None, + }, + Message::SelectPrev => match self.move_prev() { + NavigationResult::Moved(option) => Action::SelectOption(option), + NavigationResult::LastOption => Action::None, + }, } } } diff --git a/schist_desktop_gui/src/traits.rs b/schist_desktop_gui/src/traits.rs index a36ef19..9d79d27 100644 --- a/schist_desktop_gui/src/traits.rs +++ b/schist_desktop_gui/src/traits.rs @@ -1,5 +1,7 @@ mod component; +mod navigable; mod viewable; pub use component::Component; +pub use navigable::{Navigable, NavigationResult}; pub use viewable::Viewable; diff --git a/schist_desktop_gui/src/traits/navigable.rs b/schist_desktop_gui/src/traits/navigable.rs new file mode 100644 index 0000000..2693230 --- /dev/null +++ b/schist_desktop_gui/src/traits/navigable.rs @@ -0,0 +1,9 @@ +pub trait Navigable