mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-08-19 01:14:43 -05:00
* feat(#1101): auto/force light/force dark color scheme preference * fix: make colors override work with breeze --------- Co-authored-by: Gabriele Musco <gabmus@disroot.org> Co-authored-by: Ilya Zlobintsev <ilya.zl@protonmail.com>
This commit is contained in:
co-authored by
Gabriele Musco
Ilya Zlobintsev
parent
7ae78f16ad
commit
5c18e7acd8
@@ -295,6 +295,11 @@ ui = UI
|
|||||||
daemon = Daemon
|
daemon = Daemon
|
||||||
about = About
|
about = About
|
||||||
|
|
||||||
|
color-scheme = Color Scheme
|
||||||
|
color-scheme-auto = System
|
||||||
|
color-scheme-light = Light
|
||||||
|
color-scheme-dark = Dark
|
||||||
|
|
||||||
# Crash page
|
# Crash page
|
||||||
crash-page-title = Application Crashed
|
crash-page-title = Application Crashed
|
||||||
exit = Exit
|
exit = Exit
|
||||||
|
|||||||
@@ -267,3 +267,7 @@ version-mismatch-description =
|
|||||||
Se hai aggiornato LACT, è necessario riavviare il servizio con:
|
Se hai aggiornato LACT, è necessario riavviare il servizio con:
|
||||||
close = Chiudi
|
close = Chiudi
|
||||||
menu = Menu
|
menu = Menu
|
||||||
|
color-scheme = Schema di Colori
|
||||||
|
color-scheme-auto = Sistema
|
||||||
|
color-scheme-light = Chiaro
|
||||||
|
color-scheme-dark = Scuro
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ impl AsyncComponent for AppModel {
|
|||||||
if let Err(err) = styles::apply_theme(CONFIG.read().theme) {
|
if let Err(err) = styles::apply_theme(CONFIG.read().theme) {
|
||||||
error!("could not apply theme: {err:#}");
|
error!("could not apply theme: {err:#}");
|
||||||
}
|
}
|
||||||
|
CONFIG.read().color_scheme.apply();
|
||||||
|
|
||||||
let (daemon_client, conn_err) = match args.tcp_address {
|
let (daemon_client, conn_err) = match args.tcp_address {
|
||||||
Some(remote_addr) => {
|
Some(remote_addr) => {
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ use crate::{
|
|||||||
app::{
|
app::{
|
||||||
APP_BROKER,
|
APP_BROKER,
|
||||||
msg::AppMsg,
|
msg::AppMsg,
|
||||||
utils::styles::{self, AppTheme},
|
utils::{
|
||||||
|
color_scheme::AppColorScheme,
|
||||||
|
styles::{self, AppTheme},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
config::{MAX_STATS_POLL_INTERVAL_MS, MIN_STATS_POLL_INTERVAL_MS},
|
config::{MAX_STATS_POLL_INTERVAL_MS, MIN_STATS_POLL_INTERVAL_MS},
|
||||||
};
|
};
|
||||||
@@ -27,6 +30,7 @@ pub struct PreferencesDialog {
|
|||||||
pub enum PreferencesDialogMsg {
|
pub enum PreferencesDialogMsg {
|
||||||
Show,
|
Show,
|
||||||
ThemeSelected(AppTheme),
|
ThemeSelected(AppTheme),
|
||||||
|
ColorSchemeSelected(AppColorScheme),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
@@ -90,6 +94,52 @@ impl relm4::Component for PreferencesDialog {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
adw::ActionRow {
|
||||||
|
set_title: &fl!(I18N, "color-scheme"),
|
||||||
|
|
||||||
|
add_suffix = >k::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
add_css_class: "linked",
|
||||||
|
set_valign: gtk::Align::Center,
|
||||||
|
|
||||||
|
#[name = "color_scheme_auto_btn"]
|
||||||
|
gtk::ToggleButton {
|
||||||
|
set_label: &fl!(I18N, "color-scheme-auto"),
|
||||||
|
#[watch]
|
||||||
|
set_active: CONFIG.read().color_scheme == AppColorScheme::Auto,
|
||||||
|
connect_toggled[sender] => move |btn| {
|
||||||
|
if btn.is_active() {
|
||||||
|
sender.input(PreferencesDialogMsg::ColorSchemeSelected(AppColorScheme::Auto));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::ToggleButton {
|
||||||
|
set_label: &fl!(I18N, "color-scheme-light"),
|
||||||
|
set_group: Some(&color_scheme_auto_btn),
|
||||||
|
#[watch]
|
||||||
|
set_active: CONFIG.read().color_scheme == AppColorScheme::Light,
|
||||||
|
connect_toggled[sender] => move |btn| {
|
||||||
|
if btn.is_active() {
|
||||||
|
sender.input(PreferencesDialogMsg::ColorSchemeSelected(AppColorScheme::Light));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::ToggleButton {
|
||||||
|
set_label: &fl!(I18N, "color-scheme-dark"),
|
||||||
|
set_group: Some(&color_scheme_auto_btn),
|
||||||
|
#[watch]
|
||||||
|
set_active: CONFIG.read().color_scheme == AppColorScheme::Dark,
|
||||||
|
connect_toggled[sender] => move |btn| {
|
||||||
|
if btn.is_active() {
|
||||||
|
sender.input(PreferencesDialogMsg::ColorSchemeSelected(AppColorScheme::Dark));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
adw::ActionRow {
|
adw::ActionRow {
|
||||||
set_title: &fl!(I18N, "stats-update-interval"),
|
set_title: &fl!(I18N, "stats-update-interval"),
|
||||||
|
|
||||||
@@ -174,6 +224,14 @@ impl relm4::Component for PreferencesDialog {
|
|||||||
config.theme = theme;
|
config.theme = theme;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
PreferencesDialogMsg::ColorSchemeSelected(scheme) => {
|
||||||
|
scheme.apply();
|
||||||
|
CONFIG.write().edit(|config| {
|
||||||
|
config.color_scheme = scheme;
|
||||||
|
});
|
||||||
|
|
||||||
|
styles::apply_theme(CONFIG.read().theme).expect("Could not apply theme");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.update_view(widgets, sender);
|
self.update_view(widgets, sender);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum AppColorScheme {
|
||||||
|
#[default]
|
||||||
|
Auto,
|
||||||
|
Light,
|
||||||
|
Dark,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AppColorScheme> for adw::ColorScheme {
|
||||||
|
fn from(value: AppColorScheme) -> Self {
|
||||||
|
match value {
|
||||||
|
AppColorScheme::Auto => adw::ColorScheme::Default,
|
||||||
|
AppColorScheme::Light => adw::ColorScheme::ForceLight,
|
||||||
|
AppColorScheme::Dark => adw::ColorScheme::ForceDark,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppColorScheme {
|
||||||
|
pub fn apply(&self) {
|
||||||
|
adw::StyleManager::default().set_color_scheme((*self).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub(crate) mod color_scheme;
|
||||||
pub(crate) mod ext;
|
pub(crate) mod ext;
|
||||||
pub(crate) mod formatting;
|
pub(crate) mod formatting;
|
||||||
pub(crate) mod styles;
|
pub(crate) mod styles;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ use gtk::{
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
use crate::{CONFIG, app::utils::color_scheme::AppColorScheme};
|
||||||
|
|
||||||
pub const COMBINED_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/combined.css"));
|
pub const COMBINED_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/combined.css"));
|
||||||
|
|
||||||
macro_rules! include_theme_str {
|
macro_rules! include_theme_str {
|
||||||
@@ -72,9 +74,13 @@ pub fn apply_theme(theme: AppTheme) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
fn breeze_css() -> &'static str {
|
fn breeze_css() -> &'static str {
|
||||||
let settings = gio::Settings::new("org.gnome.desktop.interface");
|
let settings = gio::Settings::new("org.gnome.desktop.interface");
|
||||||
match settings.string("color-scheme").as_str() {
|
let system_colors = settings.string("color-scheme");
|
||||||
"prefer-dark" => BREEZE_DARK_CSS,
|
|
||||||
"prefer-light" => BREEZE_LIGHT_CSS,
|
let app_colors = CONFIG.read().color_scheme;
|
||||||
|
|
||||||
|
match (app_colors, system_colors.as_str()) {
|
||||||
|
(AppColorScheme::Dark, _) | (AppColorScheme::Auto, "prefer-dark") => BREEZE_DARK_CSS,
|
||||||
|
(AppColorScheme::Light, _) | (AppColorScheme::Auto, "prefer-light") => BREEZE_LIGHT_CSS,
|
||||||
_ => BREEZE_LIGHT_CSS,
|
_ => BREEZE_LIGHT_CSS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use crate::app::{graphs_window::stat::StatType, utils::styles::AppTheme};
|
use crate::app::{
|
||||||
|
graphs_window::stat::StatType,
|
||||||
|
utils::{color_scheme::AppColorScheme, styles::AppTheme},
|
||||||
|
};
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use std::{collections::HashMap, env, fs, path::PathBuf};
|
use std::{collections::HashMap, env, fs, path::PathBuf};
|
||||||
@@ -24,6 +27,8 @@ pub struct UiConfig {
|
|||||||
pub gpus: HashMap<String, UiGpuConfig>,
|
pub gpus: HashMap<String, UiGpuConfig>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub theme: AppTheme,
|
pub theme: AppTheme,
|
||||||
|
#[serde(default)]
|
||||||
|
pub color_scheme: AppColorScheme,
|
||||||
pub window_size: Option<WindowSize>,
|
pub window_size: Option<WindowSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +42,7 @@ impl Default for UiConfig {
|
|||||||
stats_poll_interval_ms: default_stats_poll_interval(),
|
stats_poll_interval_ms: default_stats_poll_interval(),
|
||||||
gpus: HashMap::new(),
|
gpus: HashMap::new(),
|
||||||
theme: AppTheme::Automatic,
|
theme: AppTheme::Automatic,
|
||||||
|
color_scheme: AppColorScheme::default(),
|
||||||
window_size: None,
|
window_size: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user