mod: adjustments
This commit is contained in:
@@ -2,6 +2,23 @@
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Appearance</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Follow _System</attribute>
|
||||
<attribute name="action">app.theme</attribute>
|
||||
<attribute name="target">system</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Dark</attribute>
|
||||
<attribute name="action">app.theme</attribute>
|
||||
<attribute name="target">dark</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About SNES Patcher</attribute>
|
||||
|
||||
+12
-5
@@ -2,11 +2,6 @@
|
||||
min-width: 356px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -21,3 +16,15 @@
|
||||
min-height: 48px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.intro-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
headerbar.titlebar {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-bottom: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
+61
-1
@@ -7,6 +7,7 @@ use std::rc::Rc;
|
||||
|
||||
use gtk4::gio;
|
||||
use gtk4::glib;
|
||||
use gtk4::glib::ToVariant;
|
||||
use gtk4::pango::EllipsizeMode;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::{
|
||||
@@ -17,6 +18,8 @@ use gtk4::{
|
||||
|
||||
const APP_ID: &str = "com.wyattjmiller.snespatcher";
|
||||
const APP_NAME: &str = "SNES Patcher";
|
||||
const THEME_SYSTEM: &str = "system";
|
||||
const THEME_DARK: &str = "dark";
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SelectionState {
|
||||
@@ -71,7 +74,7 @@ fn build_ui(app: &Application) {
|
||||
|
||||
let introduction = GtkBox::new(Orientation::Vertical, 8);
|
||||
let heading = Label::new(Some("Patch a Super Nintendo ROM"));
|
||||
heading.add_css_class("title");
|
||||
heading.add_css_class("intro-title");
|
||||
heading.set_justify(Justification::Center);
|
||||
heading.set_wrap(true);
|
||||
|
||||
@@ -192,6 +195,8 @@ fn build_header_bar(
|
||||
header_bar.pack_start(rom_info_button);
|
||||
header_bar.pack_end(&menu_button);
|
||||
|
||||
add_theme_action(app);
|
||||
|
||||
let about = gio::SimpleAction::new("about", None);
|
||||
about.connect_activate(glib::clone!(@weak window => move |_, _| {
|
||||
let dialog = AboutDialog::builder()
|
||||
@@ -219,6 +224,61 @@ fn build_header_bar(
|
||||
header_bar
|
||||
}
|
||||
|
||||
fn add_theme_action(app: &Application) {
|
||||
let preference = load_theme_preference();
|
||||
let settings = gtk4::Settings::default().expect("Could not access GTK settings");
|
||||
apply_theme_preference(&settings, &preference);
|
||||
|
||||
let theme = gio::SimpleAction::new_stateful(
|
||||
"theme",
|
||||
Some(glib::VariantTy::STRING),
|
||||
&preference.to_variant(),
|
||||
);
|
||||
theme.connect_activate(move |action, parameter| {
|
||||
let Some(preference) = parameter.and_then(|value| value.get::<String>()) else {
|
||||
return;
|
||||
};
|
||||
if preference != THEME_SYSTEM && preference != THEME_DARK {
|
||||
return;
|
||||
}
|
||||
|
||||
apply_theme_preference(&settings, &preference);
|
||||
action.set_state(&preference.to_variant());
|
||||
save_theme_preference(&preference);
|
||||
});
|
||||
app.add_action(&theme);
|
||||
}
|
||||
|
||||
fn apply_theme_preference(settings: >k4::Settings, preference: &str) {
|
||||
settings.set_gtk_application_prefer_dark_theme(preference == THEME_DARK);
|
||||
}
|
||||
|
||||
fn theme_preference_path() -> PathBuf {
|
||||
glib::user_config_dir().join(APP_ID).join("theme")
|
||||
}
|
||||
|
||||
fn load_theme_preference() -> String {
|
||||
match std::fs::read_to_string(theme_preference_path()) {
|
||||
Ok(preference) if preference.trim() == THEME_DARK => THEME_DARK.to_string(),
|
||||
_ => THEME_SYSTEM.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn save_theme_preference(preference: &str) {
|
||||
let path = theme_preference_path();
|
||||
let Some(parent) = path.parent() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Err(error) = std::fs::create_dir_all(parent) {
|
||||
eprintln!("Could not create the preferences directory: {error}");
|
||||
return;
|
||||
}
|
||||
if let Err(error) = std::fs::write(path, preference) {
|
||||
eprintln!("Could not save the theme preference: {error}");
|
||||
}
|
||||
}
|
||||
|
||||
fn selection_row(title: &str, placeholder: &str, icon_name: &str) -> SelectionRow {
|
||||
let icon = Image::from_icon_name(icon_name);
|
||||
icon.set_pixel_size(24);
|
||||
|
||||
Reference in New Issue
Block a user