Improve UX, add popover tour, metadata, and hicolor icons
- Redesign tutorial tour from modal dialogs to popovers pointing at actual UI elements - Add beginner-friendly improvements: help buttons, tooltips, welcome wizard enhancements - Add AppStream metainfo with screenshots, branding, categories, keywords, provides - Update desktop file with GTK category and SingleMainWindow - Add hicolor icon theme with all sizes (16-512px) - Fix debounce SourceId panic in rename step - Various step UI improvements and bug fixes
This commit is contained in:
@@ -109,6 +109,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.title("Enable Resize")
|
||||
.subtitle("Scale images to new dimensions")
|
||||
.active(cfg.resize_enabled)
|
||||
.tooltip_text("Toggle resizing of images on or off")
|
||||
.build();
|
||||
enable_group.add(&enable_row);
|
||||
outer.append(&enable_group);
|
||||
@@ -179,6 +180,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
let category_row = adw::ComboRow::builder()
|
||||
.title("Category")
|
||||
.use_subtitle(true)
|
||||
.tooltip_text("Choose a category of size presets")
|
||||
.build();
|
||||
category_row.set_model(Some(>k::StringList::new(CATEGORIES)));
|
||||
category_row.set_list_factory(Some(&super::full_text_list_factory()));
|
||||
@@ -187,6 +189,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.title("Size")
|
||||
.subtitle("Select a preset to fill dimensions")
|
||||
.use_subtitle(true)
|
||||
.tooltip_text("Pick a preset size to fill dimensions")
|
||||
.build();
|
||||
rebuild_size_model(&size_row, 0);
|
||||
|
||||
@@ -214,6 +217,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.label("W")
|
||||
.css_classes(["dim-label"])
|
||||
.build();
|
||||
w_label.set_accessible_role(gtk::AccessibleRole::Presentation);
|
||||
let width_spin = gtk::SpinButton::builder()
|
||||
.adjustment(>k::Adjustment::new(
|
||||
cfg.resize_width as f64, 0.0, 10000.0, 1.0, 100.0, 0.0,
|
||||
@@ -250,12 +254,28 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.label("H")
|
||||
.css_classes(["dim-label"])
|
||||
.build();
|
||||
h_label.set_accessible_role(gtk::AccessibleRole::Presentation);
|
||||
|
||||
// Unit segmented toggle (px / %)
|
||||
let unit_box = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||
unit_box.add_css_class("linked");
|
||||
let px_btn = gtk::Button::builder().label("px").build();
|
||||
let pct_btn = gtk::Button::builder().label("%").build();
|
||||
unit_box.update_property(&[
|
||||
gtk::accessible::Property::Label("Dimension unit toggle"),
|
||||
]);
|
||||
let px_btn = gtk::Button::builder()
|
||||
.label("px")
|
||||
.tooltip_text("Use pixel dimensions (currently active)")
|
||||
.build();
|
||||
px_btn.update_property(&[
|
||||
gtk::accessible::Property::Label("Pixels - currently active"),
|
||||
]);
|
||||
let pct_btn = gtk::Button::builder()
|
||||
.label("%")
|
||||
.tooltip_text("Use percentage dimensions")
|
||||
.build();
|
||||
pct_btn.update_property(&[
|
||||
gtk::accessible::Property::Label("Percentage"),
|
||||
]);
|
||||
px_btn.add_css_class("suggested-action");
|
||||
unit_box.append(&px_btn);
|
||||
unit_box.append(&pct_btn);
|
||||
@@ -273,6 +293,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.title("Mode")
|
||||
.subtitle("How dimensions are applied to images")
|
||||
.use_subtitle(true)
|
||||
.tooltip_text("Exact stretches to dimensions; Fit keeps aspect ratio")
|
||||
.build();
|
||||
mode_row.set_model(Some(>k::StringList::new(&[
|
||||
"Exact Size",
|
||||
@@ -285,6 +306,7 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.title("Allow Upscaling")
|
||||
.subtitle("Enlarge images smaller than target size")
|
||||
.active(cfg.allow_upscale)
|
||||
.tooltip_text("When off, images smaller than target are left as-is")
|
||||
.build();
|
||||
|
||||
dims_group.add(&mode_row);
|
||||
@@ -568,9 +590,15 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
if btn.is_active() {
|
||||
lb.set_icon_name("changes-prevent-symbolic");
|
||||
lb.set_tooltip_text(Some("Aspect ratio locked"));
|
||||
lb.update_property(&[
|
||||
gtk::accessible::Property::Label("Aspect ratio locked - click to unlock"),
|
||||
]);
|
||||
} else {
|
||||
lb.set_icon_name("changes-allow-symbolic");
|
||||
lb.set_tooltip_text(Some("Aspect ratio unlocked"));
|
||||
lb.update_property(&[
|
||||
gtk::accessible::Property::Label("Aspect ratio unlocked - click to lock"),
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -711,6 +739,14 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
ip.set(false);
|
||||
px.add_css_class("suggested-action");
|
||||
pct.remove_css_class("suggested-action");
|
||||
px.update_property(&[
|
||||
gtk::accessible::Property::Label("Pixels - currently active"),
|
||||
]);
|
||||
pct.update_property(&[
|
||||
gtk::accessible::Property::Label("Percentage"),
|
||||
]);
|
||||
px.set_tooltip_text(Some("Use pixel dimensions (currently active)"));
|
||||
pct.set_tooltip_text(Some("Use percentage dimensions"));
|
||||
|
||||
let dims = get_first_image_dims(&files.borrow());
|
||||
let pct_w = ws.value();
|
||||
@@ -755,6 +791,14 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
ip.set(true);
|
||||
pct.add_css_class("suggested-action");
|
||||
px.remove_css_class("suggested-action");
|
||||
pct.update_property(&[
|
||||
gtk::accessible::Property::Label("Percentage - currently active"),
|
||||
]);
|
||||
px.update_property(&[
|
||||
gtk::accessible::Property::Label("Pixels"),
|
||||
]);
|
||||
pct.set_tooltip_text(Some("Use percentage dimensions (currently active)"));
|
||||
px.set_tooltip_text(Some("Use pixel dimensions"));
|
||||
|
||||
let dims = get_first_image_dims(&files.borrow());
|
||||
let cur_w = ws.value();
|
||||
@@ -852,10 +896,31 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
gesture.set_state(gtk::EventSequenceState::Claimed);
|
||||
});
|
||||
thumb_picture.set_can_target(true);
|
||||
thumb_picture.set_focusable(true);
|
||||
thumb_picture.add_controller(click);
|
||||
thumb_picture.set_cursor_from_name(Some("pointer"));
|
||||
}
|
||||
|
||||
// Keyboard support for preview cycling (Space/Enter)
|
||||
{
|
||||
let pi = preview_index.clone();
|
||||
let rt = render_thumb.clone();
|
||||
let lf = loaded_files.clone();
|
||||
let key = gtk::EventControllerKey::new();
|
||||
key.connect_key_pressed(move |_, keyval, _, _| {
|
||||
if keyval == gtk::gdk::Key::space || keyval == gtk::gdk::Key::Return {
|
||||
let count = lf.borrow().len();
|
||||
if count > 1 {
|
||||
pi.set((pi.get() + 1) % count);
|
||||
rt();
|
||||
}
|
||||
return glib::Propagation::Stop;
|
||||
}
|
||||
glib::Propagation::Proceed
|
||||
});
|
||||
thumb_picture.add_controller(key);
|
||||
}
|
||||
|
||||
// Initial render
|
||||
{
|
||||
let rt = render_thumb.clone();
|
||||
@@ -868,10 +933,14 @@ pub fn build_resize_page(state: &AppState) -> adw::NavigationPage {
|
||||
.child(&outer)
|
||||
.build();
|
||||
|
||||
// Re-render on page map
|
||||
// Sync enable toggle and re-render on page map
|
||||
{
|
||||
let rt = render_thumb.clone();
|
||||
let jc = state.job_config.clone();
|
||||
let er = enable_row.clone();
|
||||
page.connect_map(move |_| {
|
||||
let enabled = jc.borrow().resize_enabled;
|
||||
er.set_active(enabled);
|
||||
rt();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user