diff --git a/pixstrip-gtk/src/app.rs b/pixstrip-gtk/src/app.rs index cf8e93e..9f33ee3 100644 --- a/pixstrip-gtk/src/app.rs +++ b/pixstrip-gtk/src/app.rs @@ -19,6 +19,7 @@ pub struct JobConfig { pub resize_height: u32, pub allow_upscale: bool, // Adjustments + pub adjustments_enabled: bool, pub rotation: u32, pub flip: u32, pub brightness: i32, @@ -33,12 +34,20 @@ pub struct JobConfig { // Convert pub convert_enabled: bool, pub convert_format: Option, + pub progressive_jpeg: bool, + pub format_mapping_jpeg: u32, + pub format_mapping_png: u32, + pub format_mapping_webp: u32, + pub format_mapping_tiff: u32, // Compress pub compress_enabled: bool, pub quality_preset: pixstrip_core::types::QualityPreset, pub jpeg_quality: u8, pub png_level: u8, pub webp_quality: u8, + pub avif_quality: u8, + pub webp_effort: u8, + pub avif_speed: u8, // Metadata pub metadata_enabled: bool, pub metadata_mode: MetadataMode, @@ -180,6 +189,7 @@ fn build_ui(app: &adw::Application) { resize_width: if remember { sess_state.resize_width.unwrap_or(1200) } else { 1200 }, resize_height: if remember { sess_state.resize_height.unwrap_or(0) } else { 0 }, allow_upscale: false, + adjustments_enabled: false, rotation: 0, flip: 0, brightness: 0, @@ -193,11 +203,19 @@ fn build_ui(app: &adw::Application) { canvas_padding: 0, convert_enabled: if remember { sess_state.convert_enabled.unwrap_or(false) } else { false }, convert_format: None, + progressive_jpeg: false, + format_mapping_jpeg: 0, + format_mapping_png: 0, + format_mapping_webp: 0, + format_mapping_tiff: 0, compress_enabled: if remember { sess_state.compress_enabled.unwrap_or(true) } else { true }, quality_preset: pixstrip_core::types::QualityPreset::Medium, jpeg_quality: 85, png_level: 3, webp_quality: 80, + avif_quality: 50, + webp_effort: 4, + avif_speed: 6, metadata_enabled: if remember { sess_state.metadata_enabled.unwrap_or(true) } else { true }, metadata_mode: MetadataMode::StripAll, strip_gps: true, @@ -1152,24 +1170,22 @@ fn run_processing(_window: &adw::ApplicationWindow, ui: &WizardUi) { }); } - // Rotation - job.rotation = Some(match cfg.rotation { - 1 => pixstrip_core::operations::Rotation::Cw90, - 2 => pixstrip_core::operations::Rotation::Cw180, - 3 => pixstrip_core::operations::Rotation::Cw270, - 4 => pixstrip_core::operations::Rotation::AutoOrient, - _ => pixstrip_core::operations::Rotation::None, - }); + // Rotation, Flip, and Adjustments (only when adjustments step is enabled) + if cfg.adjustments_enabled { + job.rotation = Some(match cfg.rotation { + 1 => pixstrip_core::operations::Rotation::Cw90, + 2 => pixstrip_core::operations::Rotation::Cw180, + 3 => pixstrip_core::operations::Rotation::Cw270, + 4 => pixstrip_core::operations::Rotation::AutoOrient, + _ => pixstrip_core::operations::Rotation::None, + }); - // Flip - job.flip = Some(match cfg.flip { - 1 => pixstrip_core::operations::Flip::Horizontal, - 2 => pixstrip_core::operations::Flip::Vertical, - _ => pixstrip_core::operations::Flip::None, - }); + job.flip = Some(match cfg.flip { + 1 => pixstrip_core::operations::Flip::Horizontal, + 2 => pixstrip_core::operations::Flip::Vertical, + _ => pixstrip_core::operations::Flip::None, + }); - // Adjustments - { let crop = match cfg.crop_aspect_ratio { 1 => Some((1.0, 1.0)), 2 => Some((4.0, 3.0)), diff --git a/pixstrip-gtk/src/steps/step_compress.rs b/pixstrip-gtk/src/steps/step_compress.rs index c97fbec..4f77e57 100644 --- a/pixstrip-gtk/src/steps/step_compress.rs +++ b/pixstrip-gtk/src/steps/step_compress.rs @@ -318,25 +318,25 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage { let avif_row = adw::SpinRow::builder() .title("AVIF Quality") .subtitle("1-100, higher is better quality") - .adjustment(>k::Adjustment::new(50.0, 1.0, 100.0, 1.0, 10.0, 0.0)) + .adjustment(>k::Adjustment::new(cfg.avif_quality as f64, 1.0, 100.0, 1.0, 10.0, 0.0)) .build(); let progressive_row = adw::SwitchRow::builder() .title("Progressive JPEG") .subtitle("Loads gradually, slightly larger files") - .active(false) + .active(cfg.progressive_jpeg) .build(); let webp_effort_row = adw::SpinRow::builder() .title("WebP Encoding Effort") .subtitle("0-6, higher is slower but smaller files") - .adjustment(>k::Adjustment::new(4.0, 0.0, 6.0, 1.0, 1.0, 0.0)) + .adjustment(>k::Adjustment::new(cfg.webp_effort as f64, 0.0, 6.0, 1.0, 1.0, 0.0)) .build(); let avif_speed_row = adw::SpinRow::builder() .title("AVIF Encoding Speed") .subtitle("1-10, lower is slower but better compression") - .adjustment(>k::Adjustment::new(6.0, 1.0, 10.0, 1.0, 1.0, 0.0)) + .adjustment(>k::Adjustment::new(cfg.avif_speed as f64, 1.0, 10.0, 1.0, 1.0, 0.0)) .build(); advanced_expander.add_row(&jpeg_row); @@ -493,6 +493,30 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage { jc.borrow_mut().webp_quality = row.value() as u8; }); } + { + let jc = state.job_config.clone(); + avif_row.connect_value_notify(move |row| { + jc.borrow_mut().avif_quality = row.value() as u8; + }); + } + { + let jc = state.job_config.clone(); + progressive_row.connect_active_notify(move |row| { + jc.borrow_mut().progressive_jpeg = row.is_active(); + }); + } + { + let jc = state.job_config.clone(); + webp_effort_row.connect_value_notify(move |row| { + jc.borrow_mut().webp_effort = row.value() as u8; + }); + } + { + let jc = state.job_config.clone(); + avif_speed_row.connect_value_notify(move |row| { + jc.borrow_mut().avif_speed = row.value() as u8; + }); + } scrolled.set_child(Some(&content)); diff --git a/pixstrip-gtk/src/steps/step_convert.rs b/pixstrip-gtk/src/steps/step_convert.rs index 63a5e34..d1c8589 100644 --- a/pixstrip-gtk/src/steps/step_convert.rs +++ b/pixstrip-gtk/src/steps/step_convert.rs @@ -150,7 +150,7 @@ pub fn build_convert_page(state: &AppState) -> adw::NavigationPage { let progressive_row = adw::SwitchRow::builder() .title("Progressive JPEG") .subtitle("Loads gradually in browsers, slightly larger") - .active(false) + .active(cfg.progressive_jpeg) .build(); // Format mapping rows - per input format output selection @@ -167,24 +167,28 @@ pub fn build_convert_page(state: &AppState) -> adw::NavigationPage { .subtitle("Output format for JPEG source files") .build(); jpeg_mapping.set_model(Some(>k::StringList::new(&output_choices))); + jpeg_mapping.set_selected(cfg.format_mapping_jpeg); let png_mapping = adw::ComboRow::builder() .title("PNG inputs") .subtitle("Output format for PNG source files") .build(); png_mapping.set_model(Some(>k::StringList::new(&output_choices))); + png_mapping.set_selected(cfg.format_mapping_png); let webp_mapping = adw::ComboRow::builder() .title("WebP inputs") .subtitle("Output format for WebP source files") .build(); webp_mapping.set_model(Some(>k::StringList::new(&output_choices))); + webp_mapping.set_selected(cfg.format_mapping_webp); let tiff_mapping = adw::ComboRow::builder() .title("TIFF inputs") .subtitle("Output format for TIFF source files") .build(); tiff_mapping.set_model(Some(>k::StringList::new(&output_choices))); + tiff_mapping.set_selected(cfg.format_mapping_tiff); advanced_expander.add_row(&progressive_row); advanced_expander.add_row(&mapping_header); @@ -222,6 +226,36 @@ pub fn build_convert_page(state: &AppState) -> adw::NavigationPage { label.set_label(&format_info(c.convert_format)); }); } + { + let jc = state.job_config.clone(); + progressive_row.connect_active_notify(move |row| { + jc.borrow_mut().progressive_jpeg = row.is_active(); + }); + } + { + let jc = state.job_config.clone(); + jpeg_mapping.connect_selected_notify(move |row| { + jc.borrow_mut().format_mapping_jpeg = row.selected(); + }); + } + { + let jc = state.job_config.clone(); + png_mapping.connect_selected_notify(move |row| { + jc.borrow_mut().format_mapping_png = row.selected(); + }); + } + { + let jc = state.job_config.clone(); + webp_mapping.connect_selected_notify(move |row| { + jc.borrow_mut().format_mapping_webp = row.selected(); + }); + } + { + let jc = state.job_config.clone(); + tiff_mapping.connect_selected_notify(move |row| { + jc.borrow_mut().format_mapping_tiff = row.selected(); + }); + } scrolled.set_child(Some(&content)); diff --git a/pixstrip-gtk/src/steps/step_workflow.rs b/pixstrip-gtk/src/steps/step_workflow.rs index 0f8ef36..f94f1c5 100644 --- a/pixstrip-gtk/src/steps/step_workflow.rs +++ b/pixstrip-gtk/src/steps/step_workflow.rs @@ -69,7 +69,7 @@ pub fn build_workflow_page(state: &AppState) -> adw::NavigationPage { let adjustments_check = adw::SwitchRow::builder() .title("Adjustments") .subtitle("Rotate, flip, brightness, contrast, effects") - .active(false) + .active(state.job_config.borrow().adjustments_enabled) .build(); let convert_check = adw::SwitchRow::builder() @@ -117,6 +117,12 @@ pub fn build_workflow_page(state: &AppState) -> adw::NavigationPage { jc.borrow_mut().resize_enabled = row.is_active(); }); } + { + let jc = state.job_config.clone(); + adjustments_check.connect_active_notify(move |row| { + jc.borrow_mut().adjustments_enabled = row.is_active(); + }); + } { let jc = state.job_config.clone(); convert_check.connect_active_notify(move |row| {