feat(settings): add grouped configuration hub, languages and tray controls

This commit is contained in:
aria committed 2026-10-28 03:37:22 +09:00
1 parent 6f34fd080f
commit cc3b6f903f
90 files changed
+3625 -408

No files matched your search

+67 -2
View File
@@ -1,3 +1,4 @@
mod all_options;
mod connections;
mod form_controls;
mod navigation;
@@ -8,6 +9,7 @@ mod panel_edit;
mod panel_inspector;
mod panel_preview;
mod theme_controls;
mod tray_controls;
use theme_controls::gallery_id;
@@ -62,6 +64,11 @@ fn main() -> cosmic::iced::Result {
}
Some("wallpaper") => Some(InitialPage::Wallpaper),
Some("bar") => Some(InitialPage::Bar),
Some("appearance") => Some(InitialPage::Settings(Page::Appearance)),
Some("general") => Some(InitialPage::Settings(Page::General)),
Some("theme") => Some(InitialPage::Settings(Page::Theme)),
Some("tray") => Some(InitialPage::Settings(Page::Tray)),
Some("all-options") => Some(InitialPage::Settings(Page::Configuration)),
_ => {
eprintln!("--page accepts connections, wifi, bluetooth, wallpaper, or bar");
return Ok(());
@@ -79,6 +86,9 @@ fn main() -> cosmic::iced::Result {
let path = path.canonicalize().unwrap_or(path);
fonts::families();
let initial = Snapshot::read(&path);
if let Ok(snapshot) = &initial {
ferese_config::locale::set(ferese_config::locale::from_document(&snapshot.doc));
}
let theme = visuals::native_theme(initial.as_ref().ok());
cosmic::app::run::<App>(
@@ -94,12 +104,16 @@ fn main() -> cosmic::iced::Result {
#[derive(Clone, Copy)]
enum InitialPage {
Connections(connections::Tab),
Settings(Page),
Wallpaper,
Bar,
}
#[derive(Clone, Debug)]
enum Message {
Options(all_options::Input),
TrayApps(Vec<tray_controls::Application>),
RefreshTrayApps,
ReadRenderScale(cosmic::iced::window::Id),
RenderScale(f32),
Connections(connections::Input),
@@ -165,6 +179,8 @@ enum Message {
}
struct App {
tray_apps: Vec<tray_controls::Application>,
options: all_options::State,
connections: connections::State,
displays: Vec<displays::Display>,
display_selection: Option<String>,
@@ -265,7 +281,11 @@ impl cosmic::Application for App {
let font = fonts::interface_font(&resolved.presented.tokens.typography.font_family);
let native_palette = visuals::Palette::from_resolved(&resolved.presented);
let family_sections = theme_controls::FamilySections::new(&resolved.families, &current);
ferese_config::locale::set(ferese_config::locale::from_document(&current.doc));
let options = all_options::State::load(&current);
let mut app = Self {
tray_apps: Vec::new(),
options,
connections: connections::State {
tab: match initial_page {
Some(InitialPage::Connections(tab)) => tab,
@@ -291,6 +311,7 @@ impl cosmic::Application for App {
Some(InitialPage::Connections(_)) => Page::Connections,
Some(InitialPage::Wallpaper) => Page::Wallpaper,
Some(InitialPage::Bar) => Page::Bar,
Some(InitialPage::Settings(page)) => page,
None => Page::Appearance,
},
profile_pages: std::env::var_os("FERESE_PROFILE_SETTINGS").is_some(),
@@ -328,9 +349,15 @@ impl cosmic::Application for App {
let task = app
.core
.main_window_id()
.map(|id| app.set_window_title("Ferese Settings".into(), id))
.map(|id| app.set_window_title(ferese_config::tr!("Ferese Settings").into(), id))
.unwrap_or_else(Task::none);
let tray_apps = if app.page == Page::Tray {
app.load_tray_apps()
} else {
Task::none()
};
let task = Task::batch([task, tray_apps]);
let connections = if app.page == Page::Connections {
app.refresh_connections()
} else {
@@ -347,6 +374,9 @@ impl cosmic::Application for App {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::TrayApps(apps) => self.tray_apps = apps,
Message::RefreshTrayApps => return self.load_tray_apps(),
Message::Options(input) => return self.options_input(input),
Message::DragWindow => return self.core.drag(None),
Message::ReadRenderScale(id) => {
return cosmic::iced::window::scale_factor(id)
@@ -427,11 +457,16 @@ impl cosmic::Application for App {
|| !self.inputs.is_empty()
|| !self.ranges.is_empty()
|| !self.pending.is_empty()
|| self.options.dirty()
{
self.status =
"Config changed externally · Reload when your edits are finished"
.into();
} else {
ferese_config::locale::set(ferese_config::locale::from_document(
&snapshot.doc,
));
self.options.reset(&snapshot);
self.current = snapshot.clone();
self.draft = snapshot;
self.family_sections = theme_controls::FamilySections::new(
@@ -493,6 +528,12 @@ impl cosmic::Application for App {
self.page_transition = self.profile_pages.then(std::time::Instant::now);
let leaving = self.page == Page::Connections && page != Page::Connections;
if page == Page::Configuration && !self.options.dirty() {
self.options.reset(&self.current);
}
if page == Page::Configuration {
self.options.filter = self.search.clone();
}
self.page = page;
self.search.clear();
self.visible_rows = initial_visible_rows();
@@ -507,6 +548,7 @@ impl cosmic::Application for App {
let load = match page {
Page::Displays | Page::Bar => self.load_displays(),
Page::Wallpaper => self.load_thumbnail(),
Page::Tray => self.load_tray_apps(),
_ => Task::none(),
};
return Task::batch([reset, cleanup, load]);
@@ -517,6 +559,9 @@ impl cosmic::Application for App {
if matches!(page, Page::Displays | Page::Bar) {
return Task::batch([reset, self.load_displays()]);
}
if page == Page::Tray {
return Task::batch([reset, self.load_tray_apps()]);
}
if page == Page::Wallpaper {
return Task::batch([reset, self.load_thumbnail()]);
}
@@ -725,6 +770,12 @@ impl cosmic::Application for App {
Ok((snapshot, live)) => {
self.undo = Some(std::mem::take(&mut self.saving_previous));
self.current = snapshot;
ferese_config::locale::set(ferese_config::locale::from_document(
&self.current.doc,
));
if !self.options.dirty() || self.options.applying {
self.options.reset(&self.current);
}
self.font = fonts::interface_font(
&self.resolved.presented.tokens.typography.font_family,
);
@@ -755,7 +806,18 @@ impl cosmic::Application for App {
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
Message::ExpireUndo(revision)
});
let title = self
.core
.main_window_id()
.map(|id| {
self.set_window_title(
ferese_config::tr!("Ferese Settings").into(),
id,
)
})
.unwrap_or_else(Task::none);
return Task::batch([
title,
self.update_theme(),
self.flush(),
self.load_thumbnail(),
@@ -766,12 +828,15 @@ impl cosmic::Application for App {
self.error = Some(error);
self.pending.clear();
self.draft = self.current.clone();
self.options.applying = false;
self.status = "Not saved".into();
}
}
}
Message::Reload if !self.saving => match Snapshot::read(&self.path) {
Ok(snapshot) => {
ferese_config::locale::set(ferese_config::locale::from_document(&snapshot.doc));
self.options.reset(&snapshot);
self.current = snapshot.clone();
self.draft = snapshot;
self.family_sections =
@@ -1754,7 +1819,7 @@ mod tests {
.expect("requested renderer");
eprintln!("renderer={}", Headless::name(&renderer));
for page in [Page::Shortcuts, Page::Appearance] {
for page in [Page::Shortcuts, Page::Theme] {
let mut app = shortcuts(500);
app.page = page;
let theme = app.native_palette.native_theme();