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:
@@ -273,6 +273,17 @@ fn setup_window_actions(window: &adw::ApplicationWindow, ui: &WizardUi) {
|
|||||||
action_group.add_action(&action);
|
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
|
// Connect button clicks
|
||||||
ui.back_button.connect_clicked({
|
ui.back_button.connect_clicked({
|
||||||
let action_group = action_group.clone();
|
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());
|
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);
|
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) {
|
fn update_images_count_label(ui: &WizardUi, count: usize) {
|
||||||
// Find the step-images page and switch its stack to "loaded" if we have files
|
// Find the step-images page and switch its stack to "loaded" if we have files
|
||||||
if let Some(page) = ui.pages.get(1)
|
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) {
|
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::<gtk::Label>()
|
||||||
if let Some(label) = widget.downcast_ref::<gtk::Label>() {
|
&& label.css_classes().iter().any(|c| c == "heading")
|
||||||
if label.css_classes().iter().any(|c| c == "heading") {
|
{
|
||||||
let files = pixstrip_core::storage::PresetStore::new(); // just for format_bytes
|
label.set_label(&format!("{} images loaded", count));
|
||||||
let _ = files; // unused
|
|
||||||
label.set_label(&format!("{} images loaded", count));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(bx) = widget.downcast_ref::<gtk::Box>() {
|
if let Some(bx) = widget.downcast_ref::<gtk::Box>() {
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ fn build_empty_state() -> gtk::Box {
|
|||||||
.label("Browse Files")
|
.label("Browse Files")
|
||||||
.tooltip_text("Add image files (Ctrl+O)")
|
.tooltip_text("Add image files (Ctrl+O)")
|
||||||
.halign(gtk::Align::Center)
|
.halign(gtk::Align::Center)
|
||||||
|
.action_name("win.add-files")
|
||||||
.build();
|
.build();
|
||||||
browse_button.add_css_class("suggested-action");
|
browse_button.add_css_class("suggested-action");
|
||||||
browse_button.add_css_class("pill");
|
browse_button.add_css_class("pill");
|
||||||
@@ -112,6 +113,7 @@ fn build_loaded_state() -> gtk::Box {
|
|||||||
let add_button = gtk::Button::builder()
|
let add_button = gtk::Button::builder()
|
||||||
.icon_name("list-add-symbolic")
|
.icon_name("list-add-symbolic")
|
||||||
.tooltip_text("Add more images")
|
.tooltip_text("Add more images")
|
||||||
|
.action_name("win.add-files")
|
||||||
.build();
|
.build();
|
||||||
add_button.add_css_class("flat");
|
add_button.add_css_class("flat");
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ pub fn build_output_page() -> adw::NavigationPage {
|
|||||||
.icon_name("folder-open-symbolic")
|
.icon_name("folder-open-symbolic")
|
||||||
.tooltip_text("Choose output folder")
|
.tooltip_text("Choose output folder")
|
||||||
.valign(gtk::Align::Center)
|
.valign(gtk::Align::Center)
|
||||||
|
.action_name("win.choose-output")
|
||||||
.build();
|
.build();
|
||||||
choose_button.add_css_class("flat");
|
choose_button.add_css_class("flat");
|
||||||
output_row.add_suffix(&choose_button);
|
output_row.add_suffix(&choose_button);
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ pub fn build_workflow_page() -> adw::NavigationPage {
|
|||||||
builtin_flow.append(&card);
|
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);
|
builtin_group.add(&builtin_flow);
|
||||||
content.append(&builtin_group);
|
content.append(&builtin_group);
|
||||||
|
|
||||||
@@ -52,6 +57,9 @@ pub fn build_workflow_page() -> adw::NavigationPage {
|
|||||||
.min_children_per_line(2)
|
.min_children_per_line(2)
|
||||||
.build();
|
.build();
|
||||||
custom_flow.append(&custom_card);
|
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);
|
custom_group.add(&custom_flow);
|
||||||
content.append(&custom_group);
|
content.append(&custom_group);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user