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.
180 lines
4.8 KiB
Rust
180 lines
4.8 KiB
Rust
use adw::prelude::*;
|
|
use pixstrip_core::preset::Preset;
|
|
|
|
pub fn build_workflow_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();
|
|
|
|
// Built-in presets section
|
|
let builtin_group = adw::PreferencesGroup::builder()
|
|
.title("Built-in Workflows")
|
|
.description("Select a preset to get started quickly")
|
|
.build();
|
|
|
|
let builtin_flow = gtk::FlowBox::builder()
|
|
.selection_mode(gtk::SelectionMode::Single)
|
|
.max_children_per_line(4)
|
|
.min_children_per_line(2)
|
|
.row_spacing(8)
|
|
.column_spacing(8)
|
|
.homogeneous(true)
|
|
.build();
|
|
|
|
for preset in Preset::all_builtins() {
|
|
let card = build_preset_card(&preset);
|
|
builtin_flow.append(&card);
|
|
}
|
|
|
|
builtin_group.add(&builtin_flow);
|
|
content.append(&builtin_group);
|
|
|
|
// Custom workflow section
|
|
let custom_group = adw::PreferencesGroup::builder()
|
|
.title("Custom Workflow")
|
|
.description("Choose which operations to include")
|
|
.build();
|
|
|
|
let custom_card = build_custom_card();
|
|
let custom_flow = gtk::FlowBox::builder()
|
|
.selection_mode(gtk::SelectionMode::None)
|
|
.max_children_per_line(4)
|
|
.min_children_per_line(2)
|
|
.build();
|
|
custom_flow.append(&custom_card);
|
|
custom_group.add(&custom_flow);
|
|
content.append(&custom_group);
|
|
|
|
// User presets section (initially empty)
|
|
let user_group = adw::PreferencesGroup::builder()
|
|
.title("Your Presets")
|
|
.description("Import or save your own workflows")
|
|
.build();
|
|
|
|
let import_button = gtk::Button::builder()
|
|
.label("Import Preset")
|
|
.icon_name("document-open-symbolic")
|
|
.build();
|
|
import_button.add_css_class("flat");
|
|
user_group.add(&import_button);
|
|
content.append(&user_group);
|
|
|
|
scrolled.set_child(Some(&content));
|
|
|
|
let clamp = adw::Clamp::builder()
|
|
.maximum_size(800)
|
|
.child(&scrolled)
|
|
.build();
|
|
|
|
adw::NavigationPage::builder()
|
|
.title("Choose a Workflow")
|
|
.tag("step-workflow")
|
|
.child(&clamp)
|
|
.build()
|
|
}
|
|
|
|
fn build_preset_card(preset: &Preset) -> gtk::Box {
|
|
let card = gtk::Box::builder()
|
|
.orientation(gtk::Orientation::Vertical)
|
|
.spacing(8)
|
|
.halign(gtk::Align::Center)
|
|
.valign(gtk::Align::Start)
|
|
.build();
|
|
card.add_css_class("card");
|
|
card.set_size_request(180, 120);
|
|
|
|
let inner = gtk::Box::builder()
|
|
.orientation(gtk::Orientation::Vertical)
|
|
.spacing(4)
|
|
.margin_top(16)
|
|
.margin_bottom(16)
|
|
.margin_start(12)
|
|
.margin_end(12)
|
|
.halign(gtk::Align::Center)
|
|
.valign(gtk::Align::Center)
|
|
.vexpand(true)
|
|
.build();
|
|
|
|
let icon = gtk::Image::builder()
|
|
.icon_name(&preset.icon)
|
|
.pixel_size(32)
|
|
.build();
|
|
|
|
let name_label = gtk::Label::builder()
|
|
.label(&preset.name)
|
|
.css_classes(["heading"])
|
|
.build();
|
|
|
|
let desc_label = gtk::Label::builder()
|
|
.label(&preset.description)
|
|
.css_classes(["caption", "dim-label"])
|
|
.wrap(true)
|
|
.justify(gtk::Justification::Center)
|
|
.max_width_chars(20)
|
|
.build();
|
|
|
|
inner.append(&icon);
|
|
inner.append(&name_label);
|
|
inner.append(&desc_label);
|
|
card.append(&inner);
|
|
|
|
card
|
|
}
|
|
|
|
fn build_custom_card() -> gtk::Box {
|
|
let card = gtk::Box::builder()
|
|
.orientation(gtk::Orientation::Vertical)
|
|
.spacing(8)
|
|
.halign(gtk::Align::Center)
|
|
.valign(gtk::Align::Start)
|
|
.build();
|
|
card.add_css_class("card");
|
|
card.set_size_request(180, 120);
|
|
|
|
let inner = gtk::Box::builder()
|
|
.orientation(gtk::Orientation::Vertical)
|
|
.spacing(4)
|
|
.margin_top(16)
|
|
.margin_bottom(16)
|
|
.margin_start(12)
|
|
.margin_end(12)
|
|
.halign(gtk::Align::Center)
|
|
.valign(gtk::Align::Center)
|
|
.vexpand(true)
|
|
.build();
|
|
|
|
let icon = gtk::Image::builder()
|
|
.icon_name("applications-system-symbolic")
|
|
.pixel_size(32)
|
|
.build();
|
|
|
|
let name_label = gtk::Label::builder()
|
|
.label("Custom...")
|
|
.css_classes(["heading"])
|
|
.build();
|
|
|
|
let desc_label = gtk::Label::builder()
|
|
.label("Pick your own operations")
|
|
.css_classes(["caption", "dim-label"])
|
|
.wrap(true)
|
|
.justify(gtk::Justification::Center)
|
|
.build();
|
|
|
|
inner.append(&icon);
|
|
inner.append(&name_label);
|
|
inner.append(&desc_label);
|
|
card.append(&inner);
|
|
|
|
card
|
|
}
|