Replace watermark position dropdown with visual 3x3 grid
- 9-point position grid using ToggleButtons in a Grid layout - Visual feedback with radio-checked/radio-symbolic icons - Position label below grid shows current selection name - Much better UX than ComboRow for spatial position selection
This commit is contained in:
@@ -94,7 +94,7 @@ pub fn build_watermark_page(state: &AppState) -> adw::NavigationPage {
|
||||
image_group.add(&image_path_row);
|
||||
content.append(&image_group);
|
||||
|
||||
// Position grid (9-point)
|
||||
// Visual 9-point position grid
|
||||
let position_group = adw::PreferencesGroup::builder()
|
||||
.title("Position")
|
||||
.description("Choose where the watermark appears on the image")
|
||||
@@ -106,14 +106,62 @@ pub fn build_watermark_page(state: &AppState) -> adw::NavigationPage {
|
||||
"Bottom Left", "Bottom Center", "Bottom Right",
|
||||
];
|
||||
|
||||
let position_row = adw::ComboRow::builder()
|
||||
.title("Watermark Position")
|
||||
// Build a 3x3 grid of toggle buttons
|
||||
let grid = gtk::Grid::builder()
|
||||
.row_spacing(4)
|
||||
.column_spacing(4)
|
||||
.halign(gtk::Align::Center)
|
||||
.margin_top(8)
|
||||
.margin_bottom(8)
|
||||
.build();
|
||||
let position_model = gtk::StringList::new(&position_names);
|
||||
position_row.set_model(Some(&position_model));
|
||||
position_row.set_selected(cfg.watermark_position);
|
||||
|
||||
position_group.add(&position_row);
|
||||
// Create a visual "image" area as background context
|
||||
let grid_frame = gtk::Frame::builder()
|
||||
.halign(gtk::Align::Center)
|
||||
.build();
|
||||
grid_frame.set_child(Some(&grid));
|
||||
|
||||
let mut first_button: Option<gtk::ToggleButton> = None;
|
||||
let buttons: Vec<gtk::ToggleButton> = position_names.iter().enumerate().map(|(i, name)| {
|
||||
let btn = gtk::ToggleButton::builder()
|
||||
.tooltip_text(*name)
|
||||
.width_request(48)
|
||||
.height_request(48)
|
||||
.build();
|
||||
|
||||
// Use a dot icon for each position
|
||||
let icon = if i == cfg.watermark_position as usize {
|
||||
"radio-checked-symbolic"
|
||||
} else {
|
||||
"radio-symbolic"
|
||||
};
|
||||
btn.set_child(Some(>k::Image::from_icon_name(icon)));
|
||||
btn.set_active(i == cfg.watermark_position as usize);
|
||||
|
||||
if let Some(ref first) = first_button {
|
||||
btn.set_group(Some(first));
|
||||
} else {
|
||||
first_button = Some(btn.clone());
|
||||
}
|
||||
|
||||
let row = i / 3;
|
||||
let col = i % 3;
|
||||
grid.attach(&btn, col as i32, row as i32, 1, 1);
|
||||
|
||||
btn
|
||||
}).collect();
|
||||
|
||||
position_group.add(&grid_frame);
|
||||
|
||||
// Position label showing current selection
|
||||
let position_label = gtk::Label::builder()
|
||||
.label(position_names[cfg.watermark_position as usize])
|
||||
.css_classes(["dim-label"])
|
||||
.halign(gtk::Align::Center)
|
||||
.margin_bottom(4)
|
||||
.build();
|
||||
position_group.add(&position_label);
|
||||
|
||||
content.append(&position_group);
|
||||
|
||||
// Advanced options
|
||||
@@ -200,10 +248,26 @@ pub fn build_watermark_page(state: &AppState) -> adw::NavigationPage {
|
||||
jc.borrow_mut().watermark_font_size = row.value() as f32;
|
||||
});
|
||||
}
|
||||
{
|
||||
// Wire position grid buttons
|
||||
for (i, btn) in buttons.iter().enumerate() {
|
||||
let jc = state.job_config.clone();
|
||||
position_row.connect_selected_notify(move |row| {
|
||||
jc.borrow_mut().watermark_position = row.selected();
|
||||
let label = position_label.clone();
|
||||
let names = position_names;
|
||||
let all_buttons = buttons.clone();
|
||||
btn.connect_toggled(move |b| {
|
||||
if b.is_active() {
|
||||
jc.borrow_mut().watermark_position = i as u32;
|
||||
label.set_label(names[i]);
|
||||
// Update icons
|
||||
for (j, other) in all_buttons.iter().enumerate() {
|
||||
let icon_name = if j == i {
|
||||
"radio-checked-symbolic"
|
||||
} else {
|
||||
"radio-symbolic"
|
||||
};
|
||||
other.set_child(Some(>k::Image::from_icon_name(icon_name)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user