Repository navigation
Reliable selection and editing controls - #522
Merged
mudabs merged 7 commits intoNov 9, 2026
Merged
Conversation
- Replace the separate image and annotation selection fields with one
`state.selection` ({ kind, index } or null) behind select/deselect helpers.
- Clicking an object selects it; clicking it again keeps it selected (the
second click is reserved for reaching overlapping objects in oss-slu#441).
Clicking a resize or crop handle without dragging no longer deselects.
- Escape or a click on empty canvas clears the selection for every object type.
- Tab / Shift+Tab on the canvas step through drawn objects from the top of
the stack down; past either end the selection clears and focus leaves.
- Each selection is announced with its type, label text, and stack position.
Part of oss-slu#439.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add objectsAt(scene, point) to sceneCanvas.js: every drawn object under a scene point, topmost first, matching what renderScene draws (rotated and flipped crop areas, line hit width, polygon fill, linked annotations, and colored regions clipped to their image's crop). - Clicking again in the same spot selects the next object down the stack, wrapping back to the top; Alt+click steps down from anywhere on the stack. A click in a new spot selects the topmost object there. - While objects overlap, a hint under the canvas (also announced) says how many there are and how to reach the next one; it clears on any edit. - Selecting or clearing keeps the canvas in place on screen, so the toolbar that appears above it no longer moves the scene out from under the pointer. - A double-click only opens a label's text when the clicks left that label selected, so quick clicks keep stepping down the stack. Part of oss-slu#439. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A press anywhere on the selected object drags it, even where another object is drawn over it (an image reached under a highlight with oss-slu#441's click-again); a press on any unselected object never moves anything. - The selected image now has the same keyboard controls as annotations: arrow keys move it by 1 scene pixel (10 with Shift), and Delete or Backspace removes it (announced). Both are off while a crop is edited. - Tests cover a crowded scene: dragging, nudging, and resizing a covered image, then saving and reopening; drags on unselected objects moving nothing; a selected highlight moving under the label drawn on it; and deleting images from the keyboard. Part of oss-slu#439. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on-editing-controls # Conflicts: # templates/js/scenes.js # templates/tests/sceneAnnotationEditor.test.js
- Every recorded change to the working copy (images, annotations, and the import log) becomes an undo step, up to 100. Image src strings, which can be megabytes of base64, are shared between steps rather than copied. - A run of small edits of one kind on one object - typing a label, picking a color, dragging the opacity slider, nudging with the arrow keys - undoes as one step; selecting another object or saving starts a new step. - Revisions now only count up, so undoing or redoing back to the saved version shows "Saved" again, and a new edit after an undo never looks saved. - Undo and Redo buttons next to Save, plus Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z or Ctrl+Y; text fields keep their own undo. Each step is announced. - The selected object stays selected if it still exists. History is cleared when another scene is opened or a version is reloaded, so undo never reaches into another scene. Part of oss-slu#439. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Back button, pressing Scene Editor again, and a scene's "view in the bone viewer" links now ask before leaving when the open scene has unsaved changes. Choosing to stay keeps the editor open (announced); choosing to leave keeps the working copy, which is still there on coming back. - With everything saved, the editor is left without asking, as before. - Closing or reloading the page, opening another scene, New, Delete, and Duplicate already warned (oss-slu#507); this closes the remaining gap. Part of oss-slu#439. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remex9
requested review from
jacksayshi,
leandrumartin and
mudabs
as code owners
November 5, 2026 21:11
mudabs
requested changes
Nov 9, 2026
mudabs
left a comment
Collaborator
There was a problem hiding this comment.
Thank you @Remex9 for bringing the selection, overlapping-object navigation, image editing, undo/redo, and unsaved-change protections together in PR #522. The implementation has strong coverage, and the GitHub checks, Sonar quality gate, lint, and local test suite all pass.
Please address the following before approval:
- Restore keyboard focus to the canvas after selecting an object.
- templates/js/scenes.js around selectObject() at line 1776 and handleSelectClick() at line 1819 redraw the scene but do not focus #scene-canvas.
- templates/boneset.html makes #scene-canvas the only focusable editing surface with tabindex="0".
- In browser testing, clicking a selected label left focus in the annotation text field instead of moving it to the canvas.
- As a result, Arrow, Delete, and Backspace shortcuts may not work after selecting an image or annotation with the mouse or pointer.
- Focus the canvas after selection while preserving the existing behavior that returns focus to the text field when editing a label.
- Add a regression test for the real focus path.
- Select an image or annotation through a browser-style click.
- Verify that document.activeElement becomes #scene-canvas.
- Confirm that Arrow and Delete or Backspace then modify the selected object.
- The current tests dispatch keyboard events directly to #scene-canvas, so they do not catch this focus issue.
Please rerun:
- npm run lint
- git diff --check
- npm test -- --runInBand
A press on an object can start a drag, which cancels the browser's own focus change, so focus stayed in the label's text field and the arrow keys and Delete didn't reach the canvas. The canvas now takes focus on each selecting click; a double-click on a label still opens its text. Adds tests that send keys to the focused element after a real click.
|
mudabs
approved these changes
Nov 9, 2026
mudabs
left a comment
Collaborator
There was a problem hiding this comment.
Thank you @Remex9 addressing the focus issue in PR #522.
- The canvas now receives focus after selecting an object.
- Keyboard actions such as Arrow, Delete, and Backspace work after mouse selection.
- Double-clicking a label still correctly returns focus to its text field.
- New tests verify the real browser-style focus path.
- GitHub checks pass.
- Local validation passed: 22 suites, 858 tests passed, 5 skipped.
I did not find any remaining blocking issues. This PR is ready for approval.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Pull Request Summary
Closes #439, Closes #440, Closes #441, Closes #442, Closes #443, Closes #444
Selection and editing in the Scene Editor now work reliably in crowded scenes. Images and annotations share one selection, which can be made with the mouse or the keyboard. Clicking again in the same spot reaches objects hidden under others. A drag only ever moves the selected object. Edits can be undone and redone, and leaving the editor with unsaved changes now asks first.
PR Checklist
npx jest: 856 passed, 5 skipped;npm run lintclean)Detailed Description
Selection (#440, #441)
state.selectionreplaces the separate image and annotation selections. Escape or a click on empty canvas clears it, and Tab / Shift+Tab step through objects. Each selection is announced.objectsAt(scene, point)insceneCanvas.jslists every object under a point, topmost first. Clicking again in the same spot (or Alt+click) selects the next object down, and a hint shows when objects overlap.Editing (#442, #443)
Unsaved changes (#444)
Tests
sceneCanvas.test.jsandsceneAnnotationEditor.test.jsfor each issue. Inscenes.test.js, one test now expects a second click to keep an image selected instead of deselecting it.Known limitation: image drags store unrounded coordinates, and the selection outline doesn't match a cropped image that is also flipped.