Enhance save preset dialog with settings summary and update option
This commit is contained in:
@@ -2047,40 +2047,128 @@ fn import_preset(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
||||
}
|
||||
|
||||
fn save_preset_dialog(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
||||
let dialog = adw::AlertDialog::builder()
|
||||
.heading("Save as Preset")
|
||||
.body("Enter a name for this workflow preset")
|
||||
let dialog = adw::Dialog::builder()
|
||||
.title("Save as Preset")
|
||||
.content_width(400)
|
||||
.content_height(500)
|
||||
.build();
|
||||
|
||||
let entry = gtk::Entry::builder()
|
||||
.placeholder_text("My Workflow")
|
||||
let toolbar = adw::ToolbarView::new();
|
||||
let header = adw::HeaderBar::new();
|
||||
toolbar.add_top_bar(&header);
|
||||
|
||||
let scrolled = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Never)
|
||||
.vexpand(true)
|
||||
.build();
|
||||
|
||||
let content = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.spacing(12)
|
||||
.margin_top(12)
|
||||
.margin_bottom(12)
|
||||
.margin_start(24)
|
||||
.margin_end(24)
|
||||
.build();
|
||||
dialog.set_extra_child(Some(&entry));
|
||||
|
||||
dialog.add_response("cancel", "Cancel");
|
||||
dialog.add_response("save", "Save");
|
||||
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);
|
||||
dialog.set_default_response(Some("save"));
|
||||
// Show summary of current settings
|
||||
let cfg = ui.state.job_config.borrow();
|
||||
let summary = build_preset_description(&cfg);
|
||||
drop(cfg);
|
||||
|
||||
let ui = ui.clone();
|
||||
dialog.connect_response(None, move |dlg, response| {
|
||||
if response == "save" {
|
||||
let extra = dlg.extra_child();
|
||||
let name = extra
|
||||
.as_ref()
|
||||
.and_then(|w| w.downcast_ref::<gtk::Entry>())
|
||||
.map(|e| e.text().to_string())
|
||||
.unwrap_or_default();
|
||||
let summary_group = adw::PreferencesGroup::builder()
|
||||
.title("Workflow Summary")
|
||||
.description(&summary)
|
||||
.build();
|
||||
content.append(&summary_group);
|
||||
|
||||
// Name entry
|
||||
let name_group = adw::PreferencesGroup::builder()
|
||||
.title("Save as New Preset")
|
||||
.build();
|
||||
|
||||
let name_entry = adw::EntryRow::builder()
|
||||
.title("Preset Name")
|
||||
.build();
|
||||
name_group.add(&name_entry);
|
||||
|
||||
let save_new_button = gtk::Button::builder()
|
||||
.label("Save New Preset")
|
||||
.halign(gtk::Align::Center)
|
||||
.margin_top(8)
|
||||
.build();
|
||||
save_new_button.add_css_class("suggested-action");
|
||||
save_new_button.add_css_class("pill");
|
||||
|
||||
content.append(&name_group);
|
||||
content.append(&save_new_button);
|
||||
|
||||
// "Update existing" section - show user presets
|
||||
let store = pixstrip_core::storage::PresetStore::new();
|
||||
let user_presets: Vec<String> = store
|
||||
.list()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.filter(|p| p.is_custom)
|
||||
.map(|p| p.name)
|
||||
.collect();
|
||||
|
||||
if !user_presets.is_empty() {
|
||||
let update_group = adw::PreferencesGroup::builder()
|
||||
.title("Or Update Existing Preset")
|
||||
.description("Overwrite an existing user preset with current settings")
|
||||
.build();
|
||||
|
||||
for preset_name in &user_presets {
|
||||
let row = adw::ActionRow::builder()
|
||||
.title(preset_name)
|
||||
.activatable(true)
|
||||
.build();
|
||||
row.add_prefix(>k::Image::from_icon_name("document-save-symbolic"));
|
||||
row.add_suffix(>k::Image::from_icon_name("go-next-symbolic"));
|
||||
|
||||
let ui_c = ui.clone();
|
||||
let dlg_c = dialog.clone();
|
||||
let pname = preset_name.clone();
|
||||
row.connect_activated(move |_| {
|
||||
let cfg = ui_c.state.job_config.borrow();
|
||||
let preset = build_preset_from_config(&cfg, &pname);
|
||||
drop(cfg);
|
||||
|
||||
let store = pixstrip_core::storage::PresetStore::new();
|
||||
match store.save(&preset) {
|
||||
Ok(()) => {
|
||||
let toast = adw::Toast::new(&format!("Updated preset: {}", pname));
|
||||
ui_c.toast_overlay.add_toast(toast);
|
||||
}
|
||||
Err(e) => {
|
||||
let toast = adw::Toast::new(&format!("Failed to update: {}", e));
|
||||
ui_c.toast_overlay.add_toast(toast);
|
||||
}
|
||||
}
|
||||
dlg_c.close();
|
||||
});
|
||||
|
||||
update_group.add(&row);
|
||||
}
|
||||
|
||||
content.append(&update_group);
|
||||
}
|
||||
|
||||
// Wire save new button
|
||||
{
|
||||
let ui_c = ui.clone();
|
||||
let dlg_c = dialog.clone();
|
||||
let entry_c = name_entry.clone();
|
||||
save_new_button.connect_clicked(move |_| {
|
||||
let name = entry_c.text().to_string();
|
||||
if name.trim().is_empty() {
|
||||
let toast = adw::Toast::new("Please enter a name for the preset");
|
||||
ui.toast_overlay.add_toast(toast);
|
||||
ui_c.toast_overlay.add_toast(toast);
|
||||
return;
|
||||
}
|
||||
|
||||
let cfg = ui.state.job_config.borrow();
|
||||
let cfg = ui_c.state.job_config.borrow();
|
||||
let preset = build_preset_from_config(&cfg, &name);
|
||||
drop(cfg);
|
||||
|
||||
@@ -2088,15 +2176,20 @@ fn save_preset_dialog(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
||||
match store.save(&preset) {
|
||||
Ok(()) => {
|
||||
let toast = adw::Toast::new(&format!("Saved preset: {}", name));
|
||||
ui.toast_overlay.add_toast(toast);
|
||||
ui_c.toast_overlay.add_toast(toast);
|
||||
}
|
||||
Err(e) => {
|
||||
let toast = adw::Toast::new(&format!("Failed to save: {}", e));
|
||||
ui.toast_overlay.add_toast(toast);
|
||||
ui_c.toast_overlay.add_toast(toast);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
dlg_c.close();
|
||||
});
|
||||
}
|
||||
|
||||
scrolled.set_child(Some(&content));
|
||||
toolbar.set_content(Some(&scrolled));
|
||||
dialog.set_child(Some(&toolbar));
|
||||
|
||||
dialog.present(Some(window));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user