From 32c037ec116c250975e509f478462f72aabd6e61 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 18 Aug 2026 11:17:16 -0400 Subject: [PATCH] feat(shortcuts): delete selected annotations with the delete key The delete key had to reach the app while a checkbox or slider held focus, which the old dispatcher could not do: it watched vueuse magic keys, rebuilt every watcher whenever a binding changed, and decided whether to suppress a shortcut by asking what kind of element had focus. Shortcuts now dispatch from one keydown listener against a table of parsed bindings. Anything a control handles in script reports itself through preventDefault, so arbitration only has to cover what the browser does natively and no handler announces: typing into a field, Space or Enter activating a focused control, and the arrow keys stepping through a group of values. An action can name more than one key, since the main delete key reports Backspace on macOS. Hold actions read their state through useActionHeld instead of each view resolving a binding itself, and a binding no keystroke could produce is dropped from a loaded config with a warning rather than rejecting the file. Removing a selection says how many annotations went, because the selection can hold annotations with no visible cue in the current view and there is no undo. --- src/components/ControlsModal.vue | 9 +- src/components/ControlsStripTools.vue | 33 +- src/components/MeasurementsToolList.vue | 11 +- src/components/tools/paint/PaintWidget2D.vue | 8 +- src/components/tools/polygon/PolygonTool.vue | 9 +- .../vtk/VtkCineScrubKeyManipulator.vue | 7 +- .../vtk/VtkSliceViewSlicingKeyManipulator.vue | 7 +- .../deleteSelectedAnnotations.spec.ts | 106 ++++++ .../__tests__/useKeyboardShortcuts.spec.ts | 340 +++++++++++++++++- src/composables/actions.ts | 4 +- src/composables/useKeyboardShortcuts.ts | 258 ++++++++++--- src/config.ts | 7 +- src/constants.ts | 10 + src/io/import/__tests__/configJson.spec.ts | 26 ++ src/io/import/configJson.ts | 52 ++- src/io/import/processors/handleConfig.ts | 5 +- src/store/messages.ts | 9 + .../__tests__/removeSelectedTools.spec.ts | 121 +++++++ src/store/tools/index.ts | 33 ++ tests/pageobjects/volview.page.ts | 16 +- tests/specs/annotationTestUtils.ts | 54 +++ tests/specs/cineTestUtils.ts | 8 +- tests/specs/delete-selected-annotation.e2e.ts | 147 ++++++++ tests/specs/polygon-nested-interaction.e2e.ts | 95 +---- 24 files changed, 1162 insertions(+), 213 deletions(-) create mode 100644 src/composables/__tests__/deleteSelectedAnnotations.spec.ts create mode 100644 src/store/tools/__tests__/removeSelectedTools.spec.ts create mode 100644 tests/specs/annotationTestUtils.ts create mode 100644 tests/specs/delete-selected-annotation.e2e.ts diff --git a/src/components/ControlsModal.vue b/src/components/ControlsModal.vue index c73555389..c01a43d05 100644 --- a/src/components/ControlsModal.vue +++ b/src/components/ControlsModal.vue @@ -34,7 +34,10 @@ diff --git a/src/components/ControlsStripTools.vue b/src/components/ControlsStripTools.vue index 2287ccbe1..97265d719 100644 --- a/src/components/ControlsStripTools.vue +++ b/src/components/ControlsStripTools.vue @@ -135,7 +135,7 @@