From 69cd9a3bfad9f668dc64f1fac4c347df9af19eec Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Sun, 17 Sep 2023 17:35:50 -0700 Subject: [PATCH] fix(applet): button & icon API refactor w/ applet example --- Cargo.toml | 15 +++-- examples/applet/Cargo.toml | 16 +++++ examples/applet/src/main.rs | 7 +++ examples/applet/src/window.rs | 111 ++++++++++++++++++++++++++++++++++ src/app/applet/mod.rs | 37 +++++++----- 5 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 examples/applet/Cargo.toml create mode 100644 examples/applet/src/main.rs create mode 100644 examples/applet/src/window.rs diff --git a/Cargo.toml b/Cargo.toml index 1260b80..298fd76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,13 @@ smol = ["iced/smol"] # Tokio async runtime tokio = ["dep:tokio", "ashpd/tokio", "iced/tokio"] # Wayland window support -wayland = ["ashpd?/wayland", "iced_runtime/wayland", "iced/wayland", "iced_sctk", "sctk"] +wayland = [ + "ashpd?/wayland", + "iced_runtime/wayland", + "iced/wayland", + "iced_sctk", + "sctk", +] # Render with wgpu wgpu = ["iced/wgpu", "iced_wgpu"] # X11 window support via winit @@ -39,7 +45,7 @@ derive_setters = "0.1.5" lazy_static = "1.4.0" palette = "0.7.3" tokio = { version = "1.24.2", optional = true } -sctk = { package = "smithay-client-toolkit", git = "https://github.com/smithay/client-toolkit", optional = true, rev = "c9940f4"} +sctk = { package = "smithay-client-toolkit", git = "https://github.com/smithay/client-toolkit", optional = true, rev = "c9940f4" } slotmap = "1.0.6" fraction = "0.13.0" cosmic-config = { path = "cosmic-config" } @@ -116,10 +122,7 @@ members = [ "cosmic-theme", "examples/*", ] -exclude = [ - "examples/design-demo", - "iced", -] +exclude = ["examples/design-demo", "iced"] [patch."https://github.com/pop-os/libcosmic"] libcosmic = { path = "./" } diff --git a/examples/applet/Cargo.toml b/examples/applet/Cargo.toml new file mode 100644 index 0000000..965e30a --- /dev/null +++ b/examples/applet/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "applet" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +once_cell = "1" +rust-embed = "8.0.0" +tracing = "0.1" + +[dependencies.libcosmic] +git = "https://github.com/pop-os/libcosmic" +default-features = false +features = ["applet", "tokio", "wayland"] diff --git a/examples/applet/src/main.rs b/examples/applet/src/main.rs new file mode 100644 index 0000000..5863415 --- /dev/null +++ b/examples/applet/src/main.rs @@ -0,0 +1,7 @@ +use crate::window::Window; + +mod window; + +fn main() -> cosmic::iced::Result { + cosmic::app::applet::run::(true, ()) +} diff --git a/examples/applet/src/window.rs b/examples/applet/src/window.rs new file mode 100644 index 0000000..d027ad6 --- /dev/null +++ b/examples/applet/src/window.rs @@ -0,0 +1,111 @@ +use cosmic::app::Core; +use cosmic::iced::wayland::popup::{destroy_popup, get_popup}; +use cosmic::iced::window::Id; +use cosmic::iced::{Command, Limits}; +use cosmic::iced_runtime::core::window; +use cosmic::iced_style::application; +use cosmic::theme::Button; +use cosmic::widget::{list_column, settings, toggler}; +use cosmic::{Element, Theme}; + +const ID: &str = "com.system76.CosmicAppletExample"; + +#[derive(Default)] +pub struct Window { + core: Core, + popup: Option, + id_ctr: u128, + example_row: bool, +} + +#[derive(Clone, Debug)] +pub enum Message { + TogglePopup, + PopupClosed(Id), + ToggleExampleRow(bool), +} + +impl cosmic::Application for Window { + type Executor = cosmic::SingleThreadExecutor; + type Flags = (); + type Message = Message; + const APP_ID: &'static str = ID; + + fn core(&self) -> &Core { + &self.core + } + + fn core_mut(&mut self) -> &mut Core { + &mut self.core + } + + fn init( + core: Core, + _flags: Self::Flags, + ) -> (Self, Command>) { + let window = Window { + core, + ..Default::default() + }; + (window, Command::none()) + } + + fn on_close_requested(&self, id: window::Id) -> Option { + Some(Message::PopupClosed(id)) + } + + fn update(&mut self, message: Self::Message) -> Command> { + match message { + Message::TogglePopup => { + return if let Some(p) = self.popup.take() { + destroy_popup(p) + } else { + self.id_ctr += 1; + let new_id = Id(self.id_ctr); + self.popup.replace(new_id); + let mut popup_settings = + self.core + .applet_helper + .get_popup_settings(Id(0), new_id, None, None, None); + popup_settings.positioner.size_limits = Limits::NONE + .max_width(372.0) + .min_width(300.0) + .min_height(200.0) + .max_height(1080.0); + get_popup(popup_settings) + } + } + Message::PopupClosed(id) => { + if self.popup.as_ref() == Some(&id) { + self.popup = None; + } + } + Message::ToggleExampleRow(toggled) => self.example_row = toggled, + } + Command::none() + } + + fn view(&self) -> Element { + self.core + .applet_helper + .icon_button(ID) + .on_press(Message::TogglePopup) + .style(Button::Text) + .into() + } + + fn view_window(&self, _id: Id) -> Element { + let content_list = list_column().padding(5).spacing(0).add(settings::item( + "Example row", + toggler(None, self.example_row, |value| { + Message::ToggleExampleRow(value) + }), + )); + + self.core.applet_helper.popup_container(content_list).into() + } + + fn style(&self) -> Option<::Style> { + Some(cosmic::app::applet::style()) + } +} diff --git a/src/app/applet/mod.rs b/src/app/applet/mod.rs index a6a7039..0594e3c 100644 --- a/src/app/applet/mod.rs +++ b/src/app/applet/mod.rs @@ -1,9 +1,6 @@ -use std::sync::Arc; - +use crate::widget::button::StyleSheet; use crate::{ app::Core, - cosmic_config::CosmicConfigEntry, - cosmic_theme::util::CssColor, iced::{ self, alignment::{Horizontal, Vertical}, @@ -12,16 +9,15 @@ use crate::{ }, iced_style, iced_widget, sctk, theme::{self, Button, THEME}, - Application, Element, Renderer, + widget, Application, Element, Renderer, }; pub use cosmic_panel_config; use cosmic_panel_config::{CosmicPanelBackground, PanelAnchor, PanelSize}; -use iced_style::{button::StyleSheet, container::Appearance}; +use iced_style::container::Appearance; use iced_widget::runtime::command::platform_specific::wayland::popup::{ SctkPopupSettings, SctkPositioner, }; use sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{Anchor, Gravity}; -use tracing::error; use super::cosmic; @@ -30,13 +26,21 @@ const APPLET_PADDING: u32 = 8; #[must_use] pub fn applet_button_theme() -> Button { Button::Custom { - active: Box::new(|t| iced_style::button::Appearance { + active: Box::new(|active, t| widget::button::Appearance { border_radius: 0.0.into(), - ..t.active(&Button::Text) + ..t.active(active, &Button::Text) }), - hover: Box::new(|t| iced_style::button::Appearance { + hovered: Box::new(|hovered, t| widget::button::Appearance { border_radius: 0.0.into(), - ..t.hovered(&Button::Text) + ..t.hovered(hovered, &Button::Text) + }), + pressed: Box::new(|pressed, t| widget::button::Appearance { + border_radius: 0.0.into(), + ..t.pressed(pressed, &Button::Text) + }), + disabled: Box::new(|t| widget::button::Appearance { + border_radius: 0.0.into(), + ..t.disabled(&Button::Text) }), } } @@ -128,9 +132,12 @@ impl CosmicAppletHelper { &self, icon_name: &'a str, ) -> crate::widget::Button<'a, Message, Renderer> { - crate::widget::button(theme::Button::Text) - .icon(theme::Svg::Symbolic, icon_name, self.suggested_size().0) - .padding(8) + crate::widget::button( + widget::icon::from_name(icon_name) + .prefer_svg(true) + .size(self.suggested_size().0), + ) + .padding(8) } // TODO popup container which tracks the size of itself and requests the popup to resize to match @@ -152,6 +159,7 @@ impl CosmicAppletHelper { border_radius: 12.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, + icon_color: Some(theme.cosmic().background.on.into()), }), )) .width(Length::Shrink) @@ -278,6 +286,7 @@ pub fn style() -> ::Style { iced_style::application::Appearance { background_color: Color::from_rgba(0.0, 0.0, 0.0, 0.0), text_color: theme.cosmic().on_bg_color().into(), + icon_color: theme.cosmic().on_bg_color().into(), } })) }