@oh-just-another/state 0.58.0 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +158 -0
- package/README.md +78 -27
- package/dist/.tsbuildinfo +1 -1
- package/dist/actions/actionArrange.d.ts +13 -0
- package/dist/actions/actionArrange.d.ts.map +1 -0
- package/dist/actions/actionArrange.js +130 -0
- package/dist/actions/actionArrange.js.map +1 -0
- package/dist/actions/actionClipboard.d.ts +2 -0
- package/dist/actions/actionClipboard.d.ts.map +1 -1
- package/dist/actions/actionClipboard.js +32 -1
- package/dist/actions/actionClipboard.js.map +1 -1
- package/dist/actions/actionKeyboard.d.ts.map +1 -1
- package/dist/actions/actionKeyboard.js +77 -9
- package/dist/actions/actionKeyboard.js.map +1 -1
- package/dist/actions/actionMode.d.ts +4 -0
- package/dist/actions/actionMode.d.ts.map +1 -1
- package/dist/actions/actionMode.js +54 -0
- package/dist/actions/actionMode.js.map +1 -1
- package/dist/actions/actionSelection.d.ts.map +1 -1
- package/dist/actions/actionSelection.js +1 -0
- package/dist/actions/actionSelection.js.map +1 -1
- package/dist/actions/actionText.d.ts +5 -0
- package/dist/actions/actionText.d.ts.map +1 -0
- package/dist/actions/actionText.js +37 -0
- package/dist/actions/actionText.js.map +1 -0
- package/dist/actions/actionView.d.ts +6 -0
- package/dist/actions/actionView.d.ts.map +1 -1
- package/dist/actions/actionView.js +20 -2
- package/dist/actions/actionView.js.map +1 -1
- package/dist/actions/actionZoom.d.ts.map +1 -1
- package/dist/actions/actionZoom.js +5 -0
- package/dist/actions/actionZoom.js.map +1 -1
- package/dist/actions/index.d.ts +6 -4
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +6 -4
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/registry.d.ts.map +1 -1
- package/dist/actions/registry.js +17 -0
- package/dist/actions/registry.js.map +1 -1
- package/dist/actions/types.d.ts +10 -1
- package/dist/actions/types.d.ts.map +1 -1
- package/dist/actions/types.js.map +1 -1
- package/dist/auto-layout-scheduler.d.ts +1 -3
- package/dist/auto-layout-scheduler.d.ts.map +1 -1
- package/dist/auto-layout-scheduler.js +1 -2
- package/dist/auto-layout-scheduler.js.map +1 -1
- package/dist/built-in-handlers.d.ts.map +1 -1
- package/dist/built-in-handlers.js +14 -1
- package/dist/built-in-handlers.js.map +1 -1
- package/dist/clipboard.d.ts +0 -14
- package/dist/clipboard.d.ts.map +1 -1
- package/dist/clipboard.js +1 -1
- package/dist/clipboard.js.map +1 -1
- package/dist/constants.d.ts +208 -41
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +210 -25
- package/dist/constants.js.map +1 -1
- package/dist/dom-events.d.ts +8 -2
- package/dist/dom-events.d.ts.map +1 -1
- package/dist/dom-events.js +12 -0
- package/dist/dom-events.js.map +1 -1
- package/dist/editor/animation-scene.d.ts +36 -0
- package/dist/editor/animation-scene.d.ts.map +1 -0
- package/dist/editor/animation-scene.js +194 -0
- package/dist/editor/animation-scene.js.map +1 -0
- package/dist/editor/animation.d.ts +43 -0
- package/dist/editor/animation.d.ts.map +1 -0
- package/dist/editor/animation.js +80 -0
- package/dist/editor/animation.js.map +1 -0
- package/dist/editor/applies/arrange.d.ts +46 -0
- package/dist/editor/applies/arrange.d.ts.map +1 -0
- package/dist/editor/applies/arrange.js +162 -0
- package/dist/editor/applies/arrange.js.map +1 -0
- package/dist/editor/applies/create.d.ts +0 -6
- package/dist/editor/applies/create.d.ts.map +1 -1
- package/dist/editor/applies/create.js +1 -1
- package/dist/editor/applies/create.js.map +1 -1
- package/dist/editor/applies/edge.d.ts +8 -1
- package/dist/editor/applies/edge.d.ts.map +1 -1
- package/dist/editor/applies/edge.js +31 -1
- package/dist/editor/applies/edge.js.map +1 -1
- package/dist/editor/applies/link-move.d.ts +0 -8
- package/dist/editor/applies/link-move.d.ts.map +1 -1
- package/dist/editor/applies/link-move.js +1 -1
- package/dist/editor/applies/link-move.js.map +1 -1
- package/dist/editor/applies/move.d.ts +6 -0
- package/dist/editor/applies/move.d.ts.map +1 -1
- package/dist/editor/applies/move.js +6 -0
- package/dist/editor/applies/move.js.map +1 -1
- package/dist/editor/applies/resize.d.ts +26 -5
- package/dist/editor/applies/resize.d.ts.map +1 -1
- package/dist/editor/applies/resize.js +91 -13
- package/dist/editor/applies/resize.js.map +1 -1
- package/dist/editor/caret-blink.d.ts +18 -0
- package/dist/editor/caret-blink.d.ts.map +1 -0
- package/dist/editor/caret-blink.js +42 -0
- package/dist/editor/caret-blink.js.map +1 -0
- package/dist/editor/container-ops.d.ts.map +1 -1
- package/dist/editor/container-ops.js +2 -2
- package/dist/editor/container-ops.js.map +1 -1
- package/dist/editor/dirty-rect.d.ts +23 -0
- package/dist/editor/dirty-rect.d.ts.map +1 -0
- package/dist/editor/dirty-rect.js +115 -0
- package/dist/editor/dirty-rect.js.map +1 -0
- package/dist/editor/gif-playback.d.ts +45 -0
- package/dist/editor/gif-playback.d.ts.map +1 -0
- package/dist/editor/gif-playback.js +125 -0
- package/dist/editor/gif-playback.js.map +1 -0
- package/dist/editor/hit-test.d.ts +3 -3
- package/dist/editor/hit-test.d.ts.map +1 -1
- package/dist/editor/hit-test.js +40 -15
- package/dist/editor/hit-test.js.map +1 -1
- package/dist/editor/interaction-state.d.ts +184 -0
- package/dist/editor/interaction-state.d.ts.map +1 -0
- package/dist/editor/interaction-state.js +139 -0
- package/dist/editor/interaction-state.js.map +1 -0
- package/dist/editor/link-handle-drag.d.ts +152 -0
- package/dist/editor/link-handle-drag.d.ts.map +1 -0
- package/dist/editor/link-handle-drag.js +300 -0
- package/dist/editor/link-handle-drag.js.map +1 -0
- package/dist/editor/long-press.d.ts.map +1 -1
- package/dist/editor/long-press.js +2 -2
- package/dist/editor/long-press.js.map +1 -1
- package/dist/editor/pinch.d.ts.map +1 -1
- package/dist/editor/pinch.js +6 -6
- package/dist/editor/pinch.js.map +1 -1
- package/dist/editor/pointer-binding.d.ts +9 -11
- package/dist/editor/pointer-binding.d.ts.map +1 -1
- package/dist/editor/pointer-binding.js +1191 -890
- package/dist/editor/pointer-binding.js.map +1 -1
- package/dist/editor/public/arrange-group.d.ts +3 -9
- package/dist/editor/public/arrange-group.d.ts.map +1 -1
- package/dist/editor/public/arrange-group.js +4 -6
- package/dist/editor/public/arrange-group.js.map +1 -1
- package/dist/editor/public/brush.d.ts +31 -12
- package/dist/editor/public/brush.d.ts.map +1 -1
- package/dist/editor/public/brush.js +66 -17
- package/dist/editor/public/brush.js.map +1 -1
- package/dist/editor/public/clipboard.d.ts +2 -4
- package/dist/editor/public/clipboard.d.ts.map +1 -1
- package/dist/editor/public/clipboard.js +2 -4
- package/dist/editor/public/clipboard.js.map +1 -1
- package/dist/editor/public/cursor.d.ts +29 -0
- package/dist/editor/public/cursor.d.ts.map +1 -0
- package/dist/editor/public/cursor.js +146 -0
- package/dist/editor/public/cursor.js.map +1 -0
- package/dist/editor/public/eraser.d.ts +55 -0
- package/dist/editor/public/eraser.d.ts.map +1 -0
- package/dist/editor/public/eraser.js +65 -0
- package/dist/editor/public/eraser.js.map +1 -0
- package/dist/editor/public/frame-name.d.ts +20 -0
- package/dist/editor/public/frame-name.d.ts.map +1 -0
- package/dist/editor/public/frame-name.js +54 -0
- package/dist/editor/public/frame-name.js.map +1 -0
- package/dist/editor/public/image-insert.d.ts +1 -1
- package/dist/editor/public/image-insert.d.ts.map +1 -1
- package/dist/editor/public/laser.d.ts +38 -0
- package/dist/editor/public/laser.d.ts.map +1 -0
- package/dist/editor/public/laser.js +42 -0
- package/dist/editor/public/laser.js.map +1 -0
- package/dist/editor/public/layers.d.ts.map +1 -1
- package/dist/editor/public/layers.js +2 -2
- package/dist/editor/public/layers.js.map +1 -1
- package/dist/editor/public/link.d.ts +11 -2
- package/dist/editor/public/link.d.ts.map +1 -1
- package/dist/editor/public/link.js +70 -2
- package/dist/editor/public/link.js.map +1 -1
- package/dist/editor/public/placement.d.ts +60 -2
- package/dist/editor/public/placement.d.ts.map +1 -1
- package/dist/editor/public/placement.js +193 -2
- package/dist/editor/public/placement.js.map +1 -1
- package/dist/editor/public/selection-ops.d.ts +35 -1
- package/dist/editor/public/selection-ops.d.ts.map +1 -1
- package/dist/editor/public/selection-ops.js +97 -2
- package/dist/editor/public/selection-ops.js.map +1 -1
- package/dist/editor/public/stroke-eraser-coverage.d.ts +37 -0
- package/dist/editor/public/stroke-eraser-coverage.d.ts.map +1 -0
- package/dist/editor/public/stroke-eraser-coverage.js +168 -0
- package/dist/editor/public/stroke-eraser-coverage.js.map +1 -0
- package/dist/editor/public/stroke-eraser.d.ts +50 -0
- package/dist/editor/public/stroke-eraser.d.ts.map +1 -0
- package/dist/editor/public/stroke-eraser.js +176 -0
- package/dist/editor/public/stroke-eraser.js.map +1 -0
- package/dist/editor/public/stroke-smoothing.d.ts +21 -0
- package/dist/editor/public/stroke-smoothing.d.ts.map +1 -0
- package/dist/editor/public/stroke-smoothing.js +37 -0
- package/dist/editor/public/stroke-smoothing.js.map +1 -0
- package/dist/editor/public/text-edit.d.ts +1 -10
- package/dist/editor/public/text-edit.d.ts.map +1 -1
- package/dist/editor/public/text-edit.js +2 -16
- package/dist/editor/public/text-edit.js.map +1 -1
- package/dist/editor/public/tool-ops.d.ts +130 -0
- package/dist/editor/public/tool-ops.d.ts.map +1 -0
- package/dist/editor/public/tool-ops.js +392 -0
- package/dist/editor/public/tool-ops.js.map +1 -0
- package/dist/editor/public/z-order.d.ts +1 -12
- package/dist/editor/public/z-order.d.ts.map +1 -1
- package/dist/editor/public/z-order.js +5 -5
- package/dist/editor/public/z-order.js.map +1 -1
- package/dist/editor/public/zoom-pan.d.ts +15 -4
- package/dist/editor/public/zoom-pan.d.ts.map +1 -1
- package/dist/editor/public/zoom-pan.js +39 -7
- package/dist/editor/public/zoom-pan.js.map +1 -1
- package/dist/editor/render-orchestrator.d.ts +177 -5
- package/dist/editor/render-orchestrator.d.ts.map +1 -1
- package/dist/editor/render-orchestrator.js +519 -358
- package/dist/editor/render-orchestrator.js.map +1 -1
- package/dist/editor/resize-helpers.d.ts +21 -5
- package/dist/editor/resize-helpers.d.ts.map +1 -1
- package/dist/editor/resize-helpers.js +59 -19
- package/dist/editor/resize-helpers.js.map +1 -1
- package/dist/editor/text-edit.d.ts +136 -0
- package/dist/editor/text-edit.d.ts.map +1 -0
- package/dist/editor/text-edit.js +328 -0
- package/dist/editor/text-edit.js.map +1 -0
- package/dist/editor/viewport-helpers.d.ts.map +1 -1
- package/dist/editor/viewport-helpers.js +3 -3
- package/dist/editor/viewport-helpers.js.map +1 -1
- package/dist/editor-events.d.ts +1 -1
- package/dist/editor-events.d.ts.map +1 -1
- package/dist/editor.d.ts +603 -346
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +1843 -1630
- package/dist/editor.js.map +1 -1
- package/dist/file-drop.d.ts.map +1 -1
- package/dist/file-drop.js +1 -2
- package/dist/file-drop.js.map +1 -1
- package/dist/frame-helpers.d.ts.map +1 -1
- package/dist/frame-helpers.js +5 -5
- package/dist/frame-helpers.js.map +1 -1
- package/dist/group-helpers.d.ts.map +1 -1
- package/dist/group-helpers.js +4 -4
- package/dist/group-helpers.js.map +1 -1
- package/dist/handle.d.ts +59 -6
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +99 -7
- package/dist/handle.js.map +1 -1
- package/dist/hotkeys-binding.d.ts +26 -0
- package/dist/hotkeys-binding.d.ts.map +1 -0
- package/dist/hotkeys-binding.js +35 -0
- package/dist/hotkeys-binding.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/link-selection.d.ts +3 -5
- package/dist/link-selection.d.ts.map +1 -1
- package/dist/link-selection.js +3 -12
- package/dist/link-selection.js.map +1 -1
- package/dist/machine.d.ts +27 -1
- package/dist/machine.d.ts.map +1 -1
- package/dist/machine.js +38 -0
- package/dist/machine.js.map +1 -1
- package/dist/modes.d.ts +15 -1
- package/dist/modes.d.ts.map +1 -1
- package/dist/modes.js.map +1 -1
- package/dist/overlay.d.ts +92 -6
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +582 -125
- package/dist/overlay.js.map +1 -1
- package/dist/search.d.ts +37 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +45 -0
- package/dist/search.js.map +1 -0
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +2 -10
- package/dist/selection.js.map +1 -1
- package/dist/util.d.ts +8 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +17 -0
- package/dist/util.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { caretGeometry, layoutText, pointToCaretIndex, selectionRects as textSelectionRects, } from "@oh-just-another/renderer-core";
|
|
2
|
+
import { getElement, getElementWorldBounds, isText, removeElement, updateElement, } from "@oh-just-another/scene";
|
|
3
|
+
import { CaretBlinkController } from "./caret-blink.js";
|
|
4
|
+
import { canBeginTextEdit } from "./public/text-edit.js";
|
|
5
|
+
/**
|
|
6
|
+
* Owns the inline text-edit session state (edited shape, pending creation,
|
|
7
|
+
* origin snapshot, live selection, canvas drag-select anchor and caret blink).
|
|
8
|
+
* Extracted from the Editor god-class; the Editor keeps thin delegate wrappers
|
|
9
|
+
* so its public API is unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export class TextEditController {
|
|
12
|
+
host;
|
|
13
|
+
/**
|
|
14
|
+
* Currently edited text shape (or null). Set by `begin`; cleared by
|
|
15
|
+
* `commit` / `cancel`. The host overlay (`<TextEditorOverlay>` in
|
|
16
|
+
* `@react-ui`) subscribes via `editor` and renders a `<textarea>`
|
|
17
|
+
* positioned over the shape.
|
|
18
|
+
*/
|
|
19
|
+
_editingElement = null;
|
|
20
|
+
/**
|
|
21
|
+
* When the `draw-text` tool just placed a shape and opened its
|
|
22
|
+
* editor, this holds that shape's id until the first commit. A
|
|
23
|
+
* pending creation isn't in history yet: committing non-empty text
|
|
24
|
+
* records a single add patch (whole shape = one undo); committing
|
|
25
|
+
* empty / cancelling removes it with no history entry at all.
|
|
26
|
+
*/
|
|
27
|
+
_pendingCreate = null;
|
|
28
|
+
/**
|
|
29
|
+
* Snapshot of the shape at edit start. Used to revert on cancel and
|
|
30
|
+
* as the `before` of the single commit patch. `null` for a pending
|
|
31
|
+
* creation (the shape didn't exist yet).
|
|
32
|
+
*/
|
|
33
|
+
_origin = null;
|
|
34
|
+
/**
|
|
35
|
+
* Live selection inside the edited text, mirrored from the hidden
|
|
36
|
+
* `<textarea>` (`start`/`end` are source offsets, `dir` is the
|
|
37
|
+
* anchored end). The caret is `dir === "backward" ? start : end`.
|
|
38
|
+
*/
|
|
39
|
+
_sel = null;
|
|
40
|
+
/** Anchor offset for a canvas drag-select inside the edited text. */
|
|
41
|
+
_dragAnchor = null;
|
|
42
|
+
caretBlink;
|
|
43
|
+
constructor(host) {
|
|
44
|
+
this.host = host;
|
|
45
|
+
this.caretBlink = new CaretBlinkController(() => {
|
|
46
|
+
this.host.notify();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
get editingElement() {
|
|
50
|
+
return this._editingElement;
|
|
51
|
+
}
|
|
52
|
+
get selection() {
|
|
53
|
+
return this._sel;
|
|
54
|
+
}
|
|
55
|
+
/** Caret offset = the moving end of the selection. */
|
|
56
|
+
get caret() {
|
|
57
|
+
if (!this._sel)
|
|
58
|
+
return null;
|
|
59
|
+
return this._sel.dir === "backward" ? this._sel.start : this._sel.end;
|
|
60
|
+
}
|
|
61
|
+
get caretBlinkOn() {
|
|
62
|
+
return this.caretBlink.on;
|
|
63
|
+
}
|
|
64
|
+
/** `true` while a canvas drag-select inside the edited text is active. */
|
|
65
|
+
get isDragging() {
|
|
66
|
+
return this._dragAnchor !== null;
|
|
67
|
+
}
|
|
68
|
+
/** Mark a freshly-placed `draw-text` shape as pending until the first commit. */
|
|
69
|
+
markPendingCreate(id) {
|
|
70
|
+
this._pendingCreate = id;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Begin editing a text shape's body. No-op when the shape doesn't
|
|
74
|
+
* exist or isn't a text shape. Concurrent edits commit themselves
|
|
75
|
+
* (only one shape at a time). Caret defaults to the end of the text.
|
|
76
|
+
*/
|
|
77
|
+
begin(id) {
|
|
78
|
+
if (!canBeginTextEdit(this.host.scene, id, (lid) => this.host.isLayerLocked(lid)))
|
|
79
|
+
return;
|
|
80
|
+
// Commit any in-flight edit on a different shape first.
|
|
81
|
+
if (this._editingElement !== null && this._editingElement !== id)
|
|
82
|
+
this.commit();
|
|
83
|
+
this._editingElement = id;
|
|
84
|
+
this._origin = this._pendingCreate === id ? null : (getElement(this.host.scene, id) ?? null);
|
|
85
|
+
const shape = getElement(this.host.scene, id);
|
|
86
|
+
const len = shape !== undefined && isText(shape) ? shape.text.length : 0;
|
|
87
|
+
this._sel = { start: len, end: len, dir: "forward" };
|
|
88
|
+
this.caretBlink.start();
|
|
89
|
+
this.host.notify();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Live edit transport from the hidden `<textarea>`: replace the
|
|
93
|
+
* shape's text + selection as the user types / pastes / composes.
|
|
94
|
+
* Mutates the scene WITHOUT a history entry — history is recorded
|
|
95
|
+
* once on commit. No-op when not editing.
|
|
96
|
+
*/
|
|
97
|
+
setText(value, selStart, selEnd, dir = "forward") {
|
|
98
|
+
const id = this._editingElement;
|
|
99
|
+
if (!id)
|
|
100
|
+
return;
|
|
101
|
+
const r = updateElement(this.host.scene, id, (s) => ({ ...s, text: value }));
|
|
102
|
+
this.host.scene = r.scene;
|
|
103
|
+
this._sel = { start: selStart, end: selEnd, dir };
|
|
104
|
+
this.caretBlink.wake();
|
|
105
|
+
this.host.notify();
|
|
106
|
+
}
|
|
107
|
+
/** Selection-only update (arrows / shift-select / click) — no text change. */
|
|
108
|
+
setSelection(selStart, selEnd, dir = "forward") {
|
|
109
|
+
if (!this._editingElement)
|
|
110
|
+
return;
|
|
111
|
+
this._sel = { start: selStart, end: selEnd, dir };
|
|
112
|
+
this.caretBlink.wake();
|
|
113
|
+
this.host.notify();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Map a world-space point to a caret offset in the edited text. Used
|
|
117
|
+
* to place / extend the caret from canvas clicks. Returns `null` when
|
|
118
|
+
* not editing or the shape is gone.
|
|
119
|
+
*/
|
|
120
|
+
caretIndexAtWorldPoint(worldPoint) {
|
|
121
|
+
const id = this._editingElement;
|
|
122
|
+
if (!id)
|
|
123
|
+
return null;
|
|
124
|
+
const shape = getElement(this.host.scene, id);
|
|
125
|
+
if (shape === undefined || !isText(shape))
|
|
126
|
+
return null;
|
|
127
|
+
const layout = this.editingTextLayout(shape);
|
|
128
|
+
if (!layout)
|
|
129
|
+
return null;
|
|
130
|
+
// World → shape-local: undo the element transform so the hit lands on the
|
|
131
|
+
// right glyph. Translate by position, then divide out scale (rotation
|
|
132
|
+
// while editing text is not handled — an uncommon case).
|
|
133
|
+
const sx = shape.scale.x || 1;
|
|
134
|
+
const sy = shape.scale.y || 1;
|
|
135
|
+
const local = {
|
|
136
|
+
x: (worldPoint.x - shape.position.x) / sx,
|
|
137
|
+
y: (worldPoint.y - shape.position.y) / sy,
|
|
138
|
+
};
|
|
139
|
+
const align = shape.style.textAlign ?? "left";
|
|
140
|
+
return pointToCaretIndex(layout, local, this.measureFor(shape), align);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* `true` when a point is inside the currently-edited text shape's
|
|
144
|
+
* world bounds. Used by the pointer binding to decide between
|
|
145
|
+
* repositioning the caret (inside) and committing (outside).
|
|
146
|
+
*/
|
|
147
|
+
editedElementContainsPoint(worldPoint) {
|
|
148
|
+
const id = this._editingElement;
|
|
149
|
+
if (!id)
|
|
150
|
+
return false;
|
|
151
|
+
const shape = getElement(this.host.scene, id);
|
|
152
|
+
if (!shape)
|
|
153
|
+
return false;
|
|
154
|
+
const b = getElementWorldBounds(shape);
|
|
155
|
+
return (worldPoint.x >= b.x &&
|
|
156
|
+
worldPoint.x <= b.x + b.width &&
|
|
157
|
+
worldPoint.y >= b.y &&
|
|
158
|
+
worldPoint.y <= b.y + b.height);
|
|
159
|
+
}
|
|
160
|
+
/** Place a collapsed caret at the clicked point and start a drag-select. */
|
|
161
|
+
setCaretFromPoint(worldPoint) {
|
|
162
|
+
const idx = this.caretIndexAtWorldPoint(worldPoint);
|
|
163
|
+
if (idx === null)
|
|
164
|
+
return;
|
|
165
|
+
this._dragAnchor = idx;
|
|
166
|
+
this.setSelection(idx, idx, "forward");
|
|
167
|
+
}
|
|
168
|
+
/** Extend the selection from the drag anchor to the current point. */
|
|
169
|
+
extendSelectionToPoint(worldPoint) {
|
|
170
|
+
if (this._dragAnchor === null)
|
|
171
|
+
return;
|
|
172
|
+
const idx = this.caretIndexAtWorldPoint(worldPoint);
|
|
173
|
+
if (idx === null)
|
|
174
|
+
return;
|
|
175
|
+
const anchor = this._dragAnchor;
|
|
176
|
+
if (idx >= anchor)
|
|
177
|
+
this.setSelection(anchor, idx, "forward");
|
|
178
|
+
else
|
|
179
|
+
this.setSelection(idx, anchor, "backward");
|
|
180
|
+
}
|
|
181
|
+
/** End a canvas drag-select (clears the drag anchor). */
|
|
182
|
+
endDragSelect() {
|
|
183
|
+
this._dragAnchor = null;
|
|
184
|
+
}
|
|
185
|
+
/** Build the editable layout for a text shape using the main target's metrics. */
|
|
186
|
+
editingTextLayout(shape) {
|
|
187
|
+
return layoutText(shape.text, this.measureFor(shape), {
|
|
188
|
+
fontSize: shape.fontSize,
|
|
189
|
+
...(shape.maxWidth !== undefined ? { maxWidth: shape.maxWidth } : {}),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A measure callback bound to a shape's font, using the main target's
|
|
194
|
+
* `measureText` — the SAME source the renderer draws with (WebGL2
|
|
195
|
+
* reports MSDF advances) and the bounder measures with. Caret /
|
|
196
|
+
* selection geometry therefore lines up exactly with the glyphs.
|
|
197
|
+
*/
|
|
198
|
+
measureFor(shape) {
|
|
199
|
+
const target = this.host.mainTarget;
|
|
200
|
+
// Match the rendered weight/style so caret / selection geometry lines
|
|
201
|
+
// up with bold / italic glyphs (which have different advances).
|
|
202
|
+
target.setFont(shape.fontFamily, shape.fontSize, {
|
|
203
|
+
...(shape.style.fontWeight === "bold" ? { weight: "bold" } : {}),
|
|
204
|
+
...(shape.style.fontStyle === "italic" ? { style: "italic" } : {}),
|
|
205
|
+
});
|
|
206
|
+
return (s) => target.measureText(s).width;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* World-space caret + selection geometry for the overlay pass.
|
|
210
|
+
* Returns `null` when not editing. The caret is `null` while blinked
|
|
211
|
+
* off so the overlay can simply skip drawing it.
|
|
212
|
+
*/
|
|
213
|
+
overlay() {
|
|
214
|
+
const id = this._editingElement;
|
|
215
|
+
if (!id || !this._sel)
|
|
216
|
+
return null;
|
|
217
|
+
const shape = getElement(this.host.scene, id);
|
|
218
|
+
if (shape === undefined || !isText(shape))
|
|
219
|
+
return null;
|
|
220
|
+
const layout = this.editingTextLayout(shape);
|
|
221
|
+
if (!layout)
|
|
222
|
+
return null;
|
|
223
|
+
const align = shape.style.textAlign ?? "left";
|
|
224
|
+
const measure = this.measureFor(shape);
|
|
225
|
+
const { x: px, y: py } = shape.position;
|
|
226
|
+
// The layout is in the shape's own (unscaled) space; the renderer draws it
|
|
227
|
+
// through the element transform, so caret + selection geometry must scale
|
|
228
|
+
// too or they trail the rendered text on a scaled element. (Rotation while
|
|
229
|
+
// editing text is not handled — an uncommon case.)
|
|
230
|
+
const sx = shape.scale.x;
|
|
231
|
+
const sy = shape.scale.y;
|
|
232
|
+
const local = textSelectionRects(layout, this._sel.start, this._sel.end, measure, align);
|
|
233
|
+
const selectionRects = local.map((r) => ({
|
|
234
|
+
x: px + Math.min(r.x * sx, (r.x + r.width) * sx),
|
|
235
|
+
y: py + Math.min(r.y * sy, (r.y + r.height) * sy),
|
|
236
|
+
width: Math.abs(r.width * sx),
|
|
237
|
+
height: Math.abs(r.height * sy),
|
|
238
|
+
}));
|
|
239
|
+
let caret = null;
|
|
240
|
+
if (this.caretBlink.on) {
|
|
241
|
+
const cIdx = this._sel.dir === "backward" ? this._sel.start : this._sel.end;
|
|
242
|
+
const g = caretGeometry(layout, cIdx, measure, shape.fontSize, align);
|
|
243
|
+
caret = { x: px + g.x * sx, y: py + g.y * sy, height: g.height * Math.abs(sy) };
|
|
244
|
+
}
|
|
245
|
+
return { caret, caretColor: shape.style.fill ?? "#1a1a1a", selectionRects };
|
|
246
|
+
}
|
|
247
|
+
commit(next) {
|
|
248
|
+
const id = this._editingElement;
|
|
249
|
+
if (!id)
|
|
250
|
+
return;
|
|
251
|
+
const pending = this._pendingCreate === id;
|
|
252
|
+
const origin = this._origin;
|
|
253
|
+
// Optional explicit text (keyboard / test callers); the live path
|
|
254
|
+
// passes nothing because the scene already holds the typed text.
|
|
255
|
+
if (next !== undefined) {
|
|
256
|
+
this.host.scene = updateElement(this.host.scene, id, (s) => ({ ...s, text: next })).scene;
|
|
257
|
+
}
|
|
258
|
+
this._editingElement = null;
|
|
259
|
+
this._pendingCreate = null;
|
|
260
|
+
this._origin = null;
|
|
261
|
+
this._sel = null;
|
|
262
|
+
this.caretBlink.stop();
|
|
263
|
+
const committed = getElement(this.host.scene, id);
|
|
264
|
+
const finalElement = committed !== undefined && isText(committed) ? committed : undefined;
|
|
265
|
+
const text = finalElement?.text ?? "";
|
|
266
|
+
// Empty (whitespace-only) text removes the shape. Pending = silent
|
|
267
|
+
// (never recorded); existing = recorded so undo restores the origin.
|
|
268
|
+
if (text.trim() === "") {
|
|
269
|
+
if (finalElement) {
|
|
270
|
+
this.host.scene = removeElement(this.host.scene, id).scene;
|
|
271
|
+
if (!pending && origin) {
|
|
272
|
+
this.host.pushHistory({ kind: "element", id, before: origin, after: null });
|
|
273
|
+
}
|
|
274
|
+
this.host.clearSelectionFor(id);
|
|
275
|
+
}
|
|
276
|
+
this.host.notify();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (pending) {
|
|
280
|
+
// Record the whole creation as one add patch.
|
|
281
|
+
if (finalElement)
|
|
282
|
+
this.host.pushHistory({ kind: "element", id, before: null, after: finalElement });
|
|
283
|
+
}
|
|
284
|
+
else if (origin && finalElement) {
|
|
285
|
+
// Existing edit: record ONLY the text delta. Other fields (font
|
|
286
|
+
// size etc.) changed via the panel push their own history during
|
|
287
|
+
// the edit, so the commit's `before` keeps the final non-text
|
|
288
|
+
// state and rewinds just the text.
|
|
289
|
+
const originText = isText(origin) ? origin.text : "";
|
|
290
|
+
if (originText !== finalElement.text) {
|
|
291
|
+
const before = { ...finalElement, text: originText };
|
|
292
|
+
this.host.pushHistory({ kind: "element", id, before, after: finalElement });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
this.host.notify();
|
|
296
|
+
}
|
|
297
|
+
cancel() {
|
|
298
|
+
const id = this._editingElement;
|
|
299
|
+
if (id === null)
|
|
300
|
+
return;
|
|
301
|
+
const pending = this._pendingCreate === id;
|
|
302
|
+
const origin = this._origin;
|
|
303
|
+
this._editingElement = null;
|
|
304
|
+
this._pendingCreate = null;
|
|
305
|
+
this._origin = null;
|
|
306
|
+
this._sel = null;
|
|
307
|
+
this.caretBlink.stop();
|
|
308
|
+
// Revert live edits with no history entry. Pending creations are
|
|
309
|
+
// removed entirely; existing shapes have only their TEXT restored
|
|
310
|
+
// (panel-driven field changes during the edit keep their own
|
|
311
|
+
// committed history and must survive the cancel).
|
|
312
|
+
if (pending) {
|
|
313
|
+
if (getElement(this.host.scene, id)) {
|
|
314
|
+
this.host.scene = removeElement(this.host.scene, id).scene;
|
|
315
|
+
this.host.clearSelectionFor(id);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else if (origin) {
|
|
319
|
+
const originText = isText(origin) ? origin.text : "";
|
|
320
|
+
this.host.scene = updateElement(this.host.scene, id, (s) => ({
|
|
321
|
+
...s,
|
|
322
|
+
text: originText,
|
|
323
|
+
})).scene;
|
|
324
|
+
}
|
|
325
|
+
this.host.notify();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=text-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-edit.js","sourceRoot":"","sources":["../../src/editor/text-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewport-helpers.d.ts","sourceRoot":"","sources":["../../src/editor/viewport-helpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"viewport-helpers.d.ts","sourceRoot":"","sources":["../../src/editor/viewport-helpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAKL,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAGhC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,KAAG,MAAM,GAAG,IAc5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,KAAK,EAAE,SAAS,SAAS,KAAG,MAAM,GAAG,IAS9E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,KAAK,EACZ,WAAW,QAAQ,CAAC,SAAS,CAAC,KAC7B,MAAM,GAAG,IAUX,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { bounds as B, matrix } from "@oh-just-another/math";
|
|
2
|
-
import { getScreenToWorld, getElement, getElementWorldBounds, } from "@oh-just-another/scene";
|
|
2
|
+
import { getScreenToWorld, getElement, getElementWorldBounds, isGroup, } from "@oh-just-another/scene";
|
|
3
3
|
import { VIEWPORT_CULL_PADDING_RATIO } from "../constants.js";
|
|
4
4
|
/**
|
|
5
5
|
* World-space AABB of the screen viewport, inflated by ~10% so a slow pan
|
|
@@ -34,7 +34,7 @@ export const groupChildrenUnion = (scene, groupId) => {
|
|
|
34
34
|
for (const s of scene.elements.values()) {
|
|
35
35
|
if (s.parentId !== groupId)
|
|
36
36
|
continue;
|
|
37
|
-
const inner = s
|
|
37
|
+
const inner = isGroup(s) ? groupChildrenUnion(scene, s.id) : getElementWorldBounds(s);
|
|
38
38
|
if (!inner)
|
|
39
39
|
continue;
|
|
40
40
|
acc = acc ? B.union(acc, inner) : inner;
|
|
@@ -53,7 +53,7 @@ export const combinedSelectionBounds = (scene, selection) => {
|
|
|
53
53
|
const s = getElement(scene, id);
|
|
54
54
|
if (!s)
|
|
55
55
|
continue;
|
|
56
|
-
const b = s
|
|
56
|
+
const b = isGroup(s) ? groupChildrenUnion(scene, s.id) : getElementWorldBounds(s);
|
|
57
57
|
if (!b)
|
|
58
58
|
continue;
|
|
59
59
|
acc = acc ? B.union(acc, b) : b;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewport-helpers.js","sourceRoot":"","sources":["../../src/editor/viewport-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,qBAAqB,
|
|
1
|
+
{"version":3,"file":"viewport-helpers.js","sourceRoot":"","sources":["../../src/editor/viewport-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,qBAAqB,EACrB,OAAO,GAER,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAY,EAAiB,EAAE;IAClE,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;IACxB,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;IACzB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,GAAG,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG;QACd,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACzC,CAAC;IACF,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,2BAA2B,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAY,EAAE,OAAkB,EAAiB,EAAE;IACpF,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO;YAAE,SAAS;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,KAAY,EACZ,SAA8B,EACf,EAAE;IACjB,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAClF,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC"}
|
package/dist/editor-events.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface EditorEvents {
|
|
|
27
27
|
readonly canUndo: boolean;
|
|
28
28
|
readonly canRedo: boolean;
|
|
29
29
|
}) => void;
|
|
30
|
-
/** Viewport (zoom / pan / size /
|
|
30
|
+
/** Viewport (zoom / pan / size / gridEnabled / gridStyle) changed. */
|
|
31
31
|
viewport: (scene: Scene) => void;
|
|
32
32
|
}
|
|
33
33
|
//# sourceMappingURL=editor-events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-events.d.ts","sourceRoot":"","sources":["../src/editor-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iEAAiE;IACjE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,KAAK,IAAI,CAAC;IACpD,oEAAoE;IACpE,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC9B,gEAAgE;IAChE,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,
|
|
1
|
+
{"version":3,"file":"editor-events.d.ts","sourceRoot":"","sources":["../src/editor-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iEAAiE;IACjE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,KAAK,IAAI,CAAC;IACpD,oEAAoE;IACpE,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC9B,gEAAgE;IAChE,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC"}
|