diff options
Diffstat (limited to 'schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs')
| -rw-r--r-- | schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs b/schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs new file mode 100644 index 0000000..4192059 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs @@ -0,0 +1,71 @@ +use iced::Element; + +use super::{Message, Navigation}; + +pub enum SelectOptionResult<TOption> { + AlreadySelected, + SelectedExistingOption(TOption), + SelectedNewOption(TOption), +} + +impl<'a, TOption> Navigation<TOption> +where + TOption: Clone + PartialEq + 'a, + Element<'a, Message<TOption>>: From<&'a TOption>, +{ + pub fn select_option(&mut self, option: TOption) -> SelectOptionResult<TOption> + where + TOption: Clone + PartialEq + 'a, + { + if self + .active_option + .as_ref() + .is_some_and(|active_option| TOption::eq(active_option, &option)) + { + SelectOptionResult::AlreadySelected + } else if let Some(index) = self + .options_before_active + .iter() + .position(|o| TOption::eq(o, &option)) + { + let split = self.options_before_active.split_at(index); + self.options_after_active = vec![ + self.active_option + .clone() + .map_or(vec![], |active_option| vec![active_option]), + split.1.split_at(1).1.to_vec(), + self.options_after_active.clone(), + ] + .concat(); + self.options_before_active = split.0.to_vec(); + self.active_option = Some(option.clone()); + SelectOptionResult::SelectedExistingOption(option) + } else if let Some(index) = self + .options_after_active + .iter() + .position(|o| TOption::eq(o, &option)) + { + let split = self.options_after_active.split_at(index); + self.options_before_active = vec![ + self.options_before_active.clone(), + split.0.to_vec(), + self.active_option + .clone() + .map_or(vec![], |active_option| vec![active_option]), + ] + .concat(); + self.active_option = Some(option.clone()); + self.options_after_active = split.1.split_at(1).1.to_vec(); + SelectOptionResult::SelectedExistingOption(option) + } else { + if let Some(active_option) = &self.active_option { + self.options_before_active.push(active_option.clone()); + } + self.options_before_active + .append(&mut self.options_after_active); + self.active_option = Some(option.clone()); + self.options_after_active = vec![]; + SelectOptionResult::SelectedNewOption(option) + } + } +} |
