Layers/Appearance panels: a clicked row takes Delete from a tool that claims it

After a click on a Layers or Appearance row, a plain Delete or
Backspace now goes to that panel even when the active tool claims the
key. Before, the Artboard tool (and Gradient, Width, Puppet Warp…)
took it first: Delete after a click on a layer row deleted the active
artboard, not the layer.

The Type tool still keeps Delete and Backspace while it edits text.
This commit is contained in:
FarmerGeorg
2026-11-02 14:36:10 +07:00
committed by bflatastic
parent a76c1ca50c
commit c3169524ce
2 changed files with 29 additions and 8 deletions
@@ -1013,6 +1013,25 @@ fn after_a_row_click_delete_reaches_the_layers_panel_not_edit_clear() {
assert!(d.node(rect).is_some(), "the rectangle on Layer 1 stays");
}
/// A tool that claims Delete and Backspace (the Artboard tool's active artboard) leaves them to a
/// clicked Layers row.
#[test]
fn after_a_row_click_delete_reaches_the_layers_panel_not_the_artboard_tool() {
for key in [egui::Key::Delete, egui::Key::Backspace] {
let ctx = drop_ctx();
let mut app = app_with_rect();
run(&mut app, "layer.new", json!({}));
run(&mut app, "artboard.new", json!({"width": 200, "height": 100}));
app.select_tool("artboard");
let texts = frame_events(&ctx, &mut app, vec![], boxed_layers);
let row = text_rect(&texts, "Layer 2").center();
app_click(&ctx, &mut app, row, boxed_layers);
app_key(&ctx, &mut app, key, boxed_layers);
let d = &app.session.active().unwrap().doc;
assert_eq!((d.layers.len(), d.artboards.len()), (1, 2), "{key:?}: Layer 2 is deleted, both artboards stay");
}
}
/// "Opacity:" is a link to the Transparency panel ("Click to edit"), whatever modifiers are held: on
/// a stroke's Opacity row it makes that stroke the active row first; on the object's own Opacity row
/// no fill/stroke is active.
+10 -8
View File
@@ -325,14 +325,14 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
busy_tool_keys(app, ctx, view);
return;
}
if claimed_tool_keys(app, ctx, view) {
// A plain Delete or Backspace after a click on a Layers or Appearance row is that panel's (it
// removes the highlighted rows), not a tool's (the Artboard tool's) or Edit › Clear's.
let rows_keys = crate::panels::rows_take_delete(ctx);
if claimed_tool_keys(app, ctx, view, rows_keys) {
return;
}
// Command, panel and tool shortcuts. A bound shifted punctuation chord uses its key press;
// other text keys use the typed character below. A plain Delete or Backspace after a click on
// a Layers or Appearance row is that panel's (it removes the highlighted rows), not
// Edit › Clear's.
let rows_keys = crate::panels::rows_take_delete(ctx);
// other text keys use the typed character below.
let row_key = |chord: &craft_keymap::Chord| {
rows_keys && chord.is_plain() && !chord.mods.shift && matches!(chord.key, craft_keymap::Key::Delete | craft_keymap::Key::Backspace)
};
@@ -657,9 +657,11 @@ fn busy_tool_keys(app: &mut VectorcraftApp, ctx: &egui::Context, view: ViewInfo)
}
}
/// Give keys claimed by the active tool precedence over their command shortcuts.
fn claimed_tool_keys(app: &mut VectorcraftApp, ctx: &egui::Context, view: ViewInfo) -> bool {
/// Give keys claimed by the active tool precedence over their command shortcuts, except a plain
/// Delete or Backspace while a panel's rows have them (`rows_keys`).
fn claimed_tool_keys(app: &mut VectorcraftApp, ctx: &egui::Context, view: ViewInfo, rows_keys: bool) -> bool {
let m = ctx.input(|i| i.modifiers);
let rows_take = |k: Key| rows_keys && m.is_none() && matches!(k, Key::Delete | Key::Backspace);
for (k, tk) in [
(Key::Delete, ToolKey::Delete),
(Key::Backspace, ToolKey::Backspace),
@@ -670,7 +672,7 @@ fn claimed_tool_keys(app: &mut VectorcraftApp, ctx: &egui::Context, view: ViewIn
// The Smart Pen Tool's Tab while it draws a path (the key otherwise hides the panels).
(Key::Tab, ToolKey::Tab),
] {
if ctx.input(|i| i.key_pressed(k)) && app.session.tool_claims_key(tk, view) && ctx.input_mut(|i| i.consume_key(m, k)) {
if !rows_take(k) && ctx.input(|i| i.key_pressed(k)) && app.session.tool_claims_key(tk, view) && ctx.input_mut(|i| i.consume_key(m, k)) {
let r = app.session.tool_key(tk, crate::canvas::mods(m, false), view);
// Keyboard actions can change the Artboard tool's active board too. Keep the
// navigator aligned with its valid survivor, as pointer dispatch does.