diff options
| author | Joe Carstairs <me@joeac.net> | 2026-02-07 11:52:08 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2026-02-07 12:02:27 +0000 |
| commit | 1664e741ad35ce52a01788c34029f0b2ea477e32 (patch) | |
| tree | dd6bd7c83a7e834c75815a786d67b5188cdd1f48 /schist_desktop_gui/src/gui/components/panel.rs | |
| parent | 179878d12ba10ac242da2044f4c6dfe4d4829e59 (diff) | |
task-001: can navigate file screen options with keyboard
Diffstat (limited to 'schist_desktop_gui/src/gui/components/panel.rs')
| -rw-r--r-- | schist_desktop_gui/src/gui/components/panel.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/schist_desktop_gui/src/gui/components/panel.rs b/schist_desktop_gui/src/gui/components/panel.rs new file mode 100644 index 0000000..364659b --- /dev/null +++ b/schist_desktop_gui/src/gui/components/panel.rs @@ -0,0 +1,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; + } +} |
