Add all wizard step UIs: workflow, images, resize, convert, compress, metadata, output

Full Adwaita widget-based layouts for all 7 wizard steps with
PreferencesGroups, SwitchRows, SpinRows, ComboRows, FlowBoxes,
ExpanderRows for social media presets, quality slider with named
marks, metadata radio group, and output configuration.
This commit is contained in:
2026-03-06 11:08:38 +02:00
parent 20f4c24538
commit a66db2b3bb
10 changed files with 980 additions and 26 deletions

View File

@@ -0,0 +1,189 @@
use adw::prelude::*;
pub fn build_resize_page() -> 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();
// Enable toggle
let enable_row = adw::SwitchRow::builder()
.title("Enable Resize")
.subtitle("Resize images to new dimensions")
.active(true)
.build();
let enable_group = adw::PreferencesGroup::new();
enable_group.add(&enable_row);
content.append(&enable_group);
// Resize mode selector
let mode_group = adw::PreferencesGroup::builder()
.title("Resize Mode")
.build();
// Width/Height mode
let width_row = adw::SpinRow::builder()
.title("Width")
.subtitle("Target width in pixels")
.adjustment(&gtk::Adjustment::new(1200.0, 1.0, 10000.0, 1.0, 100.0, 0.0))
.build();
let height_row = adw::SpinRow::builder()
.title("Height")
.subtitle("Target height in pixels (0 = auto from aspect ratio)")
.adjustment(&gtk::Adjustment::new(0.0, 0.0, 10000.0, 1.0, 100.0, 0.0))
.build();
mode_group.add(&width_row);
mode_group.add(&height_row);
content.append(&mode_group);
// Social media presets
let presets_group = adw::PreferencesGroup::builder()
.title("Quick Dimension Presets")
.build();
let fedi_expander = adw::ExpanderRow::builder()
.title("Fediverse / Open Platforms")
.subtitle("Mastodon, Pixelfed, Bluesky, Lemmy")
.build();
let fedi_presets = [
("Mastodon Post", "1920 x 1080"),
("Mastodon Profile", "400 x 400"),
("Mastodon Header", "1500 x 500"),
("Pixelfed Post", "1080 x 1080"),
("Pixelfed Story", "1080 x 1920"),
("Bluesky Post", "1200 x 630"),
("Bluesky Profile", "400 x 400"),
("Lemmy Post", "1200 x 630"),
];
for (name, dims) in &fedi_presets {
let row = adw::ActionRow::builder()
.title(*name)
.subtitle(*dims)
.activatable(true)
.build();
row.add_suffix(&gtk::Image::from_icon_name("go-next-symbolic"));
fedi_expander.add_row(&row);
}
let mainstream_expander = adw::ExpanderRow::builder()
.title("Mainstream Platforms")
.subtitle("Instagram, YouTube, LinkedIn, Pinterest")
.build();
let mainstream_presets = [
("Instagram Post", "1080 x 1080"),
("Instagram Story/Reel", "1080 x 1920"),
("Facebook Post", "1200 x 630"),
("YouTube Thumbnail", "1280 x 720"),
("LinkedIn Post", "1200 x 627"),
("Pinterest Pin", "1000 x 1500"),
];
for (name, dims) in &mainstream_presets {
let row = adw::ActionRow::builder()
.title(*name)
.subtitle(*dims)
.activatable(true)
.build();
row.add_suffix(&gtk::Image::from_icon_name("go-next-symbolic"));
mainstream_expander.add_row(&row);
}
let other_expander = adw::ExpanderRow::builder()
.title("Common Sizes")
.subtitle("HD, Blog, Thumbnail")
.build();
let other_presets = [
("Full HD", "1920 x 1080"),
("Blog Image", "800 wide"),
("Thumbnail", "150 x 150"),
];
for (name, dims) in &other_presets {
let row = adw::ActionRow::builder()
.title(*name)
.subtitle(*dims)
.activatable(true)
.build();
row.add_suffix(&gtk::Image::from_icon_name("go-next-symbolic"));
other_expander.add_row(&row);
}
presets_group.add(&fedi_expander);
presets_group.add(&mainstream_expander);
presets_group.add(&other_expander);
content.append(&presets_group);
// Basic adjustments (rotation/flip)
let adjust_group = adw::PreferencesGroup::builder()
.title("Basic Adjustments")
.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));
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));
adjust_group.add(&rotate_row);
adjust_group.add(&flip_row);
content.append(&adjust_group);
// Advanced options
let advanced_group = adw::PreferencesGroup::builder()
.title("Advanced Options")
.build();
let algo_row = adw::ComboRow::builder()
.title("Resize Algorithm")
.subtitle("Higher quality is slower")
.build();
let algo_model = gtk::StringList::new(&["Lanczos3 (Best)", "CatmullRom", "Bilinear", "Nearest"]);
algo_row.set_model(Some(&algo_model));
let upscale_row = adw::SwitchRow::builder()
.title("Allow Upscaling")
.subtitle("Enlarge images smaller than target size")
.active(false)
.build();
advanced_group.add(&algo_row);
advanced_group.add(&upscale_row);
content.append(&advanced_group);
scrolled.set_child(Some(&content));
let clamp = adw::Clamp::builder()
.maximum_size(600)
.child(&scrolled)
.build();
adw::NavigationPage::builder()
.title("Resize")
.tag("step-resize")
.child(&clamp)
.build()
}