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) {
|
fn save_preset_dialog(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
||||||
let dialog = adw::AlertDialog::builder()
|
let dialog = adw::Dialog::builder()
|
||||||
.heading("Save as Preset")
|
.title("Save as Preset")
|
||||||
.body("Enter a name for this workflow preset")
|
.content_width(400)
|
||||||
|
.content_height(500)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let entry = gtk::Entry::builder()
|
let toolbar = adw::ToolbarView::new();
|
||||||
.placeholder_text("My Workflow")
|
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_start(24)
|
||||||
.margin_end(24)
|
.margin_end(24)
|
||||||
.build();
|
.build();
|
||||||
dialog.set_extra_child(Some(&entry));
|
|
||||||
|
|
||||||
dialog.add_response("cancel", "Cancel");
|
// Show summary of current settings
|
||||||
dialog.add_response("save", "Save");
|
let cfg = ui.state.job_config.borrow();
|
||||||
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);
|
let summary = build_preset_description(&cfg);
|
||||||
dialog.set_default_response(Some("save"));
|
drop(cfg);
|
||||||
|
|
||||||
let ui = ui.clone();
|
let summary_group = adw::PreferencesGroup::builder()
|
||||||
dialog.connect_response(None, move |dlg, response| {
|
.title("Workflow Summary")
|
||||||
if response == "save" {
|
.description(&summary)
|
||||||
let extra = dlg.extra_child();
|
.build();
|
||||||
let name = extra
|
content.append(&summary_group);
|
||||||
.as_ref()
|
|
||||||
.and_then(|w| w.downcast_ref::<gtk::Entry>())
|
|
||||||
.map(|e| e.text().to_string())
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
|
// 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() {
|
if name.trim().is_empty() {
|
||||||
let toast = adw::Toast::new("Please enter a name for the preset");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg = ui.state.job_config.borrow();
|
let cfg = ui_c.state.job_config.borrow();
|
||||||
let preset = build_preset_from_config(&cfg, &name);
|
let preset = build_preset_from_config(&cfg, &name);
|
||||||
drop(cfg);
|
drop(cfg);
|
||||||
|
|
||||||
@@ -2088,15 +2176,20 @@ fn save_preset_dialog(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
|||||||
match store.save(&preset) {
|
match store.save(&preset) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let toast = adw::Toast::new(&format!("Saved preset: {}", name));
|
let toast = adw::Toast::new(&format!("Saved preset: {}", name));
|
||||||
ui.toast_overlay.add_toast(toast);
|
ui_c.toast_overlay.add_toast(toast);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let toast = adw::Toast::new(&format!("Failed to save: {}", 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));
|
dialog.present(Some(window));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user