summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui/components/navigation/navigation_select_option.rs
diff options
context:
space:
mode:
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.rs71
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)
+ }
+ }
+}