diff options
| author | Joe Carstairs <me@joeac.net> | 2026-01-25 10:10:24 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2026-01-25 10:10:24 +0000 |
| commit | 1feae160bd184dcea618415c0e9e55289ca8b68a (patch) | |
| tree | 1cbbedd744468df30fa346bce4eeba9a60f42565 | |
| parent | d2fccfb4fe073eefc235595d255fcb6385bfa1f1 (diff) | |
factors out navigable trait
5 files changed, 66 insertions, 34 deletions
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<TOption> for Navigation<TOption> +where + TOption: Clone + PartialEq + 'a, + Element<'a, Message<TOption>>: From<&'a TOption>, +{ + fn move_next(&mut self) -> NavigationResult<TOption> { + 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<TOption> { + 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<Option> { + fn move_next(&mut self) -> NavigationResult<Option>; + fn move_prev(&mut self) -> NavigationResult<Option>; +} + +pub enum NavigationResult<Option> { + Moved(Option), + LastOption, +} |
