From 98815f51314c4d8e76ff0abc94bb5a3263c918d7 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 20 Dec 2022 16:02:44 -0700 Subject: [PATCH] Add desktop options page --- examples/cosmic/src/window.rs | 191 +++++++++++++++++++++----------- src/theme/mod.rs | 29 ++++- src/widget/navigation/macros.rs | 8 +- 3 files changed, 159 insertions(+), 69 deletions(-) diff --git a/examples/cosmic/src/window.rs b/examples/cosmic/src/window.rs index 0527e36d..b8e4e7c6 100644 --- a/examples/cosmic/src/window.rs +++ b/examples/cosmic/src/window.rs @@ -17,14 +17,23 @@ use cosmic::{ use std::vec; use theme::Button as ButtonTheme; -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum DesktopPage { + Root, + DesktopOptions, + Wallpaper, + Appearance, + DockAndTopPanel, + Workspaces, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Page { Demo, WiFi, Networking, Bluetooth, - #[default] //TODO: what should the default page be? - Desktop, + Desktop(DesktopPage), InputDevices, Displays, PowerAndBattery, @@ -38,6 +47,13 @@ pub enum Page { Applications, } +impl Default for Page { + fn default() -> Page { + //TODO: what should the default page be? + Page::Desktop(DesktopPage::Root) + } +} + #[derive(Default)] pub struct Window { title: String, @@ -180,79 +196,129 @@ impl Window { .into() } - fn view_desktop(&self) -> Element { + fn view_desktop_root(&self) -> Element { settings::view_column(vec![ text("Desktop").size(32).into(), //TODO: simplify these buttons! - container(settings::item_row(vec![ - icon("video-display-symbolic", 16).style(theme::Svg::Symbolic).into(), - column!( - text("Desktop Options").size(16), - text("Super Key action, hot corners, window control options.").size(12), - ).into(), - horizontal_space(iced::Length::Fill).into(), - icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), - ]).spacing(16)) - .padding([20, 32]) - .style(theme::Container::Custom(list::column::style)) + iced::widget::Button::new( + container(settings::item_row(vec![ + icon("video-display-symbolic", 16).style(theme::Svg::Symbolic).into(), + column!( + text("Desktop Options").size(16), + text("Super Key action, hot corners, window control options.").size(12), + ).into(), + horizontal_space(iced::Length::Fill).into(), + icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), + ]).spacing(16)) + .padding([20, 32]) + .style(theme::Container::Custom(list::column::style)) + ) + .style(theme::Button::Transparent) + .on_press(Message::Page(Page::Desktop(DesktopPage::DesktopOptions))) .into(), - container(settings::item_row(vec![ - icon("preferences-desktop-wallpaper-symbolic", 16).style(theme::Svg::Symbolic).into(), - column!( - text("Wallpaper").size(16), - text("Background images, colors, and slideshow options.").size(12), - ).into(), - horizontal_space(iced::Length::Fill).into(), - icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), - ]).spacing(16)) - .padding([20, 32]) - .style(theme::Container::Custom(list::column::style)) + iced::widget::Button::new( + container(settings::item_row(vec![ + icon("preferences-desktop-wallpaper-symbolic", 16).style(theme::Svg::Symbolic).into(), + column!( + text("Wallpaper").size(16), + text("Background images, colors, and slideshow options.").size(12), + ).into(), + horizontal_space(iced::Length::Fill).into(), + icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), + ]).spacing(16)) + .padding([20, 32]) + .style(theme::Container::Custom(list::column::style)) + ) + .style(theme::Button::Transparent) + .on_press(Message::Page(Page::Desktop(DesktopPage::Wallpaper))) .into(), - container(settings::item_row(vec![ - icon("preferences-pop-desktop-appearance-symbolic", 16).style(theme::Svg::Symbolic).into(), - column!( - text("Appearance").size(16), - text("Accent colors and COSMIC theming").size(12), - ).into(), - horizontal_space(iced::Length::Fill).into(), - icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), - ]).spacing(16)) - .padding([20, 32]) - .style(theme::Container::Custom(list::column::style)) + iced::widget::Button::new( + container(settings::item_row(vec![ + icon("preferences-pop-desktop-appearance-symbolic", 16).style(theme::Svg::Symbolic).into(), + column!( + text("Appearance").size(16), + text("Accent colors and COSMIC theming").size(12), + ).into(), + horizontal_space(iced::Length::Fill).into(), + icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), + ]).spacing(16)) + .padding([20, 32]) + .style(theme::Container::Custom(list::column::style)) + ) + .style(theme::Button::Transparent) + .on_press(Message::Page(Page::Desktop(DesktopPage::Appearance))) .into(), - container(settings::item_row(vec![ - icon("preferences-pop-desktop-dock-symbolic", 16).style(theme::Svg::Symbolic).into(), - column!( - text("Dock & Top Panel").size(16), - text("Customize size, positions, and more for Dock and Top Panel.").size(12), - ).into(), - horizontal_space(iced::Length::Fill).into(), - icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), - ]).spacing(16)) - .padding([20, 32]) - .style(theme::Container::Custom(list::column::style)) + iced::widget::Button::new( + container(settings::item_row(vec![ + icon("preferences-pop-desktop-dock-symbolic", 16).style(theme::Svg::Symbolic).into(), + column!( + text("Dock & Top Panel").size(16), + text("Customize size, positions, and more for Dock and Top Panel.").size(12), + ).into(), + horizontal_space(iced::Length::Fill).into(), + icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), + ]).spacing(16)) + .padding([20, 32]) + .style(theme::Container::Custom(list::column::style)) + ) + .style(theme::Button::Transparent) + .on_press(Message::Page(Page::Desktop(DesktopPage::DockAndTopPanel))) .into(), - container(settings::item_row(vec![ - icon("preferences-pop-desktop-workspaces-symbolic", 16).style(theme::Svg::Symbolic).into(), - column!( - text("Workspaces").size(16), - text("Set workspace number, behavior, and placement.").size(12), - ).into(), - horizontal_space(iced::Length::Fill).into(), - icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), - ]).spacing(16)) - .padding([20, 32]) - .style(theme::Container::Custom(list::column::style)) + iced::widget::Button::new( + container(settings::item_row(vec![ + icon("preferences-pop-desktop-workspaces-symbolic", 16).style(theme::Svg::Symbolic).into(), + column!( + text("Workspaces").size(16), + text("Set workspace number, behavior, and placement.").size(12), + ).into(), + horizontal_space(iced::Length::Fill).into(), + icon("go-next-symbolic", 16).style(theme::Svg::Symbolic).into(), + ]).spacing(16)) + .padding([20, 32]) + .style(theme::Container::Custom(list::column::style)) + ) + .style(theme::Button::Transparent) + .on_press(Message::Page(Page::Desktop(DesktopPage::Workspaces))) .into(), ]) .into() } + + fn view_desktop_options(&self) -> Element { + settings::view_column(vec![ + column!( + iced::widget::Button::new(row!( + icon("go-previous-symbolic", 16).style(theme::Svg::SymbolicLink), + text("Desktop").size(16), + )) + .padding(0) + .style(theme::Button::Link) + .on_press(Message::Page(Page::Desktop(DesktopPage::Root))), + text("Desktop Options").size(32), + ) + .spacing(10) + .into(), + + settings::view_section("Super Key Action") + .add(settings::item("TODO", toggler(None, self.toggler_value, Message::TogglerToggled))) + .into(), + + settings::view_section("Hot Corner") + .add(settings::item("Enable top-left hot corner for Workspaces", toggler(None, self.toggler_value, Message::TogglerToggled))) + .into(), + + settings::view_section("Top Panel") + .add(settings::item("Show Workspaces Button", toggler(None, self.toggler_value, Message::TogglerToggled))) + .add(settings::item("Show Applications Button", toggler(None, self.toggler_value, Message::TogglerToggled))) + .into(), + ]).into() + } } impl Application for Window { @@ -342,8 +408,8 @@ impl Application for Window { .on_press(Message::Page(Page::Networking)), cosmic::nav_button!("bluetooth-active-symbolic", "Bluetooth", condensed, self.page == Page::Bluetooth) .on_press(Message::Page(Page::Bluetooth)), - cosmic::nav_button!("video-display-symbolic", "Desktop", condensed, self.page == Page::Desktop) - .on_press(Message::Page(Page::Desktop)), + cosmic::nav_button!("video-display-symbolic", "Desktop", condensed, matches!(self.page, Page::Desktop(_))) + .on_press(Message::Page(Page::Desktop(DesktopPage::Root))), cosmic::nav_button!("input-keyboard-symbolic", "Input Devices", condensed, self.page == Page::InputDevices) .on_press(Message::Page(Page::InputDevices)), cosmic::nav_button!("preferences-desktop-display-symbolic", "Displays", condensed, self.page == Page::Displays) @@ -375,7 +441,8 @@ impl Application for Window { let content: Element<_> = match self.page { Page::Demo => self.view_demo(), - Page::Desktop => self.view_desktop(), + Page::Desktop(DesktopPage::Root) => self.view_desktop_root(), + Page::Desktop(DesktopPage::DesktopOptions) => self.view_desktop_options(), _ => settings::view_column(vec![ text("Unimplemented page").into() ]).into(), diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 9ffc0671..a5ccab08 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -128,6 +128,8 @@ pub enum Button { Primary, Secondary, Text, + Link, + LinkActive, Transparent, Custom { active: fn(&Theme) -> button::Appearance, @@ -150,6 +152,8 @@ impl Button { Button::Positive => &cosmic.success, Button::Destructive => &cosmic.destructive, Button::Text => &cosmic.secondary.component, + Button::Link => &cosmic.accent, + Button::LinkActive => &cosmic.secondary.component, Button::Transparent => &TRANSPARENT_COMPONENT, Button::Deactivated => &cosmic.secondary.component, Button::Custom { .. } => &TRANSPARENT_COMPONENT @@ -168,12 +172,21 @@ impl button::StyleSheet for Theme { let cosmic = style.cosmic(self); button::Appearance { - border_radius: 24.0, + border_radius: match style { + Button::Link => 0.0, + _ => 24.0, + }, background: match style { Button::Text => None, + Button::Link => None, + Button::LinkActive => Some(Background::Color(cosmic.divider.into())), _ => Some(Background::Color(cosmic.base.into())), }, - text_color: cosmic.on.into(), + text_color: match style { + Button::Link => cosmic.base.into(), + Button::LinkActive => cosmic.selected_text.into(), + _ => cosmic.on.into(), + }, ..button::Appearance::default() } } @@ -187,7 +200,11 @@ impl button::StyleSheet for Theme { let cosmic = style.cosmic(self); button::Appearance { - background: Some(Background::Color(cosmic.hover.into())), + background: match style { + Button::Link => None, + Button::LinkActive => Some(Background::Color(cosmic.divider.into())), + _ => Some(Background::Color(cosmic.hover.into())) + }, ..active } } @@ -712,6 +729,8 @@ pub enum Svg { SymbolicActive, /// Icon fill color will match on primary color SymbolicPrimary, + /// Icon fill color will use accent color + SymbolicLink, } impl Hash for Svg { @@ -722,6 +741,7 @@ impl Hash for Svg { Svg::Symbolic => 2, Svg::SymbolicActive => 3, Svg::SymbolicPrimary => 4, + Svg::SymbolicLink => 5, }; id.hash(state); @@ -744,6 +764,9 @@ impl svg::StyleSheet for Theme { Svg::SymbolicPrimary => svg::Appearance { color: Some(self.cosmic().accent.on.into()), }, + Svg::SymbolicLink => svg::Appearance { + color: Some(self.cosmic().accent.base.into()), + }, } } } diff --git a/src/widget/navigation/macros.rs b/src/widget/navigation/macros.rs index 1896b315..3480f26f 100644 --- a/src/widget/navigation/macros.rs +++ b/src/widget/navigation/macros.rs @@ -12,14 +12,14 @@ pub mod nav_bar { $crate::iced::widget::Button::new( $crate::widget::icon($icon, 22) .style(if $active { - $crate::theme::Svg::SymbolicPrimary + $crate::theme::Svg::SymbolicLink } else { $crate::theme::Svg::Symbolic }) ) .padding(8) .style(if $active { - $crate::theme::Button::Primary + $crate::theme::Button::LinkActive } else { $crate::theme::Button::Text }) @@ -28,7 +28,7 @@ pub mod nav_bar { $crate::iced::widget::row!( $crate::widget::icon($icon, 16) .style(if $active { - $crate::theme::Svg::SymbolicPrimary + $crate::theme::Svg::SymbolicLink } else { $crate::theme::Svg::Symbolic }), @@ -40,7 +40,7 @@ pub mod nav_bar { .spacing(8) ) .style(if $active { - $crate::theme::Button::Primary + $crate::theme::Button::LinkActive } else { $crate::theme::Button::Text })