Skip to content

Commit cc2ddcb

Browse files
committed
feat(appearance): interface density
1 parent bb35fa7 commit cc2ddcb

File tree

2 files changed

+136
-4
lines changed

2 files changed

+136
-4
lines changed

cosmic-settings/src/pages/desktop/appearance.rs

Lines changed: 131 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ use cosmic::config::CosmicTk;
1111
use cosmic::cosmic_config::{Config, ConfigSet, CosmicConfigEntry};
1212
use cosmic::cosmic_theme::palette::{FromColor, Hsv, Srgb, Srgba};
1313
use cosmic::cosmic_theme::{
14-
CornerRadii, Theme, ThemeBuilder, ThemeMode, DARK_THEME_BUILDER_ID, LIGHT_THEME_BUILDER_ID,
14+
CornerRadii, Spacing, Theme, ThemeBuilder, ThemeMode, DARK_THEME_BUILDER_ID,
15+
LIGHT_THEME_BUILDER_ID,
1516
};
1617
use cosmic::iced_core::{alignment, Background, Color, Length};
1718
use cosmic::iced_widget::scrollable;
1819
use cosmic::prelude::CollectionWidget;
1920
use cosmic::widget::icon::{self, from_name, icon};
2021
use cosmic::widget::{
21-
button, color_picker::ColorPickerUpdate, container, flex_row, horizontal_space, row, settings,
22-
spin_button, text, ColorPickerModel,
22+
button, color_picker::ColorPickerUpdate, container, flex_row, horizontal_space, radio, row,
23+
settings, spin_button, text, ColorPickerModel,
2324
};
2425
use cosmic::Apply;
2526
use cosmic::{command, Command, Element};
@@ -83,6 +84,7 @@ pub struct Page {
8384
interface_text: ColorPickerModel,
8485
control_component: ColorPickerModel,
8586
roundness: Roundness,
87+
density: Density,
8688

8789
icon_theme_active: Option<usize>,
8890
icon_themes: IconThemes,
@@ -169,6 +171,7 @@ impl
169171
theme_builder_needs_update: false,
170172
context_view: None,
171173
roundness: theme_builder.corner_radii.into(),
174+
density: theme_builder.spacing.into(),
172175
custom_accent: ColorPickerModel::new(
173176
&*HEX,
174177
&*RGB,
@@ -286,6 +289,7 @@ pub enum Message {
286289
ControlComponent(ColorPickerUpdate),
287290
CustomAccent(ColorPickerUpdate),
288291
DarkMode(bool),
292+
Density(Density),
289293
Entered((IconThemes, IconHandles)),
290294
ExperimentalContextDrawer,
291295
ExportError,
@@ -315,6 +319,13 @@ pub enum Roundness {
315319
Square,
316320
}
317321

322+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
323+
pub enum Density {
324+
Comfortable,
325+
Compact,
326+
Spacious,
327+
}
328+
318329
impl From<Roundness> for CornerRadii {
319330
fn from(value: Roundness) -> Self {
320331
match value {
@@ -358,6 +369,61 @@ impl From<CornerRadii> for Roundness {
358369
}
359370
}
360371

372+
impl From<Density> for Spacing {
373+
fn from(value: Density) -> Self {
374+
match value {
375+
Density::Comfortable => Spacing {
376+
space_none: 0,
377+
space_xxxs: 4,
378+
space_xxs: 8,
379+
space_xs: 12,
380+
space_s: 16,
381+
space_m: 24,
382+
space_l: 32,
383+
space_xl: 48,
384+
space_xxl: 64,
385+
space_xxxl: 128,
386+
},
387+
Density::Compact => Spacing {
388+
space_none: 0,
389+
space_xxxs: 4,
390+
space_xxs: 8,
391+
space_xs: 10,
392+
space_s: 12,
393+
space_m: 16,
394+
space_l: 24,
395+
space_xl: 32,
396+
space_xxl: 48,
397+
space_xxxl: 72,
398+
},
399+
Density::Spacious => Spacing {
400+
space_none: 0,
401+
space_xxxs: 4,
402+
space_xxs: 8,
403+
space_xs: 16,
404+
space_s: 20,
405+
space_m: 32,
406+
space_l: 40,
407+
space_xl: 56,
408+
space_xxl: 72,
409+
space_xxxl: 144,
410+
},
411+
}
412+
}
413+
}
414+
415+
impl From<Spacing> for Density {
416+
fn from(value: Spacing) -> Self {
417+
if (value.space_m - 32) < 1 {
418+
Self::Spacious
419+
} else if (value.space_m - 24) < 1 {
420+
Self::Comfortable
421+
} else {
422+
Self::Compact
423+
}
424+
}
425+
}
426+
361427
impl Page {
362428
/// Syncs changes for dark and light theme.
363429
/// Roundness and window management settings should be consistent between dark / light mode.
@@ -420,6 +486,17 @@ impl Page {
420486
tracing::error!(?err, "Error setting corner radii");
421487
}
422488
}
489+
if theme_builder.spacing != self.theme_builder.spacing {
490+
if let Err(err) =
491+
theme_builder.set_spacing(&other_builder_config, self.theme_builder.spacing)
492+
{
493+
tracing::error!(?err, "Error setting spacing");
494+
}
495+
496+
if let Err(err) = theme.set_spacing(&other_theme_config, self.theme_builder.spacing) {
497+
tracing::error!(?err, "Error setting spacing");
498+
}
499+
}
423500

424501
Ok(())
425502
}
@@ -590,6 +667,13 @@ impl Page {
590667
Self::update_panel_radii(r);
591668
Command::none()
592669
}
670+
Message::Density(d) => {
671+
needs_sync = true;
672+
self.density = d;
673+
self.theme_builder.spacing = self.density.into();
674+
self.theme_builder_needs_update = true;
675+
Command::none()
676+
}
593677
Message::Entered((icon_themes, icon_handles)) => {
594678
*self = Self::default();
595679

@@ -1011,6 +1095,7 @@ impl page::Page<crate::pages::Message> for Page {
10111095
Some(vec![
10121096
sections.insert(mode_and_colors()),
10131097
sections.insert(style()),
1098+
sections.insert(interface_density()),
10141099
sections.insert(window_management()),
10151100
sections.insert(experimental()),
10161101
sections.insert(reset_button()),
@@ -1456,6 +1541,49 @@ pub fn style() -> Section<crate::pages::Message> {
14561541
})
14571542
}
14581543

1544+
pub fn interface_density() -> Section<crate::pages::Message> {
1545+
let mut descriptions = Slab::new();
1546+
1547+
let comfortable = descriptions.insert(fl!("interface-density", "comfortable"));
1548+
let compact = descriptions.insert(fl!("interface-density", "compact"));
1549+
let spacious = descriptions.insert(fl!("interface-density", "spacious"));
1550+
1551+
Section::default()
1552+
.title(fl!("interface-density"))
1553+
.descriptions(descriptions)
1554+
.view::<Page>(move |_binder, page, section| {
1555+
let descriptions = &section.descriptions;
1556+
1557+
settings::view_section(&section.title)
1558+
.add(settings::item_row(vec![radio(
1559+
text::body(&descriptions[comfortable]),
1560+
Density::Comfortable,
1561+
Some(page.density),
1562+
Message::Density,
1563+
)
1564+
.width(Length::Fill)
1565+
.into()]))
1566+
.add(settings::item_row(vec![radio(
1567+
text::body(&descriptions[compact]),
1568+
Density::Compact,
1569+
Some(page.density),
1570+
Message::Density,
1571+
)
1572+
.width(Length::Fill)
1573+
.into()]))
1574+
.add(settings::item_row(vec![radio(
1575+
text::body(&descriptions[spacious]),
1576+
Density::Spacious,
1577+
Some(page.density),
1578+
Message::Density,
1579+
)
1580+
.width(Length::Fill)
1581+
.into()]))
1582+
.apply(Element::from)
1583+
.map(crate::pages::Message::Appearance)
1584+
})
1585+
}
1586+
14591587
#[allow(clippy::too_many_lines)]
14601588
pub fn window_management() -> Section<crate::pages::Message> {
14611589
let mut descriptions = Slab::new();

i18n/en/cosmic_settings.ftl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ style = Style
103103
.slightly-round = Slightly round
104104
.square = Square
105105
106-
# interface density left out for now
106+
interface-density = Interface Density
107+
.comfortable = Comfortable
108+
.compact = Compact
109+
.spacious = Spacious
110+
107111
window-management-appearance = Window Management
108112
.active-hint = Active window hint size
109113
.gaps = Gaps around tiled windows

0 commit comments

Comments
 (0)