From d2c23ac6a984f5366532714d6db9ed6620b308a1 Mon Sep 17 00:00:00 2001 From: Aleksander Date: Fri, 7 Nov 2025 19:40:38 +0100 Subject: [PATCH] add settings: am/pm clock, opaque background, hide username --- dash-frontend/assets/gui/dashboard.xml | 7 ++- dash-frontend/assets/lang/de.json | 3 +- dash-frontend/assets/lang/en.json | 1 + dash-frontend/assets/lang/es.json | 3 +- dash-frontend/assets/lang/ja.json | 3 +- dash-frontend/assets/lang/pl.json | 59 ++++++++--------- dash-frontend/src/frontend.rs | 87 ++++++++++++++++++++------ dash-frontend/src/tab/home.rs | 12 +++- dash-frontend/src/tab/settings.rs | 16 ++++- 9 files changed, 132 insertions(+), 59 deletions(-) diff --git a/dash-frontend/assets/gui/dashboard.xml b/dash-frontend/assets/gui/dashboard.xml index 4f80849f..b4e804e2 100644 --- a/dash-frontend/assets/gui/dashboard.xml +++ b/dash-frontend/assets/gui/dashboard.xml @@ -64,9 +64,12 @@ height="100%" overflow_x="scroll"> + + >; pub enum FrontendTask { SetTab(TabType), + RefreshClock, + RefreshBackground, } impl Frontend { @@ -67,18 +70,26 @@ impl Frontend { let mut tasks = VecDeque::::new(); tasks.push_back(FrontendTask::SetTab(TabType::Home)); - let label_time_id = state.get_widget_id("label_time")?; + let id_label_time = state.get_widget_id("label_time")?; + let id_rect_content = state.get_widget_id("rect_content")?; - let res = Rc::new(RefCell::new(Self { + let frontend = Self { layout: rc_layout.clone(), state, current_tab: None, globals, tasks, ticks: 0, - label_time_id, + id_label_time, + id_rect_content, settings: params.settings, - })); + }; + + // init some things first + frontend.update_background()?; + frontend.update_time()?; + + let res = Rc::new(RefCell::new(frontend)); Frontend::register_widgets(&res)?; @@ -97,31 +108,65 @@ impl Frontend { } fn tick(&mut self, width: f32, height: f32, timestep_alpha: f32) -> anyhow::Result<()> { - let mut layout = self.layout.borrow_mut(); - - let mut c = layout.start_common(); - // fixme: timer events instead of this thing if self.ticks.is_multiple_of(1000) { - self.update_time(&mut c.common()); + self.update_time()?; } - c.finish()?; - layout.update(Vec2::new(width, height), timestep_alpha)?; + { + let mut layout = self.layout.borrow_mut(); + layout.update(Vec2::new(width, height), timestep_alpha)?; + } Ok(()) } - fn update_time(&self, common: &mut CallbackDataCommon) { - let Some(mut label) = common.state.widgets.get_as::(self.label_time_id) else { - return; + fn update_time(&self) -> anyhow::Result<()> { + let mut layout = self.layout.borrow_mut(); + let mut c = layout.start_common(); + let mut common = c.common(); + + { + let Some(mut label) = common.state.widgets.get_as::(self.id_label_time) else { + anyhow::bail!(""); + }; + + let now = chrono::Local::now(); + let hours = now.hour(); + let minutes = now.minute(); + + let text: String = if !self.settings.general.am_pm_clock { + format!("{hours:02}:{minutes:02}") + } else { + let hours_ampm = (hours + 11) % 12 + 1; + let suffix = if hours >= 12 { "PM" } else { "AM" }; + format!("{hours_ampm:02}:{minutes:02} {suffix}") + }; + + label.set_text(&mut common, Translation::from_raw_text(&text)); + } + + c.finish()?; + Ok(()) + } + + fn update_background(&self) -> anyhow::Result<()> { + let layout = self.layout.borrow_mut(); + + let Some(mut rect) = layout.state.widgets.get_as::(self.id_rect_content) else { + anyhow::bail!(""); }; - let now = chrono::Local::now(); - let hours = now.hour(); - let minutes = now.minute(); + let (alpha1, alpha2) = if !self.settings.general.opaque_background { + (0.8666, 0.9333) + } else { + (1.0, 1.0) + }; - label.set_text(common, Translation::from_raw_text(&format!("{hours:02}:{minutes:02}"))); + rect.params.color.a = alpha1; + rect.params.color2.a = alpha2; + + Ok(()) } pub fn get_layout(&self) -> &RcLayout { @@ -135,6 +180,8 @@ impl Frontend { fn process_task(&mut self, rc_this: &RcFrontend, task: FrontendTask) -> anyhow::Result<()> { match task { FrontendTask::SetTab(tab_type) => self.set_tab(tab_type, rc_this)?, + FrontendTask::RefreshClock => self.update_time()?, + FrontendTask::RefreshBackground => self.update_background()?, } Ok(()) } diff --git a/dash-frontend/src/tab/home.rs b/dash-frontend/src/tab/home.rs index 84819188..7472a9cb 100644 --- a/dash-frontend/src/tab/home.rs +++ b/dash-frontend/src/tab/home.rs @@ -7,6 +7,7 @@ use wgui::{ }; use crate::{ + settings, tab::{Tab, TabParams, TabType}, various, }; @@ -22,7 +23,7 @@ impl Tab for TabHome { } } -fn configure_label_hello(label_hello: &mut WidgetLabel, i18n: &mut wgui::i18n::I18n) { +fn configure_label_hello(label_hello: &mut WidgetLabel, i18n: &mut wgui::i18n::I18n, settings: &settings::Settings) { let mut username = various::get_username(); // first character as uppercase if let Some(first) = username.chars().next() { @@ -30,7 +31,12 @@ fn configure_label_hello(label_hello: &mut WidgetLabel, i18n: &mut wgui::i18n::I username.replace_range(0..1, &first); } - let translated = i18n.translate_and_replace("HELLO_USER", ("{USER}", &username)); + let translated = if !settings.home_screen.hide_username { + i18n.translate_and_replace("HELLO_USER", ("{USER}", &username)) + } else { + i18n.translate("HELLO").to_string() + }; + label_hello.set_text_simple(i18n, Translation::from_raw_text(&translated)); } @@ -47,7 +53,7 @@ impl TabHome { )?; let mut label_hello = state.fetch_widget_as::(¶ms.layout.state, "label_hello")?; - configure_label_hello(&mut label_hello, &mut params.globals.i18n()); + configure_label_hello(&mut label_hello, &mut params.globals.i18n(), params.settings); let btn_apps = state.fetch_component_as::("btn_apps")?; let btn_games = state.fetch_component_as::("btn_games")?; diff --git a/dash-frontend/src/tab/settings.rs b/dash-frontend/src/tab/settings.rs index c5d0dd79..94eb53f0 100644 --- a/dash-frontend/src/tab/settings.rs +++ b/dash-frontend/src/tab/settings.rs @@ -3,12 +3,11 @@ use std::rc::Rc; use wgui::{ assets::AssetPath, components::checkbox::ComponentCheckbox, - event::CallbackDataCommon, parser::{Fetchable, ParseDocumentParams, ParserState}, }; use crate::{ - frontend::{Frontend, RcFrontend}, + frontend::{Frontend, FrontendTask}, settings, tab::{Tab, TabParams, TabType}, }; @@ -28,6 +27,7 @@ fn init_setting_checkbox( params: &mut TabParams, checkbox: Rc, fetch_callback: fn(&mut settings::Settings) -> &mut bool, + change_callback: Option, ) -> anyhow::Result<()> { let mut c = params.layout.start_common(); @@ -36,6 +36,10 @@ fn init_setting_checkbox( checkbox.on_toggle(Box::new(move |_common, e| { let mut frontend = rc_frontend.borrow_mut(); *fetch_callback(&mut frontend.settings) = e.checked; + + if let Some(change_callback) = &change_callback { + change_callback(&mut frontend, e.checked); + } Ok(()) })); @@ -59,12 +63,16 @@ impl TabSettings { &mut params, state.data.fetch_component_as::("cb_hide_username")?, |settings| &mut settings.home_screen.hide_username, + None, )?; init_setting_checkbox( &mut params, state.data.fetch_component_as::("cb_am_pm_clock")?, |settings| &mut settings.general.am_pm_clock, + Some(|frontend, _| { + frontend.push_task(FrontendTask::RefreshClock); + }), )?; init_setting_checkbox( @@ -73,6 +81,9 @@ impl TabSettings { .data .fetch_component_as::("cb_opaque_background")?, |settings| &mut settings.general.opaque_background, + Some(|frontend, _| { + frontend.push_task(FrontendTask::RefreshBackground); + }), )?; init_setting_checkbox( @@ -81,6 +92,7 @@ impl TabSettings { .data .fetch_component_as::("cb_xwayland_by_default")?, |settings| &mut settings.tweaks.xwayland_by_default, + None, )?; Ok(Self { state })