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:
107
pixstrip-gtk/src/steps/step_convert.rs
Normal file
107
pixstrip-gtk/src/steps/step_convert.rs
Normal 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()
|
||||
}
|
||||
Reference in New Issue
Block a user