fix(ui): Open layer color choices from the visibility icon (#4001)

* fix(ui): offer label colors from the layer eye icon

* fix(ui): offer label colors from the layer eye icon

* test(ui): cover layer eye color context menu

* style(ui): keep extracted color menu indentation consistent
This commit is contained in:
Nigel Ihza Firdausy 2026-10-12 17:19:28 +07:00 committed by GitHub
parent db509dc4d9
commit 73520f8681
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 29 deletions

View File

@ -212,26 +212,31 @@ fn common_color(app: &crate::PhotocraftApp, l: &Layer, on_set: bool) -> Option<L
}
fn color_menu(app: &crate::PhotocraftApp, ui: &mut egui::Ui, l: &Layer, on_set: bool, actions: &mut Vec<(String, Value)>) {
let current = common_color(app, l, on_set);
ui.menu_button(tl!("Color"), |ui| {
crate::widgets::menu_scroll(ui, |ui| {
ui.set_min_width(170.0);
for color in LabelColor::ALL {
if color == LabelColor::Red {
ui.separator();
}
if color_button(ui, color, current == Some(color)).clicked() {
let params = if on_set {
json!({"color": color.id()})
} else {
actions.push(("layer.select".into(), json!({"layer": l.id.0})));
json!({"layer": l.id.0, "color": color.id()})
};
actions.push(("layer.setLabelColor".into(), params));
ui.close();
}
color_choices(app, ui, l, on_set, actions);
});
}
/// The eye column opens the same color choices directly, without the row's full context menu.
pub(crate) fn color_choices(app: &crate::PhotocraftApp, ui: &mut egui::Ui, l: &Layer, on_set: bool, actions: &mut Vec<(String, Value)>) {
let current = common_color(app, l, on_set);
crate::widgets::menu_scroll(ui, |ui| {
ui.set_min_width(170.0);
for color in LabelColor::ALL {
if color == LabelColor::Red {
ui.separator();
}
});
if color_button(ui, color, current == Some(color)).clicked() {
let params = if on_set {
json!({"color": color.id()})
} else {
actions.push(("layer.select".into(), json!({"layer": l.id.0})));
json!({"layer": l.id.0, "color": color.id()})
};
actions.push(("layer.setLabelColor".into(), params));
ui.close();
}
}
});
}

View File

@ -113,6 +113,21 @@ fn layer_color_background_is_confined_to_the_eye_column_in_every_theme() {
}
}
#[test]
fn right_clicking_eye_opens_color_choices_without_toggling_visibility() {
let (mut h, red, other) = harness(crate::theme::ThemeKind::Pro, 1.0);
let r = row(&h, red);
let eye = pos2(r.left() + 17.0, r.center().y);
click(&mut h, eye, PointerButton::Secondary, Modifiers::NONE);
let blue = h.get_by_label("Blue").rect().center();
click(&mut h, blue, PointerButton::Primary, Modifiers::NONE);
let st = h.state().session.active().unwrap();
assert!(st.doc.layer(red).unwrap().visible);
assert_eq!(st.doc.layer(red).unwrap().label, LabelColor::Blue);
assert_eq!(st.doc.layer(other).unwrap().label, LabelColor::None);
}
#[test]
fn layer_color_menu_marks_only_the_common_color() {
let mut h = Harness::new_ui(|ui| {

View File

@ -2636,6 +2636,10 @@ fn layer_row(
actions.push(("layer.setProps".into(), json!({"layer": l.id.0, "visible": !l.visible})));
}
}
eye_resp.context_menu(|ui| {
crate::widgets::style_spectrum_popup_menu(ui);
crate::layer_menu_ui::color_choices(app, ui, l, row.multi && selected, actions);
});
// Everything but the thumbnails, the indentation and the name, so a narrow panel squeezes
// the indentation first, then the thumbnails (a layer with two masks has three).
let others = 6.0
@ -2796,17 +2800,19 @@ fn layer_row(
if let Some(done) = crate::layer_row_ui::rename_field(ui, l.id.0, edit_rect) {
actions.push(done);
}
// Right-click context menu.
resp.context_menu(|ui| {
crate::widgets::style_spectrum_popup_menu(ui);
// Right-clicking inside a multi-selection keeps it and acts on every selected layer.
let on_set = row.multi && selected;
if crate::layer_menu_ui::show(app, ui, l, on_set, actions)
&& let Some(done) = crate::layer_row_ui::start_rename(ui.ctx(), l.id.0, &l.name)
{
actions.push(done);
}
});
// The visibility icon has its own color menu; elsewhere use the full layer menu.
if !eye_resp.secondary_clicked() && !eye_resp.context_menu_opened() {
resp.context_menu(|ui| {
crate::widgets::style_spectrum_popup_menu(ui);
// Right-clicking inside a multi-selection keeps it and acts on every selected layer.
let on_set = row.multi && selected;
if crate::layer_menu_ui::show(app, ui, l, on_set, actions)
&& let Some(done) = crate::layer_row_ui::start_rename(ui.ctx(), l.id.0, &l.name)
{
actions.push(done);
}
});
}
rect
}