Canvas tool for selection, marquee gestures, and selection transforms. More...
#include "donner/editor/SelectTool.h"
Classes | |
| struct | ActiveDragPreview |
| Preview state for an in-progress drag, consumed by the async renderer. More... | |
| struct | ActiveTransformBoundsPreview |
| Active transform chrome state for selection bounds presentation. More... | |
| struct | ActiveGesturePreview |
| Active selection gesture state for editor UI chrome. More... | |
| struct | CompletedDragWriteback |
| Payload needed to write a completed drag back into the source pane. For multi-element drags this is the primary; additional writeback entries are latched in extras. More... | |
| struct | LockedRejectionFlash |
| A transient "this element is locked, you can't select it" flash on the rejected element's outline. intensity fades from 1 → 0 over the flash duration. More... | |
Public Types | |
| enum class | ActiveGestureKind { Move , Resize , Rotate } |
| Active selection gesture kind. | |
Public Member Functions | |
| void | onMouseDown (EditorApp &editor, const Vector2d &documentPoint, MouseModifiers modifiers) override |
| Mouse button (left) was pressed at documentPoint. modifiers captures the modifier-key state at the moment of the press; implementations that don't care can ignore it. Default arguments on virtuals are banned by the style guide, so callers that don't need modifier state should pass MouseModifiers{} explicitly. | |
| void | onMouseMove (EditorApp &editor, const Vector2d &documentPoint, bool buttonHeld) override |
| Mouse moved to documentPoint. buttonHeld is true while the left button is down - i.e., this is a drag continuation rather than a hover. | |
| void | onMouseMove (EditorApp &editor, const Vector2d &documentPoint, bool buttonHeld, MouseModifiers modifiers) |
| Mouse-move variant that samples live modifiers during resize gestures. | |
| void | onMouseUp (EditorApp &editor, const Vector2d &documentPoint) override |
| Mouse button was released at documentPoint. | |
| bool | tryStartRedragOnSelected (EditorApp &editor, const Vector2d &documentPoint, MouseModifiers modifiers, std::span< const Box2d > selectionBoundsDoc, std::span< const Box2d > occludingBoundsDoc={}) |
| Snapshot-safe re-drag start. When the user clicks inside the bounds of the single currently-selected element, start a drag of that element WITHOUT calling EditorApp::hitTest. | |
| bool | clickHitsCurrentSelection (EditorApp &editor, const Vector2d &documentPoint) const |
Returns true when live hit-testing at documentPoint hits the current selectable selection or one of its renderable descendants. | |
| bool | clickHitsImmediatelySelectableElement (EditorApp &editor, const Vector2d &documentPoint) const |
Returns true when live hit-testing at documentPoint hits an element that can be selected immediately by a canvas press. | |
| bool | isDragging () const |
| Whether a drag is currently in progress (button is held after a successful hit-test on mouse-down). | |
| bool | dragHasVisualChange () const |
| Whether the active drag preview has moved away from its captured placement. | |
| bool | isMarqueeing () const |
| Whether a marquee selection is currently in progress (button is held after a onMouseDown that hit empty space). | |
| void | beginMarquee (EditorApp &editor, const Vector2d &documentPoint, bool additive) |
| Start a marquee drag from documentPoint without performing a hit-test. | |
| std::optional< Box2d > | marqueeRect () const |
| The current marquee rectangle in document coordinates, or std::nullopt if no marquee drag is active. Returned even on the very first frame of a marquee (rect collapses to a single point). Used by the overlay renderer to draw the marquee chrome. | |
| std::optional< CompletedDragWriteback > | consumeCompletedDragWriteback () |
| Returns the most recent completed drag writeback request, if any. The payload is latched until consumed so the main loop can retry writeback across busy frames without depending on the current selection. | |
| std::optional< ActiveDragPreview > | activeDragPreview () const |
| Returns the current drag preview, if a drag is in progress. | |
| std::optional< ActiveDragPreview > | documentDragPreview (const EditorApp &editor) const |
| Returns the drag transform currently committed to the DOM. | |
| std::optional< ActiveGesturePreview > | activeGesturePreview () const |
| Returns the current selection gesture preview, if a drag is in progress. | |
| std::optional< ActiveTransformBoundsPreview > | activeTransformBoundsPreview () const |
| Returns bounds chrome derived from the gesture's immutable start bounds and current transform. Available for every moved drag so the overlay does not need to walk live geometry while the render worker is active. | |
| std::optional< LockedRejectionFlash > | lockedRejectionFlash () const |
| The active locked-selection rejection flash, or std::nullopt. The overlay renderer draws this as a red outline on the rejected (locked) element. | |
| void | tickLockedRejectionFlash (float deltaSeconds) |
Advance the locked-rejection flash fade by deltaSeconds, clearing it once fully faded. Called once per frame by the editor shell. | |
| Public Member Functions inherited from donner::editor::Tool | |
| Tool (const Tool &)=delete | |
| Tool & | operator= (const Tool &)=delete |
| Tool (Tool &&)=delete | |
| Tool & | operator= (Tool &&)=delete |
Canvas tool for selection, marquee gestures, and selection transforms.
| struct donner::editor::SelectTool::ActiveDragPreview |
Preview state for an in-progress drag, consumed by the async renderer.
| Class Members | ||
|---|---|---|
| PresentationIdentity | contentIdentity | Content identity captured when this input transaction began. |
| Transform2d | documentFromCachedDocument = Transform2d() | Current affine transform from the cached document placement to the active preview placement. |
| uint64_t | dragGeneration = 0 | Monotonic id for one mouse-down/move/up drag gesture. |
| Entity | entity = entt::null | Entity being dragged. |
| vector< Entity > | extraEntities | Additional selected entities moving with entity in the same gesture. |
| vector< PresentationPose > | poses | Absolute object poses; these do not reset their reference space between gestures. |
| vector< PresentationPose > | startPoses | Absolute starting poses used to orient bounds derived from the raster's actual geometry. |
| Vector2d | translation = Vector2d::Zero() | Current drag translation in document coordinates. |
| struct donner::editor::SelectTool::ActiveTransformBoundsPreview |
Active transform chrome state for selection bounds presentation.
| Class Members | ||
|---|---|---|
| Transform2d | documentFromStartDocument = Transform2d() | Current transform from gesture-start document space to active document space. |
| Box2d | startBoundsDoc | Selection AABB captured when the transform gesture started. |
| struct donner::editor::SelectTool::ActiveGesturePreview |
Active selection gesture state for editor UI chrome.
| Class Members | ||
|---|---|---|
| SelectionTransformCorner | corner = SelectionTransformCorner::TopLeft | Transform handle corner that started the gesture. |
| Vector2d | currentDocumentDelta = Vector2d::Zero() | Current drag delta in document coordinates. |
| Transform2d | documentFromStartDocument = Transform2d() | Current transform from gesture-start document space to active document space. |
| bool | hasMoved = false | Whether the gesture has moved past the drag threshold. |
| ActiveGestureKind | kind = ActiveGestureKind::Move | Gesture kind currently being performed. |
| Box2d | startBoundsDoc | Selection bounds captured at gesture start. |
| struct donner::editor::SelectTool::CompletedDragWriteback |
Payload needed to write a completed drag back into the source pane. For multi-element drags this is the primary; additional writeback entries are latched in extras.
| Class Members | ||
|---|---|---|
| vector< CompletedDragWriteback > | extras | Additional writeback entries for extra elements in a multi-element drag. One per non-primary element that had a capturable writeback target. Empty for single-element drags. |
| optional< RcString > | sourceTransformAttributeValue | The element's transform= bytes as authored at drag start, used by the source writeback to preserve the author's function syntax instead of canonicalizing to matrix(). std::nullopt when the element had no transform attribute before the drag. |
| AttributeWritebackTarget | target | |
| Transform2d | transform | |
| struct donner::editor::SelectTool::LockedRejectionFlash |
A transient "this element is locked, you can't select it" flash on the rejected element's outline. intensity fades from 1 → 0 over the flash duration.
| Class Members | ||
|---|---|---|
| SVGElement | element | The element whose selection was rejected. |
| float | intensity = 0.0f | Fade intensity in (0, 1]. |
|
nodiscard |
Returns true when live hit-testing at documentPoint hits the current selectable selection or one of its renderable descendants.
This reads the live document through EditorApp::hitTest, so callers must only use it when the async renderer is idle. EditorShell uses this to keep clicks on already-selected elements on the immediate drag path instead of converting a held press into a marquee. Locked selected elements return false because they cannot start an immediate canvas drag.
| editor | Editor state used for hit-testing and the current selection. |
| documentPoint | Pointer location in SVG document coordinates. |
|
nodiscard |
Returns true when live hit-testing at documentPoint hits an element that can be selected immediately by a canvas press.
Locked layers and descendants of locked layers return false: they may still flash rejection on a click, but they should not block the shell's delayed marquee path.
| editor | Editor state used for hit-testing. |
| documentPoint | Pointer location in SVG document coordinates. |
|
nodiscard |
Returns the drag transform currently committed to the DOM.
Pointer input can advance activeDragPreview() while its transform command remains queued behind an in-flight render. Overlay capture reads that older DOM geometry, so presentation uses this baseline to project the captured outline into the same frame as the promoted shape tile.
|
overridevirtual |
Mouse button (left) was pressed at documentPoint. modifiers captures the modifier-key state at the moment of the press; implementations that don't care can ignore it. Default arguments on virtuals are banned by the style guide, so callers that don't need modifier state should pass MouseModifiers{} explicitly.
Implements donner::editor::Tool.
|
overridevirtual |
Mouse moved to documentPoint. buttonHeld is true while the left button is down - i.e., this is a drag continuation rather than a hover.
Implements donner::editor::Tool.
|
overridevirtual |
Mouse button was released at documentPoint.
Implements donner::editor::Tool.
|
nodiscard |
Snapshot-safe re-drag start. When the user clicks inside the bounds of the single currently-selected element, start a drag of that element WITHOUT calling EditorApp::hitTest.
selectionBoundsDoc and occludingBoundsDoc are caller-supplied AABB lists in document space. EditorShell passes the pre-snapshotted bounds from SelectionBoundsCache - that cache is refreshed on idle frames, so reading it during a busy render is race-free (no live SnapshotSelectionWorldBounds call inside this function). onMouseDown passes freshly-computed live selection bounds and no occlusion hints since its caller has already gated on !isBusy().
Returns true if a drag was started; false if the caller must fall back to the full onMouseDown path (multi-select, shift-click, click outside the selection's snapshotted bounds, click inside later-painted cached bounds, empty bounds span, the selection is the document root, etc.).
onMouseDown itself calls this first to avoid duplicating logic