summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui/components/panel.rs
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2026-02-07 11:52:08 +0000
committerJoe Carstairs <me@joeac.net>2026-02-07 12:02:27 +0000
commit1664e741ad35ce52a01788c34029f0b2ea477e32 (patch)
treedd6bd7c83a7e834c75815a786d67b5188cdd1f48 /schist_desktop_gui/src/gui/components/panel.rs
parent179878d12ba10ac242da2044f4c6dfe4d4829e59 (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.rs101
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;
+ }
+}