From 695c83c9e6edc790aee76dd21b2cdc3ebb9f6776 Mon Sep 17 00:00:00 2001 From: Tarasov Aleksandr <55220741+arabianq@users.noreply.github.com> Date: Wed, 27 May 2026 18:24:28 +0300 Subject: [PATCH] feat(gui): theme selection (#122) * fix: increment pkgrel to 2 for pwsp aur package * feat(gui): implemented theme switching * fix(gui): fixed incorrect colors in light theme * fix(gui): fixed incorrect colors in light theme --- locales/app.toml | 44 ++++++++++++++++++++++++++++++++++ packages/aur/standart/.SRCINFO | 2 +- packages/aur/standart/PKGBUILD | 2 +- src/gui/update.rs | 21 ++++++++++++++-- src/gui/views/body.rs | 10 ++++---- src/gui/views/header.rs | 3 +-- src/gui/views/hotkeys.rs | 17 ++++--------- src/gui/views/settings.rs | 37 +++++++++++++++++++++++++++- src/types/config.rs | 11 +++++++++ 9 files changed, 123 insertions(+), 24 deletions(-) diff --git a/locales/app.toml b/locales/app.toml index 9628b53..8f1cd01 100644 --- a/locales/app.toml +++ b/locales/app.toml @@ -195,6 +195,50 @@ kz = "GUI нұсқасы: %{version}" he = "גרסת ממשק משתמש: %{version}" pt-BR = "Versão da GUI: %{version}" +[gui.settings.theme.label] +en = "Color Scheme" +ru = "Цветовая схема" +es = "Esquema de color" +fr = "Schéma de couleurs" +zh = "配色方案" +ar = "نظام الألوان" +kz = "Түс схемасы" +he = "ערכת צבעים" +pt-BR = "Esquema de cores" + +[gui.settings.theme.system] +en = "System" +ru = "Системная" +es = "Sistema" +fr = "Système" +zh = "系统" +ar = "النظام" +kz = "Жүйе" +he = "מערכת" +pt-BR = "Sistema" + +[gui.settings.theme.light] +en = "Light" +ru = "Светлая" +es = "Claro" +fr = "Clair" +zh = "浅色" +ar = "فاتح" +kz = "Жарық" +he = "בהיר" +pt-BR = "Claro" + +[gui.settings.theme.dark] +en = "Dark" +ru = "Тёмная" +es = "Oscuro" +fr = "Sombre" +zh = "暗色" +ar = "داكن" +kz = "Қараңғы" +he = "כהה" +pt-BR = "Escuro" + # ---------------- # Hotkeys # ---------------- diff --git a/packages/aur/standart/.SRCINFO b/packages/aur/standart/.SRCINFO index 92d30d2..90bcd0d 100644 --- a/packages/aur/standart/.SRCINFO +++ b/packages/aur/standart/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = pwsp pkgdesc = Lets you play audio files through your microphone pkgver = 1.9.1 - pkgrel = 1 + pkgrel = 2 url = https://github.com/arabianq/pipewire-soundpad arch = any license = MIT diff --git a/packages/aur/standart/PKGBUILD b/packages/aur/standart/PKGBUILD index 1f417b3..61be050 100644 --- a/packages/aur/standart/PKGBUILD +++ b/packages/aur/standart/PKGBUILD @@ -2,7 +2,7 @@ pkgsubn=pwsp pkgname=pwsp pkgver=1.9.1 -pkgrel=1 +pkgrel=2 pkgdesc="Lets you play audio files through your microphone" arch=('any') url="https://github.com/arabianq/pipewire-soundpad" diff --git a/src/gui/update.rs b/src/gui/update.rs index 4210173..5f9fb4f 100644 --- a/src/gui/update.rs +++ b/src/gui/update.rs @@ -1,14 +1,31 @@ use crate::gui::SoundpadGui; use eframe::{App, Frame as EFrame}; -use egui::{CentralPanel, Context}; +use egui::{CentralPanel, Context, ThemePreference}; use pwsp::{ - types::socket::Request, + types::{config::PreferredTheme, socket::Request}, utils::{daemon::get_daemon_config, gui::make_request_async}, }; use std::time::{Duration, Instant}; impl App for SoundpadGui { fn logic(&mut self, ctx: &Context, _frame: &mut EFrame) { + // Update theme + let current_theme = match ctx.options(|r| r.theme_preference) { + ThemePreference::System => PreferredTheme::System, + ThemePreference::Light => PreferredTheme::Light, + ThemePreference::Dark => PreferredTheme::Dark, + }; + + if !self.config.preferred_theme.eq(¤t_theme) { + ctx.options_mut(|w| { + w.theme_preference = match self.config.preferred_theme { + PreferredTheme::System => ThemePreference::System, + PreferredTheme::Light => ThemePreference::Light, + PreferredTheme::Dark => ThemePreference::Dark, + } + }) + } + // Remove directories for path in self.app_state.dirs_to_remove.drain() { self.app_state.dirs.retain(|x| x != &path); diff --git a/src/gui/views/body.rs b/src/gui/views/body.rs index 08a0089..c0cf69b 100644 --- a/src/gui/views/body.rs +++ b/src/gui/views/body.rs @@ -76,16 +76,16 @@ impl SoundpadGui { .map(|s| s.to_string_lossy().to_string()) .unwrap_or_else(|| path.to_string_lossy().to_string()); - let mut dir_button_text = RichText::new(name.clone()); + let mut dir_button = + Button::new(RichText::new(name.clone()).atom_max_width(area_size.x)) + .frame(false); + if let Some(current_dir) = &self.app_state.current_dir && current_dir.eq(&*path) { - dir_button_text = dir_button_text.color(Color32::WHITE); + dir_button = dir_button.selected(true); } - let dir_button = - Button::new(dir_button_text.atom_max_width(area_size.x)).frame(false); - let dir_button_response = ui.add(dir_button); if dir_button_response.clicked() { dir_to_open = Some(path.clone()); diff --git a/src/gui/views/header.rs b/src/gui/views/header.rs index 99479a7..0795a8d 100644 --- a/src/gui/views/header.rs +++ b/src/gui/views/header.rs @@ -1,5 +1,5 @@ use crate::gui::SoundpadGui; -use egui::{Button, CollapsingHeader, Color32, FontFamily, Label, RichText, Slider, Ui}; +use egui::{Button, CollapsingHeader, FontFamily, Label, RichText, Slider, Ui}; use egui_material_icons::icons::*; use pwsp::types::{audio_player::TrackInfo, gui::AppState}; use pwsp::utils::gui::format_time_pair; @@ -32,7 +32,6 @@ impl SoundpadGui { .to_str() .unwrap_or_default(), ) - .color(Color32::WHITE) .family(FontFamily::Monospace), ) .default_open(true) diff --git a/src/gui/views/hotkeys.rs b/src/gui/views/hotkeys.rs index 75564e5..f45f081 100644 --- a/src/gui/views/hotkeys.rs +++ b/src/gui/views/hotkeys.rs @@ -146,32 +146,28 @@ impl SoundpadGui { ui.label( RichText::new(t!("gui.hotkeys.column_slot")) .strong() - .monospace() - .color(Color32::LIGHT_GRAY), + .monospace(), ); }); header.col(|ui| { ui.label( RichText::new(t!("gui.hotkeys.column_sound")) .strong() - .monospace() - .color(Color32::LIGHT_GRAY), + .monospace(), ); }); header.col(|ui| { ui.label( RichText::new(t!("gui.hotkeys.column_key_chord")) .strong() - .monospace() - .color(Color32::LIGHT_GRAY), + .monospace(), ); }); header.col(|ui| { ui.label( RichText::new(t!("gui.hotkeys.column_actions")) .strong() - .monospace() - .color(Color32::LIGHT_GRAY), + .monospace(), ); }); }) @@ -180,10 +176,7 @@ impl SoundpadGui { body.row(30.0, |mut row| { row.col(|_| {}); row.col(|ui| { - ui.label( - RichText::new(t!("gui.hotkeys.no_hotkeys_configured")) - .color(Color32::GRAY), - ); + ui.label(RichText::new(t!("gui.hotkeys.no_hotkeys_configured"))); }); row.col(|_| {}); row.col(|_| {}); diff --git a/src/gui/views/settings.rs b/src/gui/views/settings.rs index 5673e75..30a6998 100644 --- a/src/gui/views/settings.rs +++ b/src/gui/views/settings.rs @@ -1,6 +1,7 @@ use crate::gui::SoundpadGui; -use egui::{Align, Button, Color32, Layout, RichText, Ui}; +use egui::{Align, Button, Color32, ComboBox, Layout, RichText, Ui}; use egui_material_icons::icons::ICON_ARROW_BACK; +use pwsp::types::config::PreferredTheme; use rust_i18n::t; impl SoundpadGui { @@ -53,6 +54,40 @@ impl SoundpadGui { } // -------------------------------- + ui.separator(); + + // ---------- Selectors ----------- + let mut selected_theme = self.config.preferred_theme.clone(); + ComboBox::from_label(t!("gui.settings.theme.label")) + .selected_text(match self.config.preferred_theme { + PreferredTheme::System => t!("gui.settings.theme.system"), + PreferredTheme::Light => t!("gui.settings.theme.light"), + PreferredTheme::Dark => t!("gui.settings.theme.dark"), + }) + .show_ui(ui, |ui| { + ui.selectable_value( + &mut selected_theme, + PreferredTheme::System, + t!("gui.settings.theme.system"), + ); + ui.selectable_value( + &mut selected_theme, + PreferredTheme::Light, + t!("gui.settings.theme.light"), + ); + ui.selectable_value( + &mut selected_theme, + PreferredTheme::Dark, + t!("gui.settings.theme.dark"), + ); + }); + + if selected_theme != self.config.preferred_theme { + self.config.preferred_theme = selected_theme; + self.config.save_to_file().ok(); + } + // -------------------------------- + ui.with_layout(Layout::bottom_up(Align::Min), |ui| { ui.label(t!( "gui.settings.version", diff --git a/src/types/config.rs b/src/types/config.rs index 301d692..2fb8617 100644 --- a/src/types/config.rs +++ b/src/types/config.rs @@ -35,6 +35,13 @@ impl DaemonConfig { } } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum PreferredTheme { + System, + Light, + Dark, +} + #[derive(Clone, Serialize, Deserialize)] #[serde(default)] pub struct GuiConfig { @@ -47,6 +54,8 @@ pub struct GuiConfig { pub pause_on_exit: bool, pub dirs: Vec, + + pub preferred_theme: PreferredTheme, } impl Default for GuiConfig { @@ -61,6 +70,8 @@ impl Default for GuiConfig { pause_on_exit: false, dirs: vec![], + + preferred_theme: PreferredTheme::System, } } }