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:
142
pixstrip-gtk/src/steps/step_images.rs
Normal file
142
pixstrip-gtk/src/steps/step_images.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
use adw::prelude::*;
|
||||
|
||||
pub fn build_images_page() -> adw::NavigationPage {
|
||||
let stack = gtk::Stack::builder()
|
||||
.transition_type(gtk::StackTransitionType::Crossfade)
|
||||
.build();
|
||||
|
||||
// Empty state - drop zone
|
||||
let empty_state = build_empty_state();
|
||||
stack.add_named(&empty_state, Some("empty"));
|
||||
|
||||
// Loaded state - thumbnail grid (placeholder for now)
|
||||
let loaded_state = build_loaded_state();
|
||||
stack.add_named(&loaded_state, Some("loaded"));
|
||||
|
||||
stack.set_visible_child_name("empty");
|
||||
|
||||
adw::NavigationPage::builder()
|
||||
.title("Add Images")
|
||||
.tag("step-images")
|
||||
.child(&stack)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn build_empty_state() -> gtk::Box {
|
||||
let container = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.vexpand(true)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
|
||||
let drop_zone = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.spacing(12)
|
||||
.halign(gtk::Align::Center)
|
||||
.valign(gtk::Align::Center)
|
||||
.vexpand(true)
|
||||
.margin_top(48)
|
||||
.margin_bottom(48)
|
||||
.margin_start(48)
|
||||
.margin_end(48)
|
||||
.build();
|
||||
drop_zone.add_css_class("card");
|
||||
|
||||
let inner = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.spacing(12)
|
||||
.margin_top(48)
|
||||
.margin_bottom(48)
|
||||
.margin_start(64)
|
||||
.margin_end(64)
|
||||
.halign(gtk::Align::Center)
|
||||
.build();
|
||||
|
||||
let icon = gtk::Image::builder()
|
||||
.icon_name("folder-pictures-symbolic")
|
||||
.pixel_size(64)
|
||||
.css_classes(["dim-label"])
|
||||
.build();
|
||||
|
||||
let title = gtk::Label::builder()
|
||||
.label("Drop images here")
|
||||
.css_classes(["title-2"])
|
||||
.build();
|
||||
|
||||
let subtitle = gtk::Label::builder()
|
||||
.label("or click Browse to select files")
|
||||
.css_classes(["dim-label"])
|
||||
.build();
|
||||
|
||||
let browse_button = gtk::Button::builder()
|
||||
.label("Browse Files")
|
||||
.tooltip_text("Add image files (Ctrl+O)")
|
||||
.halign(gtk::Align::Center)
|
||||
.build();
|
||||
browse_button.add_css_class("suggested-action");
|
||||
browse_button.add_css_class("pill");
|
||||
|
||||
inner.append(&icon);
|
||||
inner.append(&title);
|
||||
inner.append(&subtitle);
|
||||
inner.append(&browse_button);
|
||||
drop_zone.append(&inner);
|
||||
|
||||
container.append(&drop_zone);
|
||||
container
|
||||
}
|
||||
|
||||
fn build_loaded_state() -> gtk::Box {
|
||||
let container = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.spacing(0)
|
||||
.build();
|
||||
|
||||
// Toolbar
|
||||
let toolbar = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.spacing(8)
|
||||
.margin_start(12)
|
||||
.margin_end(12)
|
||||
.margin_top(8)
|
||||
.margin_bottom(8)
|
||||
.build();
|
||||
|
||||
let count_label = gtk::Label::builder()
|
||||
.label("0 images (0 B)")
|
||||
.hexpand(true)
|
||||
.halign(gtk::Align::Start)
|
||||
.css_classes(["heading"])
|
||||
.build();
|
||||
|
||||
let add_button = gtk::Button::builder()
|
||||
.icon_name("list-add-symbolic")
|
||||
.tooltip_text("Add more images")
|
||||
.build();
|
||||
add_button.add_css_class("flat");
|
||||
|
||||
let select_all_button = gtk::Button::builder()
|
||||
.label("Select All")
|
||||
.tooltip_text("Select all images (Ctrl+A)")
|
||||
.build();
|
||||
select_all_button.add_css_class("flat");
|
||||
|
||||
toolbar.append(&count_label);
|
||||
toolbar.append(&add_button);
|
||||
toolbar.append(&select_all_button);
|
||||
|
||||
let separator = gtk::Separator::new(gtk::Orientation::Horizontal);
|
||||
|
||||
// Thumbnail grid placeholder
|
||||
let grid_placeholder = adw::StatusPage::builder()
|
||||
.title("Images will appear here")
|
||||
.icon_name("image-x-generic-symbolic")
|
||||
.vexpand(true)
|
||||
.build();
|
||||
|
||||
container.append(&toolbar);
|
||||
container.append(&separator);
|
||||
container.append(&grid_placeholder);
|
||||
|
||||
container
|
||||
}
|
||||
Reference in New Issue
Block a user