cloudmr-ux 4.8.4 → 4.8.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/CloudMrNiivueViewer.js +20 -11
- package/dist/CmrComponents/niivue-viewer/NiivuePatcher.js +6 -1
- package/dist/CmrComponents/niivue-viewer/mro-draw-toolkit/DrawColorPlatte.js +3 -1
- package/dist/CmrComponents/niivue-viewer/polylinePenUtils.d.ts +6 -1
- package/dist/CmrComponents/niivue-viewer/polylinePenUtils.js +18 -0
- package/package.json +1 -1
|
@@ -1309,25 +1309,34 @@ export default function CloudMrNiivueViewer(props) {
|
|
|
1309
1309
|
return undefined;
|
|
1310
1310
|
}
|
|
1311
1311
|
var canvas = document.getElementById("niiCanvas");
|
|
1312
|
-
if (!canvas) {
|
|
1313
|
-
return undefined;
|
|
1314
|
-
}
|
|
1315
1312
|
var applyOnRightClick = function (event) {
|
|
1316
1313
|
var _a;
|
|
1317
1314
|
event.preventDefault();
|
|
1318
1315
|
event.stopPropagation();
|
|
1319
1316
|
(_a = nv.onApplyActiveDraft) === null || _a === void 0 ? void 0 : _a.call(nv);
|
|
1320
1317
|
};
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1318
|
+
// Right-click on canvas: apply via Niivue's own handler.
|
|
1319
|
+
if (canvas) {
|
|
1320
|
+
canvas.addEventListener("contextmenu", applyOnRightClick, true);
|
|
1321
|
+
}
|
|
1322
|
+
// Any mousedown outside the canvas exits editing mode.
|
|
1323
|
+
// Clicks on the canvas are handled by Niivue's own mouseUpListener,
|
|
1324
|
+
// so we skip them here to avoid a double-apply race.
|
|
1325
|
+
var onDocMouseDown = function (event) {
|
|
1326
|
+
var _a;
|
|
1327
|
+
var target = event.target;
|
|
1328
|
+
var onCanvas = target === canvas || (canvas && canvas.contains(target));
|
|
1329
|
+
if (onCanvas)
|
|
1330
|
+
return;
|
|
1331
|
+
// Left or right click anywhere outside the canvas → apply draft.
|
|
1332
|
+
(_a = nv.onApplyActiveDraft) === null || _a === void 0 ? void 0 : _a.call(nv);
|
|
1325
1333
|
};
|
|
1326
|
-
|
|
1327
|
-
canvas.addEventListener("contextmenu", applyOnRightClick, true);
|
|
1334
|
+
document.addEventListener("mousedown", onDocMouseDown, true);
|
|
1328
1335
|
return function () {
|
|
1329
|
-
canvas
|
|
1330
|
-
|
|
1336
|
+
if (canvas) {
|
|
1337
|
+
canvas.removeEventListener("contextmenu", applyOnRightClick, true);
|
|
1338
|
+
}
|
|
1339
|
+
document.removeEventListener("mousedown", onDocMouseDown, true);
|
|
1331
1340
|
};
|
|
1332
1341
|
}, [shapeDraft, penDraft]);
|
|
1333
1342
|
React.useEffect(function () {
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { NI_PEN_TYPE } from "./niivuePenType.js";
|
|
13
13
|
import {
|
|
14
14
|
addPolylineVertex,
|
|
15
|
+
POLYLINE_CLOSE,
|
|
15
16
|
axCorSagFromMouse,
|
|
16
17
|
cancelPolyline,
|
|
17
18
|
finishPolyline,
|
|
@@ -1664,7 +1665,11 @@ Niivue.prototype.mouseUpListener = function cloudMrMouseUpListener() {
|
|
|
1664
1665
|
_mouseUpListener.call(this);
|
|
1665
1666
|
|
|
1666
1667
|
if (polylineClick) {
|
|
1667
|
-
addPolylineVertex(this);
|
|
1668
|
+
const result = addPolylineVertex(this);
|
|
1669
|
+
if (result === POLYLINE_CLOSE && typeof this.onApplyActiveDraft === "function") {
|
|
1670
|
+
// Double-click detected — connect last vertex back to first, fill, and commit.
|
|
1671
|
+
this.onApplyActiveDraft();
|
|
1672
|
+
}
|
|
1668
1673
|
return;
|
|
1669
1674
|
}
|
|
1670
1675
|
|
|
@@ -92,7 +92,9 @@ export default function DrawColorPlatte(_a) {
|
|
|
92
92
|
})
|
|
93
93
|
}
|
|
94
94
|
} }, { children: _jsx(FiberManualRecordIcon, { className: "color-swatch", sx: color.sx }) }), index));
|
|
95
|
-
}) })), isPolylineTool && expanded && (_jsx(Typography, __assign({ sx: { px: 1, pb: 0.5, fontSize: "0.68rem", color: "#aaa", userSelect: "none" } }, { children:
|
|
95
|
+
}) })), isPolylineTool && expanded && (_jsx(Typography, __assign({ sx: { px: 1, pb: 0.5, fontSize: "0.68rem", color: "#aaa", userSelect: "none" } }, { children: polylineVertexCount >= 3
|
|
96
|
+
? "Double-click to close & fill · Right-click to cancel"
|
|
97
|
+
: "Click to add vertices" }))), penDraftActive &&
|
|
96
98
|
expanded &&
|
|
97
99
|
((isFreehandTool && penDraftKind === "freehand") ||
|
|
98
100
|
(isPolylineTool && penDraftKind === "polyline")) && (_jsxs(Stack, __assign({ direction: "row", alignItems: "center", justifyContent: "space-between", sx: { px: 1, py: 0.5, borderTop: "1px solid #555", width: "100%" } }, { children: [_jsx(Tooltip, __assign({ title: "Delete this ROI drawing" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "delete pen draft", onClick: function () { return onDeletePenDraft === null || onDeletePenDraft === void 0 ? void 0 : onDeletePenDraft(); }, startIcon: _jsx(DeleteOutlineIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
|
|
@@ -6,7 +6,12 @@ export function notifyPolylineChange(nv: any, count: any): void;
|
|
|
6
6
|
export function resetPolylineState(nv: any): void;
|
|
7
7
|
export function cancelPolyline(nv: any): void;
|
|
8
8
|
export function previewPolylineSegment(nv: any): void;
|
|
9
|
-
export function addPolylineVertex(nv: any): boolean;
|
|
9
|
+
export function addPolylineVertex(nv: any): boolean | typeof POLYLINE_CLOSE;
|
|
10
10
|
export function finishPolyline(nv: any, { fillClosed }?: {
|
|
11
11
|
fillClosed?: boolean | undefined;
|
|
12
12
|
}): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Sentinel returned by addPolylineVertex when a double-click is detected with
|
|
15
|
+
* ≥3 existing vertices. The caller should close the polygon and auto-commit.
|
|
16
|
+
*/
|
|
17
|
+
export const POLYLINE_CLOSE: unique symbol;
|
|
@@ -46,6 +46,7 @@ export function resetPolylineState(nv) {
|
|
|
46
46
|
nv._cloudMrPolylineBaseBitmap = null;
|
|
47
47
|
nv._cloudMrPolylineSessionStartBitmap = null;
|
|
48
48
|
nv._cloudMrPolylineAxCorSag = -1;
|
|
49
|
+
nv._cloudMrLastPolylineClickMs = null;
|
|
49
50
|
notifyPolylineChange(nv, 0);
|
|
50
51
|
}
|
|
51
52
|
export function cancelPolyline(nv) {
|
|
@@ -69,12 +70,29 @@ export function previewPolylineSegment(nv) {
|
|
|
69
70
|
nv.refreshDrawing(false, false);
|
|
70
71
|
nv.drawScene();
|
|
71
72
|
}
|
|
73
|
+
/** Max ms between two clicks to be considered a double-click. */
|
|
74
|
+
var DOUBLE_CLICK_MS = 400;
|
|
75
|
+
/**
|
|
76
|
+
* Sentinel returned by addPolylineVertex when a double-click is detected with
|
|
77
|
+
* ≥3 existing vertices. The caller should close the polygon and auto-commit.
|
|
78
|
+
*/
|
|
79
|
+
export var POLYLINE_CLOSE = Symbol("POLYLINE_CLOSE");
|
|
72
80
|
export function addPolylineVertex(nv) {
|
|
73
81
|
var pt = voxFromMouse(nv);
|
|
74
82
|
if (!pt)
|
|
75
83
|
return false;
|
|
76
84
|
var penValue = nv.opts.penValue;
|
|
77
85
|
var verts = nv._cloudMrPolylineVertices || (nv._cloudMrPolylineVertices = []);
|
|
86
|
+
// Double-click detection: two clicks within DOUBLE_CLICK_MS on ≥3 vertices.
|
|
87
|
+
var now = Date.now();
|
|
88
|
+
var isDoubleClick = verts.length >= 3 &&
|
|
89
|
+
nv._cloudMrLastPolylineClickMs != null &&
|
|
90
|
+
now - nv._cloudMrLastPolylineClickMs <= DOUBLE_CLICK_MS;
|
|
91
|
+
nv._cloudMrLastPolylineClickMs = now;
|
|
92
|
+
if (isDoubleClick) {
|
|
93
|
+
// Don't add this click as a vertex — signal close instead.
|
|
94
|
+
return POLYLINE_CLOSE;
|
|
95
|
+
}
|
|
78
96
|
if (verts.length === 0) {
|
|
79
97
|
nv._cloudMrPolylineSessionStartBitmap = nv.drawBitmap.slice();
|
|
80
98
|
nv._cloudMrPolylineBaseBitmap = nv._cloudMrPolylineSessionStartBitmap.slice();
|