cloudmr-ux 4.8.9 → 5.0.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.
|
@@ -10,7 +10,8 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { Card, CardContent
|
|
13
|
+
import { Box, Button, Card, CardContent } from "@mui/material";
|
|
14
|
+
import Brightness6Icon from "@mui/icons-material/Brightness6";
|
|
14
15
|
import TKDualRange from "../tk-dualrange/TKDualRange";
|
|
15
16
|
import CmrLabel from "../label/Label";
|
|
16
17
|
import { resolveNiivueAccentColor, useNiivueViewerTheme, } from "../niivue-viewer/NiivueViewerThemeContext";
|
|
@@ -52,6 +53,43 @@ export function NiivueContrastAdjustments(_a) {
|
|
|
52
53
|
var theme = useNiivueViewerTheme();
|
|
53
54
|
var accentColor = resolveNiivueAccentColor(accentColorProp, theme);
|
|
54
55
|
var a = transformFactors.a, b = transformFactors.b;
|
|
56
|
+
var handleResetContrast = function () {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
nv.resetContrast();
|
|
59
|
+
nv.setGamma(1.0);
|
|
60
|
+
(_a = nv.onResetGamma) === null || _a === void 0 ? void 0 : _a.call(nv);
|
|
61
|
+
var vol = (_b = nv.volumes) === null || _b === void 0 ? void 0 : _b[0];
|
|
62
|
+
if (vol) {
|
|
63
|
+
setMin(vol.cal_min);
|
|
64
|
+
setMax(vol.cal_max);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var resetContrastButtonSx = {
|
|
68
|
+
color: "rgba(0, 0, 0, 0.87)",
|
|
69
|
+
textTransform: "none",
|
|
70
|
+
fontSize: "0.78rem",
|
|
71
|
+
py: 0,
|
|
72
|
+
minWidth: 0,
|
|
73
|
+
background: "none",
|
|
74
|
+
"& .MuiButton-startIcon": {
|
|
75
|
+
color: "inherit"
|
|
76
|
+
},
|
|
77
|
+
"&:hover": {
|
|
78
|
+
color: accentColor,
|
|
79
|
+
background: "none"
|
|
80
|
+
},
|
|
81
|
+
"&:active": {
|
|
82
|
+
color: accentColor,
|
|
83
|
+
opacity: 0.8,
|
|
84
|
+
background: "none"
|
|
85
|
+
},
|
|
86
|
+
"&:focus": {
|
|
87
|
+
background: "none"
|
|
88
|
+
},
|
|
89
|
+
"&.MuiButtonBase-root:hover": {
|
|
90
|
+
backgroundColor: "transparent"
|
|
91
|
+
}
|
|
92
|
+
};
|
|
55
93
|
return (_jsxs("div", __assign({ style: style, className: className }, { children: [title !== "" && (_jsx("div", __assign({ className: "title", style: { width: "100%" } }, { children: title }))), _jsx(Card, __assign({ variant: "outlined", sx: { mb: 2, borderTopLeftRadius: 0, borderTopRightRadius: 0 } }, { children: _jsx(CardContent, __assign({ sx: { "&:last-child": { paddingBottom: 2 } } }, { children: _jsxs(Box, __assign({ style: { display: "flex", flex: 1, minWidth: "245px", flexDirection: "column" } }, { children: [_jsx(TKDualRange, { name: "Values:", minDomain: (_c = (_b = nv.volumes[0]) === null || _b === void 0 ? void 0 : _b.robust_min) !== null && _c !== void 0 ? _c : 0, maxDomain: (_e = (_d = nv.volumes[0]) === null || _d === void 0 ? void 0 : _d.robust_max) !== null && _e !== void 0 ? _e : 1, valueLow: min, valueHigh: max, onChangeLow: function (newMin) {
|
|
56
94
|
var v = nv.volumes[0];
|
|
57
95
|
if (!v)
|
|
@@ -72,6 +110,6 @@ export function NiivueContrastAdjustments(_a) {
|
|
|
72
110
|
var val = Number(e.target.value);
|
|
73
111
|
setGamma(val);
|
|
74
112
|
nv.setGamma(val);
|
|
75
|
-
}, style: { width: "100%", accentColor: accentColor } }, gammaKey)] })), layerList.length > 0 && (_jsx(Box, __assign({ style: { height: "100%" } }, { children: layerList })))] })) })) }))] })));
|
|
113
|
+
}, style: { width: "100%", accentColor: accentColor } }, gammaKey)] })), _jsx(Box, __assign({ sx: { display: "flex", justifyContent: "flex-end", mt: 0.5, mb: 1 } }, { children: _jsx(Button, __assign({ size: "small", disableRipple: true, startIcon: _jsx(Brightness6Icon, { fontSize: "small" }), onClick: handleResetContrast, sx: resetContrastButtonSx }, { children: "Reset Contrast" })) })), layerList.length > 0 && (_jsx(Box, __assign({ style: { height: "100%" } }, { children: layerList })))] })) })) }))] })));
|
|
76
114
|
}
|
|
77
115
|
export default NiivueContrastAdjustments;
|
|
@@ -46,8 +46,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
49
|
-
import { Fragment, useState } from 'react';
|
|
50
|
-
import { Box, Button, CircularProgress, Stack, Switch, Tooltip, Typography } from "@mui/material";
|
|
49
|
+
import React, { Fragment, useState } from 'react';
|
|
50
|
+
import { Box, Button, CircularProgress, Stack, Switch, TextField, Tooltip, Typography } from "@mui/material";
|
|
51
51
|
import { IconButton, FormControl, Select, MenuItem, InputLabel } from "@mui/material";
|
|
52
52
|
import SettingsIcon from '@mui/icons-material/Settings';
|
|
53
53
|
import HomeIcon from '@mui/icons-material/Home';
|
|
@@ -55,7 +55,6 @@ import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
|
|
|
55
55
|
import ZoomInMapIcon from '@mui/icons-material/ZoomInMap';
|
|
56
56
|
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
|
57
57
|
import ZoomOutIcon from '@mui/icons-material/ZoomOut';
|
|
58
|
-
import Brightness6Icon from '@mui/icons-material/Brightness6';
|
|
59
58
|
import DeleteIcon from "@mui/icons-material/Delete";
|
|
60
59
|
import CmrConfirmation from "../dialogue/Confirmation";
|
|
61
60
|
import axios from "axios";
|
|
@@ -78,9 +77,65 @@ export default function Toolbar(props) {
|
|
|
78
77
|
{ value: "none", label: "Slice and None" }
|
|
79
78
|
];
|
|
80
79
|
var displayModes = ["absolute", "real", "imaginary", "phase"];
|
|
81
|
-
var _a = useState(
|
|
82
|
-
var
|
|
83
|
-
|
|
80
|
+
var _a = useState(''), zoomText = _a[0], setZoomText = _a[1];
|
|
81
|
+
var zoomEditingRef = React.useRef(false);
|
|
82
|
+
/** Compute the base pixels-per-mm at zoom=1.0, reading live canvas + volume state. */
|
|
83
|
+
var getBasePxPerMm = function () {
|
|
84
|
+
var _a;
|
|
85
|
+
var nv = props.nv;
|
|
86
|
+
var canvas = (_a = nv === null || nv === void 0 ? void 0 : nv.gl) === null || _a === void 0 ? void 0 : _a.canvas;
|
|
87
|
+
var back = nv === null || nv === void 0 ? void 0 : nv.back;
|
|
88
|
+
if (!canvas || !(back === null || back === void 0 ? void 0 : back.dims) || !(back === null || back === void 0 ? void 0 : back.pixDims))
|
|
89
|
+
return null;
|
|
90
|
+
var imgWmm = back.dims[1] * Math.abs(back.pixDims[1]);
|
|
91
|
+
var imgHmm = back.dims[2] * Math.abs(back.pixDims[2]);
|
|
92
|
+
if (imgWmm <= 0 || imgHmm <= 0)
|
|
93
|
+
return null;
|
|
94
|
+
var w = canvas.clientWidth || canvas.width;
|
|
95
|
+
var h = canvas.clientHeight || canvas.height;
|
|
96
|
+
return Math.min(w / imgWmm, h / imgHmm);
|
|
97
|
+
};
|
|
98
|
+
/** Returns the display value (number only, no unit suffix). */
|
|
99
|
+
var formatPxPerMm = function () {
|
|
100
|
+
var _a, _b, _c;
|
|
101
|
+
var zoom = (_c = (_b = (_a = props.nv) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.pan2Dxyzmm) === null || _c === void 0 ? void 0 : _c[3];
|
|
102
|
+
if (zoom == null)
|
|
103
|
+
return '';
|
|
104
|
+
var base = getBasePxPerMm();
|
|
105
|
+
if (base != null && base > 0)
|
|
106
|
+
return (base * zoom).toFixed(2);
|
|
107
|
+
return (zoom * 100).toFixed(0);
|
|
108
|
+
};
|
|
109
|
+
React.useEffect(function () {
|
|
110
|
+
var rafId;
|
|
111
|
+
var sync = function () {
|
|
112
|
+
if (!zoomEditingRef.current)
|
|
113
|
+
setZoomText(formatPxPerMm());
|
|
114
|
+
rafId = requestAnimationFrame(sync);
|
|
115
|
+
};
|
|
116
|
+
rafId = requestAnimationFrame(sync);
|
|
117
|
+
return function () { return cancelAnimationFrame(rafId); };
|
|
118
|
+
}, [props.nv]);
|
|
119
|
+
var applyZoom = function (text) {
|
|
120
|
+
var num = parseFloat(text.trim());
|
|
121
|
+
if (isNaN(num) || num <= 0)
|
|
122
|
+
return;
|
|
123
|
+
var base = getBasePxPerMm();
|
|
124
|
+
var targetZoom = (base != null && base > 0) ? num / base : num / 100;
|
|
125
|
+
var scene = props.nv.scene;
|
|
126
|
+
var current = scene.pan2Dxyzmm[3];
|
|
127
|
+
var next = Math.max(0.01, targetZoom);
|
|
128
|
+
var delta = current - next;
|
|
129
|
+
scene.pan2Dxyzmm[3] = next;
|
|
130
|
+
var mm = props.nv.frac2mm(scene.crosshairPos);
|
|
131
|
+
scene.pan2Dxyzmm[0] += delta * mm[0];
|
|
132
|
+
scene.pan2Dxyzmm[1] += delta * mm[1];
|
|
133
|
+
scene.pan2Dxyzmm[2] += delta * mm[2];
|
|
134
|
+
props.nv.drawScene();
|
|
135
|
+
};
|
|
136
|
+
var _b = useState(false), roiDeleteOpen = _b[0], setRoiDeleteOpen = _b[1];
|
|
137
|
+
var _c = useState(undefined), roiDeleteMsg = _c[0], setRoiDeleteMsg = _c[1];
|
|
138
|
+
var _d = useState(function () { return function () { }; }), roiDeleteConfirm = _d[0], setRoiDeleteConfirm = _d[1];
|
|
84
139
|
// const deleteROI= createAsyncThunk('DeleteROI', async (arg: { accessToken: string, jobId: string }) => {
|
|
85
140
|
// // const data = { jobId: arg.jobId }; // No need to stringify, axios will handle it
|
|
86
141
|
// const config = {
|
|
@@ -250,12 +305,7 @@ export default function Toolbar(props) {
|
|
|
250
305
|
alignItems: 'center'
|
|
251
306
|
}, m: 1 }, { children: [_jsx(Typography, __assign({ style: {
|
|
252
307
|
marginRight: 'auto'
|
|
253
|
-
} }, { children: "Labels Visible" })), _jsx(Switch, { defaultChecked: false, checked: props.labelsVisible, onChange: props.toggleLabelsVisible, sx: viewerTheme.muiSwitchSx })] })), _jsx(Box, { sx: { flex: 1 } }), _jsxs(Stack, __assign({ flexDirection: 'row', alignItems: 'center', sx: { m: 2, gap: 0.5 } }, { children: [_jsx(Tooltip, __assign({ title: 'Reset Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetScene(); } }, { children: _jsx(HomeIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Recenter Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.recenter(); } }, { children: _jsx(CenterFocusStrongIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Reset Zooms', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetZoom(); } }, { children: _jsx(ZoomInMapIcon, {}) })) })), _jsx(Tooltip, __assign({ title: '
|
|
254
|
-
var _a, _b;
|
|
255
|
-
props.nv.resetContrast();
|
|
256
|
-
props.nv.setGamma(1.0); // engine reset
|
|
257
|
-
(_b = (_a = props.nv).onResetGamma) === null || _b === void 0 ? void 0 : _b.call(_a); // UI reset: bumps gammaKey + sets gamma=1.0
|
|
258
|
-
} }, { children: _jsx(Brightness6Icon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Zoom Out', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
308
|
+
} }, { children: "Labels Visible" })), _jsx(Switch, { defaultChecked: false, checked: props.labelsVisible, onChange: props.toggleLabelsVisible, sx: viewerTheme.muiSwitchSx })] })), _jsx(Box, { sx: { flex: 1 } }), _jsxs(Stack, __assign({ flexDirection: 'row', alignItems: 'center', sx: { m: 2, gap: 0.5 } }, { children: [_jsx(Tooltip, __assign({ title: 'Reset Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetScene(); } }, { children: _jsx(HomeIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Recenter Views', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.recenter(); } }, { children: _jsx(CenterFocusStrongIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Reset Zooms', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () { return props.nv.resetZoom(); } }, { children: _jsx(ZoomInMapIcon, {}) })) })), _jsx(Tooltip, __assign({ title: 'Zoom Out', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
259
309
|
var scene = props.nv.scene;
|
|
260
310
|
var current = scene.pan2Dxyzmm[3];
|
|
261
311
|
var next = Math.max(0.1, current - 0.1);
|
|
@@ -270,7 +320,28 @@ export default function Toolbar(props) {
|
|
|
270
320
|
border: '1px solid',
|
|
271
321
|
borderColor: 'divider',
|
|
272
322
|
borderRadius: 1
|
|
273
|
-
} }, { children: _jsx(ZoomOutIcon, {}) })) })), _jsx(
|
|
323
|
+
} }, { children: _jsx(ZoomOutIcon, {}) })) })), _jsx(TextField, { label: "px/mm", size: "small", value: zoomText, onChange: function (e) { return setZoomText(e.target.value); }, onFocus: function (e) {
|
|
324
|
+
zoomEditingRef.current = true;
|
|
325
|
+
requestAnimationFrame(function () { return e.target.select(); });
|
|
326
|
+
}, onBlur: function () {
|
|
327
|
+
zoomEditingRef.current = false;
|
|
328
|
+
applyZoom(zoomText);
|
|
329
|
+
}, onKeyDown: function (e) {
|
|
330
|
+
if (e.key === 'Enter') {
|
|
331
|
+
e.target.blur();
|
|
332
|
+
}
|
|
333
|
+
else if (e.key === 'Escape') {
|
|
334
|
+
zoomEditingRef.current = false;
|
|
335
|
+
setZoomText(formatPxPerMm());
|
|
336
|
+
e.target.blur();
|
|
337
|
+
}
|
|
338
|
+
}, sx: {
|
|
339
|
+
width: 100,
|
|
340
|
+
'& .MuiInputBase-input': {
|
|
341
|
+
textAlign: 'center',
|
|
342
|
+
fontSize: '0.8rem'
|
|
343
|
+
}
|
|
344
|
+
} }), _jsx(Tooltip, __assign({ title: 'Zoom In', placement: 'right' }, { children: _jsx(IconButton, __assign({ onClick: function () {
|
|
274
345
|
var scene = props.nv.scene;
|
|
275
346
|
var current = scene.pan2Dxyzmm[3];
|
|
276
347
|
var next = current + 0.1;
|