diff --git a/dash-frontend/src/tab/settings/tab_look_and_feel.rs b/dash-frontend/src/tab/settings/tab_look_and_feel.rs index a63f7a72..1cc10e6e 100644 --- a/dash-frontend/src/tab/settings/tab_look_and_feel.rs +++ b/dash-frontend/src/tab/settings/tab_look_and_feel.rs @@ -1,11 +1,48 @@ +use std::rc::Rc; + +use wgui::{ + components::button::{ButtonClickEvent, ComponentButton}, + i18n::Translation, + layout::WidgetID, + palette::PALETTES, + parser::{Fetchable, TemplateParams}, + widget::label::WidgetLabel, + windowing::context_menu, +}; +use wlx_common::{config::GeneralConfig, dash_interface::ConfigChangeKind}; + use crate::tab::settings::{ - SettingType, SettingsMountParams, SettingsTab, - macros::{options_category, options_checkbox, options_dropdown, options_slider_f32}, + horiz_cell, + macros::{options_category, options_checkbox, options_dropdown, options_slider_f32, MacroParams}, + SettingType, SettingsMountParams, SettingsTab, Task, }; pub struct State {} -impl SettingsTab for State {} +impl SettingsTab for State { + fn context_menu_custom( + &mut self, + action: Rc, + config: &mut GeneralConfig, + change_kind: &mut Option, + layout: &mut wgui::layout::Layout, + state: &mut wgui::parser::ParserState, + ) -> anyhow::Result<()> { + if let (Some(_), Some(id), Some(palette_name)) = { + let mut s = action.splitn(3, ';'); + (s.next(), s.next(), s.next()) + } { + let mut common = layout.common(); + let mut label = state.fetch_widget_as::(common.state, &format!("{id}_value"))?; + label.set_text(&mut common, Translation::from_raw_text(palette_name)); + + config.color_palette = palette_name.into(); + change_kind.replace(ConfigChangeKind::WguiThemeChange); + } + + Ok(()) + } +} impl State { pub fn mount(par: SettingsMountParams) -> anyhow::Result { @@ -16,6 +53,7 @@ impl State { "dashboard/palette.svg", )?; options_dropdown::(par.mp, c, &SettingType::Language)?; + palettes_dropdown(par.mp, c)?; options_checkbox(par.mp, c, SettingType::OpaqueBackground)?; options_checkbox(par.mp, c, SettingType::HideUsername)?; options_checkbox(par.mp, c, SettingType::HideGrabHelp)?; @@ -29,3 +67,52 @@ impl State { Ok(State {}) } } + +fn palettes_dropdown(mp: &mut MacroParams, parent: WidgetID) -> anyhow::Result<()> { + let id = mp.idx.to_string(); + mp.idx += 1; + + let parent = horiz_cell(mp.layout, parent)?; + + let current_palette = mp.config.color_palette.as_ref(); + + let mut params = TemplateParams::new(); + params.insert("id", &id); + params.insert("translation", "APP_SETTINGS.COLOR_PALETTE".into()); + params.insert("tooltip", "APP_SETTINGS.COLOR_PALETTE_HELP".into()); + + mp.parser_state + .instantiate_template(mp.doc_params, "DropdownButton", mp.layout, parent, params)?; + + { + let mut label = mp + .parser_state + .fetch_widget_as::(&mp.layout.state, &format!("{id}_value"))?; + label.set_text_simple( + &mut mp.layout.state.globals.get(), + Translation::from_raw_text(current_palette), + ); + } + + let btn = mp.parser_state.fetch_component_as::(&id)?; + btn.on_click(Rc::new({ + let parent_tasks = mp.tasks.clone(); + move |_common, e: ButtonClickEvent| { + let cells = PALETTES //TODO: enumerate custom palettes + .iter() + .enumerate() + .map(|(_, item)| context_menu::Cell { + action_name: Some(format!(";{id};{}", item.0).into()), + title: Translation::from_raw_text(item.0), + tooltip: None, + attribs: vec![], + }) + .collect::>(); + + parent_tasks.push(Task::OpenContextMenu(e.mouse_pos_absolute.unwrap_or_default(), cells)); + Ok(()) + } + })); + + Ok(()) +} diff --git a/wayvr/src/config.rs b/wayvr/src/config.rs index 4d01cdc9..c83da477 100644 --- a/wayvr/src/config.rs +++ b/wayvr/src/config.rs @@ -186,6 +186,7 @@ pub struct AutoSettings { pub tutorial_graduated: bool, pub whisper_model: Arc, pub default_overlay_scale: f32, + pub color_palette: Arc, } fn get_settings_path() -> PathBuf { @@ -250,6 +251,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> { tutorial_graduated: config.tutorial_graduated, whisper_model: config.whisper_model.clone(), default_overlay_scale: config.default_overlay_scale, + color_palette: config.color_palette.clone(), }; let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic diff --git a/wlx-common/src/config.rs b/wlx-common/src/config.rs index c7ecebbc..88a93beb 100644 --- a/wlx-common/src/config.rs +++ b/wlx-common/src/config.rs @@ -249,6 +249,10 @@ fn def_empty() -> Arc { "".into() } +fn def_default() -> Arc { + "Default".into() +} + fn def_theme_path() -> Arc { "theme".into() } @@ -468,4 +472,7 @@ pub struct GeneralConfig { #[serde(default = "def_empty")] pub whisper_model: Arc, + + #[serde(default = "def_default")] + pub color_palette: Arc, } diff --git a/wlx-common/src/dash_interface.rs b/wlx-common/src/dash_interface.rs index 81cfaa26..5741e78c 100644 --- a/wlx-common/src/dash_interface.rs +++ b/wlx-common/src/dash_interface.rs @@ -82,6 +82,7 @@ pub trait DashInterface { pub enum ConfigChangeKind { OverlayConfig, EnvironmentBlend, + WguiThemeChange, // TODO: does not do anything right now /// Marks the config for saving but doesn't notify any components #[default] Other,