cloudmr-ux 4.5.3 → 4.5.6
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 +61 -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/ShapeDraftOverlay.js +3 -2
- 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,46 @@ 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]);
|
|
889
|
+
React.useEffect(function () {
|
|
890
|
+
nv._cloudMrShapeDraftActive = shapeDraft != null;
|
|
891
|
+
}, [shapeDraft]);
|
|
892
|
+
React.useEffect(function () {
|
|
893
|
+
if (!shapeDraft && !penDraft) {
|
|
894
|
+
return undefined;
|
|
895
|
+
}
|
|
896
|
+
var canvas = document.getElementById("niiCanvas");
|
|
897
|
+
if (!canvas) {
|
|
898
|
+
return undefined;
|
|
899
|
+
}
|
|
900
|
+
var applyOnRightClick = function (event) {
|
|
901
|
+
var _a;
|
|
902
|
+
event.preventDefault();
|
|
903
|
+
event.stopPropagation();
|
|
904
|
+
(_a = nv.onApplyActiveDraft) === null || _a === void 0 ? void 0 : _a.call(nv);
|
|
905
|
+
};
|
|
906
|
+
var onMouseDown = function (event) {
|
|
907
|
+
if (event.button === 2) {
|
|
908
|
+
applyOnRightClick(event);
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
canvas.addEventListener("mousedown", onMouseDown, true);
|
|
912
|
+
canvas.addEventListener("contextmenu", applyOnRightClick, true);
|
|
913
|
+
return function () {
|
|
914
|
+
canvas.removeEventListener("mousedown", onMouseDown, true);
|
|
915
|
+
canvas.removeEventListener("contextmenu", applyOnRightClick, true);
|
|
916
|
+
};
|
|
917
|
+
}, [shapeDraft, penDraft]);
|
|
868
918
|
React.useEffect(function () {
|
|
869
919
|
if (!shapeDraft && !penDraft) {
|
|
870
920
|
return undefined;
|
|
@@ -886,7 +936,7 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
886
936
|
applyShapeDraft();
|
|
887
937
|
}
|
|
888
938
|
else if (penDraft) {
|
|
889
|
-
applyPenDraftHandler(
|
|
939
|
+
applyPenDraftHandler();
|
|
890
940
|
}
|
|
891
941
|
}
|
|
892
942
|
};
|
|
@@ -1391,9 +1441,9 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
1391
1441
|
onPenDrawModeChange: syncPenDrawMode,
|
|
1392
1442
|
polylineVertexCount: polylineVertexCount,
|
|
1393
1443
|
onCancelPolyline: cancelPolylineDraft,
|
|
1394
|
-
onApplyPenDraft:
|
|
1444
|
+
onApplyPenDraft: applyPenDraftHandler,
|
|
1395
1445
|
onCancelPenDraft: cancelPenDraftHandler,
|
|
1396
|
-
|
|
1446
|
+
onFillPenDraft: fillPolylineDraftHandler,
|
|
1397
1447
|
penDraftActive: penDraft != null,
|
|
1398
1448
|
brushSize: brushSize,
|
|
1399
1449
|
updateBrushSize: nvUpdateBrushSize
|
|
@@ -1412,7 +1462,7 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
1412
1462
|
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
1463
|
var _a;
|
|
1414
1464
|
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:
|
|
1465
|
+
}, 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
1466
|
}
|
|
1417
1467
|
function niiToVolume(nii) {
|
|
1418
1468
|
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;
|
|
@@ -152,13 +152,14 @@ export function ShapeDraftOverlay(_a) {
|
|
|
152
152
|
boxSizing: "border-box",
|
|
153
153
|
cursor: "pointer",
|
|
154
154
|
zIndex: 3,
|
|
155
|
-
touchAction: "none"
|
|
155
|
+
touchAction: "none",
|
|
156
|
+
pointerEvents: "auto"
|
|
156
157
|
};
|
|
157
158
|
return (_jsxs("div", __assign({ style: {
|
|
158
159
|
position: "absolute",
|
|
159
160
|
inset: 0,
|
|
160
161
|
zIndex: 2,
|
|
161
|
-
pointerEvents: "
|
|
162
|
+
pointerEvents: "none",
|
|
162
163
|
overflow: "hidden"
|
|
163
164
|
}, "aria-label": "Adjust ROI shape" }, { children: [_jsx("div", { style: {
|
|
164
165
|
position: "absolute",
|
|
@@ -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 shape (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 (
|
|
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);
|