Add thumbnail selection for compression and watermark previews
This commit is contained in:
@@ -276,6 +276,53 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
preview_group.add(&size_box);
|
||||
preview_group.add(&preview_frame);
|
||||
|
||||
// Thumbnail strip for selecting preview image
|
||||
let thumb_scrolled = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Automatic)
|
||||
.vscrollbar_policy(gtk::PolicyType::Never)
|
||||
.max_content_height(60)
|
||||
.build();
|
||||
|
||||
let thumb_box = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.spacing(4)
|
||||
.margin_top(4)
|
||||
.margin_bottom(4)
|
||||
.halign(gtk::Align::Center)
|
||||
.build();
|
||||
thumb_scrolled.set_child(Some(&thumb_box));
|
||||
|
||||
let preview_index: Rc<RefCell<usize>> = Rc::new(RefCell::new(0));
|
||||
|
||||
// Populate thumbnails from loaded files
|
||||
{
|
||||
let files = state.loaded_files.borrow();
|
||||
let max_thumbs = files.len().min(10); // Show at most 10 thumbnails
|
||||
for i in 0..max_thumbs {
|
||||
let pic = gtk::Picture::builder()
|
||||
.content_fit(gtk::ContentFit::Cover)
|
||||
.width_request(50)
|
||||
.height_request(50)
|
||||
.build();
|
||||
pic.set_filename(Some(&files[i]));
|
||||
let frame = gtk::Frame::builder()
|
||||
.child(&pic)
|
||||
.build();
|
||||
if i == 0 {
|
||||
frame.add_css_class("accent");
|
||||
}
|
||||
|
||||
let btn = gtk::Button::builder()
|
||||
.child(&frame)
|
||||
.has_frame(false)
|
||||
.tooltip_text(files[i].file_name().and_then(|n| n.to_str()).unwrap_or("image"))
|
||||
.build();
|
||||
|
||||
thumb_box.append(&btn);
|
||||
}
|
||||
thumb_scrolled.set_visible(max_thumbs > 1);
|
||||
}
|
||||
|
||||
// "No image loaded" placeholder
|
||||
let no_image_label = gtk::Label::builder()
|
||||
.label("Add images first to see compression preview")
|
||||
@@ -284,6 +331,7 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
.margin_top(4)
|
||||
.build();
|
||||
preview_group.add(&no_image_label);
|
||||
preview_group.add(&thumb_scrolled);
|
||||
|
||||
content.append(&preview_group);
|
||||
|
||||
@@ -371,6 +419,7 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
let comp_label = compressed_size_label.clone();
|
||||
let no_img_label = no_image_label.clone();
|
||||
let jc = state.job_config.clone();
|
||||
let pidx = preview_index.clone();
|
||||
|
||||
Rc::new(move || {
|
||||
let loaded = files.borrow();
|
||||
@@ -380,8 +429,9 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
}
|
||||
no_img_label.set_visible(false);
|
||||
|
||||
// Pick the first image as sample
|
||||
let sample_path = loaded[0].clone();
|
||||
// Pick the selected preview image
|
||||
let idx = *pidx.borrow();
|
||||
let sample_path = loaded.get(idx).cloned().unwrap_or_else(|| loaded[0].clone());
|
||||
let cfg = jc.borrow();
|
||||
let preset = cfg.quality_preset;
|
||||
drop(cfg);
|
||||
@@ -449,6 +499,42 @@ pub fn build_compress_page(state: &AppState) -> adw::NavigationPage {
|
||||
})
|
||||
};
|
||||
|
||||
// Wire thumbnail buttons to switch preview image
|
||||
{
|
||||
let mut child = thumb_box.first_child();
|
||||
let mut idx = 0usize;
|
||||
while let Some(widget) = child {
|
||||
if let Some(btn) = widget.downcast_ref::<gtk::Button>() {
|
||||
let pidx = preview_index.clone();
|
||||
let up = update_preview.clone();
|
||||
let tb = thumb_box.clone();
|
||||
let current_idx = idx;
|
||||
btn.connect_clicked(move |_| {
|
||||
*pidx.borrow_mut() = current_idx;
|
||||
up();
|
||||
// Update highlight on thumbnails
|
||||
let mut c = tb.first_child();
|
||||
let mut j = 0usize;
|
||||
while let Some(w) = c {
|
||||
if let Some(b) = w.downcast_ref::<gtk::Button>() {
|
||||
if let Some(f) = b.child().and_then(|c| c.downcast::<gtk::Frame>().ok()) {
|
||||
if j == current_idx {
|
||||
f.add_css_class("accent");
|
||||
} else {
|
||||
f.remove_css_class("accent");
|
||||
}
|
||||
}
|
||||
}
|
||||
c = w.next_sibling();
|
||||
j += 1;
|
||||
}
|
||||
});
|
||||
idx += 1;
|
||||
}
|
||||
child = widget.next_sibling();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger initial preview load
|
||||
{
|
||||
let up = update_preview.clone();
|
||||
|
||||
Reference in New Issue
Block a user