From c312a86c8331940aa81956d9ae6ed271fcde1c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Tue, 10 Sep 2024 15:33:31 +0200 Subject: [PATCH 1/6] feat: interface density --- src/config/mod.rs | 57 ++++++++++++++++++++++++++++++++++++++++ src/widget/header_bar.rs | 1 + 2 files changed, 58 insertions(+) diff --git a/src/config/mod.rs b/src/config/mod.rs index ac6f0385..831cee50 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -3,6 +3,7 @@ //! Configurations available to libcosmic applications. +use crate::cosmic_theme::Spacing; use cosmic_config::cosmic_config_derive::CosmicConfigEntry; use cosmic_config::{Config, CosmicConfigEntry}; use serde::{Deserialize, Serialize}; @@ -87,10 +88,66 @@ pub struct CosmicTk { #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] pub enum Density { Compact, + Spacious, #[default] Standard, } +impl From for Spacing { + fn from(value: Density) -> Self { + match value { + Density::Compact => Spacing { + space_none: 0, + space_xxxs: 2, + space_xxs: 4, + space_xs: 8, + space_s: 12, + space_m: 16, + space_l: 24, + space_xl: 32, + space_xxl: 48, + space_xxxl: 72, + }, + Density::Spacious => Spacing { + space_none: 0, + space_xxxs: 4, + space_xxs: 8, + space_xs: 16, + space_s: 20, + space_m: 32, + space_l: 40, + space_xl: 56, + space_xxl: 72, + space_xxxl: 144, + }, + Density::Standard => Spacing { + space_none: 0, + space_xxxs: 4, + space_xxs: 8, + space_xs: 12, + space_s: 16, + space_m: 24, + space_l: 32, + space_xl: 48, + space_xxl: 64, + space_xxxl: 128, + }, + } + } +} + +impl From for Density { + fn from(value: Spacing) -> Self { + if (value.space_m - 16) < 1 { + Self::Compact + } else if (value.space_m - 24) < 1 { + Self::Standard + } else { + Self::Spacious + } + } +} + impl Default for CosmicTk { fn default() -> Self { Self { diff --git a/src/widget/header_bar.rs b/src/widget/header_bar.rs index 1dfc9eb9..2fc27b76 100644 --- a/src/widget/header_bar.rs +++ b/src/widget/header_bar.rs @@ -280,6 +280,7 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { let (height, padding) = match self.density.unwrap_or_else(crate::config::header_size) { crate::config::Density::Compact => (36.0, 2.0), crate::config::Density::Standard => (48.0, 8.0), + crate::config::Density::Spacious => (48.0, 8.0), }; // Creates the headerbar widget. From 13ed47782de97f8b3063dae8452595ed81907520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Sat, 14 Sep 2024 03:09:03 +0200 Subject: [PATCH 2/6] improv: use spacing variables in more places --- src/widget/list/column.rs | 4 ++-- src/widget/settings/item.rs | 15 +++++++++++---- src/widget/settings/mod.rs | 7 +++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/widget/list/column.rs b/src/widget/list/column.rs index b2b3b5b9..289407d8 100644 --- a/src/widget/list/column.rs +++ b/src/widget/list/column.rs @@ -4,7 +4,7 @@ use iced_core::Padding; use iced_style::container::StyleSheet; -use crate::{widget::divider, Apply, Element}; +use crate::{theme, widget::divider, Apply, Element}; pub fn list_column<'a, Message: 'static>() -> ListColumn<'a, Message> { ListColumn::default() @@ -21,7 +21,7 @@ pub struct ListColumn<'a, Message> { impl<'a, Message: 'static> Default for ListColumn<'a, Message> { fn default() -> Self { Self { - spacing: 8, + spacing: theme::THEME.lock().unwrap().cosmic().spacing.space_xxs, padding: Padding::from(0), style: ::Style::List, children: Vec::with_capacity(4), diff --git a/src/widget/settings/item.rs b/src/widget/settings/item.rs index fe86d95e..b21df312 100644 --- a/src/widget/settings/item.rs +++ b/src/widget/settings/item.rs @@ -4,6 +4,7 @@ use std::borrow::Cow; use crate::{ + theme, widget::{column, container, flex_row, horizontal_space, row, text, FlexRow, Row}, Element, }; @@ -29,10 +30,13 @@ pub fn item<'a, Message: 'static>( #[must_use] #[allow(clippy::module_name_repetitions)] pub fn item_row(children: Vec>) -> Row { + let cosmic_theme::Spacing { + space_s, space_xs, .. + } = theme::THEME.lock().unwrap().cosmic().spacing; row::with_children(children) - .spacing(12) + .spacing(space_xs) .align_items(iced::Alignment::Center) - .padding([0, 16]) + .padding([0, space_s]) } /// A settings item aligned in a flex row @@ -50,9 +54,12 @@ pub fn flex_item<'a, Message: 'static>( /// A settings item aligned in a flex row #[allow(clippy::module_name_repetitions)] pub fn flex_item_row(children: Vec>) -> FlexRow { + let cosmic_theme::Spacing { + space_s, space_xs, .. + } = theme::THEME.lock().unwrap().cosmic().spacing; flex_row(children) - .padding([0, 16]) - .spacing(12) + .padding([0, space_s]) + .spacing(space_xs) .min_item_width(200.0) .justify_items(iced::Alignment::Center) .justify_content(AlignContent::SpaceBetween) diff --git a/src/widget/settings/mod.rs b/src/widget/settings/mod.rs index b5d1abb9..f4dfbeab 100644 --- a/src/widget/settings/mod.rs +++ b/src/widget/settings/mod.rs @@ -8,10 +8,13 @@ pub use self::item::{flex_item, flex_item_row, item, item_row}; pub use self::section::{section, view_section, Section}; use crate::widget::{column, Column}; -use crate::Element; +use crate::{theme, Element}; /// A column with a predefined style for creating a settings panel #[must_use] pub fn view_column(children: Vec>) -> Column { - column::with_children(children).spacing(24).padding([0, 24]) + let spacing = theme::THEME.lock().unwrap().cosmic().spacing; + column::with_children(children) + .spacing(spacing.space_m) + .padding([0, spacing.space_m]) } From 1cf8e3d2027b672069751a8cf97a1917a96bac06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Tue, 17 Sep 2024 20:41:46 +0200 Subject: [PATCH 3/6] fix: window control button padding Makes the internal padding of window control buttons fixed (can still perfectly fit inside the Compact header bar), since they otherwise become too small when Compact. --- src/widget/header_bar.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/widget/header_bar.rs b/src/widget/header_bar.rs index 2fc27b76..98687046 100644 --- a/src/widget/header_bar.rs +++ b/src/widget/header_bar.rs @@ -362,7 +362,11 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { macro_rules! icon { ($name:expr, $size:expr, $on_press:expr) => {{ #[cfg(target_os = "linux")] - let icon = { widget::icon::from_name($name).apply(widget::button::icon) }; + let icon = { + widget::icon::from_name($name) + .apply(widget::button::icon) + .padding(8) + }; #[cfg(not(target_os = "linux"))] let icon = { @@ -373,6 +377,7 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { ))) .symbolic(true) .apply(widget::button::icon) + .padding(8) }; icon.style(crate::theme::Button::HeaderBar) From 82c10eb6a5cda90434b39667c410ed9703e2d44e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Tue, 17 Sep 2024 23:25:01 +0200 Subject: [PATCH 4/6] fix: use spacing values from design system --- src/config/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 831cee50..1a205a70 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -98,27 +98,27 @@ impl From for Spacing { match value { Density::Compact => Spacing { space_none: 0, - space_xxxs: 2, + space_xxxs: 4, space_xxs: 4, space_xs: 8, - space_s: 12, + space_s: 8, space_m: 16, space_l: 24, space_xl: 32, space_xxl: 48, - space_xxxl: 72, + space_xxxl: 64, }, Density::Spacious => Spacing { - space_none: 0, - space_xxxs: 4, - space_xxs: 8, + space_none: 4, + space_xxxs: 8, + space_xxs: 12, space_xs: 16, - space_s: 20, + space_s: 24, space_m: 32, - space_l: 40, - space_xl: 56, - space_xxl: 72, - space_xxxl: 144, + space_l: 48, + space_xl: 64, + space_xxl: 128, + space_xxxl: 160, }, Density::Standard => Spacing { space_none: 0, From ad010a466c2c14b98f44d29f811d79a33096779a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Wed, 18 Sep 2024 20:09:25 +0200 Subject: [PATCH 5/6] fix: move density to cosmic_theme --- Cargo.toml | 7 +++- cosmic-theme/src/model/density.rs | 65 +++++++++++++++++++++++++++++++ cosmic-theme/src/model/mod.rs | 2 + src/app/mod.rs | 9 ++++- src/config/mod.rs | 65 +------------------------------ src/widget/header_bar.rs | 8 ++-- 6 files changed, 85 insertions(+), 71 deletions(-) create mode 100644 cosmic-theme/src/model/density.rs diff --git a/Cargo.toml b/Cargo.toml index 1b5597c4..1041fa4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,11 +84,14 @@ derive_setters = "0.1.5" fraction = "0.15.3" image = { version = "0.25.1", optional = true } lazy_static = "1.4.0" -libc = { version = "0.2.155", optional = true } +libc = { version = "0.2.155", optional = true } mime = { version = "0.3.17", optional = true } palette = "0.7.3" rfd = { version = "0.14.0", optional = true } -rustix = { version = "0.38.34", features = ["pipe", "process"], optional = true } +rustix = { version = "0.38.34", features = [ + "pipe", + "process", +], optional = true } serde = { version = "1.0.180", features = ["derive"] } slotmap = "1.0.6" smol = { version = "2.0.0", optional = true } diff --git a/cosmic-theme/src/model/density.rs b/cosmic-theme/src/model/density.rs new file mode 100644 index 00000000..aa1685af --- /dev/null +++ b/cosmic-theme/src/model/density.rs @@ -0,0 +1,65 @@ +use crate::Spacing; +use serde::{Deserialize, Serialize}; + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub enum Density { + Compact, + Spacious, + #[default] + Standard, +} + +impl From for Spacing { + fn from(value: Density) -> Self { + match value { + Density::Compact => Spacing { + space_none: 0, + space_xxxs: 4, + space_xxs: 4, + space_xs: 8, + space_s: 8, + space_m: 16, + space_l: 24, + space_xl: 32, + space_xxl: 48, + space_xxxl: 64, + }, + Density::Spacious => Spacing { + space_none: 4, + space_xxxs: 8, + space_xxs: 12, + space_xs: 16, + space_s: 24, + space_m: 32, + space_l: 48, + space_xl: 64, + space_xxl: 128, + space_xxxl: 160, + }, + Density::Standard => Spacing { + space_none: 0, + space_xxxs: 4, + space_xxs: 8, + space_xs: 12, + space_s: 16, + space_m: 24, + space_l: 32, + space_xl: 48, + space_xxl: 64, + space_xxxl: 128, + }, + } + } +} + +impl From for Density { + fn from(value: Spacing) -> Self { + if value.space_m.saturating_sub(16) == 0 { + Self::Compact + } else if value.space_m.saturating_sub(24) == 0 { + Self::Standard + } else { + Self::Spacious + } + } +} diff --git a/cosmic-theme/src/model/mod.rs b/cosmic-theme/src/model/mod.rs index 19370dee..f48d1a8d 100644 --- a/cosmic-theme/src/model/mod.rs +++ b/cosmic-theme/src/model/mod.rs @@ -1,5 +1,6 @@ pub use corner::*; pub use cosmic_palette::*; +pub use density::*; pub use derivation::*; pub use mode::*; pub use spacing::*; @@ -7,6 +8,7 @@ pub use theme::*; mod corner; mod cosmic_palette; +mod density; mod derivation; mod mode; mod spacing; diff --git a/src/app/mod.rs b/src/app/mod.rs index a7a0665e..efb78aa9 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -48,6 +48,8 @@ pub mod message { pub use self::command::Command; pub use self::core::Core; pub use self::settings::Settings; +use crate::config::interface_density; +use crate::cosmic_theme::Density; use crate::prelude::*; use crate::theme::THEME; use crate::widget::{context_drawer, horizontal_space, id_container, menu, nav_bar, popover}; @@ -652,6 +654,11 @@ impl ApplicationExt for App { .focused_window() .is_some_and(|i| i == self.main_window_id()); + let padding = match interface_density() { + Density::Compact => 2, + _ => 8, + }; + let content_row = crate::widget::row::with_children({ let mut widgets = Vec::with_capacity(4); @@ -725,7 +732,7 @@ impl ApplicationExt for App { let content: Element<_> = if core.window.content_container { content_row .apply(crate::widget::container) - .padding([0, 8, 8, 8]) + .padding([0, padding, padding, padding]) .width(iced::Length::Fill) .height(iced::Length::Fill) .style(crate::theme::Container::WindowBackground) diff --git a/src/config/mod.rs b/src/config/mod.rs index 1a205a70..9054e956 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -3,7 +3,7 @@ //! Configurations available to libcosmic applications. -use crate::cosmic_theme::Spacing; +use crate::cosmic_theme::Density; use cosmic_config::cosmic_config_derive::CosmicConfigEntry; use cosmic_config::{Config, CosmicConfigEntry}; use serde::{Deserialize, Serialize}; @@ -85,69 +85,6 @@ pub struct CosmicTk { pub interface_density: Density, } -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] -pub enum Density { - Compact, - Spacious, - #[default] - Standard, -} - -impl From for Spacing { - fn from(value: Density) -> Self { - match value { - Density::Compact => Spacing { - space_none: 0, - space_xxxs: 4, - space_xxs: 4, - space_xs: 8, - space_s: 8, - space_m: 16, - space_l: 24, - space_xl: 32, - space_xxl: 48, - space_xxxl: 64, - }, - Density::Spacious => Spacing { - space_none: 4, - space_xxxs: 8, - space_xxs: 12, - space_xs: 16, - space_s: 24, - space_m: 32, - space_l: 48, - space_xl: 64, - space_xxl: 128, - space_xxxl: 160, - }, - Density::Standard => Spacing { - space_none: 0, - space_xxxs: 4, - space_xxs: 8, - space_xs: 12, - space_s: 16, - space_m: 24, - space_l: 32, - space_xl: 48, - space_xxl: 64, - space_xxxl: 128, - }, - } - } -} - -impl From for Density { - fn from(value: Spacing) -> Self { - if (value.space_m - 16) < 1 { - Self::Compact - } else if (value.space_m - 24) < 1 { - Self::Standard - } else { - Self::Spacious - } - } -} - impl Default for CosmicTk { fn default() -> Self { Self { diff --git a/src/widget/header_bar.rs b/src/widget/header_bar.rs index 98687046..eabb3cd6 100644 --- a/src/widget/header_bar.rs +++ b/src/widget/header_bar.rs @@ -1,7 +1,7 @@ // Copyright 2022 System76 // SPDX-License-Identifier: MPL-2.0 -use crate::config::Density; +use crate::cosmic_theme::Density; use crate::{ext::CollectionWidget, widget, Element}; use apply::Apply; use derive_setters::Setters; @@ -278,9 +278,9 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { end.push(self.window_controls()); let (height, padding) = match self.density.unwrap_or_else(crate::config::header_size) { - crate::config::Density::Compact => (36.0, 2.0), - crate::config::Density::Standard => (48.0, 8.0), - crate::config::Density::Spacious => (48.0, 8.0), + Density::Compact => (36.0, 2.0), + Density::Spacious => (48.0, 8.0), + Density::Standard => (48.0, 8.0), }; // Creates the headerbar widget. From 6201654e6a32dbe893c8b5e27d58ab37338ef4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Sat, 21 Sep 2024 18:44:44 +0200 Subject: [PATCH 6/6] fix(text_input): make icon padding fixed This prevents the icons from becoming too large or too small relative to the input box, that leads to visual issues. --- src/widget/text_input/input.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/widget/text_input/input.rs b/src/widget/text_input/input.rs index eaf633a4..343ae80d 100644 --- a/src/widget/text_input/input.rs +++ b/src/widget/text_input/input.rs @@ -107,7 +107,7 @@ where crate::widget::icon::from_name("system-search-symbolic") .size(16) .apply(crate::widget::container) - .padding([spacing, spacing, spacing, spacing]) + .padding(8) .into(), ) } @@ -131,7 +131,7 @@ where crate::widget::icon::from_name("system-lock-screen-symbolic") .size(16) .apply(crate::widget::container) - .padding([spacing, spacing, spacing, spacing]) + .padding(8) .into(), ); if hidden { @@ -148,7 +148,7 @@ where .apply(crate::widget::button::custom) .style(crate::theme::Button::Icon) .on_press(msg) - .padding([spacing, spacing, spacing, spacing]) + .padding(8) .into(), ) } else { @@ -496,17 +496,13 @@ where } pub fn on_clear(self, on_clear: Message) -> Self { - let spacing = THEME.lock().unwrap().cosmic().space_xxs(); - self.trailing_icon( crate::widget::icon::from_name("edit-clear-symbolic") .size(16) .apply(crate::widget::button::custom) .style(crate::theme::Button::Icon) - .width(32) - .height(32) .on_press(on_clear) - .padding([spacing, spacing, spacing, spacing]) + .padding(8) .into(), ) }