summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui/components/navigation/navigation_set_options.rs
blob: 3eb455c07485b1c2dea9923b2c2efc2f7dbe31a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use iced::Element;

use crate::traits::Focusable;

use super::{Message, Navigation};

pub enum SetOptionsResult<TOption> {
    SetOptionsAndKeptSelection,
    SetOptionsAndSetSelectedOption(TOption),
}

impl<'a, TOption> Navigation<TOption>
where
    TOption: Clone + Focusable + PartialEq + 'a,
    Element<'a, Message<TOption>>: From<&'a TOption>,
{
    pub fn set_options(&mut self, options: &mut Vec<TOption>) -> SetOptionsResult<TOption> {
        options.iter_mut().for_each(TOption::unfocus);

        let active_option_index =
            self.active_option
                .clone()
                .map_or(Option::None, |active_option| {
                    options
                        .iter()
                        .position(|option| active_option == option.clone())
                });
        if let Some(active_option_index) = active_option_index {
            let split = options.split_at(active_option_index);
            self.options_before_active = split.0.to_vec();
            self.options_after_active = split.1.split_at(1).1.to_vec();
            SetOptionsResult::SetOptionsAndKeptSelection
        } else {
            self.options_before_active = options
                .split_last()
                .map_or_else(Vec::new, |(_last, rest)| rest.to_vec());
            self.active_option = options.last().cloned();
            self.active_option.iter_mut().for_each(TOption::focus);
            options.last().cloned().map_or(
                SetOptionsResult::SetOptionsAndKeptSelection,
                SetOptionsResult::SetOptionsAndSetSelectedOption,
            )
        }
    }
}