summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui/components/navigation/navigate_navigation.rs
blob: 72bc50369a4f69ddea7eb9d68121596d9a843a91 (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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use iced::Element;

use crate::traits::{Focusable, Navigable, NavigationResult};

use super::{Message, Navigation};

impl<'a, TOption> Navigable<TOption> for Navigation<TOption>
where
    TOption: Clone + Focusable + 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_mut() {
            self.options_before_active = vec![
                self.options_before_active.clone(),
                self.active_option.clone().map_or_else(Vec::new, |mut o| {
                    o.unfocus();
                    vec![o]
                }),
            ]
            .concat();
            next.focus();
            self.active_option = Some(next.clone());
            self.options_after_active.remove(0);
            NavigationResult::Moved(next.clone())
        } else if let Some(first) = self
            .options_before_active
            .clone()
            .first_mut()
            .filter(|_| self.active_option.is_none())
        {
            self.options_after_active = self.options_before_active.split_at(1).1.to_vec();
            self.options_before_active = Vec::new();
            first.focus();
            self.active_option = Some(first.clone());
            NavigationResult::Moved(first.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![], |mut o| {
                    o.unfocus();
                    vec![o]
                }),
                self.options_after_active.clone(),
            ]
            .concat();
            self.active_option = Some(prev.clone());
            self.active_option.iter_mut().for_each(TOption::focus);
            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
        }
    }
}