diff --git a/pixstrip-gtk/src/app.rs b/pixstrip-gtk/src/app.rs index e075c95..27e2cbd 100644 --- a/pixstrip-gtk/src/app.rs +++ b/pixstrip-gtk/src/app.rs @@ -273,6 +273,17 @@ fn setup_window_actions(window: &adw::ApplicationWindow, ui: &WizardUi) { action_group.add_action(&action); } + // Choose output directory action + { + let window = window.clone(); + let ui = ui.clone(); + let action = gtk::gio::SimpleAction::new("choose-output", None); + action.connect_activate(move |_, _| { + open_output_chooser(&window, &ui); + }); + action_group.add_action(&action); + } + // Connect button clicks ui.back_button.connect_clicked({ let action_group = action_group.clone(); @@ -316,6 +327,21 @@ fn navigate_to_step(ui: &WizardUi, target: usize) { ui.title.set_subtitle(&ui.pages[target].title()); } + // Update dynamic content on certain steps + if target == 6 { + // Output step - update image count + let count = ui.state.loaded_files.borrow().len(); + if let Some(page) = ui.pages.get(6) { + walk_widgets(&page.child(), &|widget| { + if let Some(row) = widget.downcast_ref::() + && row.title().as_str() == "Images to process" + { + row.set_subtitle(&format!("{} images", count)); + } + }); + } + } + update_nav_buttons(&s, &ui.back_button, &ui.next_button); } @@ -378,6 +404,36 @@ fn open_file_chooser(window: &adw::ApplicationWindow, ui: &WizardUi) { }); } +fn open_output_chooser(window: &adw::ApplicationWindow, ui: &WizardUi) { + let dialog = gtk::FileDialog::builder() + .title("Choose Output Folder") + .modal(true) + .build(); + + let ui = ui.clone(); + dialog.select_folder(Some(window), gtk::gio::Cancellable::NONE, move |result| { + if let Ok(folder) = result + && let Some(path) = folder.path() + { + *ui.state.output_dir.borrow_mut() = Some(path.clone()); + update_output_label(&ui, &path); + } + }); +} + +fn update_output_label(ui: &WizardUi, path: &std::path::Path) { + // Find the output step page (index 6) and update the output location subtitle + if let Some(page) = ui.pages.get(6) { + walk_widgets(&page.child(), &|widget| { + if let Some(row) = widget.downcast_ref::() + && row.title().as_str() == "Output Location" + { + row.set_subtitle(&path.display().to_string()); + } + }); + } +} + fn update_images_count_label(ui: &WizardUi, count: usize) { // Find the step-images page and switch its stack to "loaded" if we have files if let Some(page) = ui.pages.get(1) @@ -393,13 +449,10 @@ fn update_images_count_label(ui: &WizardUi, count: usize) { } fn update_count_in_box(widget: >k::Widget, count: usize) { - // Walk the widget tree to find the heading label with "images" text - if let Some(label) = widget.downcast_ref::() { - if label.css_classes().iter().any(|c| c == "heading") { - let files = pixstrip_core::storage::PresetStore::new(); // just for format_bytes - let _ = files; // unused - label.set_label(&format!("{} images loaded", count)); - } + if let Some(label) = widget.downcast_ref::() + && label.css_classes().iter().any(|c| c == "heading") + { + label.set_label(&format!("{} images loaded", count)); return; } if let Some(bx) = widget.downcast_ref::() { diff --git a/pixstrip-gtk/src/steps/step_images.rs b/pixstrip-gtk/src/steps/step_images.rs index 043f0a8..6a10661 100644 --- a/pixstrip-gtk/src/steps/step_images.rs +++ b/pixstrip-gtk/src/steps/step_images.rs @@ -72,6 +72,7 @@ fn build_empty_state() -> gtk::Box { .label("Browse Files") .tooltip_text("Add image files (Ctrl+O)") .halign(gtk::Align::Center) + .action_name("win.add-files") .build(); browse_button.add_css_class("suggested-action"); browse_button.add_css_class("pill"); @@ -112,6 +113,7 @@ fn build_loaded_state() -> gtk::Box { let add_button = gtk::Button::builder() .icon_name("list-add-symbolic") .tooltip_text("Add more images") + .action_name("win.add-files") .build(); add_button.add_css_class("flat"); diff --git a/pixstrip-gtk/src/steps/step_output.rs b/pixstrip-gtk/src/steps/step_output.rs index 5191750..64bfad9 100644 --- a/pixstrip-gtk/src/steps/step_output.rs +++ b/pixstrip-gtk/src/steps/step_output.rs @@ -46,6 +46,7 @@ pub fn build_output_page() -> adw::NavigationPage { .icon_name("folder-open-symbolic") .tooltip_text("Choose output folder") .valign(gtk::Align::Center) + .action_name("win.choose-output") .build(); choose_button.add_css_class("flat"); output_row.add_suffix(&choose_button); diff --git a/pixstrip-gtk/src/steps/step_workflow.rs b/pixstrip-gtk/src/steps/step_workflow.rs index a598f53..c203e70 100644 --- a/pixstrip-gtk/src/steps/step_workflow.rs +++ b/pixstrip-gtk/src/steps/step_workflow.rs @@ -36,6 +36,11 @@ pub fn build_workflow_page() -> adw::NavigationPage { builtin_flow.append(&card); } + // When a preset card is activated, advance to the next step + builtin_flow.connect_child_activated(|flow, _child| { + flow.activate_action("win.next-step", None).ok(); + }); + builtin_group.add(&builtin_flow); content.append(&builtin_group); @@ -52,6 +57,9 @@ pub fn build_workflow_page() -> adw::NavigationPage { .min_children_per_line(2) .build(); custom_flow.append(&custom_card); + custom_flow.connect_child_activated(|flow, _child| { + flow.activate_action("win.next-step", None).ok(); + }); custom_group.add(&custom_flow); content.append(&custom_group);