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,107 @@
use adw::prelude::*;
pub fn build_convert_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 Format Conversion")
.subtitle("Convert images to a different format")
.active(false)
.build();
let enable_group = adw::PreferencesGroup::new();
enable_group.add(&enable_row);
content.append(&enable_group);
// Format selection
let format_group = adw::PreferencesGroup::builder()
.title("Output Format")
.build();
let formats = [
("Keep Original", "No conversion - output in same format as input"),
("JPEG", "Universal photo format, lossy compression"),
("PNG", "Lossless format, good for graphics and screenshots"),
("WebP", "Modern web format, excellent compression, wide support"),
("AVIF", "Next-gen format, best compression, growing support"),
];
let format_flow = gtk::FlowBox::builder()
.selection_mode(gtk::SelectionMode::Single)
.max_children_per_line(5)
.min_children_per_line(2)
.row_spacing(8)
.column_spacing(8)
.homogeneous(true)
.build();
for (name, desc) in &formats {
let card = gtk::Box::builder()
.orientation(gtk::Orientation::Vertical)
.spacing(4)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
card.add_css_class("card");
card.set_size_request(140, 80);
let inner = gtk::Box::builder()
.orientation(gtk::Orientation::Vertical)
.spacing(4)
.margin_top(12)
.margin_bottom(12)
.margin_start(8)
.margin_end(8)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.vexpand(true)
.build();
let name_label = gtk::Label::builder()
.label(*name)
.css_classes(["heading"])
.build();
let desc_label = gtk::Label::builder()
.label(*desc)
.css_classes(["caption", "dim-label"])
.wrap(true)
.justify(gtk::Justification::Center)
.max_width_chars(18)
.build();
inner.append(&name_label);
inner.append(&desc_label);
card.append(&inner);
format_flow.append(&card);
}
format_group.add(&format_flow);
content.append(&format_group);
scrolled.set_child(Some(&content));
let clamp = adw::Clamp::builder()
.maximum_size(600)
.child(&scrolled)
.build();
adw::NavigationPage::builder()
.title("Convert")
.tag("step-convert")
.child(&clamp)
.build()
}