Wire settings dialog to persist config via ConfigStore
- Load current settings from ConfigStore on dialog open - All switches, combos, and entries reflect saved values - Save all settings back to ConfigStore on dialog close - Covers: output, overwrite, skill level, threads, errors, accessibility, and notification preferences
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
use adw::prelude::*;
|
||||
use pixstrip_core::config::{AppConfig, ErrorBehavior, OverwriteBehavior, SkillLevel};
|
||||
use pixstrip_core::storage::ConfigStore;
|
||||
|
||||
pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
let dialog = adw::PreferencesDialog::builder()
|
||||
.title("Settings")
|
||||
.build();
|
||||
|
||||
let config_store = ConfigStore::new();
|
||||
let config = config_store.load().unwrap_or_default();
|
||||
|
||||
// General page
|
||||
let general_page = adw::PreferencesPage::builder()
|
||||
.title("General")
|
||||
@@ -17,7 +22,7 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
|
||||
let subfolder_row = adw::EntryRow::builder()
|
||||
.title("Default output subfolder")
|
||||
.text("processed")
|
||||
.text(&config.output_subfolder)
|
||||
.build();
|
||||
|
||||
let overwrite_row = adw::ComboRow::builder()
|
||||
@@ -31,11 +36,17 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
"Skip existing files",
|
||||
]);
|
||||
overwrite_row.set_model(Some(&overwrite_model));
|
||||
overwrite_row.set_selected(match config.overwrite_behavior {
|
||||
OverwriteBehavior::Ask => 0,
|
||||
OverwriteBehavior::AutoRename => 1,
|
||||
OverwriteBehavior::Overwrite => 2,
|
||||
OverwriteBehavior::Skip => 3,
|
||||
});
|
||||
|
||||
let remember_row = adw::SwitchRow::builder()
|
||||
.title("Remember last-used settings")
|
||||
.subtitle("Restore wizard state on next launch")
|
||||
.active(true)
|
||||
.active(config.remember_settings)
|
||||
.build();
|
||||
|
||||
output_group.add(&subfolder_row);
|
||||
@@ -53,6 +64,10 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
.build();
|
||||
let skill_model = gtk::StringList::new(&["Simple", "Detailed"]);
|
||||
skill_row.set_model(Some(&skill_model));
|
||||
skill_row.set_selected(match config.skill_level {
|
||||
SkillLevel::Simple => 0,
|
||||
SkillLevel::Detailed => 1,
|
||||
});
|
||||
|
||||
ui_group.add(&skill_row);
|
||||
general_page.add(&ui_group);
|
||||
@@ -81,6 +96,10 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
.build();
|
||||
let error_model = gtk::StringList::new(&["Skip and continue", "Pause on error"]);
|
||||
error_row.set_model(Some(&error_model));
|
||||
error_row.set_selected(match config.error_behavior {
|
||||
ErrorBehavior::SkipAndContinue => 0,
|
||||
ErrorBehavior::PauseOnError => 1,
|
||||
});
|
||||
|
||||
threads_group.add(&threads_row);
|
||||
threads_group.add(&error_row);
|
||||
@@ -101,19 +120,19 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
let contrast_row = adw::SwitchRow::builder()
|
||||
.title("High contrast")
|
||||
.subtitle("Increase visual contrast throughout the app")
|
||||
.active(false)
|
||||
.active(config.high_contrast)
|
||||
.build();
|
||||
|
||||
let large_text_row = adw::SwitchRow::builder()
|
||||
.title("Large text")
|
||||
.subtitle("Increase text size throughout the app")
|
||||
.active(false)
|
||||
.active(config.large_text)
|
||||
.build();
|
||||
|
||||
let motion_row = adw::SwitchRow::builder()
|
||||
.title("Reduced motion")
|
||||
.subtitle("Minimize animations and transitions")
|
||||
.active(false)
|
||||
.active(config.reduced_motion)
|
||||
.build();
|
||||
|
||||
a11y_group.add(&contrast_row);
|
||||
@@ -135,19 +154,19 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
let desktop_notify_row = adw::SwitchRow::builder()
|
||||
.title("Desktop notification")
|
||||
.subtitle("Show notification when processing completes")
|
||||
.active(true)
|
||||
.active(config.notify_on_completion)
|
||||
.build();
|
||||
|
||||
let sound_row = adw::SwitchRow::builder()
|
||||
.title("Completion sound")
|
||||
.subtitle("Play a sound when processing completes")
|
||||
.active(false)
|
||||
.active(config.play_completion_sound)
|
||||
.build();
|
||||
|
||||
let auto_open_row = adw::SwitchRow::builder()
|
||||
.title("Auto-open output folder")
|
||||
.subtitle("Open the output folder in file manager when done")
|
||||
.active(false)
|
||||
.active(config.auto_open_output)
|
||||
.build();
|
||||
|
||||
notify_group.add(&desktop_notify_row);
|
||||
@@ -156,5 +175,39 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
|
||||
notify_page.add(¬ify_group);
|
||||
dialog.add(¬ify_page);
|
||||
|
||||
// Save settings when the dialog closes
|
||||
dialog.connect_closed(move |_| {
|
||||
let new_config = AppConfig {
|
||||
first_run_complete: true,
|
||||
output_subfolder: subfolder_row.text().to_string(),
|
||||
output_fixed_path: None,
|
||||
overwrite_behavior: match overwrite_row.selected() {
|
||||
1 => OverwriteBehavior::AutoRename,
|
||||
2 => OverwriteBehavior::Overwrite,
|
||||
3 => OverwriteBehavior::Skip,
|
||||
_ => OverwriteBehavior::Ask,
|
||||
},
|
||||
remember_settings: remember_row.is_active(),
|
||||
skill_level: match skill_row.selected() {
|
||||
1 => SkillLevel::Detailed,
|
||||
_ => SkillLevel::Simple,
|
||||
},
|
||||
thread_count: pixstrip_core::config::ThreadCount::Auto,
|
||||
error_behavior: match error_row.selected() {
|
||||
1 => ErrorBehavior::PauseOnError,
|
||||
_ => ErrorBehavior::SkipAndContinue,
|
||||
},
|
||||
notify_on_completion: desktop_notify_row.is_active(),
|
||||
play_completion_sound: sound_row.is_active(),
|
||||
auto_open_output: auto_open_row.is_active(),
|
||||
high_contrast: contrast_row.is_active(),
|
||||
large_text: large_text_row.is_active(),
|
||||
reduced_motion: motion_row.is_active(),
|
||||
};
|
||||
|
||||
let store = ConfigStore::new();
|
||||
let _ = store.save(&new_config);
|
||||
});
|
||||
|
||||
dialog
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user