Add Adjustments, Watermark, Rename wizard steps; expand to 10-step wizard

- New step_adjustments: rotation (5 options) and flip (3 options)
- New step_watermark: text/image watermark with position, opacity, font size
- New step_rename: prefix/suffix/counter with live preview and template engine
- Updated step_metadata: added Custom mode with per-category checkboxes
  (GPS, camera, software, timestamps, copyright) with show/hide toggle
- Expanded JobConfig with all operation fields (watermark, rename, metadata custom)
- Updated wizard from 7 to 10 steps in correct pipeline order
- Fixed page index references from 6 to 9 for output step
- Added MetadataMode::Custom handling in preset builder and output summary
This commit is contained in:
2026-03-06 12:15:02 +02:00
parent a7f1df2ba5
commit 8154324929
7 changed files with 796 additions and 12 deletions

View File

@@ -0,0 +1,87 @@
use adw::prelude::*;
use crate::app::AppState;
pub fn build_adjustments_page(state: &AppState) -> adw::NavigationPage {
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();
let cfg = state.job_config.borrow();
// Rotate
let rotate_group = adw::PreferencesGroup::builder()
.title("Rotation")
.build();
let rotate_row = adw::ComboRow::builder()
.title("Rotate")
.subtitle("Rotation applied after resize")
.build();
let rotate_model = gtk::StringList::new(&[
"None",
"90 clockwise",
"180",
"270 clockwise",
"Auto-orient (EXIF)",
]);
rotate_row.set_model(Some(&rotate_model));
rotate_row.set_selected(cfg.rotation);
rotate_group.add(&rotate_row);
content.append(&rotate_group);
// Flip
let flip_group = adw::PreferencesGroup::builder()
.title("Flip")
.build();
let flip_row = adw::ComboRow::builder()
.title("Flip")
.subtitle("Mirror the image")
.build();
let flip_model = gtk::StringList::new(&["None", "Horizontal", "Vertical"]);
flip_row.set_model(Some(&flip_model));
flip_row.set_selected(cfg.flip);
flip_group.add(&flip_row);
content.append(&flip_group);
drop(cfg);
// Wire signals
{
let jc = state.job_config.clone();
rotate_row.connect_selected_notify(move |row| {
jc.borrow_mut().rotation = row.selected();
});
}
{
let jc = state.job_config.clone();
flip_row.connect_selected_notify(move |row| {
jc.borrow_mut().flip = row.selected();
});
}
scrolled.set_child(Some(&content));
let clamp = adw::Clamp::builder()
.maximum_size(600)
.child(&scrolled)
.build();
adw::NavigationPage::builder()
.title("Adjustments")
.tag("step-adjustments")
.child(&clamp)
.build()
}