Donner SVG Editor & Engine
SVG-native editor and embeddable SVG2 + CSS3 engine in C++20, with GPU (WebGPU) and compact CPU renderers, built for correctness, security, and performance.
Loading...
Searching...
No Matches
donner::editor::SelectTool Class Referencefinal
Inheritance diagram for donner::editor::SelectTool:
[legend]

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 (design doc 0033 §M8). 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 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< Box2dmarqueeRect () 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< CompletedDragWritebackconsumeCompletedDragWriteback ()
 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< ActiveDragPreviewactiveDragPreview () const
 Returns the current drag preview, if a drag is in progress.
std::optional< ActiveGesturePreviewactiveGesturePreview () const
 Returns the current selection gesture preview, if a drag is in progress.
std::optional< ActiveTransformBoundsPreviewactiveTransformBoundsPreview () 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< LockedRejectionFlashlockedRejectionFlash () 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

Class Documentation

◆ donner::editor::SelectTool::ActiveDragPreview

struct donner::editor::SelectTool::ActiveDragPreview

Preview state for an in-progress drag, consumed by the async renderer.

Class Members
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.
Vector2d translation = Vector2d::Zero() Current drag translation in document coordinates.

◆ donner::editor::SelectTool::ActiveTransformBoundsPreview

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.

◆ donner::editor::SelectTool::ActiveGesturePreview

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.

◆ donner::editor::SelectTool::CompletedDragWriteback

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

◆ donner::editor::SelectTool::LockedRejectionFlash

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].

Member Function Documentation

◆ clickHitsCurrentSelection()

bool donner::editor::SelectTool::clickHitsCurrentSelection ( EditorApp & editor,
const Vector2d & documentPoint ) const
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.

Parameters
editorEditor state used for hit-testing and the current selection.
documentPointPointer location in SVG document coordinates.
Returns
true when the point hits an unlocked selected element or selected descendant.

◆ clickHitsImmediatelySelectableElement()

bool donner::editor::SelectTool::clickHitsImmediatelySelectableElement ( EditorApp & editor,
const Vector2d & documentPoint ) const
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.

Parameters
editorEditor state used for hit-testing.
documentPointPointer location in SVG document coordinates.
Returns
true when the point hits an unlocked geometry element.

◆ onMouseDown()

void donner::editor::SelectTool::onMouseDown ( EditorApp & editor,
const Vector2d & documentPoint,
MouseModifiers modifiers )
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.

◆ onMouseMove()

void donner::editor::SelectTool::onMouseMove ( EditorApp & editor,
const Vector2d & documentPoint,
bool buttonHeld )
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.

◆ onMouseUp()

void donner::editor::SelectTool::onMouseUp ( EditorApp & editor,
const Vector2d & documentPoint )
overridevirtual

Mouse button was released at documentPoint.

Implements donner::editor::Tool.

◆ tryStartRedragOnSelected()

bool donner::editor::SelectTool::tryStartRedragOnSelected ( EditorApp & editor,
const Vector2d & documentPoint,
MouseModifiers modifiers,
std::span< const Box2d > selectionBoundsDoc,
std::span< const Box2d > occludingBoundsDoc = {} )
nodiscard

Snapshot-safe re-drag start (design doc 0033 §M8). When the user clicks inside the bounds of the single currently-selected element, start a drag of that element WITHOUT calling EditorApp::hitTest.

  • so the call is safe to run even while the async-renderer worker is mid-render (hitTest would race the worker's prepareDocumentForRendering).

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, etc.).

onMouseDown itself calls this first to avoid duplicating logic

  • so plain clicks on the selection always take the no-hit-test path regardless of busy state. The split exists so EditorShell can run it BEFORE checking isBusy() for the click handler.

The documentation for this class was generated from the following file: