Wire up step buttons: Browse, preset cards, output directory picker

- Browse Files button triggers win.add-files action
- Add More button in loaded state triggers win.add-files action
- Preset card activation (click) advances to next wizard step
- Custom workflow card activation advances to next step
- Choose output folder button opens folder dialog
- Output step shows current image count when navigated to
- Clean up dead code in update_count_in_box
This commit is contained in:
2026-03-06 11:41:46 +02:00
parent b6aae711ec
commit c20e0db2ff
4 changed files with 71 additions and 7 deletions

View File

@@ -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::<adw::ActionRow>()
&& 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::<adw::ActionRow>()
&& 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: &gtk::Widget, count: usize) {
// Walk the widget tree to find the heading label with "images" text
if let Some(label) = widget.downcast_ref::<gtk::Label>() {
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::<gtk::Label>()
&& label.css_classes().iter().any(|c| c == "heading")
{
label.set_label(&format!("{} images loaded", count));
return;
}
if let Some(bx) = widget.downcast_ref::<gtk::Box>() {

View File

@@ -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");

View File

@@ -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);

View File

@@ -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);