use iced::Element; use crate::traits::Focusable; use super::{Message, Navigation}; pub enum SelectOptionResult { AlreadySelected, SelectedExistingOption(TOption), SelectedNewOption(TOption), } impl<'a, TOption> Navigation where TOption: Clone + Focusable + PartialEq + 'a, Element<'a, Message>: From<&'a TOption>, { pub fn select_option(&mut self, option: TOption) -> SelectOptionResult 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.as_mut().map_or(vec![], |active_option| { active_option.unfocus(); vec![active_option.clone()] }), 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()); self.active_option.iter_mut().for_each(TOption::focus); 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.as_mut().map_or(vec![], |active_option| { active_option.unfocus(); vec![active_option.clone()] }), ] .concat(); self.active_option = Some(option.clone()); self.active_option.iter_mut().for_each(TOption::focus); self.options_after_active = split.1.split_at(1).1.to_vec(); SelectOptionResult::SelectedExistingOption(option) } else { if let Some(active_option) = &mut self.active_option { active_option.unfocus(); 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.active_option.iter_mut().for_each(TOption::focus); self.options_after_active = vec![]; SelectOptionResult::SelectedNewOption(option) } } }