chore: update libcosmic

This commit is contained in:
Vukašin Vojinović 2026-04-04 17:50:25 +02:00 committed by Jacob Kauffmann
parent 09c4d04b49
commit 96ce377ebf
28 changed files with 729 additions and 960 deletions

406
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -75,11 +75,13 @@ cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//",
# cosmic-config = { path = "../libcosmic/cosmic-config" }
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }
# iced_futures = { path = "../libcosmic/iced/futures" }
#
#iced_futures = { git = "https://github.com/pop-os/libcosmic//" }
#libcosmic = { git = "https://github.com/pop-os/libcosmic//" }
#cosmic-config = { git = "https://github.com/pop-os/libcosmic//" }
#cosmic-theme = { git = "https://github.com/pop-os/libcosmic//" }
# iced_winit = { path = "../libcosmic/iced/winit" }
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" }
# cosmic-config = { git = "https://github.com/pop-os/libcosmic//" }
# cosmic-theme = { git = "https://github.com/pop-os/libcosmic//" }
# iced_futures = { git = "https://github.com/pop-os/libcosmic//" }
# iced_winit = { git = "https://github.com/pop-os/libcosmic//" }
# [patch.'https://github.com/pop-os/dbus-settings-bindings']
# cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" }

View file

@ -219,19 +219,18 @@ pub fn magnifier(
.add(
settings::item::builder(&descriptions[magnifier])
.description(&descriptions[controls])
.control(
widget::toggler(page.magnifier_state).on_toggle(Message::SetMagnifier),
.toggler(page.magnifier_state, Message::SetMagnifier),
)
.add(
settings::item::builder(&descriptions[scroll_controls]).toggler(
page.zoom_config.enable_mouse_zoom_shortcuts,
Message::SetMouseShortcuts,
),
)
.add(settings::item(
&descriptions[scroll_controls],
widget::toggler(page.zoom_config.enable_mouse_zoom_shortcuts)
.on_toggle(Message::SetMouseShortcuts),
))
.add(settings::item(
&descriptions[show_overlay],
widget::toggler(page.zoom_config.show_overlay).on_toggle(Message::SetOverlay),
))
.add(
settings::item::builder(&descriptions[show_overlay])
.toggler(page.zoom_config.show_overlay, Message::SetOverlay),
)
.add(settings::item(
&descriptions[increment],
widget::dropdown::popup_dropdown(
@ -247,10 +246,10 @@ pub fn magnifier(
},
),
))
.add(settings::item(
&descriptions[signin],
widget::toggler(page.zoom_config.start_on_login).on_toggle(Message::SetSignin),
))
.add(
settings::item::builder(&descriptions[signin])
.toggler(page.zoom_config.start_on_login, Message::SetSignin),
)
.apply(Element::from)
.map(crate::pages::Message::AccessibilityMagnifier)
})
@ -300,36 +299,21 @@ pub fn view_movement() -> section::Section<crate::pages::Message> {
settings::section()
.title(&section.title)
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&descriptions[continuous]),
.add(settings::item::builder(&descriptions[continuous]).radio(
ZoomMovement::Continuously,
Some(page.zoom_config.view_moves),
Message::SetMovement,
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&descriptions[onedge]),
))
.add(settings::item::builder(&descriptions[onedge]).radio(
ZoomMovement::OnEdge,
Some(page.zoom_config.view_moves),
Message::SetMovement,
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&descriptions[centered]),
))
.add(settings::item::builder(&descriptions[centered]).radio(
ZoomMovement::Centered,
Some(page.zoom_config.view_moves),
Message::SetMovement,
)
.width(Length::Fill)
.into(),
]))
))
.apply(Element::from)
.map(crate::pages::Message::AccessibilityMagnifier)
})

View file

@ -1,11 +1,11 @@
use cosmic::{
Task,
Apply, Element, Task,
cosmic_theme::{CosmicPalette, ThemeBuilder},
iced::core::text::Wrapping,
iced::stream,
surface,
theme::CosmicTheme,
widget::{dropdown, settings, text, toggler},
widget::{dropdown, list, settings, text},
};
pub use cosmic_comp_config::ZoomMovement;
use cosmic_config::CosmicConfigEntry;
@ -200,17 +200,6 @@ pub fn vision() -> section::Section<crate::pages::Message> {
.view::<Page>(move |binder, page, section| {
let descriptions = &section.descriptions;
settings::section()
.title(&section.title)
.add(
settings::item::builder(&descriptions[screen_reader]).toggler(
page.reader_enabled,
|enabled| {
crate::pages::Message::from(Message::ScreenReaderEnabled(enabled))
},
),
)
.add({
let (magnifier_entity, _magnifier_info) = binder
.info
.iter()
@ -227,14 +216,23 @@ pub fn vision() -> section::Section<crate::pages::Message> {
&descriptions[unavailable]
};
crate::widget::go_next_with_item(
settings::section()
.title(&section.title)
.add(
settings::item::builder(&descriptions[screen_reader]).toggler(
page.reader_enabled,
|enabled| {
crate::pages::Message::from(Message::ScreenReaderEnabled(enabled))
},
),
)
.add(crate::widget::go_next_with_item(
&descriptions[magnifier],
text::body(status_text).wrapping(Wrapping::Word),
page.wayland_available
.is_some()
.then_some(crate::pages::Message::Page(magnifier_entity)),
)
})
))
.add(
settings::item::builder(&descriptions[high_contrast])
.toggler(page.theme.is_high_contrast, |enable| {
@ -242,22 +240,20 @@ pub fn vision() -> section::Section<crate::pages::Message> {
}),
)
.add(
settings::item::builder(&descriptions[invert_colors]).control(
toggler(page.screen_inverted).on_toggle_maybe(
settings::item::builder(&descriptions[invert_colors]).toggler_maybe(
page.screen_inverted,
page.wayland_available
.is_some_and(|ver| ver >= 2)
.then_some(|set| Message::SetScreenInverted(set).into()),
),
),
)
.add(
settings::item::builder(&descriptions[color_filters]).control(
toggler(page.screen_filter_active).on_toggle_maybe(
settings::item::builder(&descriptions[color_filters]).toggler_maybe(
page.screen_filter_active,
page.wayland_available
.is_some_and(|ver| ver >= 2)
.then_some(|set| Message::SetScreenFilterActive(set).into()),
),
),
)
.add({
let selections = if page.screen_filter_selection == ColorFilter::Unknown {
@ -304,13 +300,11 @@ pub fn hearing() -> section::Section<crate::pages::Message> {
settings::section()
.title(&section.title)
.add(
cosmic::Element::from(
settings::item::builder(&descriptions[mono])
.toggler(page.daemon_config.mono_sound, Message::SetSoundMono),
)
.map(crate::pages::Message::Accessibility),
)
.into()
.apply(Element::from)
.map(crate::pages::Message::Accessibility)
})
}

View file

@ -14,7 +14,7 @@ use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet},
iced::{Length, stream},
surface,
widget::{self, dropdown, text},
widget::{self, dropdown, settings, text},
};
use cosmic_comp_config::{EavesdroppingKeyboardMode, XwaylandDescaling, XwaylandEavesdropping};
use cosmic_randr_shell::List;
@ -277,61 +277,46 @@ pub fn legacy_application_global_shortcuts() -> Section<crate::pages::Message> {
.title(fl!("legacy-app-global-shortcuts"))
.descriptions(descriptions)
.view::<Page>(move |_binder, page, section| {
let title = widget::text::body(&section.title).font(cosmic::font::bold());
let description = widget::text::body(&section.descriptions[desc]);
let title = text::body(&section.title).font(cosmic::font::bold());
let description = text::body(&section.descriptions[desc]);
let content = widget::settings::section::<'_, crate::pages::Message>()
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&section.descriptions[none]),
let content = settings::section::<'_, crate::pages::Message>()
.add(settings::item::builder(&section.descriptions[none]).radio(
EavesdroppingKeyboardMode::None,
Some(page.comp_config_xwayland_eavesdropping.keyboard),
|t| Message::SetXwaylandKeyboardMode(t).into(),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&section.descriptions[modifiers]),
))
.add(
settings::item::builder(&section.descriptions[modifiers]).radio(
EavesdroppingKeyboardMode::Modifiers,
Some(page.comp_config_xwayland_eavesdropping.keyboard),
|t| Message::SetXwaylandKeyboardMode(t).into(),
),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&section.descriptions[combination]),
.add(
settings::item::builder(&section.descriptions[combination]).radio(
EavesdroppingKeyboardMode::Combinations,
Some(page.comp_config_xwayland_eavesdropping.keyboard),
|t| Message::SetXwaylandKeyboardMode(t).into(),
),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
text::body(&section.descriptions[all]),
.add(settings::item::builder(&section.descriptions[all]).radio(
EavesdroppingKeyboardMode::All,
Some(page.comp_config_xwayland_eavesdropping.keyboard),
|t| Message::SetXwaylandKeyboardMode(t).into(),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item(
&section.descriptions[mouse],
widget::toggler(page.comp_config_xwayland_eavesdropping.pointer)
.on_toggle(|t| Message::SetXwaylandMouseButtonMode(t).into()),
));
))
.add(
settings::item::builder(&section.descriptions[mouse])
.toggler(page.comp_config_xwayland_eavesdropping.pointer, |t| {
Message::SetXwaylandMouseButtonMode(t).into()
}),
);
widget::column::with_capacity(3)
.push(title)
.push(description)
.push(content)
.spacing(cosmic::theme::active().cosmic().spacing.space_xxs)
.spacing(cosmic::theme::spacing().space_xxs)
.apply(cosmic::Element::from)
.map(Into::into)
})
@ -356,42 +341,33 @@ pub fn legacy_application_scaling() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions;
widget::settings::section()
.title(&section.title)
.add(widget::settings::item_row(vec![
widget::radio(
widget::column::with_capacity(2)
.push(text::body(&descriptions[gaming]))
.push(text::caption(&descriptions[gaming_desc])),
.add(
widget::settings::item::builder(&descriptions[gaming])
.description(&descriptions[gaming_desc])
.radio(
XwaylandDescaling::Fractional,
Some(page.comp_config_descale_xwayland),
Message::SetXwaylandDescaling,
),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
widget::column::with_capacity(2)
.push(text::body(&descriptions[apps]))
.push(text::caption(&descriptions[apps_desc])),
.add(
widget::settings::item::builder(&descriptions[apps])
.description(&descriptions[apps_desc])
.radio(
XwaylandDescaling::Enabled,
Some(page.comp_config_descale_xwayland),
Message::SetXwaylandDescaling,
),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item_row(vec![
widget::radio(
widget::column::with_capacity(2)
.push(text::body(&descriptions[compat]))
.push(text::caption(&descriptions[compat_desc])),
.add(
widget::settings::item::builder(&descriptions[compat])
.description(&descriptions[compat_desc])
.radio(
XwaylandDescaling::Disabled,
Some(page.comp_config_descale_xwayland),
Message::SetXwaylandDescaling,
),
)
.width(Length::Fill)
.into(),
]))
.add(widget::settings::item(
&descriptions[preferred_display],
dropdown::popup_dropdown(

View file

@ -772,12 +772,10 @@ fn status() -> Section<crate::pages::Message> {
}
widget::list_column()
.add(
bluetooth_toggle.control(
widget::toggler(matches!(status, Active::Enabling | Active::Enabled))
.on_toggle(|active| Message::SetActive(active).into()),
),
)
.add(bluetooth_toggle.toggler(
matches!(status, Active::Enabling | Active::Enabled),
|active| Message::SetActive(active).into(),
))
.apply(Element::from)
})
}

View file

@ -4,7 +4,7 @@ use cosmic::cosmic_config::{Config, ConfigSet};
use cosmic::cosmic_theme::Spacing;
use cosmic::iced::core::{Color, Length};
use cosmic::widget::{
ColorPickerModel, color_picker::ColorPickerUpdate, container, flex_row, settings, text,
ColorPickerModel, color_picker::ColorPickerUpdate, container, flex_row, list, settings, text,
};
use cosmic::{Apply, Task};
use cosmic::{Element, widget};

View file

@ -1,18 +1,18 @@
// Copyright 2024 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use std::rc::Rc;
use std::sync::Arc;
use cosmic::{
Apply, Element, Task,
config::{CosmicTk, FontConfig},
iced::core::text::Wrapping,
widget::{self, settings, space::horizontal as horizontal_space, svg},
widget::{self, settings, svg},
};
use cosmic_config::ConfigSet;
use crate::app;
use crate::widget::selection_context_item;
use super::{ContextView, Message, drawer};
@ -177,10 +177,6 @@ impl Model {
context_view: &ContextView,
callback: impl Fn(Arc<str>) -> super::Message,
) -> Element<'_, super::Message> {
let svg_accent = Rc::new(|theme: &cosmic::Theme| svg::Style {
color: Some(theme.cosmic().accent_text_color().into()),
});
let (mut families, current_font) = match *context_view {
ContextView::MonospaceFont => {
(&self.monospace_font_families, &self.monospace_font.family)
@ -193,36 +189,16 @@ impl Model {
families = &self.font_filter;
}
let list = families.iter().fold(widget::list_column(), |list, family| {
let list = families.iter().fold(
widget::list_column::with_capacity(families.len()),
|list, family| {
let selected = &**family == current_font;
list.add(
settings::item_row(vec![
widget::text::body(&**family)
.class(if selected {
cosmic::theme::Text::Accent
} else {
cosmic::theme::Text::Default
})
.wrapping(Wrapping::Word)
.width(cosmic::iced::Length::Fill)
.into(),
if selected {
widget::icon::from_name("object-select-symbolic")
.size(16)
.icon()
.class(cosmic::theme::Svg::Custom(svg_accent.clone()))
.into()
} else {
horizontal_space().width(16.).into()
},
])
.apply(widget::container)
.class(cosmic::theme::Container::List)
.apply(widget::button::custom)
.class(cosmic::theme::Button::Transparent)
widget::list::button(selection_context_item(&**family, selected))
.on_press(callback(family.clone())),
)
});
},
);
list.into()
}

View file

@ -22,8 +22,8 @@ use cosmic::dialog::file_chooser::{self, FileFilter};
use cosmic::iced::Subscription;
use cosmic::iced::core::{Alignment, Length};
use cosmic::widget::{
button, color_picker::ColorPickerUpdate, container, radio, row, settings,
space::horizontal as horizontal_space, text,
button, color_picker::ColorPickerUpdate, container, list, row, settings, space::horizontal,
text,
};
use cosmic::{Apply, Element, Task, widget};
#[cfg(feature = "wayland")]
@ -790,36 +790,21 @@ pub fn interface_density() -> Section<crate::pages::Message> {
settings::section()
.title(&section.title)
.add(settings::item_row(vec![
radio(
text::body(&descriptions[compact]),
.add(settings::item::builder(&descriptions[compact]).radio(
Density::Compact,
Some(page.density),
Message::Density,
)
.width(Length::Fill)
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[comfortable]),
))
.add(settings::item::builder(&descriptions[comfortable]).radio(
Density::Standard,
Some(page.density),
Message::Density,
)
.width(Length::Fill)
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[spacious]),
))
.add(settings::item::builder(&descriptions[spacious]).radio(
Density::Spacious,
Some(page.density),
Message::Density,
)
.width(Length::Fill)
.into(),
]))
))
.apply(Element::from)
.map(crate::pages::Message::Appearance)
})
@ -933,7 +918,7 @@ pub fn reset_button() -> Section<crate::pages::Message> {
.on_press(Message::Reset)
.into()
} else {
horizontal_space().width(1.).apply(Element::from)
horizontal().width(1.).apply(Element::from)
}
.map(crate::pages::Message::Appearance)
})

View file

@ -4,7 +4,7 @@ use cosmic::cosmic_theme::palette::Srgba;
use cosmic::iced::ContentFit;
use cosmic::iced::core::{Alignment, Length};
use cosmic::widget::icon::{from_name, icon};
use cosmic::widget::{self, button, container, settings, text};
use cosmic::widget::{self, button, container, list, settings, text};
use cosmic::{Apply, Element};
use cosmic_settings_page::Section;
use cosmic_settings_wallpaper as wallpaper;
@ -64,10 +64,11 @@ fn container_background<'a>(
page: &Page,
section: &'a Section<crate::pages::Message>,
labels: &HashMap<String, usize>,
) -> impl Into<Element<'a, Message>> {
) -> list::ListButton<'a, Message> {
let descriptions = &section.descriptions;
let go_next_icon = from_name("go-next-symbolic").handle();
list::button(
settings::item::builder(&descriptions[labels["container_bg"]])
.description(&descriptions[labels["container_bg_desc"]])
.control(
@ -95,16 +96,19 @@ fn container_background<'a>(
)
.into()
},
),
)
.on_press(Message::DrawerOpen(ContextView::ContainerBackground))
}
fn application_background<'a>(
page: &Page,
section: &'a Section<crate::pages::Message>,
labels: &HashMap<String, usize>,
) -> impl Into<Element<'a, Message>> {
) -> list::ListButton<'a, Message> {
let descriptions = &section.descriptions;
list::button(
settings::item::builder(&descriptions[labels["app_bg"]]).control(
page.drawer
.application_background
@ -114,16 +118,19 @@ fn application_background<'a>(
)
.width(Length::Fixed(48.0))
.height(Length::Fixed(24.0)),
),
)
.on_press(Message::DrawerOpen(ContextView::ApplicationBackground))
}
fn control_tint<'a>(
page: &Page,
section: &'a Section<crate::pages::Message>,
labels: &HashMap<String, usize>,
) -> impl Into<Element<'a, Message>> {
) -> list::ListButton<'a, Message> {
let descriptions = &section.descriptions;
list::button(
settings::item::builder(&descriptions[labels["control_tint"]])
.description(&descriptions[labels["control_tint_desc"]])
.control(
@ -135,16 +142,19 @@ fn control_tint<'a>(
)
.width(Length::Fixed(48.0))
.height(Length::Fixed(24.0)),
),
)
.on_press(Message::DrawerOpen(ContextView::ControlComponent))
}
fn interface_text<'a>(
page: &Page,
section: &'a Section<crate::pages::Message>,
labels: &HashMap<String, usize>,
) -> impl Into<Element<'a, Message>> {
) -> list::ListButton<'a, Message> {
let descriptions = &section.descriptions;
list::button(
settings::item::builder(&descriptions[labels["text_tint"]])
.description(&descriptions[labels["text_tint_desc"]])
.control(
@ -156,13 +166,15 @@ fn interface_text<'a>(
)
.width(Length::Fixed(48.0))
.height(Length::Fixed(24.0)),
),
)
.on_press(Message::DrawerOpen(ContextView::InterfaceText))
}
fn auto_switch<'a>(
page: &Page,
section: &'a Section<crate::pages::Message>,
labels: &HashMap<String, usize>,
) -> impl Into<Element<'a, Message>> {
) -> list::ListButton<'a, Message> {
let descriptions = &section.descriptions;
settings::item::builder(&descriptions[labels["auto_switch"]])

View file

@ -4,7 +4,7 @@ use cosmic::Apply;
use cosmic::{
Element, Task,
cosmic_config::{ConfigSet, CosmicConfigEntry},
widget::{settings, text, toggler},
widget::{settings, text},
};
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
use cosmic_settings_page::{self as page, Section, section};
@ -170,16 +170,15 @@ pub(crate) fn enable() -> Section<crate::pages::Message> {
};
settings::section()
.title(&section.title)
.add(settings::item(
&descriptions[dock],
toggler(
.add(
settings::item::builder(&descriptions[dock]).toggler(
container_config
.config_list
.iter()
.any(|e| e.name.as_str() == "Dock"),
Message::EnableDock,
),
)
.on_toggle(Message::EnableDock),
))
.apply(Element::from)
.map(crate::pages::Message::Dock)
})

View file

@ -4,11 +4,8 @@ use cosmic::{
cosmic_config::{self, CosmicConfigEntry},
cosmic_theme::Density,
iced::{Alignment, Length},
surface, theme,
widget::{
button, container, dropdown, icon, row, settings, slider,
space::horizontal as horizontal_space, text, toggler,
},
surface,
widget::{button, container, dropdown, list, row, settings, slider, space, text},
};
use cosmic::Apply;
@ -119,10 +116,10 @@ pub(crate) fn behavior_and_position<
};
settings::section()
.title(&section.title)
.add(settings::item(
&descriptions[autohide_label],
toggler(panel_config.autohide.is_some()).on_toggle(Message::AutoHidePanel),
))
.add(
settings::item::builder(&descriptions[autohide_label])
.toggler(panel_config.autohide.is_some(), Message::AutoHidePanel),
)
.add(settings::item(
&descriptions[position],
dropdown::popup_dropdown(
@ -180,14 +177,14 @@ pub(crate) fn style<
};
settings::section()
.title(&section.title)
.add(settings::item(
&descriptions[gap_label],
toggler(panel_config.anchor_gap).on_toggle(Message::AnchorGap),
))
.add(settings::item(
&descriptions[extend_label],
toggler(panel_config.expand_to_edges).on_toggle(Message::ExtendToEdge),
))
.add(
settings::item::builder(&descriptions[gap_label])
.toggler(panel_config.anchor_gap, Message::AnchorGap),
)
.add(
settings::item::builder(&descriptions[extend_label])
.toggler(panel_config.expand_to_edges, Message::ExtendToEdge),
)
.add(settings::item(
&descriptions[appearance],
dropdown::popup_dropdown(
@ -292,24 +289,10 @@ pub(crate) fn configuration<P: page::Page<crate::pages::Message> + PanelPage>(
.iter()
.find(|(_, v)| v.id == page.applets_page_id())
{
let control = row::with_children(vec![
horizontal_space().into(),
icon::from_name("go-next-symbolic").size(16).into(),
]);
settings.add(
settings::item::builder(&*descriptions[applets_label])
.control(control)
.spacing(16)
.width(Length::Fill)
.apply(container)
.class(theme::Container::List)
.apply(button::custom)
.width(Length::Fill)
.class(theme::Button::Transparent)
.width(Length::Fill)
.on_press(crate::pages::Message::Page(panel_applets_entity)),
)
settings.add(crate::widget::go_next_item(
&*descriptions[applets_label],
crate::pages::Message::Page(panel_applets_entity),
))
} else {
settings
};
@ -358,7 +341,7 @@ pub fn reset_button<
let descriptions = &section.descriptions;
let inner = page.inner();
if inner.system_default == inner.panel_config {
Element::from(horizontal_space().width(1.))
Element::from(space())
} else {
button::standard(&descriptions[reset_to_default])
.on_press(Message::ResetPanel)

View file

@ -28,7 +28,7 @@ use cosmic::{
segmented_button::{self, SingleSelectModel},
settings,
space::horizontal as horizontal_space,
tab_bar, text, toggler,
tab_bar, text,
},
};
use cosmic::{
@ -1275,18 +1275,17 @@ pub fn settings() -> Section<crate::pages::Message> {
children.push({
let mut column = list_column()
.add(settings::item(
&descriptions[same_label],
toggler(page.wallpaper_service_config.same_on_all)
.on_toggle(Message::SameWallpaper),
.add(settings::item::builder(&descriptions[same_label]).toggler(
page.wallpaper_service_config.same_on_all,
Message::SameWallpaper,
))
.add(settings::item(&descriptions[fit_label], wallpaper_fit));
if show_slideshow_toggle {
column = column.add(settings::item(
&descriptions[slide_label],
toggler(slideshow_enabled).on_toggle(Message::Slideshow),
));
column = column.add(
settings::item::builder(&descriptions[slide_label])
.toggler(slideshow_enabled, Message::Slideshow),
);
}
// The rotation frequency dropdown should only be shown when the slideshow is enabled.

View file

@ -5,7 +5,7 @@ use cosmic::{
Apply, Element,
iced::{Alignment, Length},
surface,
widget::{self, settings, toggler},
widget::{self, settings},
};
use cosmic_comp_config::CosmicCompConfig;
@ -259,14 +259,11 @@ pub fn window_management() -> Section<crate::pages::Message> {
),
))
.add(
settings::flex_item(
&descriptions[edge_gravity],
toggler(page.edge_snap_threshold != 0).on_toggle(|is_enabled| {
settings::item::builder(&descriptions[edge_gravity])
.toggler(page.edge_snap_threshold != 0, |is_enabled| {
Message::SetEdgeSnapThreshold(if is_enabled { 10 } else { 0 })
}),
)
.align_items(Alignment::Center),
)
.apply(Element::from)
.map(crate::pages::Message::WindowManagement)
})
@ -287,18 +284,18 @@ pub fn window_controls() -> Section<crate::pages::Message> {
settings::section()
.title(&section.title)
.add(settings::item(
&descriptions[active_window_hint],
toggler(page.show_active_hint).on_toggle(Message::ShowActiveWindowHint),
))
.add(settings::item(
&descriptions[maximize],
toggler(cosmic::config::show_maximize()).on_toggle(Message::ShowMaximizeButton),
))
.add(settings::item(
&descriptions[minimize],
toggler(cosmic::config::show_minimize()).on_toggle(Message::ShowMinimizeButton),
))
.add(
settings::item::builder(&descriptions[active_window_hint])
.toggler(page.show_active_hint, Message::ShowActiveWindowHint),
)
.add(
settings::item::builder(&descriptions[maximize])
.toggler(cosmic::config::show_maximize(), Message::ShowMaximizeButton),
)
.add(
settings::item::builder(&descriptions[minimize])
.toggler(cosmic::config::show_minimize(), Message::ShowMinimizeButton),
)
.apply(Element::from)
.map(crate::pages::Message::WindowManagement)
})
@ -319,10 +316,10 @@ pub fn focus_navigation() -> Section<crate::pages::Message> {
settings::section()
.title(&section.title)
.add(settings::item(
&descriptions[focus_follows_cursor],
toggler(page.focus_follows_cursor).on_toggle(Message::SetFocusFollowsCursor),
))
.add(
settings::item::builder(&descriptions[focus_follows_cursor])
.toggler(page.focus_follows_cursor, Message::SetFocusFollowsCursor),
)
.add(settings::item(
&descriptions[focus_follows_cursor_delay],
widget::editable_input("", &page.focus_delay_text, false, |editing| {
@ -333,10 +330,10 @@ pub fn focus_navigation() -> Section<crate::pages::Message> {
.on_submit(|_| Message::SaveFocusFollowsCursorDelay(true))
.width(Length::Fixed(80.0)),
))
.add(settings::item(
&descriptions[cursor_follows_focus],
toggler(page.cursor_follows_focus).on_toggle(Message::SetCursorFollowsFocus),
))
.add(
settings::item::builder(&descriptions[cursor_follows_focus])
.toggler(page.cursor_follows_focus, Message::SetCursorFollowsFocus),
)
.apply(Element::from)
.map(crate::pages::Message::WindowManagement)
})

View file

@ -8,7 +8,7 @@ use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet},
iced::Length,
surface,
widget::{self, radio, settings, text},
widget::{self, settings, text},
};
use cosmic_comp_config::workspace::{Action, WorkspaceConfig, WorkspaceLayout, WorkspaceMode};
use cosmic_settings_page::Section;
@ -209,26 +209,16 @@ fn multi_behavior() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions;
settings::section()
.title(&section.title)
.add(settings::item_row(vec![
radio(
text::body(&descriptions[span]),
.add(settings::item::builder(&descriptions[span]).radio(
WorkspaceMode::Global,
Some(page.comp_workspace_config.workspace_mode),
Message::SetWorkspaceMode,
)
.width(Length::Fill)
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[separate]),
))
.add(settings::item::builder(&descriptions[separate]).radio(
WorkspaceMode::OutputBound,
Some(page.comp_workspace_config.workspace_mode),
Message::SetWorkspaceMode,
)
.width(Length::Fill)
.into(),
]))
))
.apply(Element::from)
.map(crate::pages::Message::DesktopWorkspaces)
})
@ -247,26 +237,16 @@ fn workspace_orientation() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions;
settings::section()
.title(&section.title)
.add(settings::item_row(vec![
radio(
text::body(&descriptions[vertical]),
.add(settings::item::builder(&descriptions[vertical]).radio(
WorkspaceLayout::Vertical,
Some(page.comp_workspace_config.workspace_layout),
Message::SetWorkspaceLayout,
)
.width(Length::Fill)
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[horizontal]),
))
.add(settings::item::builder(&descriptions[horizontal]).radio(
WorkspaceLayout::Horizontal,
Some(page.comp_workspace_config.workspace_layout),
Message::SetWorkspaceLayout,
)
.width(Length::Fill)
.into(),
]))
))
.apply(Element::from)
.map(crate::pages::Message::DesktopWorkspaces)
})

View file

@ -10,7 +10,7 @@ use cosmic::iced::core::text::{Ellipsize, EllipsizeHeightLimit};
use cosmic::iced::widget::scrollable::RelativeOffset;
use cosmic::iced::{Alignment, Length, stream, time};
use cosmic::widget::{
self, column, container, dropdown, list_column, segmented_button, tab_bar, text, toggler,
self, column, container, dropdown, list_column, segmented_button, tab_bar, text,
};
use cosmic::{Apply, Element, Task, surface};
use cosmic_randr_shell::{
@ -1370,10 +1370,10 @@ pub fn display_configuration() -> Section<crate::pages::Message> {
|| !active_output.enabled
{
list_column()
.add(widget::settings::item(
&descriptions[enable_label],
toggler(active_output.enabled).on_toggle(Message::DisplayToggle),
))
.add(
widget::settings::item::builder(&descriptions[enable_label])
.toggler(active_output.enabled, Message::DisplayToggle),
)
.add(widget::settings::item(
&descriptions[mirroring_label],
widget::dropdown::multi::dropdown(

View file

@ -11,7 +11,7 @@ use cosmic::{
cosmic_config::{self, ConfigSet},
iced::{Alignment, Length},
theme,
widget::{self, ListColumn, button, container, icon, radio, row, settings},
widget::{self, ListColumn, button, container, icon, list, row, settings},
};
use cosmic_comp_config::{KeyboardConfig, NumlockState, XkbConfig};
use cosmic_settings_page::{self as page, Section, section};
@ -243,15 +243,10 @@ fn special_char_radio_row<'a>(
desc: &'a str,
value: Option<&'static str>,
current_value: Option<&'a str>,
) -> cosmic::Element<'a, Message> {
settings::item_row(vec![
radio(desc, value, Some(current_value), |_| {
) -> list::ListButton<'a, Message> {
settings::item::builder(desc).radio(value, Some(current_value), |_| {
Message::SpecialCharacterSelect(value)
})
.width(Length::Fill)
.into(),
])
.into()
}
impl page::Page<crate::pages::Message> for Page {
@ -552,9 +547,11 @@ impl Page {
pub fn add_input_source_view(&self) -> Element<'_, crate::pages::Message> {
let space_l = theme::spacing().space_l;
let toggler = settings::item::builder(fl!("show-extended-input-sources")).toggler(
let toggler = settings::section().add(
settings::item::builder(fl!("show-extended-input-sources")).toggler(
self.show_extended_input_sources,
Message::SetShowExtendedInputSources,
),
);
let mut list = widget::list_column();
@ -653,16 +650,11 @@ impl Page {
let mut list = cosmic::widget::list_column();
for (desc, state) in options {
list = list.add(settings::item_row(vec![
radio(
cosmic::widget::text(desc),
list = list.add(settings::item::builder(desc).radio(
Some(state),
Some(Some(current)),
|_| Message::SetNumlockState(state),
)
.width(Length::Fill)
.into(),
]));
));
}
list.into()

View file

@ -779,10 +779,7 @@ fn context_drawer<'a>(
show_action: bool,
) -> Element<'a, ShortcutMessage> {
let cosmic::cosmic_theme::Spacing {
space_xxs,
space_xs,
space_l,
..
space_xs, space_l, ..
} = theme::spacing();
let model = &shortcuts[id];
@ -798,7 +795,7 @@ fn context_drawer<'a>(
});
let bindings = model.bindings.iter().enumerate().fold(
widget::list_column().spacing(space_xxs),
widget::list_column(),
|section, (_, (bind_id, shortcut))| {
let editing = editing == Some(bind_id);
let text: Cow<'_, str> = if !editing && shortcut.binding.is_set() {

View file

@ -452,7 +452,7 @@ impl Page {
.padding([16, 24]);
let keys = self.add_shortcut.keys.iter().fold(
widget::list_column().spacing(0),
widget::list_column(),
|column, (id, (text, widget_id))| {
let key_combination = widget::editable_input(
fl!("type-key-combination"),
@ -474,7 +474,7 @@ impl Page {
},
);
let controls = widget::list_column().add(input_fields).add(keys).spacing(0);
let controls = widget::list_column().add(input_fields).add(keys);
let add_keybinding_button = widget::button::standard(fl!("add-another-keybinding"))
.on_press(Message::AddShortcut)

View file

@ -166,27 +166,17 @@ fn click_behavior() -> Section<crate::pages::Message> {
settings::section()
.title(&*section.title)
// Secondary click via two fingers, and middle-click via three fingers
.add(settings::item_row(vec![
widget::radio(
text::body(&descriptions[click_finger]),
.add(settings::item::builder(&descriptions[click_finger]).radio(
ClickMethod::Clickfinger,
page.input_touchpad.click_method,
|option| Message::SetSecondaryClickBehavior(Some(option), true),
)
.width(Length::Fill)
.into(),
]))
))
// Secondary and middle-click via button areas.
.add(settings::item_row(vec![
widget::radio(
text::body(&descriptions[button_areas]),
.add(settings::item::builder(&descriptions[button_areas]).radio(
ClickMethod::ButtonAreas,
page.input_touchpad.click_method,
|option| Message::SetSecondaryClickBehavior(Some(option), true),
)
.width(Length::Fill)
.into(),
]))
))
.add(
settings::item::builder(&descriptions[tap_to_click]).toggler(
page.input_touchpad
@ -222,33 +212,27 @@ fn scrolling() -> Section<crate::pages::Message> {
settings::section()
.title(&section.title)
// Two-finger scrolling toggle
.add(settings::item_row(vec![
widget::radio(
text::body(&descriptions[two_finger]),
.add(
settings::item::builder(&descriptions[two_finger]).radio(
ScrollMethod::TwoFinger,
page.input_touchpad
.scroll_config
.as_ref()
.and_then(|x| x.method),
|option| Message::SetScrollMethod(Some(option), true),
),
)
.width(Length::Fill)
.into(),
]))
// Edge scrolling toggle
.add(settings::item_row(vec![
widget::radio(
text::body(&descriptions[edge]),
.add(
settings::item::builder(&descriptions[edge]).radio(
ScrollMethod::Edge,
page.input_touchpad
.scroll_config
.as_ref()
.and_then(|x| x.method),
|option| Message::SetScrollMethod(Some(option), true),
),
)
.width(Length::Fill)
.into(),
]))
// Scroll speed slider
.add(settings::item(&descriptions[scroll_speed], {
let value = page

View file

@ -13,7 +13,7 @@ use cosmic::{
iced::core::text::Wrapping,
iced::{Alignment, Length, widget::operation::focus_next},
task,
widget::{self, column, icon, space::horizontal as horizontal_space, text_input::focus},
widget::{self, column, icon, space::horizontal, text_input::focus},
};
use cosmic_settings_network_manager_subscription::{
self as network_manager, NetworkManagerState,
@ -195,7 +195,7 @@ impl page::Page<crate::pages::Message> for Page {
widget::button::standard(fl!("cancel")).on_press(Message::CancelDialog);
let control: Element<_> = if let Some(identity) = identity {
widget::Column::new()
column::with_capacity(2)
.spacing(8)
.push(
widget::text_input::text_input(fl!("identity"), identity)
@ -883,7 +883,7 @@ fn devices_view() -> Section<crate::pages::Message> {
let spacing = cosmic::theme::spacing();
let wifi_enable = widget::settings::item::builder(&section.descriptions[wifi_txt])
.control(widget::toggler(state.wifi_enabled).on_toggle(Message::WiFiEnable));
.toggler(state.wifi_enabled, Message::WiFiEnable);
let mut view = widget::column::with_capacity(4)
.push(widget::list_column().add(wifi_enable))
@ -1019,7 +1019,7 @@ fn devices_view() -> Section<crate::pages::Message> {
let item = widget::settings::item_row(vec![
identifier.into(),
horizontal_space().into(),
horizontal().into(),
controls.into(),
]);
@ -1124,7 +1124,7 @@ fn devices_view() -> Section<crate::pages::Message> {
let item = widget::settings::item_row(vec![
identifier.into(),
horizontal_space().into(),
horizontal().into(),
controls.into(),
]);
@ -1234,7 +1234,7 @@ fn devices_view() -> Section<crate::pages::Message> {
let item = widget::settings::item_row(vec![
identifier.into(),
horizontal_space().into(),
horizontal().into(),
connect,
]);

View file

@ -7,7 +7,7 @@ use cosmic::Task;
use cosmic::iced::core::text::{Ellipsize, EllipsizeHeightLimit};
use cosmic::iced::widget::{column, row};
use cosmic::iced::{self, Alignment, Length, stream};
use cosmic::widget::{self, radio, settings, space::horizontal as horizontal_space, text};
use cosmic::widget::{self, settings, space, text};
use cosmic::{Apply, surface};
use cosmic_config::{Config, CosmicConfigEntry};
use cosmic_idle_config::CosmicIdleConfig;
@ -508,12 +508,8 @@ fn connected_devices() -> Section<crate::pages::Message> {
.map(|mut device_row| {
cosmic::Element::from(
row!(
device_row.next().unwrap_or(
horizontal_space().width(Length::Fill).into()
),
device_row.next().unwrap_or(
horizontal_space().width(Length::Fill).into()
),
device_row.next().unwrap_or(space::horizontal().into()),
device_row.next().unwrap_or(space::horizontal().into()),
)
.spacing(8),
)
@ -543,18 +539,9 @@ fn profiles() -> Section<crate::pages::Message> {
section = profiles
.into_iter()
.map(|profile| {
settings::item_row(vec![
radio(
widget::column::with_capacity(2)
.push(text::body(profile.title()))
.push(text::caption(profile.description())),
profile,
Some(current_profile),
Message::PowerProfileChange,
)
.width(Length::Fill)
.into(),
])
settings::item::builder(profile.title())
.description(profile.description())
.radio(profile, Some(current_profile), Message::PowerProfileChange)
})
.fold(section, settings::Section::add);
}

View file

@ -320,10 +320,9 @@ fn input() -> Section<crate::pages::Message> {
controls = controls.add(
settings::item::builder(&*section.descriptions[amplification])
.description(&*section.descriptions[amplification_desc])
.control(
widget::toggler(page.amplification_source)
.on_toggle(|t| Message::ToggleOverAmplificationSource(t).into()),
),
.toggler(page.amplification_source, |t| {
Message::ToggleOverAmplificationSource(t).into()
}),
);
Element::from(controls)
@ -435,10 +434,9 @@ fn output() -> Section<crate::pages::Message> {
controls = controls.add(
settings::item::builder(&*section.descriptions[amplification])
.description(&*section.descriptions[amplification_desc])
.control(
widget::toggler(page.amplification_sink)
.on_toggle(|t| Message::ToggleOverAmplificationSink(t).into()),
),
.toggler(page.amplification_sink, |t| {
Message::ToggleOverAmplificationSink(t).into()
}),
);
Element::from(controls)

View file

@ -8,7 +8,7 @@ use cosmic::{
Apply, Element,
dialog::file_chooser,
iced::{Alignment, Length},
widget::{self, column, icon, row, settings, space::horizontal as horizontal_space, text},
widget::{self, column, icon, list, row, settings, space::horizontal, text},
};
use cosmic_settings_page::{self as page, Section, section};
use image::GenericImageView;
@ -322,7 +322,7 @@ impl page::Page<crate::pages::Message> for Page {
)))
.width(Length::Fill),
)
.push(horizontal_space().width(5.))
.push(horizontal().width(5.))
.push(admin_toggler)
.align_y(Alignment::Center),
),
@ -785,16 +785,13 @@ fn user_list() -> Section<crate::pages::Message> {
.descriptions(descriptions)
.view::<Page>(move |_binder, page, section| {
let descriptions = &section.descriptions;
let cosmic::cosmic_theme::Spacing {
space_xxs, space_m, ..
} = cosmic::theme::active().cosmic().spacing;
let space_xxs = cosmic::theme::spacing().space_xxs;
let users_list = page
.users
.iter()
.enumerate()
.flat_map(|(idx, user)| {
.map(|(idx, user)| {
let expanded =
matches!(page.selected_user_idx, Some(user_idx) if user_idx == idx);
@ -832,37 +829,6 @@ fn user_list() -> Section<crate::pages::Message> {
&descriptions[user_type_standard]
});
let expanded_details = expanded.then(|| {
let mut details_list = widget::list_column()
.add(settings::item(&page.fullname_label, fullname))
.add(settings::item(&page.username_label, username))
.add(settings::item(&page.password_label, password))
.add(settings::item_row(vec![
column::with_capacity(2)
.push(text::body(crate::fl!("administrator")))
.push(text::caption(crate::fl!("administrator", "desc")))
.width(Length::Fill)
.into(),
horizontal_space().width(5.).into(),
widget::toggler(user.is_admin)
.on_toggle(|enabled| {
Message::SelectedUserSetAdmin(user.id, enabled)
})
.into(),
]));
if page.users.len() > 1 {
details_list = details_list.add(settings::item_row(vec![
horizontal_space().width(Length::Fill).into(),
widget::button::destructive(crate::fl!("remove-user"))
.on_press(Message::SelectedUserDelete(user.id))
.into(),
]));
}
details_list.apply(Element::from)
});
let profile_icon_handle = user
.profile_icon
.clone()
@ -884,8 +850,8 @@ fn user_list() -> Section<crate::pages::Message> {
)
.align_y(Alignment::Center)
.spacing(space_xxs)
.width(Length::Fill)
.into(),
horizontal_space().width(Length::Fill).into(),
icon::from_name(if expanded {
"go-up-symbolic"
} else {
@ -896,28 +862,49 @@ fn user_list() -> Section<crate::pages::Message> {
.into(),
]);
let account_details = Some(
widget::button::custom(account_details_content)
.padding([space_xxs, space_m])
.on_press(Message::SelectUser(idx))
.class(cosmic::theme::Button::ListItem)
.width(Length::Fill)
let mut user_list = widget::list_column().add(
list::button(account_details_content)
.selected(expanded)
.apply(Element::from),
.on_press(Message::SelectUser(idx)),
);
vec![account_details, expanded_details]
if expanded {
user_list = user_list
.add(settings::item(&page.fullname_label, fullname))
.add(settings::item(&page.username_label, username))
.add(settings::item(&page.password_label, password))
.add(settings::item_row(vec![
column::with_capacity(2)
.push(text::body(crate::fl!("administrator")))
.push(text::caption(crate::fl!("administrator", "desc")))
.width(Length::Fill)
.into(),
horizontal().width(5.).into(),
widget::toggler(user.is_admin)
.on_toggle(|enabled| {
Message::SelectedUserSetAdmin(user.id, enabled)
})
.into(),
]));
if page.users.len() > 1 {
user_list = user_list.add(settings::item_row(vec![
horizontal().width(Length::Fill).into(),
widget::button::destructive(crate::fl!("remove-user"))
.on_press(Message::SelectedUserDelete(user.id))
.into(),
]));
}
}
Element::from(user_list)
})
.flatten()
.fold(
widget::list_column()
.spacing(0)
.padding([8, 0])
.divider_padding(0)
.list_item_padding(0),
widget::ListColumn::add,
widget::column::with_capacity(page.users.len()),
|col, user| col.push(user),
)
.apply(|list| Element::from(settings::section::with_column(list)));
.spacing(space_xxs)
.width(Length::Fill);
let add_user = widget::button::standard(crate::fl!("add-user"))
.on_press(Message::Dialog(Some(Dialog::AddNewUser(User::default()))))
@ -928,7 +915,7 @@ fn user_list() -> Section<crate::pages::Message> {
widget::column::with_capacity(2)
.push(users_list)
.push(add_user)
.spacing(space_m)
.spacing(space_xxs)
.apply(Element::from)
.map(crate::pages::Message::User)
})

View file

@ -1,13 +1,14 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use crate::widget::selection_context_item;
use cosmic::{
Apply, Element, Task,
app::ContextDrawer,
cosmic_config::{self, ConfigGet, ConfigSet},
iced::core::text::Wrapping,
surface,
widget::{self, dropdown, settings, space::horizontal as horizontal_space},
widget::{self, dropdown, list, settings},
};
use cosmic_settings_page::{self as page, Section, section};
use icu::{
@ -20,7 +21,6 @@ use icu::{
locale::{Locale, preferences::extensions::unicode::keywords::HourCycle},
};
use slotmap::{Key, SlotMap};
use std::rc::Rc;
pub use timedate_zbus::TimeDateProxy;
use tracing::error;
@ -335,7 +335,10 @@ impl Page {
for (id, timezone) in self.timezone_list.iter().enumerate() {
if search_input.is_empty() || timezone.to_lowercase().contains(search_input) {
list = list.add(self.timezone_context_item(id, timezone));
list = list.add(
list::button(selection_context_item(timezone, Some(id) == self.timezone))
.on_press(Message::Timezone(id)),
);
}
}
@ -343,40 +346,6 @@ impl Page {
.map(crate::pages::Message::DateAndTime)
}
fn timezone_context_item<'a>(&self, id: usize, timezone: &'a str) -> Element<'a, Message> {
let svg_accent = Rc::new(|theme: &cosmic::Theme| cosmic::widget::svg::Style {
color: Some(theme.cosmic().accent_text_color().into()),
});
let selected = Some(id) == self.timezone;
widget::settings::item_row(vec![
widget::text::body(timezone)
.class(if selected {
cosmic::theme::Text::Accent
} else {
cosmic::theme::Text::Default
})
.wrapping(Wrapping::Word)
.width(cosmic::iced::Length::Fill)
.into(),
if selected {
widget::icon::from_name("object-select-symbolic")
.size(16)
.icon()
.class(cosmic::theme::Svg::Custom(svg_accent.clone()))
.into()
} else {
horizontal_space().width(16.).into()
},
])
.apply(widget::container)
.class(cosmic::theme::Container::List)
.apply(widget::button::custom)
.class(cosmic::theme::Button::Transparent)
.on_press(Message::Timezone(id))
.into()
}
fn update_local_time(&mut self) {
self.local_time = Some(update_local_time());
@ -498,30 +467,19 @@ fn timezone() -> Section<crate::pages::Message> {
.title(fl!("time-zone"))
.descriptions(descriptions)
.view::<Page>(move |_binder, page, section| {
let timezone_context_button = widget::row::with_capacity(2)
.spacing(12)
.push(
settings::section()
.title(&section.title)
// Time zone select
.add(crate::widget::go_next_with_item(
&*section.descriptions[time_zone],
widget::text::body(
page.timezone
.map(|id| &*page.timezone_list[id])
.unwrap_or_default(),
)
.wrapping(Wrapping::Word),
)
.push(widget::icon::from_name("go-next-symbolic").size(16).icon())
.apply(widget::container)
.class(cosmic::theme::Container::List)
.apply(widget::button::custom)
.class(cosmic::theme::Button::Transparent)
.on_press(Message::TimezoneContext);
settings::section()
.title(&section.title)
// Time zone select
.add(
settings::item::builder(&*section.descriptions[time_zone])
.control(timezone_context_button),
)
Message::TimezoneContext,
))
.apply(cosmic::Element::from)
.map(crate::pages::Message::DateAndTime)
})

View file

@ -2,13 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-only
use std::collections::{BTreeMap, BTreeSet};
use std::rc::Rc;
use std::sync::Arc;
use crate::widget::selection_context_item;
use cosmic::app::{ContextDrawer, context_drawer};
use cosmic::iced::core::text::Wrapping;
use cosmic::iced::{Alignment, Length};
use cosmic::widget::{self, button, space::horizontal as horizontal_space};
use cosmic::widget::{self, button, list};
use cosmic::{Apply, Element};
use cosmic_config::{ConfigGet, ConfigSet};
use cosmic_settings_page::Section;
@ -361,14 +360,9 @@ impl Page {
}
fn add_language_view(&self) -> cosmic::Element<'_, crate::pages::Message> {
let mut list = widget::list_column();
let mut list = widget::list_column::with_capacity(self.available_languages.len());
let search_input = &self.add_language_search.trim().to_lowercase();
let svg_accent = Rc::new(|theme: &cosmic::Theme| cosmic::widget::svg::Style {
color: Some(theme.cosmic().accent_text_color().into()),
});
for (id, available_language) in &self.available_languages {
if search_input.is_empty()
|| available_language
@ -381,37 +375,17 @@ impl Page {
.as_ref()
.is_some_and(|(_, locales)| locales.contains(&available_language.lang_code));
let button = widget::settings::item_row(vec![
widget::text::body(&available_language.display_name)
.class(if is_installed {
cosmic::theme::Text::Accent
} else {
cosmic::theme::Text::Default
})
.wrapping(Wrapping::Word)
.width(Length::Fill)
.into(),
if is_installed {
widget::icon::from_name("object-select-symbolic")
.size(16)
.icon()
.class(cosmic::theme::Svg::Custom(svg_accent.clone()))
.into()
} else {
horizontal_space().width(16.).into()
},
])
.apply(widget::container)
.class(cosmic::theme::Container::List)
.apply(widget::button::custom)
.class(cosmic::theme::Button::Transparent)
list = list.add(
list::button(selection_context_item(
&available_language.display_name,
is_installed,
))
.on_press(if is_installed {
Message::RemoveLanguage(id)
} else {
Message::AddLanguage(id)
});
list = list.add(button)
}),
)
}
}
@ -492,12 +466,7 @@ impl Page {
}
fn region_view(&self) -> cosmic::Element<'_, crate::pages::Message> {
let svg_accent = Rc::new(|theme: &cosmic::Theme| {
let color = theme.cosmic().accent_text_color().into();
cosmic::widget::svg::Style { color: Some(color) }
});
let mut list = widget::list_column();
let mut list = widget::list_column::with_capacity(self.available_languages.len());
let search_input = &self.add_language_search.trim().to_lowercase();
@ -509,37 +478,14 @@ impl Page {
.as_ref()
.is_some_and(|l| l.lang_code == locale.lang_code);
let button = widget::settings::item_row(vec![
widget::text::body(&locale.region_name)
.class(if is_selected {
cosmic::theme::Text::Accent
} else {
cosmic::theme::Text::Default
})
.wrapping(Wrapping::Word)
.width(Length::Fill)
.into(),
if is_selected {
widget::icon::from_name("object-select-symbolic")
.size(16)
.icon()
.class(cosmic::theme::Svg::Custom(svg_accent.clone()))
.into()
} else {
horizontal_space().width(16.).into()
},
])
.apply(widget::container)
.class(cosmic::theme::Container::List)
.apply(widget::button::custom)
.class(cosmic::theme::Button::Transparent)
list = list.add(
list::button(selection_context_item(&locale.region_name, is_selected))
.on_press_maybe(if is_selected {
None
} else {
Some(Message::SelectRegion(id))
});
list = list.add(button)
}),
)
}
}

View file

@ -2,14 +2,15 @@
// SPDX-License-Identifier: GPL-3.0-only
use std::borrow::Cow;
use std::rc::Rc;
use cosmic::cosmic_theme::Spacing;
use cosmic::iced::core::text::Wrapping;
use cosmic::iced::{Alignment, Length};
use cosmic::widget::color_picker::ColorPickerUpdate;
use cosmic::widget::{
self, ColorPickerModel, button, column, container, divider, icon, row, settings,
space::{horizontal as horizontal_space, vertical as vertical_space},
self, ColorPickerModel, button, column, container, divider, icon, list, row, settings,
space::{horizontal, vertical},
text,
};
use cosmic::{Apply, Element, theme};
@ -75,7 +76,7 @@ pub fn search_header<Message>(
.into(),
);
column_children.push(vertical_space().height(Length::Fixed(8.)).into());
column_children.push(vertical().height(Length::Fixed(8.)).into());
column_children.push(divider::horizontal::heavy().into());
column::with_children(column_children).into()
@ -89,12 +90,12 @@ pub fn search_page_link<Message: 'static>(title: &str) -> button::TextButton<'_,
pub fn page_title<Message: 'static>(page: &page::Info) -> Element<'_, Message> {
row::with_capacity(2)
.push(text::title3(page.title.as_str()))
.push(horizontal_space())
.push(horizontal())
.into()
}
#[must_use]
pub fn unimplemented_page<Message: 'static>() -> Element<'static, Message> {
pub fn unimplemented_page<Message: Clone + 'static>() -> Element<'static, Message> {
settings::section().title("")
.add(text::body("We haven't created that panel yet, and/or it is using a similar idea as current Pop! designs."))
.into()
@ -184,50 +185,68 @@ pub fn sub_page_header<'a, Message: 'static + Clone>(
.into()
}
pub fn go_next_item<Msg: Clone + 'static>(
pub fn go_next_item<Msg: 'static>(
description: &str,
msg_opt: impl Into<Option<Msg>>,
) -> cosmic::Element<'_, Msg> {
) -> list::ListButton<'_, Msg> {
settings::item_row(vec![
text::body(description).wrapping(Wrapping::Word).into(),
horizontal_space().into(),
text::body(description)
.width(Length::Fill)
.wrapping(Wrapping::Word)
.into(),
icon::from_name("go-next-symbolic").size(16).icon().into(),
])
.width(Length::Fill)
.apply(widget::container)
.class(cosmic::theme::Container::List)
.width(Length::Fill)
.apply(button::custom)
.width(Length::Fill)
.padding(0)
.class(theme::Button::Transparent)
.apply(list::button)
.on_press_maybe(msg_opt.into())
}
pub fn go_next_with_item<'a, Msg: 'static>(
description: &'a str,
item: impl Into<cosmic::Element<'a, Msg>>,
msg_opt: impl Into<Option<Msg>>,
) -> list::ListButton<'_, Msg> {
settings::item_row(vec![
text::body(description).wrapping(Wrapping::Word).into(),
horizontal().into(),
row::with_capacity(2)
.push(item)
.push(icon::from_name("go-next-symbolic").size(16).icon())
.align_y(Alignment::Center)
.spacing(theme::spacing().space_s)
.into(),
])
.apply(list::button)
.on_press_maybe(msg_opt.into())
.into()
}
pub fn go_next_with_item<'a, Msg: Clone + 'static>(
description: &'a str,
item: impl Into<cosmic::Element<'a, Msg>>,
msg_opt: impl Into<Option<Msg>>,
pub fn selection_context_item<'a, Msg: 'static>(
name: &'a str,
selected: bool,
) -> cosmic::Element<'a, Msg> {
let svg_accent = Rc::new(|theme: &cosmic::Theme| widget::svg::Style {
color: Some(theme.cosmic().accent_text_color().into()),
});
settings::item_row(vec![
text::body(description).wrapping(Wrapping::Word).into(),
horizontal_space().into(),
widget::row::with_capacity(2)
.push(item)
.push(icon::from_name("go-next-symbolic").size(16).icon())
.align_y(Alignment::Center)
.spacing(cosmic::theme::spacing().space_s)
text::body(name)
.class(if selected {
theme::Text::Accent
} else {
theme::Text::Default
})
.wrapping(Wrapping::Word)
.width(Length::Fill)
.into(),
if selected {
icon::from_name("object-select-symbolic")
.size(16)
.icon()
.class(theme::Svg::Custom(svg_accent.clone()))
.into()
} else {
horizontal().width(16.).into()
},
])
.width(Length::Fill)
.apply(widget::container)
.class(cosmic::theme::Container::List)
.width(Length::Fill)
.apply(button::custom)
.padding(0)
.width(Length::Fill)
.class(theme::Button::Transparent)
.on_press_maybe(msg_opt.into())
.into()
}

View file

@ -40,7 +40,7 @@ pub struct Section<Message> {
pub search_ignore: bool,
}
impl<Message: 'static> Default for Section<Message> {
impl<Message: Clone + 'static> Default for Section<Message> {
fn default() -> Self {
Self {
title: String::new(),
@ -120,7 +120,7 @@ impl<Message: Clone + 'static> Section<Message> {
#[must_use]
#[inline]
pub fn unimplemented<'a, Message: 'static>(
pub fn unimplemented<'a, Message: Clone + 'static>(
_binder: &'a Binder<Message>,
_page: &'a dyn Page<Message>,
_section: &'a Section<Message>,