summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui/components/panel.rs
blob: 364659b7747d375bfcd0a306a04e4f5fc31639b6 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use iced::{
    widget::{button::Status, column},
    Theme,
};

use crate::{
    gui::components::{navigation, panel_button, Text},
    traits::Focusable,
};

#[derive(Clone, Debug, PartialEq)]
pub struct Panel<Id> {
    pub err: Option<String>,
    pub id: Id,
    pub small: Option<String>,
    pub name: String,
    pub is_focused: bool,
}

impl<Id> Panel<Id> {
    pub fn new(id: Id, text: &str, small: Option<String>, err: Option<String>) -> Self {
        Self {
            err: err.clone(),
            id,
            small: small.clone(),
            name: text.to_string(),
            is_focused: false,
        }
    }
}

impl<'a, Id> From<&'a Panel<Id>> for iced::Element<'a, navigation::Message<Panel<Id>>>
where
    Id: Clone,
{
    fn from(value: &'a Panel<Id>) -> Self {
        let mut cols: Vec<iced::Element<'a, navigation::Message<Panel<Id>>>> = Vec::new();
        if let Some(err) = &value.err {
            cols.push(
                Text::default(err)
                    .highlight_maybe(value.is_focused)
                    .small()
                    .danger()
                    .into(),
            );
        }
        if let Some(small) = &value.small {
            cols.push(
                Text::default(small)
                    .highlight_maybe(value.is_focused)
                    .small()
                    .weak()
                    .into(),
            );
        }
        cols.push(
            Text::default(&value.name)
                .highlight_maybe(value.is_focused)
                .into(),
        );
        panel_button(
            column(cols),
            navigation::Message::ActivateOption(value.clone()),
        )
        .style(|theme, status| match (status, value.is_focused) {
            (Status::Hovered, false) => hovered_style(theme),
            (_, true) | (Status::Pressed, _) => focused_style(theme),
            (Status::Active, false) | (Status::Disabled, false) => Default::default(),
        })
        .into()
    }
}

fn hovered_style(theme: &Theme) -> iced::widget::button::Style {
    iced::widget::button::Style {
        background: Some(iced::Background::Color(
            theme.extended_palette().background.weak.color,
        )),
        text_color: theme.extended_palette().primary.base.text,
        ..Default::default()
    }
}

fn focused_style(theme: &Theme) -> iced::widget::button::Style {
    iced::widget::button::Style {
        background: Some(iced::Background::Color(
            theme.extended_palette().primary.base.text,
        )),
        text_color: theme.extended_palette().primary.base.color,
        ..Default::default()
    }
}

impl<Id> Focusable for Panel<Id> {
    fn focus(&mut self) {
        self.is_focused = true;
    }
    fn unfocus(&mut self) {
        self.is_focused = false;
    }
}