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-config = { path = "../libcosmic/cosmic-config" }
# cosmic-theme = { path = "../libcosmic/cosmic-theme" } # cosmic-theme = { path = "../libcosmic/cosmic-theme" }
# iced_futures = { path = "../libcosmic/iced/futures" } # iced_futures = { path = "../libcosmic/iced/futures" }
# # iced_winit = { path = "../libcosmic/iced/winit" }
#iced_futures = { git = "https://github.com/pop-os/libcosmic//" }
# libcosmic = { 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-config = { git = "https://github.com/pop-os/libcosmic//" }
# cosmic-theme = { 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'] # [patch.'https://github.com/pop-os/dbus-settings-bindings']
# cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" } # cosmic-dbus-networkmanager = { path = "../dbus-settings-bindings/networkmanager" }

View file

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

View file

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

View file

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

View file

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

View file

@ -4,7 +4,7 @@ use cosmic::cosmic_config::{Config, ConfigSet};
use cosmic::cosmic_theme::Spacing; use cosmic::cosmic_theme::Spacing;
use cosmic::iced::core::{Color, Length}; use cosmic::iced::core::{Color, Length};
use cosmic::widget::{ 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::{Apply, Task};
use cosmic::{Element, widget}; use cosmic::{Element, widget};

View file

@ -1,18 +1,18 @@
// Copyright 2024 System76 <info@system76.com> // Copyright 2024 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use cosmic::{ use cosmic::{
Apply, Element, Task, Apply, Element, Task,
config::{CosmicTk, FontConfig}, config::{CosmicTk, FontConfig},
iced::core::text::Wrapping, iced::core::text::Wrapping,
widget::{self, settings, space::horizontal as horizontal_space, svg}, widget::{self, settings, svg},
}; };
use cosmic_config::ConfigSet; use cosmic_config::ConfigSet;
use crate::app; use crate::app;
use crate::widget::selection_context_item;
use super::{ContextView, Message, drawer}; use super::{ContextView, Message, drawer};
@ -177,10 +177,6 @@ impl Model {
context_view: &ContextView, context_view: &ContextView,
callback: impl Fn(Arc<str>) -> super::Message, callback: impl Fn(Arc<str>) -> super::Message,
) -> Element<'_, 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 { let (mut families, current_font) = match *context_view {
ContextView::MonospaceFont => { ContextView::MonospaceFont => {
(&self.monospace_font_families, &self.monospace_font.family) (&self.monospace_font_families, &self.monospace_font.family)
@ -193,36 +189,16 @@ impl Model {
families = &self.font_filter; 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; let selected = &**family == current_font;
list.add( list.add(
settings::item_row(vec![ widget::list::button(selection_context_item(&**family, selected))
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)
.on_press(callback(family.clone())), .on_press(callback(family.clone())),
) )
}); },
);
list.into() list.into()
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@ use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet}, cosmic_config::{self, ConfigGet, ConfigSet},
iced::Length, iced::Length,
surface, surface,
widget::{self, radio, settings, text}, widget::{self, settings, text},
}; };
use cosmic_comp_config::workspace::{Action, WorkspaceConfig, WorkspaceLayout, WorkspaceMode}; use cosmic_comp_config::workspace::{Action, WorkspaceConfig, WorkspaceLayout, WorkspaceMode};
use cosmic_settings_page::Section; use cosmic_settings_page::Section;
@ -209,26 +209,16 @@ fn multi_behavior() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions; let descriptions = &section.descriptions;
settings::section() settings::section()
.title(&section.title) .title(&section.title)
.add(settings::item_row(vec![ .add(settings::item::builder(&descriptions[span]).radio(
radio(
text::body(&descriptions[span]),
WorkspaceMode::Global, WorkspaceMode::Global,
Some(page.comp_workspace_config.workspace_mode), Some(page.comp_workspace_config.workspace_mode),
Message::SetWorkspaceMode, Message::SetWorkspaceMode,
) ))
.width(Length::Fill) .add(settings::item::builder(&descriptions[separate]).radio(
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[separate]),
WorkspaceMode::OutputBound, WorkspaceMode::OutputBound,
Some(page.comp_workspace_config.workspace_mode), Some(page.comp_workspace_config.workspace_mode),
Message::SetWorkspaceMode, Message::SetWorkspaceMode,
) ))
.width(Length::Fill)
.into(),
]))
.apply(Element::from) .apply(Element::from)
.map(crate::pages::Message::DesktopWorkspaces) .map(crate::pages::Message::DesktopWorkspaces)
}) })
@ -247,26 +237,16 @@ fn workspace_orientation() -> Section<crate::pages::Message> {
let descriptions = &section.descriptions; let descriptions = &section.descriptions;
settings::section() settings::section()
.title(&section.title) .title(&section.title)
.add(settings::item_row(vec![ .add(settings::item::builder(&descriptions[vertical]).radio(
radio(
text::body(&descriptions[vertical]),
WorkspaceLayout::Vertical, WorkspaceLayout::Vertical,
Some(page.comp_workspace_config.workspace_layout), Some(page.comp_workspace_config.workspace_layout),
Message::SetWorkspaceLayout, Message::SetWorkspaceLayout,
) ))
.width(Length::Fill) .add(settings::item::builder(&descriptions[horizontal]).radio(
.into(),
]))
.add(settings::item_row(vec![
radio(
text::body(&descriptions[horizontal]),
WorkspaceLayout::Horizontal, WorkspaceLayout::Horizontal,
Some(page.comp_workspace_config.workspace_layout), Some(page.comp_workspace_config.workspace_layout),
Message::SetWorkspaceLayout, Message::SetWorkspaceLayout,
) ))
.width(Length::Fill)
.into(),
]))
.apply(Element::from) .apply(Element::from)
.map(crate::pages::Message::DesktopWorkspaces) .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::widget::scrollable::RelativeOffset;
use cosmic::iced::{Alignment, Length, stream, time}; use cosmic::iced::{Alignment, Length, stream, time};
use cosmic::widget::{ 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::{Apply, Element, Task, surface};
use cosmic_randr_shell::{ use cosmic_randr_shell::{
@ -1370,10 +1370,10 @@ pub fn display_configuration() -> Section<crate::pages::Message> {
|| !active_output.enabled || !active_output.enabled
{ {
list_column() list_column()
.add(widget::settings::item( .add(
&descriptions[enable_label], widget::settings::item::builder(&descriptions[enable_label])
toggler(active_output.enabled).on_toggle(Message::DisplayToggle), .toggler(active_output.enabled, Message::DisplayToggle),
)) )
.add(widget::settings::item( .add(widget::settings::item(
&descriptions[mirroring_label], &descriptions[mirroring_label],
widget::dropdown::multi::dropdown( widget::dropdown::multi::dropdown(

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@ use cosmic::{
Apply, Element, Apply, Element,
dialog::file_chooser, dialog::file_chooser,
iced::{Alignment, Length}, 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 cosmic_settings_page::{self as page, Section, section};
use image::GenericImageView; use image::GenericImageView;
@ -322,7 +322,7 @@ impl page::Page<crate::pages::Message> for Page {
))) )))
.width(Length::Fill), .width(Length::Fill),
) )
.push(horizontal_space().width(5.)) .push(horizontal().width(5.))
.push(admin_toggler) .push(admin_toggler)
.align_y(Alignment::Center), .align_y(Alignment::Center),
), ),
@ -785,16 +785,13 @@ fn user_list() -> Section<crate::pages::Message> {
.descriptions(descriptions) .descriptions(descriptions)
.view::<Page>(move |_binder, page, section| { .view::<Page>(move |_binder, page, section| {
let descriptions = &section.descriptions; let descriptions = &section.descriptions;
let space_xxs = cosmic::theme::spacing().space_xxs;
let cosmic::cosmic_theme::Spacing {
space_xxs, space_m, ..
} = cosmic::theme::active().cosmic().spacing;
let users_list = page let users_list = page
.users .users
.iter() .iter()
.enumerate() .enumerate()
.flat_map(|(idx, user)| { .map(|(idx, user)| {
let expanded = let expanded =
matches!(page.selected_user_idx, Some(user_idx) if user_idx == idx); 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] &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 let profile_icon_handle = user
.profile_icon .profile_icon
.clone() .clone()
@ -884,8 +850,8 @@ fn user_list() -> Section<crate::pages::Message> {
) )
.align_y(Alignment::Center) .align_y(Alignment::Center)
.spacing(space_xxs) .spacing(space_xxs)
.width(Length::Fill)
.into(), .into(),
horizontal_space().width(Length::Fill).into(),
icon::from_name(if expanded { icon::from_name(if expanded {
"go-up-symbolic" "go-up-symbolic"
} else { } else {
@ -896,28 +862,49 @@ fn user_list() -> Section<crate::pages::Message> {
.into(), .into(),
]); ]);
let account_details = Some( let mut user_list = widget::list_column().add(
widget::button::custom(account_details_content) list::button(account_details_content)
.padding([space_xxs, space_m])
.on_press(Message::SelectUser(idx))
.class(cosmic::theme::Button::ListItem)
.width(Length::Fill)
.selected(expanded) .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( .fold(
widget::list_column() widget::column::with_capacity(page.users.len()),
.spacing(0) |col, user| col.push(user),
.padding([8, 0])
.divider_padding(0)
.list_item_padding(0),
widget::ListColumn::add,
) )
.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")) let add_user = widget::button::standard(crate::fl!("add-user"))
.on_press(Message::Dialog(Some(Dialog::AddNewUser(User::default())))) .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) widget::column::with_capacity(2)
.push(users_list) .push(users_list)
.push(add_user) .push(add_user)
.spacing(space_m) .spacing(space_xxs)
.apply(Element::from) .apply(Element::from)
.map(crate::pages::Message::User) .map(crate::pages::Message::User)
}) })

View file

@ -1,13 +1,14 @@
// Copyright 2023 System76 <info@system76.com> // Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::widget::selection_context_item;
use cosmic::{ use cosmic::{
Apply, Element, Task, Apply, Element, Task,
app::ContextDrawer, app::ContextDrawer,
cosmic_config::{self, ConfigGet, ConfigSet}, cosmic_config::{self, ConfigGet, ConfigSet},
iced::core::text::Wrapping, iced::core::text::Wrapping,
surface, 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 cosmic_settings_page::{self as page, Section, section};
use icu::{ use icu::{
@ -20,7 +21,6 @@ use icu::{
locale::{Locale, preferences::extensions::unicode::keywords::HourCycle}, locale::{Locale, preferences::extensions::unicode::keywords::HourCycle},
}; };
use slotmap::{Key, SlotMap}; use slotmap::{Key, SlotMap};
use std::rc::Rc;
pub use timedate_zbus::TimeDateProxy; pub use timedate_zbus::TimeDateProxy;
use tracing::error; use tracing::error;
@ -335,7 +335,10 @@ impl Page {
for (id, timezone) in self.timezone_list.iter().enumerate() { for (id, timezone) in self.timezone_list.iter().enumerate() {
if search_input.is_empty() || timezone.to_lowercase().contains(search_input) { 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) .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) { fn update_local_time(&mut self) {
self.local_time = Some(update_local_time()); self.local_time = Some(update_local_time());
@ -498,30 +467,19 @@ fn timezone() -> Section<crate::pages::Message> {
.title(fl!("time-zone")) .title(fl!("time-zone"))
.descriptions(descriptions) .descriptions(descriptions)
.view::<Page>(move |_binder, page, section| { .view::<Page>(move |_binder, page, section| {
let timezone_context_button = widget::row::with_capacity(2) settings::section()
.spacing(12) .title(&section.title)
.push( // Time zone select
.add(crate::widget::go_next_with_item(
&*section.descriptions[time_zone],
widget::text::body( widget::text::body(
page.timezone page.timezone
.map(|id| &*page.timezone_list[id]) .map(|id| &*page.timezone_list[id])
.unwrap_or_default(), .unwrap_or_default(),
) )
.wrapping(Wrapping::Word), .wrapping(Wrapping::Word),
) Message::TimezoneContext,
.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),
)
.apply(cosmic::Element::from) .apply(cosmic::Element::from)
.map(crate::pages::Message::DateAndTime) .map(crate::pages::Message::DateAndTime)
}) })

View file

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

View file

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

View file

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