mod: adjustments

This commit is contained in:
2026-08-27 22:50:40 -04:00
parent 2f4cfe51b7
commit 8c44a35398
3 changed files with 90 additions and 6 deletions
+17
View File
@@ -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
View File
@@ -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
View File
@@ -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: &gtk4::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);