refactor: use Slab for storing page section descriptions
This commit is contained in:
parent
17a74a512b
commit
f6e50f1d9b
24 changed files with 666 additions and 639 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1366,6 +1366,7 @@ dependencies = [
|
|||
"ron",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"slab",
|
||||
"slotmap",
|
||||
"static_init",
|
||||
"sunrise",
|
||||
|
|
@ -1397,6 +1398,7 @@ dependencies = [
|
|||
"libcosmic",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"slab",
|
||||
"slotmap",
|
||||
"tokio",
|
||||
"url",
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ url = "2.5.0"
|
|||
xkb-data = "0.1.0"
|
||||
zbus = { version = "4.2.1", features = ["tokio"] }
|
||||
tachyonix = "0.2.1"
|
||||
slab = "0.4.9"
|
||||
|
||||
[dependencies.i18n-embed]
|
||||
version = "0.14.1"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ use cosmic_settings_page::Section;
|
|||
use cosmic_settings_page::{self as page, section};
|
||||
use cosmic_settings_wallpaper as wallpaper;
|
||||
use ron::ser::PrettyConfig;
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
|
||||
|
|
@ -40,15 +41,15 @@ const ICON_PREV_ROW: usize = 3;
|
|||
const ICON_TRY_SIZES: [u16; 3] = [32, 48, 64];
|
||||
const ICON_THUMB_SIZE: u16 = 32;
|
||||
const ICON_NAME_TRUNC: usize = 20;
|
||||
type IconThemes = Vec<IconTheme>;
|
||||
type IconHandles = Vec<[icon::Handle; ICON_PREV_N]>;
|
||||
|
||||
pub type IconThemes = Vec<IconTheme>;
|
||||
pub type IconHandles = Vec<[icon::Handle; ICON_PREV_N]>;
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static HEX: String = fl!("hex");
|
||||
static RGB: String = fl!("rgb");
|
||||
static RESET_TO_DEFAULT: String = fl!("reset-to-default");
|
||||
static ICON_THEME: String = fl!("icon-theme");
|
||||
static ICON_THEME_DESC: String = fl!("icon-theme", "desc");
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
|
@ -1134,34 +1135,26 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let auto_switch = descriptions.insert(fl!("auto-switch"));
|
||||
let accent_color = descriptions.insert(fl!("accent-color"));
|
||||
let app_bg = descriptions.insert(fl!("app-background"));
|
||||
let container_bg = descriptions.insert(fl!("container-background"));
|
||||
let container_bg_desc = descriptions.insert(fl!("container-background", "desc"));
|
||||
let text_tint = descriptions.insert(fl!("text-tint"));
|
||||
let text_tint_desc = descriptions.insert(fl!("text-tint", "desc"));
|
||||
let control_tint = descriptions.insert(fl!("control-tint"));
|
||||
let control_tint_desc = descriptions.insert(fl!("control-tint", "desc"));
|
||||
let window_hint_toggle = descriptions.insert(fl!("window-hint-accent-toggle"));
|
||||
let window_hint = descriptions.insert(fl!("window-hint-accent"));
|
||||
let dark = descriptions.insert(fl!("dark"));
|
||||
let light = descriptions.insert(fl!("light"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("mode-and-colors"))
|
||||
.descriptions(vec![
|
||||
// 0
|
||||
fl!("auto-switch").into(),
|
||||
//1
|
||||
fl!("accent-color").into(),
|
||||
//2
|
||||
fl!("app-background").into(),
|
||||
//3
|
||||
fl!("container-background").into(),
|
||||
fl!("container-background", "desc").into(),
|
||||
fl!("container-background", "desc-detail").into(),
|
||||
fl!("container-background", "reset").into(),
|
||||
// 7
|
||||
fl!("text-tint").into(),
|
||||
fl!("text-tint", "desc").into(),
|
||||
// 9
|
||||
fl!("control-tint").into(),
|
||||
fl!("control-tint", "desc").into(),
|
||||
// 11
|
||||
fl!("window-hint-accent-toggle").into(),
|
||||
fl!("window-hint-accent").into(),
|
||||
// 13
|
||||
fl!("dark").into(),
|
||||
fl!("light").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let palette = &page.theme_builder.palette.as_ref();
|
||||
let cur_accent = page
|
||||
|
|
@ -1182,7 +1175,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
.padding([8, 0])
|
||||
.selected(page.theme_mode.is_dark)
|
||||
.on_press(Message::DarkMode(true)),
|
||||
text(&*descriptions[13])
|
||||
text(&descriptions[dark])
|
||||
]
|
||||
.spacing(8)
|
||||
.width(Length::FillPortion(1))
|
||||
|
|
@ -1197,7 +1190,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
.selected(!page.theme_mode.is_dark)
|
||||
.padding([8, 0])
|
||||
.on_press(Message::DarkMode(false)),
|
||||
text(&*descriptions[14])
|
||||
text(&descriptions[light])
|
||||
]
|
||||
.spacing(8)
|
||||
.width(Length::FillPortion(1))
|
||||
|
|
@ -1211,7 +1204,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
.align_x(cosmic::iced_core::alignment::Horizontal::Center),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[0])
|
||||
settings::item::builder(&descriptions[auto_switch])
|
||||
.description(
|
||||
if !page.day_time && page.theme_mode.is_dark {
|
||||
&page.auto_switch_descs[0]
|
||||
|
|
@ -1228,7 +1221,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
)
|
||||
.add(
|
||||
cosmic::iced::widget::column![
|
||||
text(&*descriptions[1]),
|
||||
text(&descriptions[accent_color]),
|
||||
scrollable(
|
||||
cosmic::iced::widget::row![
|
||||
color_button(
|
||||
|
|
@ -1324,7 +1317,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
.spacing(8),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[2]).control(
|
||||
settings::item::builder(&descriptions[app_bg]).control(
|
||||
page.application_background
|
||||
.picker_button(Message::ApplicationBackground, Some(24))
|
||||
.width(Length::Fixed(48.0))
|
||||
|
|
@ -1332,8 +1325,8 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[3])
|
||||
.description(&*descriptions[4])
|
||||
settings::item::builder(&descriptions[container_bg])
|
||||
.description(&descriptions[container_bg_desc])
|
||||
.control(if page.container_background.get_applied_color().is_some() {
|
||||
Element::from(
|
||||
page.container_background
|
||||
|
|
@ -1353,8 +1346,8 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
}),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[7])
|
||||
.description(&*descriptions[8])
|
||||
settings::item::builder(&descriptions[text_tint])
|
||||
.description(&descriptions[text_tint_desc])
|
||||
.control(
|
||||
page.interface_text
|
||||
.picker_button(Message::InterfaceText, Some(24))
|
||||
|
|
@ -1363,8 +1356,8 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[9])
|
||||
.description(&*descriptions[10])
|
||||
settings::item::builder(&descriptions[control_tint])
|
||||
.description(&descriptions[control_tint_desc])
|
||||
.control(
|
||||
page.control_component
|
||||
.picker_button(Message::ControlComponent, Some(24))
|
||||
|
|
@ -1373,12 +1366,12 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[11])
|
||||
settings::item::builder(&descriptions[window_hint_toggle])
|
||||
.toggler(page.no_custom_window_hint, Message::UseDefaultWindowHint),
|
||||
);
|
||||
if !page.no_custom_window_hint {
|
||||
section = section.add(
|
||||
settings::item::builder(&*descriptions[12]).control(
|
||||
settings::item::builder(&descriptions[window_hint]).control(
|
||||
page.accent_window_hint
|
||||
.picker_button(Message::AccentWindowHint, Some(24))
|
||||
.width(Length::Fixed(48.0))
|
||||
|
|
@ -1394,14 +1387,16 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn style() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let round = descriptions.insert(fl!("style", "round"));
|
||||
let slightly_round = descriptions.insert(fl!("style", "slightly-round"));
|
||||
let square = descriptions.insert(fl!("style", "square"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("style"))
|
||||
.descriptions(vec![
|
||||
fl!("style", "round").into(),
|
||||
fl!("style", "slightly-round").into(),
|
||||
fl!("style", "square").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
|
|
@ -1425,7 +1420,7 @@ pub fn style() -> Section<crate::pages::Message> {
|
|||
.style(button::Style::Image)
|
||||
.padding(8)
|
||||
.on_press(Message::Roundness(Roundness::Round)),
|
||||
text(&*descriptions[0])
|
||||
text(&descriptions[round])
|
||||
]
|
||||
.spacing(8)
|
||||
.width(Length::FillPortion(1))
|
||||
|
|
@ -1447,7 +1442,7 @@ pub fn style() -> Section<crate::pages::Message> {
|
|||
.style(button::Style::Image)
|
||||
.padding(8)
|
||||
.on_press(Message::Roundness(Roundness::SlightlyRound)),
|
||||
text(&*descriptions[1])
|
||||
text(&descriptions[slightly_round])
|
||||
]
|
||||
.spacing(8)
|
||||
.width(Length::FillPortion(1))
|
||||
|
|
@ -1470,7 +1465,7 @@ pub fn style() -> Section<crate::pages::Message> {
|
|||
.style(button::Style::Image)
|
||||
.padding(8)
|
||||
.on_press(Message::Roundness(Roundness::Square)),
|
||||
text(&*descriptions[2])
|
||||
text(&descriptions[square])
|
||||
]
|
||||
.spacing(8)
|
||||
.align_items(cosmic::iced_core::Alignment::Center)
|
||||
|
|
@ -1490,23 +1485,25 @@ pub fn style() -> Section<crate::pages::Message> {
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn window_management() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let active_hint = descriptions.insert(fl!("window-management", "active-hint"));
|
||||
let gaps = descriptions.insert(fl!("window-management", "gaps"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("window-management"))
|
||||
.descriptions(vec![
|
||||
fl!("window-management", "active-hint").into(),
|
||||
fl!("window-management", "gaps").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item::builder(&*descriptions[0]).control(
|
||||
.add(settings::item::builder(&descriptions[active_hint]).control(
|
||||
cosmic::widget::spin_button(
|
||||
page.theme_builder.active_hint.to_string(),
|
||||
Message::WindowHintSize,
|
||||
),
|
||||
))
|
||||
.add(settings::item::builder(&*descriptions[1]).control(
|
||||
.add(settings::item::builder(&descriptions[gaps]).control(
|
||||
cosmic::widget::spin_button(
|
||||
page.theme_builder.gaps.1.to_string(),
|
||||
Message::GapSize,
|
||||
|
|
@ -1518,10 +1515,14 @@ pub fn window_management() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
pub fn experimental() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let experimental_label = descriptions.insert(fl!("experimental-settings"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![fl!("experimental-settings").into()])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
let descriptions = &*section.descriptions;
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
let control = row::with_children(vec![
|
||||
horizontal_space(Length::Fill).into(),
|
||||
|
|
@ -1530,7 +1531,7 @@ pub fn experimental() -> Section<crate::pages::Message> {
|
|||
|
||||
settings::view_section("")
|
||||
.add(
|
||||
settings::item::builder(&*descriptions[0])
|
||||
settings::item::builder(&descriptions[experimental_label])
|
||||
.control(control)
|
||||
.apply(container)
|
||||
.style(cosmic::theme::Container::List)
|
||||
|
|
@ -1545,12 +1546,16 @@ pub fn experimental() -> Section<crate::pages::Message> {
|
|||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn reset_button() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let reset_to_default = descriptions.insert(fl!("reset-to-default"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![fl!("reset-to-default").into()])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
if page.can_reset {
|
||||
button::standard(&*descriptions[0])
|
||||
button::standard(&descriptions[reset_to_default])
|
||||
.on_press(Message::Reset)
|
||||
.into()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use cosmic::{
|
|||
cosmic_config::CosmicConfigEntry,
|
||||
iced::{alignment, Length},
|
||||
iced_runtime::Command,
|
||||
widget::{button, container, row, text},
|
||||
widget::{button, container, row},
|
||||
Apply, Element,
|
||||
};
|
||||
use cosmic_panel_config::CosmicPanelConfig;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use cosmic::{
|
|||
};
|
||||
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
use tracing::error;
|
||||
|
||||
|
|
@ -142,16 +143,20 @@ impl Default for Page {
|
|||
}
|
||||
|
||||
pub(crate) fn enable() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let dock = descriptions.insert(fl!("dock"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![fl!("dock").into()])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let Some(container_config) = page.inner.container_config.as_ref() else {
|
||||
return Element::from(text(fl!("unknown")));
|
||||
};
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[0],
|
||||
&descriptions[dock],
|
||||
toggler(
|
||||
None,
|
||||
container_config
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use cosmic::{
|
|||
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -44,27 +45,29 @@ impl page::AutoBind<crate::pages::Message> for Page {
|
|||
}
|
||||
|
||||
pub fn super_key_action() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let launcher = descriptions.insert(fl!("super-key-action", "launcher"));
|
||||
let workspaces = descriptions.insert(fl!("super-key-action", "workspaces"));
|
||||
let applications = descriptions.insert(fl!("super-key-action", "applications"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("super-key-action"))
|
||||
.descriptions(vec![
|
||||
fl!("super-key-action", "launcher").into(),
|
||||
fl!("super-key-action", "workspaces").into(),
|
||||
fl!("super-key-action", "applications").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item(
|
||||
&*descriptions[0],
|
||||
&descriptions[launcher],
|
||||
horizontal_space(Length::Fill),
|
||||
))
|
||||
.add(settings::item(
|
||||
&*descriptions[1],
|
||||
&descriptions[workspaces],
|
||||
horizontal_space(Length::Fill),
|
||||
))
|
||||
.add(settings::item(
|
||||
&*descriptions[2],
|
||||
&descriptions[applications],
|
||||
horizontal_space(Length::Fill),
|
||||
))
|
||||
.into()
|
||||
|
|
@ -72,13 +75,15 @@ pub fn super_key_action() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
pub fn window_controls() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let minimize = descriptions.insert(fl!("window-controls", "minimize"));
|
||||
let maximize = descriptions.insert(fl!("window-controls", "maximize"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("window-controls"))
|
||||
.descriptions(vec![
|
||||
fl!("window-controls", "minimize").into(),
|
||||
fl!("window-controls", "maximize").into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let desktop = binder
|
||||
.page::<super::Page>()
|
||||
.expect("desktop page not found");
|
||||
|
|
@ -86,7 +91,7 @@ pub fn window_controls() -> Section<crate::pages::Message> {
|
|||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[0],
|
||||
&descriptions[minimize],
|
||||
toggler(
|
||||
None,
|
||||
desktop.cosmic_tk.show_minimize,
|
||||
|
|
@ -94,7 +99,7 @@ pub fn window_controls() -> Section<crate::pages::Message> {
|
|||
),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[1],
|
||||
&descriptions[maximize],
|
||||
toggler(
|
||||
None,
|
||||
desktop.cosmic_tk.show_maximize,
|
||||
|
|
@ -109,7 +114,7 @@ pub fn window_controls() -> Section<crate::pages::Message> {
|
|||
pub fn panel_dock_links() -> Section<crate::pages::Message> {
|
||||
Section::default()
|
||||
.title(fl!("desktop-panels-and-applets"))
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
// TODO probably a way of getting the entity and its info
|
||||
let mut settings = settings::view_section(§ion.title);
|
||||
settings = if let Some((panel_entity, panel_info)) =
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use cosmic_panel_config::{
|
|||
CosmicPanelOuput, PanelAnchor, PanelSize,
|
||||
};
|
||||
use cosmic_settings_page::{self as page, Section};
|
||||
use slab::Slab;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct PageInner {
|
||||
|
|
@ -93,13 +94,15 @@ pub(crate) fn behavior_and_position<
|
|||
p: &P,
|
||||
msg_map: T,
|
||||
) -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let autohide_label = descriptions.insert(p.autohide_label());
|
||||
let position = descriptions.insert(fl!("panel-behavior-and-position", "position"));
|
||||
let display = descriptions.insert(fl!("panel-behavior-and-position", "display"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("panel-behavior-and-position"))
|
||||
.descriptions(vec![
|
||||
p.autohide_label().into(),
|
||||
fl!("panel-behavior-and-position", "position").into(),
|
||||
fl!("panel-behavior-and-position", "display").into(),
|
||||
])
|
||||
.descriptions(descriptions)
|
||||
.view::<P>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let page = page.inner();
|
||||
|
|
@ -108,13 +111,13 @@ pub(crate) fn behavior_and_position<
|
|||
};
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[0],
|
||||
&descriptions[autohide_label],
|
||||
toggler(None, panel_config.autohide.is_some(), |value| {
|
||||
Message::AutoHidePanel(value)
|
||||
}),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[1],
|
||||
&descriptions[position],
|
||||
dropdown(
|
||||
page.anchors.as_slice(),
|
||||
Some(panel_config.anchor as usize),
|
||||
|
|
@ -122,7 +125,7 @@ pub(crate) fn behavior_and_position<
|
|||
),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[2],
|
||||
&descriptions[display],
|
||||
dropdown(
|
||||
page.outputs.as_slice(),
|
||||
match &panel_config.output {
|
||||
|
|
@ -145,15 +148,17 @@ pub(crate) fn style<
|
|||
p: &P,
|
||||
msg_map: T,
|
||||
) -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let gap_label = descriptions.insert(p.gap_label());
|
||||
let extend_label = descriptions.insert(p.extend_label());
|
||||
let appearance = descriptions.insert(fl!("panel-style", "appearance"));
|
||||
let background_opacity = descriptions.insert(fl!("panel-style", "background-opacity"));
|
||||
let size = descriptions.insert(fl!("panel-style", "size"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("panel-style"))
|
||||
.descriptions(vec![
|
||||
p.gap_label().into(),
|
||||
p.extend_label().into(),
|
||||
fl!("panel-style", "appearance").into(),
|
||||
fl!("panel-style", "size").into(),
|
||||
fl!("panel-style", "background-opacity").into(),
|
||||
])
|
||||
.descriptions(descriptions)
|
||||
.view::<P>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let inner = page.inner();
|
||||
|
|
@ -162,19 +167,19 @@ pub(crate) fn style<
|
|||
};
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[0],
|
||||
&descriptions[gap_label],
|
||||
toggler(None, panel_config.anchor_gap, |value| {
|
||||
Message::AnchorGap(value)
|
||||
}),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[1],
|
||||
&descriptions[extend_label],
|
||||
toggler(None, panel_config.expand_to_edges, |value| {
|
||||
Message::ExtendToEdge(value)
|
||||
}),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[2],
|
||||
&descriptions[appearance],
|
||||
dropdown(
|
||||
inner.backgrounds.as_slice(),
|
||||
match panel_config.background {
|
||||
|
|
@ -187,7 +192,7 @@ pub(crate) fn style<
|
|||
),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[3],
|
||||
&descriptions[size],
|
||||
// TODO custom discrete slider variant
|
||||
row::with_children(vec![
|
||||
text(fl!("small")).into(),
|
||||
|
|
@ -220,7 +225,7 @@ pub(crate) fn style<
|
|||
.spacing(12),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*descriptions[4],
|
||||
&descriptions[background_opacity],
|
||||
row::with_children(vec![
|
||||
text(fl!("number", HashMap::from_iter(vec![("number", 0)]))).into(),
|
||||
slider(0..=100, (panel_config.opacity * 100.0) as i32, |v| {
|
||||
|
|
@ -240,9 +245,13 @@ pub(crate) fn style<
|
|||
pub(crate) fn configuration<P: page::Page<crate::pages::Message> + PanelPage>(
|
||||
p: &P,
|
||||
) -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let applets_label = descriptions.insert(p.configure_applets_label());
|
||||
|
||||
Section::default()
|
||||
.title(fl!("panel-applets"))
|
||||
.descriptions(vec![p.configure_applets_label().into()])
|
||||
.descriptions(descriptions)
|
||||
.view::<P>(move |binder, page, section| {
|
||||
let mut settings = settings::view_section(§ion.title);
|
||||
let descriptions = §ion.descriptions;
|
||||
|
|
@ -257,7 +266,7 @@ pub(crate) fn configuration<P: page::Page<crate::pages::Message> + PanelPage>(
|
|||
]);
|
||||
|
||||
settings.add(
|
||||
settings::item::builder(&*descriptions[0])
|
||||
settings::item::builder(&*descriptions[applets_label])
|
||||
.control(control)
|
||||
.spacing(16)
|
||||
.apply(container)
|
||||
|
|
@ -281,12 +290,16 @@ pub(crate) fn add_panel<
|
|||
>(
|
||||
msg_map: T,
|
||||
) -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let reset_to_default = descriptions.insert(fl!("reset-to-default"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("panel-missing"))
|
||||
.descriptions(vec![fl!("reset-to-default").into()])
|
||||
.descriptions(descriptions)
|
||||
.view::<P>(move |_binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
button::standard(&*descriptions[0])
|
||||
button::standard(&descriptions[reset_to_default])
|
||||
.on_press(Message::FullReset)
|
||||
.apply(Element::from)
|
||||
.map(msg_map)
|
||||
|
|
@ -300,15 +313,19 @@ pub fn reset_button<
|
|||
>(
|
||||
msg_map: T,
|
||||
) -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let reset_to_default = descriptions.insert(fl!("reset-to-default"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![fl!("reset-to-default").into()])
|
||||
.descriptions(descriptions)
|
||||
.view::<P>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let inner = page.inner();
|
||||
if inner.system_default == inner.panel_config {
|
||||
Element::from(horizontal_space(1))
|
||||
} else {
|
||||
button::standard(&*descriptions[0])
|
||||
button::standard(&descriptions[reset_to_default])
|
||||
.on_press(Message::ResetPanel)
|
||||
.into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use cosmic::{app, command, Apply, Command};
|
||||
use cosmic::{command, Apply, Command};
|
||||
use cosmic::{
|
||||
dialog::file_chooser,
|
||||
widget::{
|
||||
|
|
@ -46,6 +46,7 @@ use cosmic_settings_page::{self as page, section};
|
|||
use cosmic_settings_wallpaper::{self as wallpaper, Entry, ScalingMode};
|
||||
use image::imageops::FilterType::Lanczos3;
|
||||
use image::{ImageBuffer, Rgba};
|
||||
use slab::Slab;
|
||||
use slotmap::{DefaultKey, SecondaryMap, SlotMap};
|
||||
|
||||
const ZOOM: usize = 0;
|
||||
|
|
@ -1145,23 +1146,19 @@ pub async fn change_folder(current_folder: PathBuf, recurse: bool) -> Context {
|
|||
update
|
||||
}
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static WALLPAPER_SAME: String = fl!("wallpaper", "same");
|
||||
static WALLPAPER_FIT: String = fl!("wallpaper", "fit");
|
||||
static WALLPAPER_SLIDE: String = fl!("wallpaper", "slide");
|
||||
static WALLPAPER_CHANGE: String = fl!("wallpaper", "change");
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn settings() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let same_label = descriptions.insert(fl!("wallpaper", "same"));
|
||||
let fit_label = descriptions.insert(fl!("wallpaper", "fit"));
|
||||
let slide_label = descriptions.insert(fl!("wallpaper", "slide"));
|
||||
let change_label = descriptions.insert(fl!("wallpaper", "change"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![
|
||||
WALLPAPER_SAME.as_str().into(),
|
||||
WALLPAPER_FIT.as_str().into(),
|
||||
WALLPAPER_SLIDE.as_str().into(),
|
||||
WALLPAPER_CHANGE.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, _section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let mut children = Vec::with_capacity(3);
|
||||
|
||||
let mut show_slideshow_toggle = true;
|
||||
|
|
@ -1227,18 +1224,18 @@ pub fn settings() -> Section<crate::pages::Message> {
|
|||
children.push({
|
||||
let mut column = list_column()
|
||||
.add(settings::flex_item(
|
||||
&*WALLPAPER_SAME,
|
||||
&descriptions[same_label],
|
||||
toggler(
|
||||
None,
|
||||
page.wallpaper_service_config.same_on_all,
|
||||
Message::SameWallpaper,
|
||||
),
|
||||
))
|
||||
.add(settings::flex_item(&*WALLPAPER_FIT, wallpaper_fit));
|
||||
.add(settings::flex_item(&descriptions[fit_label], wallpaper_fit));
|
||||
|
||||
if show_slideshow_toggle {
|
||||
column = column.add(settings::flex_item(
|
||||
&*WALLPAPER_SLIDE,
|
||||
&descriptions[slide_label],
|
||||
toggler(None, slideshow_enabled, Message::Slideshow),
|
||||
));
|
||||
}
|
||||
|
|
@ -1247,7 +1244,7 @@ pub fn settings() -> Section<crate::pages::Message> {
|
|||
if slideshow_enabled {
|
||||
column
|
||||
.add(settings::flex_item(
|
||||
&*WALLPAPER_CHANGE,
|
||||
&descriptions[change_label],
|
||||
dropdown(
|
||||
&page.rotation_options,
|
||||
Some(page.selected_rotation),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use cosmic::{
|
|||
use cosmic_comp_config::workspace::{WorkspaceConfig, WorkspaceLayout, WorkspaceMode};
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
use tracing::error;
|
||||
|
||||
|
|
@ -114,24 +115,26 @@ impl Page {
|
|||
}
|
||||
|
||||
fn multi_behavior() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let span = descriptions.insert(fl!("workspaces-multi-behavior", "span"));
|
||||
let separate = descriptions.insert(fl!("workspaces-multi-behavior", "separate"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("workspaces-multi-behavior"))
|
||||
.descriptions(vec![
|
||||
fl!("workspaces-multi-behavior", "span").into(),
|
||||
fl!("workspaces-multi-behavior", "separate").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item_row(vec![radio(
|
||||
&*descriptions[0],
|
||||
&descriptions[span],
|
||||
WorkspaceMode::Global,
|
||||
Some(page.comp_workspace_config.workspace_mode),
|
||||
Message::SetWorkspaceMode,
|
||||
)
|
||||
.into()]))
|
||||
.add(settings::item_row(vec![radio(
|
||||
&*descriptions[1],
|
||||
&descriptions[separate],
|
||||
WorkspaceMode::OutputBound,
|
||||
Some(page.comp_workspace_config.workspace_mode),
|
||||
Message::SetWorkspaceMode,
|
||||
|
|
@ -143,24 +146,26 @@ fn multi_behavior() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn workspace_orientation() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let vertical = descriptions.insert(fl!("workspaces-orientation", "vertical"));
|
||||
let horizontal = descriptions.insert(fl!("workspaces-orientation", "horizontal"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("workspaces-orientation"))
|
||||
.descriptions(vec![
|
||||
fl!("workspaces-orientation", "vertical").into(),
|
||||
fl!("workspaces-orientation", "horizontal").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item_row(vec![radio(
|
||||
&*descriptions[0],
|
||||
&*descriptions[vertical],
|
||||
WorkspaceLayout::Vertical,
|
||||
Some(page.comp_workspace_config.workspace_layout),
|
||||
Message::SetWorkspaceLayout,
|
||||
)
|
||||
.into()]))
|
||||
.add(settings::item_row(vec![radio(
|
||||
&*descriptions[1],
|
||||
&*descriptions[horizontal],
|
||||
WorkspaceLayout::Horizontal,
|
||||
Some(page.comp_workspace_config.workspace_layout),
|
||||
Message::SetWorkspaceLayout,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
pub mod arrangement;
|
||||
// pub mod night_light;
|
||||
pub mod text;
|
||||
|
||||
use crate::{app, pages};
|
||||
use arrangement::Arrangement;
|
||||
|
|
@ -16,6 +15,7 @@ use cosmic::widget::{
|
|||
use cosmic::{command, Apply, Command, Element};
|
||||
use cosmic_randr_shell::{List, Output, OutputKey, Transform};
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use slab::Slab;
|
||||
use slotmap::{Key, SlotMap};
|
||||
use std::collections::BTreeMap;
|
||||
use std::{process::ExitStatus, sync::Arc};
|
||||
|
|
@ -145,7 +145,7 @@ struct Config {
|
|||
#[derive(Default)]
|
||||
struct ViewCache {
|
||||
modes: BTreeMap<(u32, u32), Vec<u32>>,
|
||||
orientations: [&'static str; 4],
|
||||
orientations: [String; 4],
|
||||
refresh_rates: Vec<String>,
|
||||
resolutions: Vec<String>,
|
||||
orientation_selected: Option<usize>,
|
||||
|
|
@ -170,33 +170,12 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
// text::NIGHT_LIGHT_AUTO.as_str().into(),
|
||||
// text::NIGHT_LIGHT_DESCRIPTION.as_str().into(),
|
||||
// ])
|
||||
// .view::<Page>(|_binder, page, _section| page.night_light_view()),
|
||||
// .view::<Page>(move |_binder, page, _section| page.night_light_view()),
|
||||
// ),
|
||||
// Display arrangement
|
||||
sections.insert(
|
||||
Section::default()
|
||||
.title(&*text::DISPLAY_ARRANGEMENT)
|
||||
.descriptions(vec![
|
||||
text::DISPLAY_ARRANGEMENT.as_str().into(),
|
||||
text::DISPLAY_ARRANGEMENT_DESC.as_str().into(),
|
||||
])
|
||||
// Show section when there is more than 1 display
|
||||
.show_while::<Page>(|page| page.list.outputs.len() > 1)
|
||||
.view::<Page>(|_binder, page, _section| page.display_arrangement_view()),
|
||||
),
|
||||
sections.insert(display_arrangement()),
|
||||
// Display configuration
|
||||
sections.insert(
|
||||
Section::default()
|
||||
.descriptions([
|
||||
text::DISPLAY.as_str().into(),
|
||||
text::DISPLAY_REFRESH_RATE.as_str().into(),
|
||||
text::DISPLAY_SCALE.as_str().into(),
|
||||
text::ORIENTATION.as_str().into(),
|
||||
text::ORIENTATION_STANDARD.as_str().into(),
|
||||
text::ORIENTATION_ROTATE_90.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, _section| page.display_view()),
|
||||
),
|
||||
sections.insert(display_configuration()),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
@ -368,10 +347,10 @@ impl Page {
|
|||
}
|
||||
|
||||
self.cache.orientations = [
|
||||
text::ORIENTATION_STANDARD.as_str(),
|
||||
text::ORIENTATION_ROTATE_90.as_str(),
|
||||
text::ORIENTATION_ROTATE_180.as_str(),
|
||||
text::ORIENTATION_ROTATE_270.as_str(),
|
||||
fl!("orientation", "standard"),
|
||||
fl!("orientation", "rotate-90"),
|
||||
fl!("orientation", "rotate-180"),
|
||||
fl!("orientation", "rotate-270"),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -382,119 +361,6 @@ impl Page {
|
|||
)
|
||||
}
|
||||
|
||||
/// View for the display arrangement section.
|
||||
pub fn display_arrangement_view(&self) -> Element<pages::Message> {
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
column()
|
||||
.padding(cosmic::iced::Padding::from([
|
||||
theme.cosmic().space_s(),
|
||||
theme.cosmic().space_m(),
|
||||
]))
|
||||
.spacing(theme.cosmic().space_xs())
|
||||
.push(cosmic::widget::text::body(&*text::DISPLAY_ARRANGEMENT_DESC))
|
||||
.push({
|
||||
Arrangement::new(&self.list, &self.display_tabs)
|
||||
.on_select(|id| pages::Message::Displays(Message::Display(id)))
|
||||
.on_placement(|id, x, y| pages::Message::Displays(Message::Position(id, x, y)))
|
||||
.apply(cosmic::widget::scrollable)
|
||||
.id(self.display_arrangement_scrollable.clone())
|
||||
.width(Length::Shrink)
|
||||
.direction(Direction::Horizontal(Properties::new()))
|
||||
.apply(container)
|
||||
.center_x()
|
||||
.width(Length::Fill)
|
||||
})
|
||||
.apply(cosmic::widget::list::container)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// View for the display configuration section.
|
||||
pub fn display_view(&self) -> Element<pages::Message> {
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
let Some(&active_id) = self.display_tabs.active_data::<OutputKey>() else {
|
||||
return column().into();
|
||||
};
|
||||
|
||||
let active_output = &self.list.outputs[active_id];
|
||||
|
||||
let display_options = active_output.enabled.then(|| {
|
||||
list_column()
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&*text::DISPLAY_RESOLUTION,
|
||||
dropdown(
|
||||
&self.cache.resolutions,
|
||||
self.cache.resolution_selected,
|
||||
Message::Resolution,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&*text::DISPLAY_REFRESH_RATE,
|
||||
dropdown(
|
||||
&self.cache.refresh_rates,
|
||||
self.cache.refresh_rate_selected,
|
||||
Message::RefreshRate,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&*text::DISPLAY_SCALE,
|
||||
dropdown(
|
||||
&["50%", "75%", "100%", "125%", "150%", "175%", "200%"],
|
||||
self.cache.scale_selected,
|
||||
Message::Scale,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&*text::ORIENTATION,
|
||||
dropdown(
|
||||
&self.cache.orientations,
|
||||
self.cache.orientation_selected,
|
||||
|id| {
|
||||
Message::Orientation(match id {
|
||||
0 => Transform::Normal,
|
||||
1 => Transform::Rotate90,
|
||||
2 => Transform::Rotate180,
|
||||
_ => Transform::Rotate270,
|
||||
})
|
||||
},
|
||||
),
|
||||
))
|
||||
});
|
||||
|
||||
let mut content = column().spacing(theme.cosmic().space_m());
|
||||
|
||||
if self.list.outputs.len() > 1 {
|
||||
let display_switcher = tab_bar::horizontal(&self.display_tabs)
|
||||
.button_alignment(Alignment::Center)
|
||||
.on_activate(Message::Display);
|
||||
|
||||
let display_enable = (self
|
||||
// Don't allow disabling display if it's the only active
|
||||
.list
|
||||
.outputs
|
||||
.values()
|
||||
.filter(|display| display.enabled)
|
||||
.count()
|
||||
> 1
|
||||
|| !active_output.enabled)
|
||||
.then(|| {
|
||||
list_column().add(cosmic::widget::settings::flex_item(
|
||||
&*text::DISPLAY_ENABLE,
|
||||
toggler(None, active_output.enabled, Message::DisplayToggle),
|
||||
))
|
||||
});
|
||||
|
||||
content = content.push(display_switcher).push_maybe(display_enable);
|
||||
}
|
||||
|
||||
content
|
||||
.push(cosmic::widget::text::heading(&*text::DISPLAY_OPTIONS))
|
||||
.push_maybe(display_options)
|
||||
.apply(Element::from)
|
||||
.map(pages::Message::Displays)
|
||||
}
|
||||
|
||||
/// Displays the night light context drawer.
|
||||
// pub fn night_light_context_view(&self) -> Element<pages::Message> {
|
||||
// column().into()
|
||||
|
|
@ -519,7 +385,7 @@ impl Page {
|
|||
.map(|(key, output)| (&*output.name, key))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
for (pos, (name, id)) in sorted_outputs.into_iter().enumerate() {
|
||||
for (pos, (_name, id)) in sorted_outputs.into_iter().enumerate() {
|
||||
let Some(output) = self.list.outputs.get(id) else {
|
||||
continue;
|
||||
};
|
||||
|
|
@ -824,6 +690,151 @@ impl Page {
|
|||
}
|
||||
}
|
||||
|
||||
/// View for the display arrangement section.
|
||||
pub fn display_arrangement() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
_ = descriptions.insert(fl!("display", "arrangement"));
|
||||
let display_arrangement_desc = descriptions.insert(fl!("display", "arrangement-desc"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("display", "arrangement"))
|
||||
.descriptions(descriptions)
|
||||
// Show section when there is more than 1 display
|
||||
.show_while::<Page>(|page| page.list.outputs.len() > 1)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
column()
|
||||
.padding(cosmic::iced::Padding::from([
|
||||
theme.cosmic().space_s(),
|
||||
theme.cosmic().space_m(),
|
||||
]))
|
||||
.spacing(theme.cosmic().space_xs())
|
||||
.push(cosmic::widget::text::body(
|
||||
&descriptions[display_arrangement_desc],
|
||||
))
|
||||
.push({
|
||||
Arrangement::new(&page.list, &page.display_tabs)
|
||||
.on_select(|id| pages::Message::Displays(Message::Display(id)))
|
||||
.on_placement(|id, x, y| {
|
||||
pages::Message::Displays(Message::Position(id, x, y))
|
||||
})
|
||||
.apply(cosmic::widget::scrollable)
|
||||
.id(page.display_arrangement_scrollable.clone())
|
||||
.width(Length::Shrink)
|
||||
.direction(Direction::Horizontal(Properties::new()))
|
||||
.apply(container)
|
||||
.center_x()
|
||||
.width(Length::Fill)
|
||||
})
|
||||
.apply(cosmic::widget::list::container)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
/// View for the display configuration section.
|
||||
pub fn display_configuration() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let _display = descriptions.insert(fl!("display"));
|
||||
let refresh_rate = descriptions.insert(fl!("display", "refresh-rate"));
|
||||
let resolution = descriptions.insert(fl!("display", "resolution"));
|
||||
let scale = descriptions.insert(fl!("display", "scale"));
|
||||
let orientation = descriptions.insert(fl!("orientation"));
|
||||
let enable_label = descriptions.insert(fl!("display", "enable"));
|
||||
let options_label = descriptions.insert(fl!("display", "options"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
let Some(&active_id) = page.display_tabs.active_data::<OutputKey>() else {
|
||||
return column().into();
|
||||
};
|
||||
|
||||
let active_output = &page.list.outputs[active_id];
|
||||
|
||||
let display_options = active_output.enabled.then(|| {
|
||||
list_column()
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&descriptions[resolution],
|
||||
dropdown(
|
||||
&page.cache.resolutions,
|
||||
page.cache.resolution_selected,
|
||||
Message::Resolution,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&descriptions[refresh_rate],
|
||||
dropdown(
|
||||
&page.cache.refresh_rates,
|
||||
page.cache.refresh_rate_selected,
|
||||
Message::RefreshRate,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&descriptions[scale],
|
||||
dropdown(
|
||||
&["50%", "75%", "100%", "125%", "150%", "175%", "200%"],
|
||||
page.cache.scale_selected,
|
||||
Message::Scale,
|
||||
),
|
||||
))
|
||||
.add(cosmic::widget::settings::flex_item(
|
||||
&descriptions[orientation],
|
||||
dropdown(
|
||||
&page.cache.orientations,
|
||||
page.cache.orientation_selected,
|
||||
|id| {
|
||||
Message::Orientation(match id {
|
||||
0 => Transform::Normal,
|
||||
1 => Transform::Rotate90,
|
||||
2 => Transform::Rotate180,
|
||||
_ => Transform::Rotate270,
|
||||
})
|
||||
},
|
||||
),
|
||||
))
|
||||
});
|
||||
|
||||
let mut content = column().spacing(theme.cosmic().space_m());
|
||||
|
||||
if page.list.outputs.len() > 1 {
|
||||
let display_switcher = tab_bar::horizontal(&page.display_tabs)
|
||||
.button_alignment(Alignment::Center)
|
||||
.on_activate(Message::Display);
|
||||
|
||||
let display_enable = (page
|
||||
// Don't allow disabling display if it's the only active
|
||||
.list
|
||||
.outputs
|
||||
.values()
|
||||
.filter(|display| display.enabled)
|
||||
.count()
|
||||
> 1
|
||||
|| !active_output.enabled)
|
||||
.then(|| {
|
||||
list_column().add(cosmic::widget::settings::flex_item(
|
||||
&descriptions[enable_label],
|
||||
toggler(None, active_output.enabled, Message::DisplayToggle),
|
||||
))
|
||||
});
|
||||
|
||||
content = content.push(display_switcher).push_maybe(display_enable);
|
||||
}
|
||||
|
||||
content
|
||||
.push(cosmic::widget::text::heading(&descriptions[options_label]))
|
||||
.push_maybe(display_options)
|
||||
.apply(Element::from)
|
||||
.map(pages::Message::Displays)
|
||||
})
|
||||
}
|
||||
|
||||
fn cache_rates(cached_rates: &mut Vec<String>, rates: &[u32]) {
|
||||
*cached_rates = rates
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
pub static COLOR: String = fl!("color");
|
||||
pub static COLOR_DEPTH: String = fl!("color", "depth");
|
||||
pub static COLOR_PROFILE: String = fl!("color", "profile");
|
||||
pub static COLOR_PROFILES: String = fl!("color", "sidebar");
|
||||
pub static COLOR_TEMPERATURE: String = fl!("color", "temperature");
|
||||
|
||||
pub static DISPLAY: String = fl!("display");
|
||||
pub static DISPLAY_ARRANGEMENT: String = fl!("display", "arrangement");
|
||||
pub static DISPLAY_ARRANGEMENT_DESC: String = fl!("display", "arrangement-desc");
|
||||
pub static DISPLAY_ENABLE: String = fl!("display", "enable");
|
||||
pub static DISPLAY_EXTERNAL: String = fl!("display", "external");
|
||||
pub static DISPLAY_LAPTOP: String = fl!("display", "laptop");
|
||||
pub static DISPLAY_OPTIONS: String = fl!("display", "options");
|
||||
pub static DISPLAY_REFRESH_RATE: String = fl!("display", "refresh-rate");
|
||||
pub static DISPLAY_RESOLUTION: String = fl!("display", "resolution");
|
||||
pub static DISPLAY_SCALE: String = fl!("display", "scale");
|
||||
|
||||
pub static MIRRORING: String = fl!("mirroring");
|
||||
|
||||
pub static NIGHT_LIGHT: String = fl!("night-light");
|
||||
pub static NIGHT_LIGHT_AUTO: String = fl!("night-light", "auto");
|
||||
pub static NIGHT_LIGHT_DESCRIPTION: String = fl!("night-light", "desc");
|
||||
|
||||
pub static ORIENTATION: String = fl!("orientation");
|
||||
pub static ORIENTATION_STANDARD: String = fl!("orientation", "standard");
|
||||
pub static ORIENTATION_ROTATE_90: String = fl!("orientation", "rotate-90");
|
||||
pub static ORIENTATION_ROTATE_180: String = fl!("orientation", "rotate-180");
|
||||
pub static ORIENTATION_ROTATE_270: String = fl!("orientation", "rotate-270");
|
||||
|
||||
pub static SCHEDULING: String = fl!("scheduling");
|
||||
pub static SCHEDULING_MANUAL: String = fl!("scheduling", "manual");
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ use cosmic::{
|
|||
use cosmic_comp_config::XkbConfig;
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use itertools::Itertools;
|
||||
use slab::Slab;
|
||||
use slotmap::{DefaultKey, SlotMap};
|
||||
|
||||
static COMPOSE_OPTIONS: &[(&str, &str)] = &[
|
||||
|
|
@ -568,7 +569,7 @@ impl page::AutoBind<crate::pages::Message> for Page {
|
|||
fn input_sources() -> Section<crate::pages::Message> {
|
||||
Section::default()
|
||||
.title(fl!("keyboard-sources"))
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
// TODO Need something more custom, with drag and drop
|
||||
let mut section = settings::view_section(§ion.title);
|
||||
|
||||
|
|
@ -596,22 +597,24 @@ fn input_sources() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn special_character_entry() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let alternate = descriptions.insert(fl!("keyboard-special-char", "alternate"));
|
||||
let compose = descriptions.insert(fl!("keyboard-special-char", "compose"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("keyboard-special-char"))
|
||||
.descriptions(vec![
|
||||
fl!("keyboard-special-char", "alternate").into(),
|
||||
fl!("keyboard-special-char", "compose").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(go_next_item(
|
||||
&*descriptions[0],
|
||||
&*descriptions[alternate],
|
||||
Message::OpenSpecialCharacterContext(SpecialKey::AlternateCharacters),
|
||||
))
|
||||
.add(go_next_item(
|
||||
&*descriptions[1],
|
||||
&*descriptions[compose],
|
||||
Message::OpenSpecialCharacterContext(SpecialKey::Compose),
|
||||
))
|
||||
.apply(cosmic::Element::from)
|
||||
|
|
@ -620,10 +623,14 @@ fn special_character_entry() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn keyboard_shortcuts() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let shortcuts_desc = descriptions.insert(fl!("keyboard-shortcuts", "desc"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("keyboard-shortcuts"))
|
||||
.descriptions(vec![fl!("keyboard-shortcuts", "desc").into()])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
let mut section = settings::view_section(§ion.title);
|
||||
|
|
@ -633,7 +640,7 @@ fn keyboard_shortcuts() -> Section<crate::pages::Message> {
|
|||
.find(|(_, v)| v.id == "keyboard-shortcuts")
|
||||
{
|
||||
section = section.add(go_next_item(
|
||||
&*descriptions[0],
|
||||
&descriptions[shortcuts_desc],
|
||||
crate::pages::Message::Page(shortcuts_entity),
|
||||
));
|
||||
}
|
||||
|
|
@ -642,22 +649,24 @@ fn keyboard_shortcuts() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn keyboard_typing_assist() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let repeat_delay = descriptions.insert(fl!("keyboard-typing-assist", "repeat-delay"));
|
||||
let repeat_rate = descriptions.insert(fl!("keyboard-typing-assist", "repeat-rate"));
|
||||
let short = descriptions.insert(fl!("short"));
|
||||
let long = descriptions.insert(fl!("long"));
|
||||
let slow = descriptions.insert(fl!("slow"));
|
||||
let fast = descriptions.insert(fl!("fast"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("keyboard-typing-assist"))
|
||||
.descriptions(vec![
|
||||
fl!("keyboard-typing-assist", "repeat-delay").into(),
|
||||
fl!("keyboard-typing-assist", "repeat-rate").into(),
|
||||
fl!("short").into(),
|
||||
fl!("long").into(),
|
||||
fl!("slow").into(),
|
||||
fl!("fast").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(&*descriptions[0], {
|
||||
.add(settings::flex_item(&descriptions[repeat_delay], {
|
||||
// Delay
|
||||
let delay_slider = cosmic::widget::slider(
|
||||
KB_REPEAT_DELAY_MIN..=KB_REPEAT_DELAY_MAX,
|
||||
|
|
@ -671,11 +680,11 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
|
|||
row::with_capacity(3)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(&*descriptions[2])
|
||||
.push(widget::text::body(&descriptions[short]))
|
||||
.push(delay_slider)
|
||||
.push(&*descriptions[3])
|
||||
.push(widget::text::body(&descriptions[long]))
|
||||
}))
|
||||
.add(settings::flex_item(&*descriptions[1], {
|
||||
.add(settings::flex_item(&descriptions[repeat_rate], {
|
||||
// Repeat rate
|
||||
let rate_slider = cosmic::widget::slider(
|
||||
KB_REPEAT_RATE_MIN..=KB_REPEAT_RATE_MAX,
|
||||
|
|
@ -689,9 +698,9 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
|
|||
row::with_capacity(3)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(&*descriptions[4])
|
||||
.push(widget::text::body(&descriptions[slow]))
|
||||
.push(rate_slider)
|
||||
.push(&*descriptions[5])
|
||||
.push(widget::text::body(&descriptions[fast]))
|
||||
}))
|
||||
.apply(cosmic::Element::from)
|
||||
.map(crate::pages::Message::Keyboard)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use cosmic::widget::{column, settings};
|
|||
use cosmic::{Apply, Element};
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -27,9 +28,11 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn shortcuts() -> Section<crate::pages::Message> {
|
||||
let descriptions = Slab::new();
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
// TODO need something more custom
|
||||
/*
|
||||
settings::view_section(§ion.title)
|
||||
|
|
|
|||
|
|
@ -14,17 +14,6 @@ pub mod keyboard;
|
|||
pub mod mouse;
|
||||
pub mod touchpad;
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static ACCELERATION_DESC: String = fl!("acceleration-desc");
|
||||
static DISABLE_WHILE_TYPING: String = fl!("disable-while-typing");
|
||||
static PRIMARY_BUTTON: String = fl!("primary-button");
|
||||
static SCROLLING_EDGE: String = fl!("scrolling", "edge");
|
||||
static SCROLLING_NATURAL_DESC: String = fl!("scrolling", "natural-desc");
|
||||
static SCROLLING_NATURAL: String = fl!("scrolling", "natural");
|
||||
static SCROLLING_SPEED: String = fl!("scrolling", "speed");
|
||||
static SCROLLING_TWO_FINGER: String = fl!("scrolling", "two-finger");
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
// seperate close message, to make sure another isn't closed?
|
||||
|
|
|
|||
|
|
@ -4,15 +4,11 @@ use cosmic::{Apply, Element};
|
|||
use cosmic_comp_config::input::AccelProfile;
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
use super::Message;
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static MOUSE_ACCELERATION: String = fl!("mouse", "acceleration");
|
||||
static MOUSE_SPEED: String = fl!("mouse", "speed");
|
||||
}
|
||||
|
||||
pub fn default_primary_button() -> cosmic::widget::segmented_button::SingleSelectModel {
|
||||
let mut model = cosmic::widget::segmented_button::SingleSelectModel::builder()
|
||||
.insert(|b| b.text(fl!("primary-button", "left")))
|
||||
|
|
@ -43,48 +39,53 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn mouse() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let mouse_acceleration = descriptions.insert(fl!("mouse", "acceleration"));
|
||||
let mouse_speed = descriptions.insert(fl!("mouse", "speed"));
|
||||
let primary_button = descriptions.insert(fl!("primary-button"));
|
||||
let acceleration_desc = descriptions.insert(fl!("acceleration-desc"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![
|
||||
super::PRIMARY_BUTTON.as_str().into(),
|
||||
MOUSE_SPEED.as_str().into(),
|
||||
MOUSE_ACCELERATION.as_str().into(),
|
||||
super::ACCELERATION_DESC.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let input = binder.page::<super::Page>().expect("input page not found");
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*super::PRIMARY_BUTTON,
|
||||
&descriptions[primary_button],
|
||||
cosmic::widget::segmented_control::horizontal(&input.primary_button)
|
||||
.minimum_button_width(0)
|
||||
.on_activate(|x| Message::PrimaryButtonSelected(x, false)),
|
||||
))
|
||||
.add(settings::item::builder(&*MOUSE_SPEED).flex_control({
|
||||
let value = (input
|
||||
.input_default
|
||||
.acceleration
|
||||
.as_ref()
|
||||
.map_or(0.0, |x| x.speed)
|
||||
+ 1.0)
|
||||
* 50.0;
|
||||
|
||||
let slider = widget::slider(10.0..=80.0, value, |value| {
|
||||
Message::SetMouseSpeed((value / 50.0) - 1.0, false)
|
||||
})
|
||||
.width(250.0)
|
||||
.breakpoints(&[45.0]);
|
||||
|
||||
row::with_capacity(2)
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(text(format!("{:.0}", value.round())))
|
||||
.push(slider)
|
||||
}))
|
||||
.add(
|
||||
settings::item::builder(&*MOUSE_ACCELERATION)
|
||||
.description(&*super::ACCELERATION_DESC)
|
||||
settings::item::builder(&descriptions[mouse_speed]).flex_control({
|
||||
let value = (input
|
||||
.input_default
|
||||
.acceleration
|
||||
.as_ref()
|
||||
.map_or(0.0, |x| x.speed)
|
||||
+ 1.0)
|
||||
* 50.0;
|
||||
|
||||
let slider = widget::slider(10.0..=80.0, value, |value| {
|
||||
Message::SetMouseSpeed((value / 50.0) - 1.0, false)
|
||||
})
|
||||
.width(250.0)
|
||||
.breakpoints(&[45.0]);
|
||||
|
||||
row::with_capacity(2)
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(text(format!("{:.0}", value.round())))
|
||||
.push(slider)
|
||||
}),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&descriptions[mouse_acceleration])
|
||||
.description(&descriptions[acceleration_desc])
|
||||
.toggler(
|
||||
input
|
||||
.input_default
|
||||
|
|
@ -100,19 +101,22 @@ fn mouse() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn scrolling() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let natural = descriptions.insert(fl!("scrolling", "natural"));
|
||||
let natural_desc = descriptions.insert(fl!("scrolling", "natural-desc"));
|
||||
let scroll_speed = descriptions.insert(fl!("scrolling", "speed"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("scrolling"))
|
||||
.descriptions(vec![
|
||||
super::SCROLLING_SPEED.as_str().into(),
|
||||
super::SCROLLING_NATURAL.as_str().into(),
|
||||
super::SCROLLING_NATURAL_DESC.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let input = binder.page::<super::Page>().expect("input page not found");
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(&*super::SCROLLING_SPEED, {
|
||||
.add(settings::flex_item(&descriptions[scroll_speed], {
|
||||
let value = input
|
||||
.input_default
|
||||
.scroll_config
|
||||
|
|
@ -136,8 +140,8 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
.push(slider)
|
||||
}))
|
||||
.add(
|
||||
settings::item::builder(&*super::SCROLLING_NATURAL)
|
||||
.description(&*super::SCROLLING_NATURAL_DESC)
|
||||
settings::item::builder(&descriptions[natural])
|
||||
.description(&descriptions[natural_desc])
|
||||
.toggler(
|
||||
input
|
||||
.input_default
|
||||
|
|
|
|||
|
|
@ -4,32 +4,11 @@ use cosmic::{Apply, Element};
|
|||
use cosmic_comp_config::input::{AccelProfile, ClickMethod, ScrollMethod};
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
use super::Message;
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static CLICK_BEHAVIOR_CLICK_FINGER: String = fl!("click-behavior", "click-finger");
|
||||
static CLICK_BEHAVIOR_BUTTON_AREAS: String = fl!("click-behavior", "button-areas");
|
||||
|
||||
static TAP_TO_CLICK: String = fl!("tap-to-click");
|
||||
static TAP_TO_CLICK_DESC: String = fl!("tap-to-click", "desc");
|
||||
|
||||
static TOUCHPAD_ACCELERAION: String = fl!("touchpad", "acceleration");
|
||||
static TOUCHPAD_SPEED: String = fl!("touchpad", "speed");
|
||||
|
||||
static OPEN_APPLICATION_LIBRARY: String = fl!("open-application-library");
|
||||
static OPEN_WORKSPACES_VIEW: String = fl!("open-workspaces-view");
|
||||
static SWIPING_FOUR_FINGER_DOWN: String = fl!("gestures", "four-finger-down");
|
||||
static SWIPING_FOUR_FINGER_LEFT: String = fl!("gestures", "four-finger-left");
|
||||
static SWIPING_FOUR_FINGER_RIGHT: String = fl!("gestures", "four-finger-right");
|
||||
static SWIPING_FOUR_FINGER_UP: String = fl!("gestures", "four-finger-up");
|
||||
static SWIPING_THREE_FINGER_ANY: String = fl!("gestures", "three-finger-any");
|
||||
static SWITCH_BETWEEN_WINDOWS: String = fl!("switch-between-windows");
|
||||
static SWITCH_TO_NEXT_WORKSPACE: String = fl!("switch-to-next-workspace");
|
||||
static SWITCH_TO_PREV_WORKSPACE: String = fl!("switch-to-prev-workspace");
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Page;
|
||||
|
||||
|
|
@ -56,49 +35,54 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn touchpad() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let primary_button = descriptions.insert(fl!("primary-button"));
|
||||
let touchpad_speed = descriptions.insert(fl!("touchpad", "speed"));
|
||||
let acceleration = descriptions.insert(fl!("touchpad", "acceleration"));
|
||||
let acceleration_desc = descriptions.insert(fl!("acceleration-desc"));
|
||||
let disable_while_typing = descriptions.insert(fl!("disable-while-typing"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![
|
||||
super::PRIMARY_BUTTON.as_str().into(),
|
||||
TOUCHPAD_SPEED.as_str().into(),
|
||||
TOUCHPAD_ACCELERAION.as_str().into(),
|
||||
super::ACCELERATION_DESC.as_str().into(),
|
||||
super::DISABLE_WHILE_TYPING.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let input = binder.page::<super::Page>().expect("input page not found");
|
||||
let theme = cosmic::theme::active();
|
||||
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*super::PRIMARY_BUTTON,
|
||||
&descriptions[primary_button],
|
||||
cosmic::widget::segmented_control::horizontal(&input.touchpad_primary_button)
|
||||
.minimum_button_width(0)
|
||||
.on_activate(|x| Message::PrimaryButtonSelected(x, true)),
|
||||
))
|
||||
.add(settings::item::builder(&*TOUCHPAD_SPEED).flex_control({
|
||||
let value = (input
|
||||
.input_touchpad
|
||||
.acceleration
|
||||
.as_ref()
|
||||
.map_or(0.0, |x| x.speed)
|
||||
+ 1.0)
|
||||
* 50.0;
|
||||
|
||||
let slider = widget::slider(10.0..=80.0, value, |value| {
|
||||
Message::SetMouseSpeed((value / 50.0) - 1.0, true)
|
||||
})
|
||||
.width(250.0)
|
||||
.breakpoints(&[45.0]);
|
||||
|
||||
row::with_capacity(2)
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(text(format!("{:.0}", value.round())))
|
||||
.push(slider)
|
||||
}))
|
||||
.add(
|
||||
settings::item::builder(&*TOUCHPAD_ACCELERAION)
|
||||
.description(&*super::ACCELERATION_DESC)
|
||||
settings::item::builder(&descriptions[touchpad_speed]).flex_control({
|
||||
let value = (input
|
||||
.input_touchpad
|
||||
.acceleration
|
||||
.as_ref()
|
||||
.map_or(0.0, |x| x.speed)
|
||||
+ 1.0)
|
||||
* 50.0;
|
||||
|
||||
let slider = widget::slider(10.0..=80.0, value, |value| {
|
||||
Message::SetMouseSpeed((value / 50.0) - 1.0, true)
|
||||
})
|
||||
.width(250.0)
|
||||
.breakpoints(&[45.0]);
|
||||
|
||||
row::with_capacity(2)
|
||||
.align_items(Alignment::Center)
|
||||
.spacing(theme.cosmic().space_s())
|
||||
.push(text(format!("{:.0}", value.round())))
|
||||
.push(slider)
|
||||
}),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&descriptions[acceleration])
|
||||
.description(&descriptions[acceleration_desc])
|
||||
.toggler(
|
||||
input
|
||||
.input_touchpad
|
||||
|
|
@ -109,7 +93,7 @@ fn touchpad() -> Section<crate::pages::Message> {
|
|||
),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*super::DISABLE_WHILE_TYPING).toggler(
|
||||
settings::item::builder(&descriptions[disable_while_typing]).toggler(
|
||||
input.input_touchpad.disable_while_typing.unwrap_or(false),
|
||||
|enabled| Message::DisableWhileTyping(enabled, true),
|
||||
),
|
||||
|
|
@ -120,15 +104,18 @@ fn touchpad() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn click_behavior() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let click_finger = descriptions.insert(fl!("click-behavior", "click-finger"));
|
||||
let button_areas = descriptions.insert(fl!("click-behavior", "button-areas"));
|
||||
let tap_to_click = descriptions.insert(fl!("tap-to-click"));
|
||||
let _tap_to_click_desc = descriptions.insert(fl!("tap-to-click", "desc"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("click-behavior"))
|
||||
.descriptions(vec![
|
||||
CLICK_BEHAVIOR_CLICK_FINGER.as_str().into(),
|
||||
CLICK_BEHAVIOR_BUTTON_AREAS.as_str().into(),
|
||||
TAP_TO_CLICK.as_str().into(),
|
||||
TAP_TO_CLICK_DESC.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let page = binder
|
||||
.page::<super::Page>()
|
||||
.expect("input devices page not found");
|
||||
|
|
@ -136,7 +123,7 @@ fn click_behavior() -> Section<crate::pages::Message> {
|
|||
settings::view_section(&*section.title)
|
||||
// Secondary click via two fingers, and middle-click via three fingers
|
||||
.add(settings::item_row(vec![widget::radio(
|
||||
&*CLICK_BEHAVIOR_CLICK_FINGER,
|
||||
&descriptions[click_finger],
|
||||
ClickMethod::Clickfinger,
|
||||
page.input_touchpad.click_method,
|
||||
|option| Message::SetSecondaryClickBehavior(Some(option), true),
|
||||
|
|
@ -144,14 +131,14 @@ fn click_behavior() -> Section<crate::pages::Message> {
|
|||
.into()]))
|
||||
// Secondary and middle-click via button areas.
|
||||
.add(settings::item_row(vec![widget::radio(
|
||||
&*CLICK_BEHAVIOR_BUTTON_AREAS,
|
||||
&descriptions[button_areas],
|
||||
ClickMethod::ButtonAreas,
|
||||
page.input_touchpad.click_method,
|
||||
|option| Message::SetSecondaryClickBehavior(Some(option), true),
|
||||
)
|
||||
.into()]))
|
||||
.add(
|
||||
settings::item::builder(&*TAP_TO_CLICK).toggler(
|
||||
settings::item::builder(&descriptions[tap_to_click]).toggler(
|
||||
page.input_touchpad
|
||||
.tap_config
|
||||
.as_ref()
|
||||
|
|
@ -165,16 +152,19 @@ fn click_behavior() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn scrolling() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let edge = descriptions.insert(fl!("scrolling", "edge"));
|
||||
let natural = descriptions.insert(fl!("scrolling", "natural"));
|
||||
let natural_desc = descriptions.insert(fl!("scrolling", "natural-desc"));
|
||||
let scroll_speed = descriptions.insert(fl!("scrolling", "speed"));
|
||||
let two_finger = descriptions.insert(fl!("scrolling", "two-finger"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("scrolling"))
|
||||
.descriptions(vec![
|
||||
super::SCROLLING_TWO_FINGER.as_str().into(),
|
||||
super::SCROLLING_EDGE.as_str().into(),
|
||||
super::SCROLLING_SPEED.as_str().into(),
|
||||
super::SCROLLING_NATURAL.as_str().into(),
|
||||
super::SCROLLING_NATURAL_DESC.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
let page = binder
|
||||
.page::<super::Page>()
|
||||
.expect("input devices page not found");
|
||||
|
|
@ -183,7 +173,7 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
settings::view_section(§ion.title)
|
||||
// Two-finger scrolling toggle
|
||||
.add(settings::item_row(vec![widget::radio(
|
||||
&*super::SCROLLING_TWO_FINGER,
|
||||
&descriptions[two_finger],
|
||||
ScrollMethod::TwoFinger,
|
||||
page.input_touchpad
|
||||
.scroll_config
|
||||
|
|
@ -194,7 +184,7 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
.into()]))
|
||||
// Edge scrolling toggle
|
||||
.add(settings::item_row(vec![widget::radio(
|
||||
&*super::SCROLLING_EDGE,
|
||||
&descriptions[edge],
|
||||
ScrollMethod::Edge,
|
||||
page.input_touchpad
|
||||
.scroll_config
|
||||
|
|
@ -204,7 +194,7 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
)
|
||||
.into()]))
|
||||
// Scroll speed slider
|
||||
.add(settings::item(&*super::SCROLLING_SPEED, {
|
||||
.add(settings::item(&descriptions[scroll_speed], {
|
||||
let value = page
|
||||
.input_touchpad
|
||||
.scroll_config
|
||||
|
|
@ -229,8 +219,8 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
}))
|
||||
// Natural scrolling toggle
|
||||
.add(
|
||||
settings::item::builder(&*super::SCROLLING_NATURAL)
|
||||
.description(&*super::SCROLLING_NATURAL_DESC)
|
||||
settings::item::builder(&descriptions[natural])
|
||||
.description(&descriptions[natural_desc])
|
||||
.toggler(
|
||||
page.input_touchpad
|
||||
.scroll_config
|
||||
|
|
@ -245,36 +235,46 @@ fn scrolling() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn swiping() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let four_finger_down = descriptions.insert(fl!("gestures", "four-finger-down"));
|
||||
// let four_finger_left = descriptions.insert(fl!("gestures", "four-finger-left"));
|
||||
// let four_finger_right = descriptions.insert(fl!("gestures", "four-finger-right"));
|
||||
let four_finger_up = descriptions.insert(fl!("gestures", "four-finger-up"));
|
||||
// let three_finger_any = descriptions.insert(fl!("gestures", "three-finger-any"));
|
||||
|
||||
// let open_application_library = descriptions.insert(fl!("open-application-library"));
|
||||
// let open_workspaces_view = descriptions.insert(fl!("open-workspaces-view"));
|
||||
// let switch_between_windows = descriptions.insert(fl!("switch-between-windows"));
|
||||
let switch_to_next_workspace = descriptions.insert(fl!("switch-to-next-workspace"));
|
||||
let switch_to_prev_workspace = descriptions.insert(fl!("switch-to-prev-workspace"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("gestures"))
|
||||
.descriptions(vec![
|
||||
SWIPING_FOUR_FINGER_DOWN.as_str().into(),
|
||||
SWIPING_FOUR_FINGER_LEFT.as_str().into(),
|
||||
SWIPING_FOUR_FINGER_RIGHT.as_str().into(),
|
||||
SWIPING_FOUR_FINGER_UP.as_str().into(),
|
||||
SWIPING_THREE_FINGER_ANY.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
settings::view_section(&*section.title)
|
||||
// .add(
|
||||
// settings::item::builder(&*SWIPING_THREE_FINGER_ANY)
|
||||
// .flex_control(text(&*SWITCH_BETWEEN_WINDOWS)),
|
||||
// settings::item::builder(&descriptions[three_finger_any])
|
||||
// .flex_control(text(&descriptions[switch_between_windows])),
|
||||
// )
|
||||
.add(
|
||||
settings::item::builder(&*SWIPING_FOUR_FINGER_UP)
|
||||
.flex_control(text(&*SWITCH_TO_PREV_WORKSPACE)),
|
||||
settings::item::builder(&descriptions[four_finger_up])
|
||||
.flex_control(text(&descriptions[switch_to_prev_workspace])),
|
||||
)
|
||||
.add(
|
||||
settings::item::builder(&*SWIPING_FOUR_FINGER_DOWN)
|
||||
.flex_control(text(&*SWITCH_TO_NEXT_WORKSPACE)),
|
||||
settings::item::builder(&descriptions[four_finger_down])
|
||||
.flex_control(text(&descriptions[switch_to_next_workspace])),
|
||||
)
|
||||
// .add(
|
||||
// settings::item::builder(&*SWIPING_FOUR_FINGER_LEFT)
|
||||
// .flex_control(text(&*OPEN_WORKSPACES_VIEW)),
|
||||
// settings::item::builder(&descriptions[four_finger_left])
|
||||
// .flex_control(text(&descriptions[open_workspaces_view])),
|
||||
// )
|
||||
// .add(
|
||||
// settings::item::builder(&*SWIPING_FOUR_FINGER_RIGHT)
|
||||
// .flex_control(text(&*OPEN_APPLICATION_LIBRARY)),
|
||||
// settings::item::builder(&descriptions[four_finger_right])
|
||||
// .flex_control(text(&descriptions[open_application_library])),
|
||||
// )
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::Input)
|
||||
|
|
|
|||
|
|
@ -109,15 +109,15 @@ impl SetPowerProfile for S76Backend {
|
|||
|
||||
match profile {
|
||||
PowerProfile::Battery => match daemon.battery().await {
|
||||
Ok(x) => tracing::info!("Battery mode activated."),
|
||||
Ok(()) => tracing::info!("Battery mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
PowerProfile::Balanced => match daemon.balanced().await {
|
||||
Ok(x) => tracing::info!("Balanced mode activated."),
|
||||
Ok(()) => tracing::info!("Balanced mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
PowerProfile::Performance => match daemon.performance().await {
|
||||
Ok(x) => tracing::info!("Performance mode activated."),
|
||||
Ok(()) => tracing::info!("Performance mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
}
|
||||
|
|
@ -181,15 +181,15 @@ impl SetPowerProfile for PPBackend {
|
|||
|
||||
match profile {
|
||||
PowerProfile::Battery => match daemon.set_active_profile("power-saver").await {
|
||||
Ok(x) => tracing::info!("Battery mode activated."),
|
||||
Ok(()) => tracing::info!("Battery mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
PowerProfile::Balanced => match daemon.set_active_profile("balanced").await {
|
||||
Ok(x) => tracing::info!("Balanced mode activated."),
|
||||
Ok(()) => tracing::info!("Balanced mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
PowerProfile::Performance => match daemon.set_active_profile("performance").await {
|
||||
Ok(x) => tracing::info!("Performance mode activated."),
|
||||
Ok(()) => tracing::info!("Performance mode activated."),
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
mod backend;
|
||||
use self::backend::{GetCurrentPowerProfile, SetPowerProfile};
|
||||
use backend::PowerProfile;
|
||||
|
||||
use cosmic::widget;
|
||||
use cosmic::{widget::settings, Apply};
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
use self::backend::{GetCurrentPowerProfile, SetPowerProfile};
|
||||
|
||||
mod backend;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Page;
|
||||
|
||||
|
|
@ -48,10 +48,14 @@ impl Page {
|
|||
}
|
||||
|
||||
fn profiles() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let _power_desc = descriptions.insert(fl!("power", "desc"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("power-mode"))
|
||||
.descriptions(vec![fl!("power", "desc").into()])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
let mut section = settings::view_section(§ion.title);
|
||||
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
|
|
|||
|
|
@ -3,25 +3,9 @@
|
|||
|
||||
use cosmic::widget::{settings, text};
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
// crate::cache_dynamic_lazy! {
|
||||
// pub static SOUND_ALERTS_VOLUME: String = fl!("sound-alerts", "volume");
|
||||
// pub static SOUND_ALERTS_SOUND: String = fl!("sound-alerts", "sound");
|
||||
|
||||
// pub static SOUND_APPLICATIONS_DESC: String = fl!("sound-applications", "desc");
|
||||
|
||||
// pub static SOUND_INPUT_VOLUME: String = fl!("sound-input", "volume");
|
||||
// pub static SOUND_INPUT_DEVICE: String = fl!("sound-input", "device");
|
||||
// pub static SOUND_INPUT_LEVEL: String = fl!("sound-input", "level");
|
||||
|
||||
// pub static SOUND_OUTPUT_VOLUME: String = fl!("sound-output", "volume");
|
||||
// pub static SOUND_OUTPUT_DEVICE: String = fl!("sound-output", "device");
|
||||
// pub static SOUND_OUTPUT_LEVEL: String = fl!("sound-output", "level");
|
||||
// pub static SOUND_OUTPUT_CONFIG: String = fl!("sound-output", "config");
|
||||
// pub static SOUND_OUTPUT_BALANCE: String = fl!("sound-output", "balance");
|
||||
// }
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Page;
|
||||
|
||||
|
|
@ -48,64 +32,76 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn alerts() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
let volume = descriptions.insert(fl!("sound-alerts", "volume"));
|
||||
let sound = descriptions.insert(fl!("sound-alerts", "sound"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("sound-alerts"))
|
||||
.descriptions(vec![
|
||||
fl!("sound-alerts", "volume").into(),
|
||||
fl!("sound-alerts", "sound").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item(&*section.descriptions[0], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[1], text("TODO")))
|
||||
.add(settings::item(§ion.descriptions[volume], text("TODO")))
|
||||
.add(settings::item(§ion.descriptions[sound], text("TODO")))
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
fn applications() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let applications = descriptions.insert(fl!("sound-applications", "desc"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("sound-applications"))
|
||||
.descriptions(vec![fl!("sound-applications", "desc").into()])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item(&*section.descriptions[0], text("TODO")))
|
||||
.add(settings::item(
|
||||
&*section.descriptions[applications],
|
||||
text("TODO"),
|
||||
))
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
fn input() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let volume = descriptions.insert(fl!("sound-input", "volume"));
|
||||
let device = descriptions.insert(fl!("sound-input", "device"));
|
||||
let level = descriptions.insert(fl!("sound-input", "level"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("sound-input"))
|
||||
.descriptions(vec![
|
||||
fl!("sound-input", "volume").into(),
|
||||
fl!("sound-input", "device").into(),
|
||||
fl!("sound-input", "level").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item(&*section.descriptions[0], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[1], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[2], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[volume], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[device], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[level], text("TODO")))
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
fn output() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let volume = descriptions.insert(fl!("sound-output", "volume"));
|
||||
let device = descriptions.insert(fl!("sound-output", "device"));
|
||||
let level = descriptions.insert(fl!("sound-output", "level"));
|
||||
let config = descriptions.insert(fl!("sound-output", "config"));
|
||||
// let balance = descriptions.insert(fl!("sound-output", "balance"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("sound-output"))
|
||||
.descriptions(vec![
|
||||
fl!("sound-output", "volume").into(),
|
||||
fl!("sound-output", "device").into(),
|
||||
fl!("sound-output", "level").into(),
|
||||
fl!("sound-output", "config").into(),
|
||||
fl!("sound-output", "balance").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, _page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, _page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::item(&*section.descriptions[0], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[1], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[2], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[3], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[volume], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[device], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[level], text("TODO")))
|
||||
.add(settings::item(&*section.descriptions[config], text("TODO")))
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use cosmic::iced::Length;
|
||||
use cosmic_settings_page::{self as page, section, Section};
|
||||
|
||||
use cosmic::widget::{self, editable_input, list_column, settings, text};
|
||||
use cosmic::widget::{editable_input, list_column, settings, text};
|
||||
use cosmic::{command, Apply, Command};
|
||||
use cosmic_settings_system::about::Info;
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -105,12 +105,14 @@ impl Page {
|
|||
}
|
||||
|
||||
fn device() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let device = descriptions.insert(fl!("about-device"));
|
||||
let device_desc = descriptions.insert(fl!("about-device", "desc"));
|
||||
|
||||
Section::default()
|
||||
.descriptions(vec![
|
||||
fl!("about-device").into(),
|
||||
fl!("about-device", "desc").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let desc = §ion.descriptions;
|
||||
|
||||
let hostname_input = editable_input(
|
||||
|
|
@ -122,8 +124,8 @@ fn device() -> Section<crate::pages::Message> {
|
|||
.on_input(Message::HostnameInput)
|
||||
.on_submit(Message::HostnameSubmit);
|
||||
|
||||
let device_name = settings::item::builder(&*desc[0])
|
||||
.description(&*desc[1])
|
||||
let device_name = settings::item::builder(&*desc[device])
|
||||
.description(&*desc[device_desc])
|
||||
.flex_control(hostname_input);
|
||||
|
||||
list_column()
|
||||
|
|
@ -134,33 +136,38 @@ fn device() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn hardware() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let model = descriptions.insert(fl!("about-hardware", "model"));
|
||||
let memory = descriptions.insert(fl!("about-hardware", "memory"));
|
||||
let processor = descriptions.insert(fl!("about-hardware", "processor"));
|
||||
let graphics = descriptions.insert(fl!("about-hardware", "graphics"));
|
||||
let disk_capacity = descriptions.insert(fl!("about-hardware", "disk-capacity"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("about-hardware"))
|
||||
.descriptions(vec![
|
||||
fl!("about-hardware", "model").into(),
|
||||
fl!("about-hardware", "memory").into(),
|
||||
fl!("about-hardware", "processor").into(),
|
||||
fl!("about-hardware", "graphics").into(),
|
||||
fl!("about-hardware", "disk-capacity").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let desc = §ion.descriptions;
|
||||
|
||||
let mut sections = settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*desc[0],
|
||||
&*desc[model],
|
||||
text(&page.info.hardware_model),
|
||||
))
|
||||
.add(settings::flex_item(&*desc[1], text(&page.info.memory)))
|
||||
.add(settings::flex_item(&*desc[2], text(&page.info.processor)));
|
||||
.add(settings::flex_item(&*desc[memory], text(&page.info.memory)))
|
||||
.add(settings::flex_item(
|
||||
&*desc[processor],
|
||||
text(&page.info.processor),
|
||||
));
|
||||
|
||||
for card in &page.info.graphics {
|
||||
sections = sections.add(settings::flex_item(&*desc[3], text(card.as_str())));
|
||||
sections = sections.add(settings::flex_item(&*desc[graphics], text(card.as_str())));
|
||||
}
|
||||
|
||||
sections
|
||||
.add(settings::flex_item(
|
||||
&*desc[4],
|
||||
&*desc[disk_capacity],
|
||||
text(&page.info.disk_capacity),
|
||||
))
|
||||
.into()
|
||||
|
|
@ -168,31 +175,33 @@ fn hardware() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn os() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let os = descriptions.insert(fl!("about-os", "os"));
|
||||
let os_arch = descriptions.insert(fl!("about-os", "os-architecture"));
|
||||
let desktop = descriptions.insert(fl!("about-os", "desktop-environment"));
|
||||
let windowing_system = descriptions.insert(fl!("about-os", "windowing-system"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("about-os"))
|
||||
.descriptions(vec![
|
||||
fl!("about-os", "os").into(),
|
||||
fl!("about-os", "os-architecture").into(),
|
||||
fl!("about-os", "desktop-environment").into(),
|
||||
fl!("about-os", "windowing-system").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
let desc = §ion.descriptions;
|
||||
settings::view_section(§ion.title)
|
||||
.add(settings::flex_item(
|
||||
&*desc[0],
|
||||
&*desc[os],
|
||||
text(&page.info.operating_system),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*desc[1],
|
||||
&*desc[os_arch],
|
||||
text(&page.info.os_architecture),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*desc[2],
|
||||
&*desc[desktop],
|
||||
text(&page.info.desktop_environment),
|
||||
))
|
||||
.add(settings::flex_item(
|
||||
&*desc[3],
|
||||
&*desc[windowing_system],
|
||||
text(&page.info.windowing_system),
|
||||
))
|
||||
.into()
|
||||
|
|
@ -204,7 +213,7 @@ fn os() -> Section<crate::pages::Message> {
|
|||
// Section::default()
|
||||
// .title(fl!("about-related"))
|
||||
// .descriptions(vec![fl!("about-related", "support").into()])
|
||||
// .view::<Page>(|_binder, _page, section| {
|
||||
// .view::<Page>(move |_binder, _page, section| {
|
||||
// settings::view_section(§ion.title)
|
||||
// .add(settings::item(&*section.descriptions[0], text("TODO")))
|
||||
// .into()
|
||||
|
|
|
|||
|
|
@ -9,16 +9,12 @@ use cosmic::{
|
|||
};
|
||||
use cosmic_settings_page::Section;
|
||||
use cosmic_settings_page::{self as page, section};
|
||||
// use icu::calendar::{DateTime, Gregorian};
|
||||
|
||||
use slab::Slab;
|
||||
use slotmap::SlotMap;
|
||||
use tracing::error;
|
||||
|
||||
crate::cache_dynamic_lazy! {
|
||||
static TIME_FORMAT_TWENTY_FOUR: String = fl!("time-format", "twenty-four");
|
||||
static TIME_FORMAT_FIRST: String = fl!("time-format", "first");
|
||||
static TIME_FORMAT_SHOW_DATE: String = fl!("time-format", "show-date");
|
||||
static TIME_FORMAT_WEEKDAYS: [String; 4] = [fl!("time-format", "friday"), fl!("time-format", "saturday"), fl!("time-format", "sunday"), fl!("time-format", "monday")];
|
||||
static WEEKDAYS: [String; 4] = [fl!("time-format", "friday"), fl!("time-format", "saturday"), fl!("time-format", "sunday"), fl!("time-format", "monday")];
|
||||
}
|
||||
|
||||
pub struct Page {
|
||||
|
|
@ -28,7 +24,6 @@ pub struct Page {
|
|||
military_time: bool,
|
||||
first_day_of_week: usize,
|
||||
show_date_in_top_panel: bool,
|
||||
// info: Option<cosmic_settings_time::Info>,
|
||||
}
|
||||
|
||||
impl Default for Page {
|
||||
|
|
@ -115,20 +110,22 @@ pub enum Message {
|
|||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
fn date() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let auto = descriptions.insert(fl!("time-date", "auto"));
|
||||
let title = descriptions.insert(fl!("time-date"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("time-date"))
|
||||
.descriptions(vec![
|
||||
fl!("time-date", "auto").into(),
|
||||
fl!("time-date").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
.add(
|
||||
settings::item::builder(&*section.descriptions[0])
|
||||
settings::item::builder(&*section.descriptions[auto])
|
||||
.toggler(page.auto, Message::Automatic),
|
||||
)
|
||||
.add(settings::item(
|
||||
&*section.descriptions[1],
|
||||
&*section.descriptions[title],
|
||||
horizontal_space(Length::Fill),
|
||||
))
|
||||
.apply(cosmic::Element::from)
|
||||
|
|
@ -137,24 +134,26 @@ fn date() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn format() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let military = descriptions.insert(fl!("time-format", "twenty-four"));
|
||||
let first = descriptions.insert(fl!("time-format", "first"));
|
||||
let show_date = descriptions.insert(fl!("time-format", "show-date"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("time-format"))
|
||||
.descriptions(vec![
|
||||
TIME_FORMAT_TWENTY_FOUR.as_str().into(),
|
||||
TIME_FORMAT_FIRST.as_str().into(),
|
||||
TIME_FORMAT_SHOW_DATE.as_str().into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
// 24-hour toggle
|
||||
.add(
|
||||
settings::item::builder(&*TIME_FORMAT_TWENTY_FOUR)
|
||||
settings::item::builder(§ion.descriptions[military])
|
||||
.toggler(page.military_time, Message::MilitaryTime),
|
||||
)
|
||||
// First day of week
|
||||
.add(
|
||||
settings::item::builder(&*TIME_FORMAT_FIRST).flex_control(dropdown(
|
||||
&*TIME_FORMAT_WEEKDAYS,
|
||||
settings::item::builder(§ion.descriptions[first]).flex_control(dropdown(
|
||||
&*WEEKDAYS,
|
||||
match page.first_day_of_week {
|
||||
4 => Some(0), // friday
|
||||
5 => Some(1), // saturday
|
||||
|
|
@ -173,7 +172,7 @@ fn format() -> Section<crate::pages::Message> {
|
|||
)
|
||||
// Date on top panel toggle
|
||||
.add(
|
||||
settings::item::builder(&*TIME_FORMAT_SHOW_DATE)
|
||||
settings::item::builder(§ion.descriptions[show_date])
|
||||
.toggler(page.show_date_in_top_panel, Message::ShowDate),
|
||||
)
|
||||
.apply(cosmic::Element::from)
|
||||
|
|
@ -182,24 +181,26 @@ fn format() -> Section<crate::pages::Message> {
|
|||
}
|
||||
|
||||
fn timezone() -> Section<crate::pages::Message> {
|
||||
let mut descriptions = Slab::new();
|
||||
|
||||
let auto = descriptions.insert(fl!("time-zone", "auto"));
|
||||
let auto_info = descriptions.insert(fl!("time-zone", "auto-info"));
|
||||
let time_zone = descriptions.insert(fl!("time-zone"));
|
||||
|
||||
Section::default()
|
||||
.title(fl!("time-zone"))
|
||||
.descriptions(vec![
|
||||
fl!("time-zone", "auto").into(),
|
||||
fl!("time-zone", "auto-info").into(),
|
||||
fl!("time-zone").into(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
.descriptions(descriptions)
|
||||
.view::<Page>(move |_binder, page, section| {
|
||||
settings::view_section(§ion.title)
|
||||
// Automatic timezone toggle
|
||||
.add(
|
||||
settings::item::builder(&*section.descriptions[0])
|
||||
.description(&*section.descriptions[1])
|
||||
settings::item::builder(&*section.descriptions[auto])
|
||||
.description(&*section.descriptions[auto_info])
|
||||
.toggler(page.auto_timezone, Message::AutomaticTimezone),
|
||||
)
|
||||
// Time zone select
|
||||
.add(
|
||||
settings::item::builder(&*section.descriptions[2])
|
||||
settings::item::builder(&*section.descriptions[time_zone])
|
||||
.control(horizontal_space(Length::Fill)),
|
||||
)
|
||||
.apply(cosmic::Element::from)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
use cosmic::iced::Length;
|
||||
use cosmic::widget::{
|
||||
button, column, container, divider, horizontal_space, icon, list, row, settings, text,
|
||||
vertical_space,
|
||||
button, column, container, divider, horizontal_space, icon, row, settings, text, vertical_space,
|
||||
};
|
||||
use cosmic::{theme, Apply, Element};
|
||||
use cosmic_settings_page as page;
|
||||
|
|
|
|||
|
|
@ -12,4 +12,5 @@ generator = "0.7.5"
|
|||
downcast-rs = "1.2.0"
|
||||
once_cell = "1.19.0"
|
||||
tokio.workspace = true
|
||||
url = "2.5.0"
|
||||
url = "2.5.0"
|
||||
slab = "0.4.9"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use derive_setters::Setters;
|
||||
use regex::Regex;
|
||||
use std::borrow::Cow;
|
||||
use slab::Slab;
|
||||
|
||||
use crate::{Binder, Page};
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ pub struct Section<Message> {
|
|||
#[setters(into)]
|
||||
pub title: String,
|
||||
#[setters(into)]
|
||||
pub descriptions: Vec<Cow<'static, str>>,
|
||||
pub descriptions: Slab<String>,
|
||||
#[setters(skip)]
|
||||
pub show_while: Option<ShowWhileFn<Message>>,
|
||||
#[setters(skip)]
|
||||
|
|
@ -44,7 +44,7 @@ impl<Message: 'static> Default for Section<Message> {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
title: String::new(),
|
||||
descriptions: Vec::new(),
|
||||
descriptions: Slab::new(),
|
||||
show_while: None,
|
||||
view_fn: Box::new(unimplemented),
|
||||
search_ignore: false,
|
||||
|
|
@ -63,7 +63,7 @@ impl<Message: 'static> Section<Message> {
|
|||
return true;
|
||||
}
|
||||
|
||||
for description in &*self.descriptions {
|
||||
for (_, description) in &self.descriptions {
|
||||
if rule.is_match(description) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue