cloudmr-ux 4.5.2 → 4.5.5
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/dist/CmrComponents/niivue-viewer/CloudMrNiivuePanel.d.ts +2 -1
- package/dist/CmrComponents/niivue-viewer/CloudMrNiivueViewer.js +32 -11
- package/dist/CmrComponents/niivue-viewer/NiivuePatcher.js +30 -0
- package/dist/CmrComponents/niivue-viewer/PenDraftOverlay.d.ts +1 -1
- package/dist/CmrComponents/niivue-viewer/PenDraftOverlay.js +38 -33
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/DrawColorPlatte.d.ts +2 -2
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/DrawColorPlatte.js +4 -4
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/MroDrawToolkit.js +1 -1
- package/dist/CmrComponents/niivue-viewer/penDraftUtils.d.ts +9 -14
- package/dist/CmrComponents/niivue-viewer/penDraftUtils.js +27 -20
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ export type CloudMrDrawToolkitProps = Omit<DrawToolkitProps, "rois" | "selectedR
|
|
|
9
9
|
onCancelPolyline?: () => void;
|
|
10
10
|
onApplyPenDraft?: () => void;
|
|
11
11
|
onCancelPenDraft?: () => void;
|
|
12
|
-
|
|
12
|
+
onFillPenDraft?: () => void;
|
|
13
13
|
penDraftActive?: boolean;
|
|
14
14
|
shapeDraftActive?: boolean;
|
|
15
15
|
onApplyShapeDraft?: () => void;
|
|
@@ -57,6 +57,7 @@ export interface CloudMrNiivuePanelProps {
|
|
|
57
57
|
penValue: number;
|
|
58
58
|
vertices?: [number, number, number][];
|
|
59
59
|
strokeVoxels?: [number, number, number][];
|
|
60
|
+
filled?: boolean;
|
|
60
61
|
bounds?: {
|
|
61
62
|
x1: number;
|
|
62
63
|
y1: number;
|
|
@@ -63,7 +63,7 @@ import { SettingsPanel } from './SettingsPanel';
|
|
|
63
63
|
import { NumberPicker } from './NumberPicker';
|
|
64
64
|
import { ColorPicker } from './ColorPicker';
|
|
65
65
|
import { LayersPanel } from './LayersPanel';
|
|
66
|
-
import { applyPenDraft, cancelPenDraft, polylineDraftFromNv, syncPolylineDraftToNv, } from './penDraftUtils';
|
|
66
|
+
import { applyPenDraft, cancelPenDraft, fillPolylineDraft, polylineDraftFromNv, syncPolylineDraftToNv, } from './penDraftUtils';
|
|
67
67
|
import { CloudMrNiivuePanel } from './CloudMrNiivuePanel';
|
|
68
68
|
import { Niivue } from './NiivuePatcher';
|
|
69
69
|
import NVSwitch from './Switch';
|
|
@@ -777,13 +777,12 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
777
777
|
nvSetDrawingEnabled(true);
|
|
778
778
|
}
|
|
779
779
|
}
|
|
780
|
-
function applyPenDraftHandler(
|
|
780
|
+
function applyPenDraftHandler() {
|
|
781
781
|
var _a;
|
|
782
|
-
if (fillClosed === void 0) { fillClosed = false; }
|
|
783
782
|
var draft = penDraftRef.current;
|
|
784
783
|
if (!draft)
|
|
785
784
|
return;
|
|
786
|
-
applyPenDraft(nv, draft
|
|
785
|
+
applyPenDraft(nv, draft);
|
|
787
786
|
if (draft.kind === "polyline") {
|
|
788
787
|
(_a = nv.cloudMrResetPolyline) === null || _a === void 0 ? void 0 : _a.call(nv);
|
|
789
788
|
setPolylineVertexCount(0);
|
|
@@ -797,6 +796,13 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
797
796
|
}
|
|
798
797
|
resampleImage();
|
|
799
798
|
}
|
|
799
|
+
function fillPolylineDraftHandler() {
|
|
800
|
+
var draft = penDraftRef.current;
|
|
801
|
+
if (!draft || draft.kind !== "polyline" || draft.vertices.length < 3)
|
|
802
|
+
return;
|
|
803
|
+
var next = fillPolylineDraft(nv, draft);
|
|
804
|
+
onPenDraftChange(next);
|
|
805
|
+
}
|
|
800
806
|
function onPenDraftChange(draft) {
|
|
801
807
|
setPenDraft(draft);
|
|
802
808
|
penDraftRef.current = draft;
|
|
@@ -814,16 +820,20 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
814
820
|
nvSetDrawingEnabled(false);
|
|
815
821
|
};
|
|
816
822
|
nv.onPolylineChange = function (count) {
|
|
817
|
-
var _a;
|
|
823
|
+
var _a, _b;
|
|
818
824
|
setPolylineVertexCount(count);
|
|
819
825
|
if (penDrawModeRef.current === "polyline" && count >= 2) {
|
|
820
|
-
var
|
|
826
|
+
var prev = penDraftRef.current;
|
|
827
|
+
var preserveFill = (prev === null || prev === void 0 ? void 0 : prev.kind) === "polyline" &&
|
|
828
|
+
prev.filled &&
|
|
829
|
+
((_a = prev.vertices) === null || _a === void 0 ? void 0 : _a.length) === count;
|
|
830
|
+
var draft = polylineDraftFromNv(nv, { filled: preserveFill });
|
|
821
831
|
if (draft) {
|
|
822
832
|
setPenDraft(draft);
|
|
823
833
|
penDraftRef.current = draft;
|
|
824
834
|
}
|
|
825
835
|
}
|
|
826
|
-
else if (((
|
|
836
|
+
else if (((_b = penDraftRef.current) === null || _b === void 0 ? void 0 : _b.kind) === "polyline") {
|
|
827
837
|
setPenDraft(null);
|
|
828
838
|
penDraftRef.current = null;
|
|
829
839
|
}
|
|
@@ -865,6 +875,17 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
865
875
|
nv._cloudMrShapeDraftActive = true;
|
|
866
876
|
nvSetDrawingEnabled(false);
|
|
867
877
|
};
|
|
878
|
+
nv.onApplyActiveDraft = function () {
|
|
879
|
+
if (shapeDraftRef.current) {
|
|
880
|
+
applyShapeDraft();
|
|
881
|
+
}
|
|
882
|
+
else if (penDraftRef.current) {
|
|
883
|
+
applyPenDraftHandler();
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
React.useEffect(function () {
|
|
887
|
+
nv._cloudMrPenDraftActive = penDraft != null;
|
|
888
|
+
}, [penDraft]);
|
|
868
889
|
React.useEffect(function () {
|
|
869
890
|
if (!shapeDraft && !penDraft) {
|
|
870
891
|
return undefined;
|
|
@@ -886,7 +907,7 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
886
907
|
applyShapeDraft();
|
|
887
908
|
}
|
|
888
909
|
else if (penDraft) {
|
|
889
|
-
applyPenDraftHandler(
|
|
910
|
+
applyPenDraftHandler();
|
|
890
911
|
}
|
|
891
912
|
}
|
|
892
913
|
};
|
|
@@ -1391,9 +1412,9 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
1391
1412
|
onPenDrawModeChange: syncPenDrawMode,
|
|
1392
1413
|
polylineVertexCount: polylineVertexCount,
|
|
1393
1414
|
onCancelPolyline: cancelPolylineDraft,
|
|
1394
|
-
onApplyPenDraft:
|
|
1415
|
+
onApplyPenDraft: applyPenDraftHandler,
|
|
1395
1416
|
onCancelPenDraft: cancelPenDraftHandler,
|
|
1396
|
-
|
|
1417
|
+
onFillPenDraft: fillPolylineDraftHandler,
|
|
1397
1418
|
penDraftActive: penDraft != null,
|
|
1398
1419
|
brushSize: brushSize,
|
|
1399
1420
|
updateBrushSize: nvUpdateBrushSize
|
|
@@ -1412,7 +1433,7 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
1412
1433
|
props.rois[selectedROI].filename : undefined) }), props.niis[selectedVolume] != undefined && _jsx(CloudMrNiivuePanel, { nv: nv, transformFactors: transformFactors, decimalPrecision: decimalPrecision, locationData: locationData, locationTableVisible: locationTableVisible, pipelineID: props.pipelineID, resampleImage: resampleImage, rois: rois, drawToolkitProps: drawToolkitProps, drawShapeTool: drawShapeTool, setDrawShapeTool: setDrawShapeTool, mins: boundMins, maxs: boundMaxs, mms: mms, min: min, max: max, setMin: setMin, setMax: setMax, unzipAndRenderROI: unpackROI, zipAndSendROI: zipAndSendDrawingLayer, setLabelAlias: setLabelAlias, onAfterRoiUpload: function () {
|
|
1413
1434
|
var _a;
|
|
1414
1435
|
void ((_a = props.refreshPipelineRois) === null || _a === void 0 ? void 0 : _a.call(props));
|
|
1415
|
-
}, gamma: gamma, gammaKey: gammaKey, setGamma: setGamma, shapeDraft: shapeDraft, onShapeDraftChange: onShapeDraftChange, onApplyShapeDraft: applyShapeDraft, onCancelShapeDraft: cancelShapeDraft, penDraft: penDraft, onPenDraftChange: onPenDraftChange, onApplyPenDraft:
|
|
1436
|
+
}, gamma: gamma, gammaKey: gammaKey, setGamma: setGamma, shapeDraft: shapeDraft, onShapeDraftChange: onShapeDraftChange, onApplyShapeDraft: applyShapeDraft, onCancelShapeDraft: cancelShapeDraft, penDraft: penDraft, onPenDraftChange: onPenDraftChange, onApplyPenDraft: applyPenDraftHandler, onCancelPenDraft: cancelPenDraftHandler }, "".concat(selectedVolume))] })));
|
|
1416
1437
|
}
|
|
1417
1438
|
function niiToVolume(nii) {
|
|
1418
1439
|
return {
|
|
@@ -1465,8 +1465,29 @@ Niivue.prototype.cloudMrResetPolyline = function cloudMrResetPolyline() {
|
|
|
1465
1465
|
resetPolylineState(this);
|
|
1466
1466
|
};
|
|
1467
1467
|
|
|
1468
|
+
const RIGHT_MOUSE_BUTTON = 2;
|
|
1469
|
+
|
|
1470
|
+
function cloudMrHasApplyableDraft(nv) {
|
|
1471
|
+
return !!(nv._cloudMrShapeDraftActive || nv._cloudMrPenDraftActive);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
function cloudMrTryApplyDraftOnRightClick(nv, event) {
|
|
1475
|
+
if (!cloudMrHasApplyableDraft(nv)) {
|
|
1476
|
+
return false;
|
|
1477
|
+
}
|
|
1478
|
+
event.preventDefault();
|
|
1479
|
+
event.stopPropagation();
|
|
1480
|
+
if (typeof nv.onApplyActiveDraft === "function") {
|
|
1481
|
+
nv.onApplyActiveDraft();
|
|
1482
|
+
}
|
|
1483
|
+
return true;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1468
1486
|
const _mouseDownListener = Niivue.prototype.mouseDownListener;
|
|
1469
1487
|
Niivue.prototype.mouseDownListener = function cloudMrMouseDownListener(e) {
|
|
1488
|
+
if (e.button === RIGHT_MOUSE_BUTTON && cloudMrTryApplyDraftOnRightClick(this, e)) {
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1470
1491
|
if (shouldDeferFreehandCommit(this) && this.drawBitmap) {
|
|
1471
1492
|
this._cloudMrFreehandSessionStartBitmap = this.drawBitmap.slice();
|
|
1472
1493
|
this._cloudMrFreehandAxCorSag = -1;
|
|
@@ -1480,6 +1501,15 @@ Niivue.prototype.mouseDownListener = function cloudMrMouseDownListener(e) {
|
|
|
1480
1501
|
}
|
|
1481
1502
|
};
|
|
1482
1503
|
|
|
1504
|
+
const _mouseContextMenuListener = Niivue.prototype.mouseContextMenuListener;
|
|
1505
|
+
Niivue.prototype.mouseContextMenuListener = function cloudMrMouseContextMenuListener(e) {
|
|
1506
|
+
if (cloudMrHasApplyableDraft(this)) {
|
|
1507
|
+
e.preventDefault();
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
return _mouseContextMenuListener.call(this, e);
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1483
1513
|
const _mouseClick = Niivue.prototype.mouseClick;
|
|
1484
1514
|
Niivue.prototype.mouseClick = function cloudMrMouseClick(...args) {
|
|
1485
1515
|
if (isPolylinePenActive(this)) {
|
|
@@ -20,12 +20,15 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
20
20
|
};
|
|
21
21
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
22
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
23
|
-
import { boundsToFreehandCorners, redrawFreehandDraft, redrawPolylineDraft,
|
|
24
|
-
import { canvasDeltaToVoxDelta, clientToCanvasPos,
|
|
23
|
+
import { boundsToFreehandCorners, redrawFreehandDraft, redrawPolylineDraft, syncPolylineDraftToNv, translateFreehandDraft, translatePolylineVertices, updatePolylineVertex, } from "./penDraftUtils";
|
|
24
|
+
import { canvasDeltaToVoxDelta, clientToCanvasPos, voxToOverlayPos, voxUnderClient, } from "./shapeDraftUtils";
|
|
25
25
|
var HANDLE_SIZE = 10;
|
|
26
26
|
var ACCENT = "#580f8b";
|
|
27
|
+
function cloneFreehandDraft(draft) {
|
|
28
|
+
return __assign(__assign({}, draft), { strokeVoxels: draft.strokeVoxels.map(function (v) { return __spreadArray([], v, true); }), bounds: draft.bounds ? __assign({}, draft.bounds) : draft.bounds });
|
|
29
|
+
}
|
|
27
30
|
/**
|
|
28
|
-
* Adjust handles for polyline (vertex drag) or freehand (
|
|
31
|
+
* Adjust handles for polyline (vertex drag) or freehand (move only) drafts.
|
|
29
32
|
*/
|
|
30
33
|
export function PenDraftOverlay(_a) {
|
|
31
34
|
var nv = _a.nv, draft = _a.draft, onDraftChange = _a.onDraftChange, overlayKey = _a.overlayKey;
|
|
@@ -55,12 +58,10 @@ export function PenDraftOverlay(_a) {
|
|
|
55
58
|
return boundsToFreehandCorners(draft.bounds, draft.axCorSag);
|
|
56
59
|
}, [draft, isPolyline, overlayKey]);
|
|
57
60
|
var cornerCss = useMemo(function () {
|
|
58
|
-
if (isPolyline)
|
|
59
|
-
return
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
.filter(Boolean);
|
|
63
|
-
}, [draft === null || draft === void 0 ? void 0 : draft.axCorSag, freehandCorners, isPolyline, nv, overlayKey, vertexCss]);
|
|
61
|
+
if (!isPolyline)
|
|
62
|
+
return [];
|
|
63
|
+
return vertexCss;
|
|
64
|
+
}, [isPolyline, vertexCss]);
|
|
64
65
|
var centerCss = useMemo(function () {
|
|
65
66
|
var _a;
|
|
66
67
|
if (!draft)
|
|
@@ -82,10 +83,13 @@ export function PenDraftOverlay(_a) {
|
|
|
82
83
|
return null;
|
|
83
84
|
}, [draft, isPolyline, nv, overlayKey]);
|
|
84
85
|
var boxStyle = useMemo(function () {
|
|
85
|
-
|
|
86
|
+
var points = isPolyline ? cornerCss : freehandCorners
|
|
87
|
+
.map(function (vox) { return voxToOverlayPos(nv, vox, draft === null || draft === void 0 ? void 0 : draft.axCorSag); })
|
|
88
|
+
.filter(Boolean);
|
|
89
|
+
if (points.length < 2)
|
|
86
90
|
return null;
|
|
87
|
-
var xs =
|
|
88
|
-
var ys =
|
|
91
|
+
var xs = points.map(function (p) { return p.x; });
|
|
92
|
+
var ys = points.map(function (p) { return p.y; });
|
|
89
93
|
var left = Math.min.apply(Math, xs);
|
|
90
94
|
var top = Math.min.apply(Math, ys);
|
|
91
95
|
var width = Math.max.apply(Math, xs) - left;
|
|
@@ -93,7 +97,7 @@ export function PenDraftOverlay(_a) {
|
|
|
93
97
|
if (width < 2 && height < 2)
|
|
94
98
|
return null;
|
|
95
99
|
return { left: left, top: top, width: Math.max(width, 2), height: Math.max(height, 2) };
|
|
96
|
-
}, [cornerCss]);
|
|
100
|
+
}, [cornerCss, draft === null || draft === void 0 ? void 0 : draft.axCorSag, freehandCorners, isPolyline, nv, overlayKey]);
|
|
97
101
|
var applyDraft = useCallback(function (nextDraft) {
|
|
98
102
|
if (nextDraft.kind === "polyline") {
|
|
99
103
|
redrawPolylineDraft(nv, nextDraft);
|
|
@@ -115,50 +119,50 @@ export function PenDraftOverlay(_a) {
|
|
|
115
119
|
};
|
|
116
120
|
onPointerMoveRef.current = function (event) {
|
|
117
121
|
var drag = dragRef.current;
|
|
118
|
-
|
|
119
|
-
if (!drag || !current)
|
|
122
|
+
if (!drag)
|
|
120
123
|
return;
|
|
121
124
|
event.preventDefault();
|
|
125
|
+
var canvas = nv.canvas || document.getElementById("niiCanvas");
|
|
126
|
+
if (!canvas)
|
|
127
|
+
return;
|
|
128
|
+
var startCanvas = clientToCanvasPos(canvas, drag.startClientX, drag.startClientY);
|
|
129
|
+
var endCanvas = clientToCanvasPos(canvas, event.clientX, event.clientY);
|
|
130
|
+
var delta = canvasDeltaToVoxDelta(nv, startCanvas, endCanvas);
|
|
122
131
|
if (drag.mode === "move") {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return;
|
|
126
|
-
var startCanvas = clientToCanvasPos(canvas, drag.startClientX, drag.startClientY);
|
|
127
|
-
var endCanvas = clientToCanvasPos(canvas, event.clientX, event.clientY);
|
|
128
|
-
var delta = canvasDeltaToVoxDelta(nv, startCanvas, endCanvas);
|
|
129
|
-
if (current.kind === "polyline") {
|
|
130
|
-
applyDraft(__assign(__assign({}, current), { vertices: translatePolylineVertices(drag.startVertices, delta) }));
|
|
132
|
+
if (drag.kind === "polyline") {
|
|
133
|
+
applyDraft(__assign(__assign({}, drag.startDraft), { vertices: translatePolylineVertices(drag.startVertices, delta) }));
|
|
131
134
|
}
|
|
132
135
|
else {
|
|
133
|
-
applyDraft(translateFreehandDraft(
|
|
136
|
+
applyDraft(translateFreehandDraft(drag.startFreehandDraft, delta));
|
|
134
137
|
}
|
|
135
138
|
return;
|
|
136
139
|
}
|
|
137
140
|
var vox = voxUnderClient(nv, event.clientX, event.clientY);
|
|
138
141
|
if (!vox)
|
|
139
142
|
return;
|
|
140
|
-
|
|
141
|
-
applyDraft(__assign(__assign({}, current), { vertices: updatePolylineVertex(drag.startVertices, drag.cornerIndex, vox) }));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
applyDraft(resizeFreehandDraft(current, drag.cornerIndex, vox));
|
|
145
|
-
}
|
|
143
|
+
applyDraft(__assign(__assign({}, drag.startDraft), { vertices: updatePolylineVertex(drag.startVertices, drag.cornerIndex, vox) }));
|
|
146
144
|
};
|
|
147
145
|
var startDrag = useCallback(function (event, mode, cornerIndex) {
|
|
148
146
|
var _a, _b;
|
|
149
147
|
if (cornerIndex === void 0) { cornerIndex = -1; }
|
|
150
148
|
event.preventDefault();
|
|
151
149
|
event.stopPropagation();
|
|
150
|
+
var current = draftRef.current;
|
|
151
|
+
if (!current)
|
|
152
|
+
return;
|
|
152
153
|
dragRef.current = {
|
|
153
154
|
mode: mode,
|
|
154
155
|
cornerIndex: cornerIndex,
|
|
156
|
+
kind: current.kind,
|
|
155
157
|
startClientX: event.clientX,
|
|
156
158
|
startClientY: event.clientY,
|
|
157
|
-
|
|
159
|
+
startDraft: current,
|
|
160
|
+
startVertices: (_b = (_a = current.vertices) === null || _a === void 0 ? void 0 : _a.map(function (v) { return __spreadArray([], v, true); })) !== null && _b !== void 0 ? _b : [],
|
|
161
|
+
startFreehandDraft: current.kind === "freehand" ? cloneFreehandDraft(current) : null
|
|
158
162
|
};
|
|
159
163
|
window.addEventListener("pointermove", onPointerMoveRef.current);
|
|
160
164
|
window.addEventListener("pointerup", finishDragRef.current);
|
|
161
|
-
}, [
|
|
165
|
+
}, []);
|
|
162
166
|
useEffect(function () { return function () {
|
|
163
167
|
var _a;
|
|
164
168
|
(_a = finishDragRef.current) === null || _a === void 0 ? void 0 : _a.call(finishDragRef);
|
|
@@ -196,6 +200,7 @@ export function PenDraftOverlay(_a) {
|
|
|
196
200
|
background: "rgba(88, 15, 139, 0.08)",
|
|
197
201
|
boxSizing: "border-box",
|
|
198
202
|
pointerEvents: "none"
|
|
199
|
-
} }), centerCss && (_jsx("div", { role: "presentation", onPointerDown: function (e) { return startDrag(e, "move"); }, style: __assign(__assign({}, handleStyle), { left: centerCss.x, top: centerCss.y, cursor: "move", borderRadius: 2, width: 12, height: 12, marginLeft: -6, marginTop: -6 }), title: "Move shape" })),
|
|
203
|
+
} }), centerCss && (_jsx("div", { role: "presentation", onPointerDown: function (e) { return startDrag(e, "move"); }, style: __assign(__assign({}, handleStyle), { left: centerCss.x, top: centerCss.y, cursor: "move", borderRadius: 2, width: 12, height: 12, marginLeft: -6, marginTop: -6 }), title: "Move shape" })), isPolyline &&
|
|
204
|
+
cornerCss.map(function (pos, i) { return (_jsx("div", { role: "presentation", onPointerDown: function (e) { return startDrag(e, "corner", i); }, style: __assign(__assign({}, handleStyle), { left: pos.x, top: pos.y, cursor: "grab" }), title: "Move vertex" }, "handle-".concat(i))); })] })));
|
|
200
205
|
}
|
|
201
206
|
export default PenDraftOverlay;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEnabled, showPenModes, penDrawMode, onPenDrawModeChange, polylineVertexCount, penDraftActive, onApplyPenDraft, onCancelPenDraft,
|
|
1
|
+
export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEnabled, showPenModes, penDrawMode, onPenDrawModeChange, polylineVertexCount, penDraftActive, onApplyPenDraft, onCancelPenDraft, onFillPenDraft, brushSize, updateBrushSize, shapeDraftActive, onApplyShapeDraft, onCancelShapeDraft, }: {
|
|
2
2
|
expanded: any;
|
|
3
3
|
updateDrawPen: any;
|
|
4
4
|
setDrawingEnabled: any;
|
|
@@ -9,7 +9,7 @@ export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEna
|
|
|
9
9
|
penDraftActive?: boolean | undefined;
|
|
10
10
|
onApplyPenDraft: any;
|
|
11
11
|
onCancelPenDraft: any;
|
|
12
|
-
|
|
12
|
+
onFillPenDraft: any;
|
|
13
13
|
brushSize?: number | undefined;
|
|
14
14
|
updateBrushSize: any;
|
|
15
15
|
shapeDraftActive?: boolean | undefined;
|
|
@@ -37,7 +37,7 @@ var modeBtnSx = function (active) { return ({
|
|
|
37
37
|
px: 0.75
|
|
38
38
|
}); };
|
|
39
39
|
export default function DrawColorPlatte(_a) {
|
|
40
|
-
var expanded = _a.expanded, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled, _b = _a.showPenModes, showPenModes = _b === void 0 ? false : _b, _c = _a.penDrawMode, penDrawMode = _c === void 0 ? "freehand" : _c, onPenDrawModeChange = _a.onPenDrawModeChange, _d = _a.polylineVertexCount, polylineVertexCount = _d === void 0 ? 0 : _d, _e = _a.penDraftActive, penDraftActive = _e === void 0 ? false : _e, onApplyPenDraft = _a.onApplyPenDraft, onCancelPenDraft = _a.onCancelPenDraft,
|
|
40
|
+
var expanded = _a.expanded, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled, _b = _a.showPenModes, showPenModes = _b === void 0 ? false : _b, _c = _a.penDrawMode, penDrawMode = _c === void 0 ? "freehand" : _c, onPenDrawModeChange = _a.onPenDrawModeChange, _d = _a.polylineVertexCount, polylineVertexCount = _d === void 0 ? 0 : _d, _e = _a.penDraftActive, penDraftActive = _e === void 0 ? false : _e, onApplyPenDraft = _a.onApplyPenDraft, onCancelPenDraft = _a.onCancelPenDraft, onFillPenDraft = _a.onFillPenDraft, _f = _a.brushSize, brushSize = _f === void 0 ? 1 : _f, updateBrushSize = _a.updateBrushSize, _g = _a.shapeDraftActive, shapeDraftActive = _g === void 0 ? false : _g, onApplyShapeDraft = _a.onApplyShapeDraft, onCancelShapeDraft = _a.onCancelShapeDraft;
|
|
41
41
|
return (_jsxs(Stack, __assign({ style: {
|
|
42
42
|
position: "absolute",
|
|
43
43
|
top: "100%",
|
|
@@ -62,14 +62,14 @@ export default function DrawColorPlatte(_a) {
|
|
|
62
62
|
py: 0.25,
|
|
63
63
|
px: 0.75,
|
|
64
64
|
"& .MuiButton-startIcon": { mr: 0.5, ml: 0 }
|
|
65
|
-
} }, { children: "Cancel" })) })), _jsxs(Stack, __assign({ direction: "row", alignItems: "center", spacing: 1 }, { children: [penDrawMode === "polyline" && polylineVertexCount >= 3 && (_jsx(Tooltip, __assign({ title: "
|
|
65
|
+
} }, { children: "Cancel" })) })), _jsxs(Stack, __assign({ direction: "row", alignItems: "center", spacing: 1 }, { children: [penDrawMode === "polyline" && polylineVertexCount >= 3 && (_jsx(Tooltip, __assign({ title: "Fill interior (keeps outline editable until Apply)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "fill polyline", onClick: function () { return onFillPenDraft === null || onFillPenDraft === void 0 ? void 0 : onFillPenDraft(); }, sx: {
|
|
66
66
|
color: "#c9a0e8",
|
|
67
67
|
fontSize: ACTION_FONT_SIZE,
|
|
68
68
|
textTransform: "none",
|
|
69
69
|
minWidth: 0,
|
|
70
70
|
py: 0.25,
|
|
71
71
|
px: 0.75
|
|
72
|
-
} }, { children: "
|
|
72
|
+
} }, { children: "Fill" })) }))), _jsx(Tooltip, __assign({ title: "Apply (Enter or right-click)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply pen draft", onClick: function () { return onApplyPenDraft === null || onApplyPenDraft === void 0 ? void 0 : onApplyPenDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
|
|
73
73
|
color: "#c9a0e8",
|
|
74
74
|
fontSize: ACTION_FONT_SIZE,
|
|
75
75
|
textTransform: "none",
|
|
@@ -85,7 +85,7 @@ export default function DrawColorPlatte(_a) {
|
|
|
85
85
|
py: 0.25,
|
|
86
86
|
px: 0.75,
|
|
87
87
|
"& .MuiButton-startIcon": { mr: 0.5, ml: 0 }
|
|
88
|
-
} }, { children: "Cancel" })) })), _jsx(Tooltip, __assign({ title: "Apply shape (Enter)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply shape", onClick: function () { return onApplyShapeDraft === null || onApplyShapeDraft === void 0 ? void 0 : onApplyShapeDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
|
|
88
|
+
} }, { children: "Cancel" })) })), _jsx(Tooltip, __assign({ title: "Apply shape (Enter or right-click)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply shape", onClick: function () { return onApplyShapeDraft === null || onApplyShapeDraft === void 0 ? void 0 : onApplyShapeDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
|
|
89
89
|
color: "#c9a0e8",
|
|
90
90
|
fontSize: ACTION_FONT_SIZE,
|
|
91
91
|
textTransform: "none",
|
|
@@ -172,7 +172,7 @@ export function MroDrawToolkit(props) {
|
|
|
172
172
|
alignItems: "center",
|
|
173
173
|
gap: 4,
|
|
174
174
|
overflow: "visible"
|
|
175
|
-
} }, { children: [_jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "d" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Pen" }, { children: _jsx(IconButton, __assign({ "aria-label": "pen", size: "small", onClick: clickPen, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("pen")) }, { children: _jsx(DrawIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "d", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, showPenModes: true, penDrawMode: props.penDrawMode, onPenDrawModeChange: props.onPenDrawModeChange, polylineVertexCount: props.polylineVertexCount, onCancelPolyline: props.onCancelPolyline, penDraftActive: props.penDraftActive, onApplyPenDraft: props.onApplyPenDraft, onCancelPenDraft: props.onCancelPenDraft,
|
|
175
|
+
} }, { children: [_jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "d" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Pen" }, { children: _jsx(IconButton, __assign({ "aria-label": "pen", size: "small", onClick: clickPen, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("pen")) }, { children: _jsx(DrawIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "d", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, showPenModes: true, penDrawMode: props.penDrawMode, onPenDrawModeChange: props.onPenDrawModeChange, polylineVertexCount: props.polylineVertexCount, onCancelPolyline: props.onCancelPolyline, penDraftActive: props.penDraftActive, onApplyPenDraft: props.onApplyPenDraft, onCancelPenDraft: props.onCancelPenDraft, onFillPenDraft: props.onFillPenDraft, brushSize: props.brushSize, updateBrushSize: props.updateBrushSize })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "r" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Rectangle" }, { children: _jsx(IconButton, __assign({ "aria-label": "rectangle", size: "small", onClick: clickRectangle, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("rectangle")) }, { children: _jsx(CropSquareOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "r", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "rectangle", onApplyShapeDraft: props.onApplyShapeDraft, onCancelShapeDraft: props.onCancelShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "l" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Ellipse" }, { children: _jsx(IconButton, __assign({ "aria-label": "ellipse", size: "small", onClick: clickEllipse, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("ellipse")) }, { children: _jsx(CircleOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "l", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "ellipse", onApplyShapeDraft: props.onApplyShapeDraft, onCancelShapeDraft: props.onCancelShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "e" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Eraser" }, { children: _jsx(IconButton, __assign({ "aria-label": "erase", size: "small", onClick: clickEraser, sx: toolBtnSx }, { children: filled || expandedOption !== "e" ? (_jsx(EraserIcon, {})) : (_jsx(AutoFixNormalOutlinedIcon, { sx: { color: ICON_COLOR } })) })) })), _jsx(EraserPlatte, { expandEraseOptions: expandedOption === "e", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, brushSize: props.brushSize, updateBrushSize: props.updateBrushSize })] })), _jsx(Tooltip, __assign({ title: "Undo" }, { children: _jsx(IconButton, __assign({ "aria-label": "revert", size: "small", onClick: function () { return props.drawUndo(); }, sx: toolBtnSx }, { children: _jsx(ReplyIcon, { sx: { color: ICON_COLOR } }) })) })), _jsx(Tooltip, __assign({ title: "Save screenshot" }, { children: _jsx("span", { children: _jsx(IconButton, __assign({ "aria-label": "capture", size: "small", disabled: !vol, onClick: function () { return vol && props.nv.saveScene("".concat(vol.name, "_drawing.png")); }, sx: toolBtnSx }, { children: _jsx(CameraAltIcon, { sx: { color: ICON_COLOR } }) })) }) })), _jsx(Tooltip, __assign({ title: "Clear drawing" }, { children: _jsx(IconButton, __assign({ "aria-label": "delete", size: "small", onClick: function () {
|
|
176
176
|
props.nv.clearDrawing();
|
|
177
177
|
props.resampleImage();
|
|
178
178
|
props.setDrawingChanged(false);
|
|
@@ -8,19 +8,10 @@
|
|
|
8
8
|
* @property {[number, number, number][]} [vertices]
|
|
9
9
|
* @property {[number, number, number][]} [strokeVoxels]
|
|
10
10
|
* @property {{ x1: number, y1: number, x2: number, y2: number, z1: number, z2: number }} [bounds]
|
|
11
|
+
* @property {boolean} [filled]
|
|
11
12
|
*/
|
|
12
13
|
export function isFreehandPenActive(nv: any): any;
|
|
13
14
|
export function shouldDeferFreehandCommit(nv: any): any;
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {Object} PenDraft
|
|
16
|
-
* @property {PenDraftKind} kind
|
|
17
|
-
* @property {Uint8Array} baseBitmap
|
|
18
|
-
* @property {number} axCorSag
|
|
19
|
-
* @property {number} penValue
|
|
20
|
-
* @property {[number, number, number][]} [vertices]
|
|
21
|
-
* @property {[number, number, number][]} [strokeVoxels]
|
|
22
|
-
* @property {{ x1: number, y1: number, x2: number, y2: number, z1: number, z2: number }} [bounds]
|
|
23
|
-
*/
|
|
24
15
|
export function redrawPolylineDraft(nv: any, draft: any): void;
|
|
25
16
|
export function translatePolylineVertices(vertices: any, delta: any): any;
|
|
26
17
|
export function updatePolylineVertex(vertices: any, index: any, newVox: any): any;
|
|
@@ -44,16 +35,19 @@ export function redrawFreehandDraft(nv: any, draft: any): void;
|
|
|
44
35
|
export function translateFreehandDraft(draft: any, delta: any): any;
|
|
45
36
|
export function resizeFreehandDraft(draft: any, cornerIndex: any, newVox: any): any;
|
|
46
37
|
export function boundsToFreehandCorners(bounds: any, axCorSag: any): any[][];
|
|
47
|
-
export function polylineDraftFromNv(nv: any
|
|
38
|
+
export function polylineDraftFromNv(nv: any, { filled }?: {
|
|
39
|
+
filled?: boolean | undefined;
|
|
40
|
+
}): {
|
|
48
41
|
kind: string;
|
|
49
42
|
vertices: any;
|
|
50
43
|
baseBitmap: Uint8Array;
|
|
51
44
|
axCorSag: any;
|
|
52
45
|
penValue: any;
|
|
46
|
+
filled: boolean;
|
|
53
47
|
} | null;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
/** Fill polyline interior without closing the outline or committing the draft. */
|
|
49
|
+
export function fillPolylineDraft(nv: any, draft: any): any;
|
|
50
|
+
export function applyPenDraft(nv: any, draft: any): void;
|
|
57
51
|
export function cancelPenDraft(nv: any, draft: any): void;
|
|
58
52
|
export type PenDraftKind = 'polyline' | 'freehand';
|
|
59
53
|
export type PenDraft = {
|
|
@@ -71,4 +65,5 @@ export type PenDraft = {
|
|
|
71
65
|
z1: number;
|
|
72
66
|
z2: number;
|
|
73
67
|
} | undefined;
|
|
68
|
+
filled?: boolean | undefined;
|
|
74
69
|
};
|
|
@@ -30,6 +30,7 @@ import { NI_PEN_TYPE } from "./niivuePenType";
|
|
|
30
30
|
* @property {[number, number, number][]} [vertices]
|
|
31
31
|
* @property {[number, number, number][]} [strokeVoxels]
|
|
32
32
|
* @property {{ x1: number, y1: number, x2: number, y2: number, z1: number, z2: number }} [bounds]
|
|
33
|
+
* @property {boolean} [filled]
|
|
33
34
|
*/
|
|
34
35
|
export function isFreehandPenActive(nv) {
|
|
35
36
|
return (nv.opts.isFilledPen &&
|
|
@@ -40,16 +41,6 @@ export function isFreehandPenActive(nv) {
|
|
|
40
41
|
export function shouldDeferFreehandCommit(nv) {
|
|
41
42
|
return !!nv.opts.deferFreehandCommit && isFreehandPenActive(nv);
|
|
42
43
|
}
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {Object} PenDraft
|
|
45
|
-
* @property {PenDraftKind} kind
|
|
46
|
-
* @property {Uint8Array} baseBitmap
|
|
47
|
-
* @property {number} axCorSag
|
|
48
|
-
* @property {number} penValue
|
|
49
|
-
* @property {[number, number, number][]} [vertices]
|
|
50
|
-
* @property {[number, number, number][]} [strokeVoxels]
|
|
51
|
-
* @property {{ x1: number, y1: number, x2: number, y2: number, z1: number, z2: number }} [bounds]
|
|
52
|
-
*/
|
|
53
44
|
export function redrawPolylineDraft(nv, draft) {
|
|
54
45
|
var _a;
|
|
55
46
|
if (!((_a = draft === null || draft === void 0 ? void 0 : draft.vertices) === null || _a === void 0 ? void 0 : _a.length) || !draft.baseBitmap)
|
|
@@ -59,6 +50,12 @@ export function redrawPolylineDraft(nv, draft) {
|
|
|
59
50
|
for (var i = 1; i < draft.vertices.length; i++) {
|
|
60
51
|
nv.drawPenLine(draft.vertices[i], draft.vertices[i - 1], draft.penValue);
|
|
61
52
|
}
|
|
53
|
+
if (draft.filled && draft.vertices.length >= 3) {
|
|
54
|
+
nv.drawPenAxCorSag = draft.axCorSag;
|
|
55
|
+
nv.drawPenFillPts = draft.vertices.map(function (v) { return __spreadArray([], v, true); });
|
|
56
|
+
nv._cloudMrSkipNextUndoBitmap = true;
|
|
57
|
+
nv.drawPenFilled();
|
|
58
|
+
}
|
|
62
59
|
nv.refreshDrawing(false, false);
|
|
63
60
|
nv.drawScene();
|
|
64
61
|
}
|
|
@@ -220,7 +217,8 @@ export function boundsToFreehandCorners(bounds, axCorSag) {
|
|
|
220
217
|
[x, y2, z2],
|
|
221
218
|
];
|
|
222
219
|
}
|
|
223
|
-
export function polylineDraftFromNv(nv) {
|
|
220
|
+
export function polylineDraftFromNv(nv, _a) {
|
|
221
|
+
var _b = _a === void 0 ? {} : _a, _c = _b.filled, filled = _c === void 0 ? false : _c;
|
|
224
222
|
var vertices = nv._cloudMrPolylineVertices;
|
|
225
223
|
var baseBitmap = nv._cloudMrPolylineSessionStartBitmap;
|
|
226
224
|
if (!(vertices === null || vertices === void 0 ? void 0 : vertices.length) || vertices.length < 2 || !baseBitmap)
|
|
@@ -230,19 +228,28 @@ export function polylineDraftFromNv(nv) {
|
|
|
230
228
|
vertices: vertices.map(function (v) { return __spreadArray([], v, true); }),
|
|
231
229
|
baseBitmap: new Uint8Array(baseBitmap),
|
|
232
230
|
axCorSag: nv._cloudMrPolylineAxCorSag,
|
|
233
|
-
penValue: nv.opts.penValue
|
|
231
|
+
penValue: nv.opts.penValue,
|
|
232
|
+
filled: filled
|
|
234
233
|
};
|
|
235
234
|
}
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
/** Fill polyline interior without closing the outline or committing the draft. */
|
|
236
|
+
export function fillPolylineDraft(nv, draft) {
|
|
237
|
+
if (!(draft === null || draft === void 0 ? void 0 : draft.vertices) || draft.vertices.length < 3)
|
|
238
|
+
return draft;
|
|
239
|
+
redrawPolylineDraft(nv, __assign(__assign({}, draft), { filled: false }));
|
|
240
|
+
nv.drawPenAxCorSag = draft.axCorSag;
|
|
241
|
+
nv.drawPenFillPts = draft.vertices.map(function (v) { return __spreadArray([], v, true); });
|
|
242
|
+
nv._cloudMrSkipNextUndoBitmap = true;
|
|
243
|
+
nv.drawPenFilled();
|
|
244
|
+
nv.refreshDrawing(false, false);
|
|
245
|
+
nv.drawScene();
|
|
246
|
+
var next = __assign(__assign({}, draft), { filled: true });
|
|
247
|
+
syncPolylineDraftToNv(nv, next);
|
|
248
|
+
return next;
|
|
249
|
+
}
|
|
250
|
+
export function applyPenDraft(nv, draft) {
|
|
238
251
|
if (draft.kind === "polyline") {
|
|
239
252
|
redrawPolylineDraft(nv, draft);
|
|
240
|
-
if (fillClosed && draft.vertices.length >= 3) {
|
|
241
|
-
nv.drawPenAxCorSag = draft.axCorSag;
|
|
242
|
-
nv.drawPenLine(draft.vertices[0], draft.vertices[draft.vertices.length - 1], draft.penValue);
|
|
243
|
-
nv.drawPenFillPts = draft.vertices.map(function (v) { return __spreadArray([], v, true); });
|
|
244
|
-
nv.drawPenFilled();
|
|
245
|
-
}
|
|
246
253
|
}
|
|
247
254
|
else {
|
|
248
255
|
redrawFreehandDraft(nv, draft);
|