@ohif/app 3.8.0-beta.7 → 3.8.0-beta.70
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/{220.bundle.f7e1c96c94245e70f2be.js → 109.bundle.b4fee2a22b622839baf5.js} +4466 -3715
- package/dist/{471.bundle.49c8d281adbae4a2c4df.js → 121.bundle.21827fec690c01ee9ab3.js} +85 -112
- package/dist/{19.bundle.e5579df6d7b74af50b1d.js → 155.bundle.0dabe8513b605b01ac3d.js} +334 -287
- package/dist/{687.bundle.9d0330ea5d61fe3117da.js → 164.bundle.0b1a2be351543c1433e8.js} +22 -38
- package/dist/17dd54813d5acc10bf8f.wasm +0 -0
- package/dist/{506.bundle.ab8226d3d81abe874544.js → 188.bundle.81e83b073b6fd4ae0058.js} +23 -28
- package/dist/191.bundle.7d89c921abefd1140d50.js +30360 -0
- package/dist/{221.bundle.c2dc03d8fa4235dc1285.js → 2.bundle.04dbbf67a52fe109749c.js} +351 -546
- package/dist/20fc4c659b85ccd2a9c0.wasm +0 -0
- package/dist/290.bundle.952de53057f98e2c5ef0.js +8883 -0
- package/dist/{451.bundle.57c21db5d003c75e9d61.js → 295.bundle.3a0d5062d65296c4bf5d.js} +102 -127
- package/dist/{125.bundle.253395f320b72180da63.js → 297.bundle.194d8985ab974839b5b6.js} +7 -8
- package/dist/{202.bundle.d3490836f71e001dd30f.js → 342.bundle.6e49f63ea7cea4645c0a.js} +544 -860
- package/dist/41.bundle.6ec0794a483e9a30eb94.js +831 -0
- package/dist/425.bundle.ffcdde2143a5757926b9.js +2957 -0
- package/dist/425.css +2 -0
- package/dist/{126.bundle.42df2dafc9c0310da188.js → 448.bundle.9177b9d909654efbc8d5.js} +316 -427
- package/dist/{957.bundle.9ea4506963ef8b2d84ba.js → 504.bundle.993d7e2dec36257d4ce4.js} +14338 -27291
- package/dist/{886.bundle.c8dd3ecc42a4253de278.js → 530.bundle.566bfd08dccb4cf6d98b.js} +75 -105
- package/dist/{250.bundle.aea3335667054bdefe36.js → 544.bundle.1110b24e96863d719a95.js} +39 -56
- package/dist/{663.bundle.9f359963019cd8ccf8f9.js → 559.bundle.4f111410af43324629ca.js} +151 -147
- package/dist/{181.bundle.a62b9f0ec692299acb35.js → 574.bundle.83afbc7922736fc6846d.js} +1246 -289
- package/dist/{181.css → 574.css} +1 -1
- package/dist/{410.bundle.38c9d3820e152e89288e.js → 594.bundle.ffeebda1bb9a81182a80.js} +183 -221
- package/dist/{776.bundle.004382036bdbd8ee2b95.js → 595.bundle.1c1a50c4ff87763b786a.js} +3128 -1028
- package/dist/{774.bundle.4b2dc46a35012b898e1a.js → 644.bundle.1e77691d2eeb96a423b0.js} +1852 -8945
- package/dist/699.bundle.db05df7b8e2ad605e928.js +767 -0
- package/dist/{359.bundle.8abe0036a7bf6b5fd115.js → 724.bundle.eada9d6c23678a5a2947.js} +130 -254
- package/dist/{757.bundle.ec8301d8e70d2b990f65.js → 726.bundle.c8de818cf1a3ff0cf7d2.js} +512 -879
- package/dist/{530.bundle.a03b6f942ace3e1baa1e.js → 835.bundle.15aff0b7433bb0dd6d6d.js} +37 -30
- package/dist/{822.bundle.82cdc418f8f56da6060b.js → 862.bundle.959ef65b18c1d3b5e2b4.js} +77 -96
- package/dist/{236.bundle.c9e70d55e7b2574c1ecd.js → 889.bundle.67c6e5f988c9b1d289ef.js} +198 -197
- package/dist/{342.bundle.d9668551811e3a88aaa4.js → 90.bundle.f41c8c4fc78cdfd4de30.js} +1430 -1055
- package/dist/{281.bundle.16a2933086a57e60c96c.js → 905.bundle.eb821474b36b96b897f9.js} +155 -122
- package/dist/{814.bundle.a1aba9c1e3d336008351.js → 907.bundle.ca904d9747480a0e4bf1.js} +16 -30
- package/dist/{417.bundle.af0a207c29b109f84159.js → 931.bundle.d270a1fda9a2836c3cc5.js} +26 -26
- package/dist/{686.bundle.dccef1f36e4bc79bcc48.js → 939.bundle.9d93b2e47c52338747a2.js} +7 -8
- package/dist/{12.bundle.37a8b47d2ae587cb9226.js → 961.bundle.65967b1a4af002af1d1d.js} +16 -31
- package/dist/987.bundle.6bdfb3cd8762b8889632.js +122950 -0
- package/dist/app-config.js +1 -0
- package/dist/app.bundle.css +15 -13
- package/dist/{app.bundle.437d085e13599d1e1ced.js → app.bundle.e21e5afd46fb064cb5de.js} +147713 -61638
- package/dist/assets/images/CT-AAA.png +0 -0
- package/dist/assets/images/CT-AAA2.png +0 -0
- package/dist/assets/images/CT-Air.png +0 -0
- package/dist/assets/images/CT-Bone.png +0 -0
- package/dist/assets/images/CT-Bones.png +0 -0
- package/dist/assets/images/CT-Cardiac.png +0 -0
- package/dist/assets/images/CT-Cardiac2.png +0 -0
- package/dist/assets/images/CT-Cardiac3.png +0 -0
- package/dist/assets/images/CT-Chest-Contrast-Enhanced.png +0 -0
- package/dist/assets/images/CT-Chest-Vessels.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries-2.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries-3.png +0 -0
- package/dist/assets/images/CT-Coronary-Arteries.png +0 -0
- package/dist/assets/images/CT-Cropped-Volume-Bone.png +0 -0
- package/dist/assets/images/CT-Fat.png +0 -0
- package/dist/assets/images/CT-Liver-Vasculature.png +0 -0
- package/dist/assets/images/CT-Lung.png +0 -0
- package/dist/assets/images/CT-MIP.png +0 -0
- package/dist/assets/images/CT-Muscle.png +0 -0
- package/dist/assets/images/CT-Pulmonary-Arteries.png +0 -0
- package/dist/assets/images/CT-Soft-Tissue.png +0 -0
- package/dist/assets/images/DTI-FA-Brain.png +0 -0
- package/dist/assets/images/MR-Angio.png +0 -0
- package/dist/assets/images/MR-Default.png +0 -0
- package/dist/assets/images/MR-MIP.png +0 -0
- package/dist/assets/images/MR-T2-Brain.png +0 -0
- package/dist/assets/images/VolumeRendering.png +0 -0
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/{dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js → dicom-microscopy-viewer.bundle.d3a56dc9f62df5e11019.js} +3 -3
- package/dist/index.html +1 -1
- package/dist/{index.worker.e62ecca63f1a2e124230.worker.js → index.worker.64c896c4316fcd506666.worker.js} +2 -2
- package/dist/index.worker.64c896c4316fcd506666.worker.js.map +1 -0
- package/dist/polySeg.bundle.e7b4c29fb9173e8567b8.js +252 -0
- package/dist/serve.json +12 -0
- package/dist/sw.js +1 -1
- package/package.json +25 -22
- package/dist/23.bundle.e008ad788170f2ed5569.js +0 -900
- package/dist/604.bundle.a51f83e64004bca5f497.js +0 -1848
- package/dist/613.bundle.aed640a7900dbcb688f5.js +0 -532
- package/dist/743.bundle.489f7df3a089d4d374e1.js +0 -78007
- package/dist/75788f12450d4c5ed494.wasm +0 -0
- package/dist/775.bundle.2285e7e0e67878948c0d.js +0 -1009
- package/dist/788.bundle.dcd53828d1bb2ac64d04.js +0 -2682
- package/dist/82.bundle.5a94dd7645e5c5476f59.js +0 -1049
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +0 -1
- /package/dist/{19.css → 155.css} +0 -0
- /package/dist/{221.css → 2.css} +0 -0
- /package/dist/{579.css → 481.css} +0 -0
- /package/dist/{250.css → 544.css} +0 -0
- /package/dist/{776.css → 595.css} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(
|
|
2
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[574],{
|
|
3
3
|
|
|
4
|
-
/***/
|
|
4
|
+
/***/ 71574:
|
|
5
5
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
6
6
|
|
|
7
7
|
// ESM COMPAT FLAG
|
|
@@ -13,22 +13,22 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
// EXTERNAL MODULE: ../../../node_modules/react/index.js
|
|
16
|
-
var react = __webpack_require__(
|
|
16
|
+
var react = __webpack_require__(41766);
|
|
17
17
|
// EXTERNAL MODULE: ../../../node_modules/react-resize-detector/build/index.esm.js
|
|
18
|
-
var index_esm = __webpack_require__(
|
|
18
|
+
var index_esm = __webpack_require__(78668);
|
|
19
19
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
20
|
-
var prop_types = __webpack_require__(
|
|
20
|
+
var prop_types = __webpack_require__(11374);
|
|
21
21
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
22
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js +
|
|
23
|
-
var esm = __webpack_require__(
|
|
24
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js +
|
|
25
|
-
var dist_esm = __webpack_require__(
|
|
26
|
-
// EXTERNAL MODULE: ../../core/src/index.ts +
|
|
27
|
-
var src = __webpack_require__(
|
|
28
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
29
|
-
var ui_src = __webpack_require__(
|
|
22
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 16 modules
|
|
23
|
+
var esm = __webpack_require__(20767);
|
|
24
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 383 modules
|
|
25
|
+
var dist_esm = __webpack_require__(50719);
|
|
26
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 68 modules
|
|
27
|
+
var src = __webpack_require__(85073);
|
|
28
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 542 modules
|
|
29
|
+
var ui_src = __webpack_require__(48804);
|
|
30
30
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/state.ts
|
|
31
|
-
var state = __webpack_require__(
|
|
31
|
+
var state = __webpack_require__(71353);
|
|
32
32
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.css
|
|
33
33
|
// extracted by mini-css-extract-plugin
|
|
34
34
|
|
|
@@ -38,16 +38,15 @@ var state = __webpack_require__(73704);
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
function CornerstoneImageScrollbar(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} = _ref;
|
|
41
|
+
function CornerstoneImageScrollbar({
|
|
42
|
+
viewportData,
|
|
43
|
+
viewportId,
|
|
44
|
+
element,
|
|
45
|
+
imageSliceData,
|
|
46
|
+
setImageSliceData,
|
|
47
|
+
scrollbarHeight,
|
|
48
|
+
servicesManager
|
|
49
|
+
}) {
|
|
51
50
|
const {
|
|
52
51
|
cineService,
|
|
53
52
|
cornerstoneViewportService
|
|
@@ -140,7 +139,7 @@ function CornerstoneImageScrollbar(_ref) {
|
|
|
140
139
|
element.removeEventListener(dist_esm.Enums.Events.VOLUME_NEW_IMAGE, updateVolumeIndex);
|
|
141
140
|
};
|
|
142
141
|
}, [viewportData, element]);
|
|
143
|
-
return /*#__PURE__*/react.createElement(ui_src/* ImageScrollbar */.
|
|
142
|
+
return /*#__PURE__*/react.createElement(ui_src/* ImageScrollbar */.uq, {
|
|
144
143
|
onChange: evt => onImageScrollbarChange(evt, viewportId),
|
|
145
144
|
max: imageSliceData.numberOfSlices ? imageSliceData.numberOfSlices - 1 : 0,
|
|
146
145
|
height: scrollbarHeight,
|
|
@@ -158,9 +157,9 @@ CornerstoneImageScrollbar.propTypes = {
|
|
|
158
157
|
};
|
|
159
158
|
/* harmony default export */ const ViewportImageScrollbar = (CornerstoneImageScrollbar);
|
|
160
159
|
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 10 modules
|
|
161
|
-
var gl_matrix_esm = __webpack_require__(
|
|
160
|
+
var gl_matrix_esm = __webpack_require__(83636);
|
|
162
161
|
// EXTERNAL MODULE: ../../../node_modules/moment/moment.js
|
|
163
|
-
var moment = __webpack_require__(
|
|
162
|
+
var moment = __webpack_require__(8291);
|
|
164
163
|
var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
|
|
165
164
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/Overlays/utils.ts
|
|
166
165
|
|
|
@@ -183,8 +182,7 @@ function isValidNumber(value) {
|
|
|
183
182
|
* @param {number} precision
|
|
184
183
|
* @returns {number} formatted number.
|
|
185
184
|
*/
|
|
186
|
-
function formatNumberPrecision(number) {
|
|
187
|
-
let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
185
|
+
function formatNumberPrecision(number, precision = 0) {
|
|
188
186
|
if (number !== null) {
|
|
189
187
|
return parseFloat(number).toFixed(precision);
|
|
190
188
|
}
|
|
@@ -197,8 +195,7 @@ function formatNumberPrecision(number) {
|
|
|
197
195
|
* @param {string} strFormat
|
|
198
196
|
* @returns {string} formatted date.
|
|
199
197
|
*/
|
|
200
|
-
function formatDICOMDate(date) {
|
|
201
|
-
let strFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'MMM D, YYYY';
|
|
198
|
+
function formatDICOMDate(date, strFormat = 'MMM D, YYYY') {
|
|
202
199
|
return moment_default()(date, 'YYYYMMDD').format(strFormat);
|
|
203
200
|
}
|
|
204
201
|
|
|
@@ -215,8 +212,7 @@ function formatDICOMDate(date) {
|
|
|
215
212
|
* @param {string} strFormat
|
|
216
213
|
* @returns {string} formatted name.
|
|
217
214
|
*/
|
|
218
|
-
function formatDICOMTime(time) {
|
|
219
|
-
let strFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'HH:mm:ss';
|
|
215
|
+
function formatDICOMTime(time, strFormat = 'HH:mm:ss') {
|
|
220
216
|
return moment_default()(time, 'HH:mm:ss').format(strFormat);
|
|
221
217
|
}
|
|
222
218
|
|
|
@@ -266,104 +262,32 @@ function getCompression(imageId) {
|
|
|
266
262
|
|
|
267
263
|
|
|
268
264
|
const EPSILON = 1e-4;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
voi,
|
|
275
|
-
customization
|
|
276
|
-
} = _ref;
|
|
277
|
-
const {
|
|
278
|
-
windowWidth,
|
|
279
|
-
windowCenter
|
|
280
|
-
} = voi;
|
|
281
|
-
if (typeof windowCenter !== 'number' || typeof windowWidth !== 'number') {
|
|
282
|
-
return null;
|
|
283
|
-
}
|
|
284
|
-
return /*#__PURE__*/react.createElement("div", {
|
|
285
|
-
className: "overlay-item flex flex-row",
|
|
286
|
-
style: {
|
|
287
|
-
color: customization && customization.color || undefined
|
|
288
|
-
}
|
|
289
|
-
}, /*#__PURE__*/react.createElement("span", {
|
|
290
|
-
className: "mr-1 shrink-0"
|
|
291
|
-
}, "W:"), /*#__PURE__*/react.createElement("span", {
|
|
292
|
-
className: "ml-1 mr-2 shrink-0 font-light"
|
|
293
|
-
}, windowWidth.toFixed(0)), /*#__PURE__*/react.createElement("span", {
|
|
294
|
-
className: "mr-1 shrink-0"
|
|
295
|
-
}, "L:"), /*#__PURE__*/react.createElement("span", {
|
|
296
|
-
className: "ml-1 shrink-0 font-light"
|
|
297
|
-
}, windowCenter.toFixed(0)));
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Zoom Level Overlay item
|
|
302
|
-
*/
|
|
303
|
-
function ZoomOverlayItem(_ref2) {
|
|
304
|
-
let {
|
|
305
|
-
scale,
|
|
306
|
-
customization
|
|
307
|
-
} = _ref2;
|
|
308
|
-
return /*#__PURE__*/react.createElement("div", {
|
|
309
|
-
className: "overlay-item flex flex-row",
|
|
310
|
-
style: {
|
|
311
|
-
color: customization && customization.color || undefined
|
|
312
|
-
}
|
|
313
|
-
}, /*#__PURE__*/react.createElement("span", {
|
|
314
|
-
className: "mr-1 shrink-0"
|
|
315
|
-
}, "Zoom:"), /*#__PURE__*/react.createElement("span", {
|
|
316
|
-
className: "font-light"
|
|
317
|
-
}, scale.toFixed(2), "x"));
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Instance Number Overlay Item
|
|
322
|
-
*/
|
|
323
|
-
function InstanceNumberOverlayItem(_ref3) {
|
|
324
|
-
let {
|
|
325
|
-
instanceNumber,
|
|
326
|
-
imageSliceData,
|
|
327
|
-
customization
|
|
328
|
-
} = _ref3;
|
|
329
|
-
const {
|
|
330
|
-
imageIndex,
|
|
331
|
-
numberOfSlices
|
|
332
|
-
} = imageSliceData;
|
|
333
|
-
return /*#__PURE__*/react.createElement("div", {
|
|
334
|
-
className: "overlay-item flex flex-row",
|
|
335
|
-
style: {
|
|
336
|
-
color: customization && customization.color || undefined
|
|
337
|
-
}
|
|
338
|
-
}, /*#__PURE__*/react.createElement("span", {
|
|
339
|
-
className: "mr-1 shrink-0"
|
|
340
|
-
}, "I:"), /*#__PURE__*/react.createElement("span", {
|
|
341
|
-
className: "font-light"
|
|
342
|
-
}, instanceNumber !== undefined && instanceNumber !== null ? `${instanceNumber} (${imageIndex + 1}/${numberOfSlices})` : `${imageIndex + 1}/${numberOfSlices}`));
|
|
343
|
-
}
|
|
265
|
+
const OverlayItemComponents = {
|
|
266
|
+
'ohif.overlayItem.windowLevel': VOIOverlayItem,
|
|
267
|
+
'ohif.overlayItem.zoomLevel': ZoomOverlayItem,
|
|
268
|
+
'ohif.overlayItem.instanceNumber': InstanceNumberOverlayItem
|
|
269
|
+
};
|
|
344
270
|
|
|
345
271
|
/**
|
|
346
272
|
* Customizable Viewport Overlay
|
|
347
273
|
*/
|
|
348
|
-
function CustomizableViewportOverlay(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
} = _ref4;
|
|
274
|
+
function CustomizableViewportOverlay({
|
|
275
|
+
element,
|
|
276
|
+
viewportData,
|
|
277
|
+
imageSliceData,
|
|
278
|
+
viewportId,
|
|
279
|
+
servicesManager
|
|
280
|
+
}) {
|
|
356
281
|
const {
|
|
357
|
-
toolbarService,
|
|
358
282
|
cornerstoneViewportService,
|
|
359
|
-
customizationService
|
|
283
|
+
customizationService,
|
|
284
|
+
toolGroupService
|
|
360
285
|
} = servicesManager.services;
|
|
361
286
|
const [voi, setVOI] = (0,react.useState)({
|
|
362
287
|
windowCenter: null,
|
|
363
288
|
windowWidth: null
|
|
364
289
|
});
|
|
365
290
|
const [scale, setScale] = (0,react.useState)(1);
|
|
366
|
-
const [activeTools, setActiveTools] = (0,react.useState)([]);
|
|
367
291
|
const {
|
|
368
292
|
imageIndex
|
|
369
293
|
} = imageSliceData;
|
|
@@ -378,19 +302,7 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
378
302
|
return null;
|
|
379
303
|
}
|
|
380
304
|
}, [viewportData, imageIndex]);
|
|
381
|
-
const instanceNumber = (0,react.useMemo)(() =>
|
|
382
|
-
if (viewportData != null) {
|
|
383
|
-
return _getInstanceNumber(viewportData, viewportId, imageIndex, cornerstoneViewportService);
|
|
384
|
-
}
|
|
385
|
-
return null;
|
|
386
|
-
}, [viewportData, viewportId, imageIndex, cornerstoneViewportService]);
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Initial toolbar state
|
|
390
|
-
*/
|
|
391
|
-
(0,react.useEffect)(() => {
|
|
392
|
-
setActiveTools(toolbarService.getActiveTools());
|
|
393
|
-
}, []);
|
|
305
|
+
const instanceNumber = (0,react.useMemo)(() => viewportData ? getInstanceNumber(viewportData, viewportId, imageIndex, cornerstoneViewportService) : null, [viewportData, viewportId, imageIndex, cornerstoneViewportService]);
|
|
394
306
|
|
|
395
307
|
/**
|
|
396
308
|
* Updating the VOI when the viewport changes its voi
|
|
@@ -457,21 +369,6 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
457
369
|
element.removeEventListener(dist_esm.Enums.Events.CAMERA_MODIFIED, updateScale);
|
|
458
370
|
};
|
|
459
371
|
}, [viewportId, viewportData, cornerstoneViewportService, element]);
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Updating the active tools when the toolbar changes
|
|
463
|
-
*/
|
|
464
|
-
// Todo: this should act on the toolGroups instead of the toolbar state
|
|
465
|
-
(0,react.useEffect)(() => {
|
|
466
|
-
const {
|
|
467
|
-
unsubscribe
|
|
468
|
-
} = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED, () => {
|
|
469
|
-
setActiveTools(toolbarService.getActiveTools());
|
|
470
|
-
});
|
|
471
|
-
return () => {
|
|
472
|
-
unsubscribe();
|
|
473
|
-
};
|
|
474
|
-
}, [toolbarService]);
|
|
475
372
|
const _renderOverlayItem = (0,react.useCallback)(item => {
|
|
476
373
|
const overlayItemProps = {
|
|
477
374
|
element,
|
|
@@ -487,17 +384,19 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
487
384
|
formatNumberPrecision: formatNumberPrecision
|
|
488
385
|
},
|
|
489
386
|
instance,
|
|
490
|
-
// calculated
|
|
491
387
|
voi,
|
|
492
388
|
scale,
|
|
493
389
|
instanceNumber
|
|
494
390
|
};
|
|
495
|
-
if (item
|
|
496
|
-
return
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
391
|
+
if (!item) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
const {
|
|
395
|
+
customizationType
|
|
396
|
+
} = item;
|
|
397
|
+
const OverlayItemComponent = OverlayItemComponents[customizationType];
|
|
398
|
+
if (OverlayItemComponent) {
|
|
399
|
+
return /*#__PURE__*/react.createElement(OverlayItemComponent, overlayItemProps);
|
|
501
400
|
} else {
|
|
502
401
|
const renderItem = customizationService.transform(item);
|
|
503
402
|
if (typeof renderItem.content === 'function') {
|
|
@@ -505,41 +404,62 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
505
404
|
}
|
|
506
405
|
}
|
|
507
406
|
}, [element, viewportData, imageSliceData, viewportId, servicesManager, customizationService, instance, voi, scale, instanceNumber]);
|
|
508
|
-
const
|
|
509
|
-
const items =
|
|
407
|
+
const getContent = (0,react.useCallback)((customization, defaultItems, keyPrefix) => {
|
|
408
|
+
const items = customization?.items ?? defaultItems;
|
|
409
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, items.map((item, index) => /*#__PURE__*/react.createElement("div", {
|
|
410
|
+
key: `${keyPrefix}_${index}`
|
|
411
|
+
}, item?.condition ? item.condition({
|
|
412
|
+
instance,
|
|
413
|
+
formatters: {
|
|
414
|
+
formatDate: formatDICOMDate
|
|
415
|
+
}
|
|
416
|
+
}) ? _renderOverlayItem(item) : null : _renderOverlayItem(item))));
|
|
417
|
+
}, [_renderOverlayItem]);
|
|
418
|
+
return /*#__PURE__*/react.createElement(ui_src/* ViewportOverlay */.pU, {
|
|
419
|
+
topLeft:
|
|
420
|
+
/**
|
|
421
|
+
* Inline default overlay items for a more standard expansion
|
|
422
|
+
*/
|
|
423
|
+
getContent(topLeftCustomization, [{
|
|
424
|
+
id: 'StudyDate',
|
|
425
|
+
customizationType: 'ohif.overlayItem',
|
|
426
|
+
label: '',
|
|
427
|
+
title: 'Study date',
|
|
428
|
+
condition: ({
|
|
429
|
+
instance
|
|
430
|
+
}) => instance && instance.StudyDate,
|
|
431
|
+
contentF: ({
|
|
432
|
+
instance,
|
|
433
|
+
formatters: {
|
|
434
|
+
formatDate
|
|
435
|
+
}
|
|
436
|
+
}) => formatDate(instance.StudyDate)
|
|
437
|
+
}, {
|
|
438
|
+
id: 'SeriesDescription',
|
|
439
|
+
customizationType: 'ohif.overlayItem',
|
|
440
|
+
label: '',
|
|
441
|
+
title: 'Series description',
|
|
442
|
+
attribute: 'SeriesDescription',
|
|
443
|
+
condition: ({
|
|
444
|
+
instance
|
|
445
|
+
}) => instance && instance.SeriesDescription
|
|
446
|
+
}], 'topLeftOverlayItem'),
|
|
447
|
+
topRight: getContent(topRightCustomization, [], 'topRightOverlayItem'),
|
|
448
|
+
bottomLeft: getContent(bottomLeftCustomization, [{
|
|
510
449
|
id: 'WindowLevel',
|
|
511
450
|
customizationType: 'ohif.overlayItem.windowLevel'
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
451
|
+
}, {
|
|
452
|
+
id: 'ZoomLevel',
|
|
453
|
+
customizationType: 'ohif.overlayItem.zoomLevel',
|
|
454
|
+
condition: () => {
|
|
455
|
+
const activeToolName = toolGroupService.getActiveToolForViewport(viewportId);
|
|
456
|
+
return activeToolName === 'Zoom';
|
|
457
|
+
}
|
|
458
|
+
}], 'bottomLeftOverlayItem'),
|
|
459
|
+
bottomRight: getContent(bottomRightCustomization, [{
|
|
460
|
+
id: 'InstanceNumber',
|
|
520
461
|
customizationType: 'ohif.overlayItem.instanceNumber'
|
|
521
|
-
}]
|
|
522
|
-
return /*#__PURE__*/react.createElement(react.Fragment, null, items.map((item, i) => /*#__PURE__*/react.createElement("div", {
|
|
523
|
-
key: `topRightOverlayItem_${i}`
|
|
524
|
-
}, _renderOverlayItem(item))));
|
|
525
|
-
}, [topRightCustomization, _renderOverlayItem]);
|
|
526
|
-
const getBottomLeftContent = (0,react.useCallback)(() => {
|
|
527
|
-
const items = bottomLeftCustomization?.items || [];
|
|
528
|
-
return /*#__PURE__*/react.createElement(react.Fragment, null, items.map((item, i) => /*#__PURE__*/react.createElement("div", {
|
|
529
|
-
key: `bottomLeftOverlayItem_${i}`
|
|
530
|
-
}, _renderOverlayItem(item))));
|
|
531
|
-
}, [bottomLeftCustomization, _renderOverlayItem]);
|
|
532
|
-
const getBottomRightContent = (0,react.useCallback)(() => {
|
|
533
|
-
const items = bottomRightCustomization?.items || [];
|
|
534
|
-
return /*#__PURE__*/react.createElement(react.Fragment, null, items.map((item, i) => /*#__PURE__*/react.createElement("div", {
|
|
535
|
-
key: `bottomRightOverlayItem_${i}`
|
|
536
|
-
}, _renderOverlayItem(item))));
|
|
537
|
-
}, [bottomRightCustomization, _renderOverlayItem]);
|
|
538
|
-
return /*#__PURE__*/react.createElement(ui_src/* ViewportOverlay */.No, {
|
|
539
|
-
topLeft: getTopLeftContent(),
|
|
540
|
-
topRight: getTopRightContent(),
|
|
541
|
-
bottomLeft: getBottomLeftContent(),
|
|
542
|
-
bottomRight: getBottomRightContent()
|
|
462
|
+
}], 'bottomRightOverlayItem')
|
|
543
463
|
});
|
|
544
464
|
}
|
|
545
465
|
function _getViewportInstance(viewportData, imageIndex) {
|
|
@@ -555,18 +475,18 @@ function _getViewportInstance(viewportData, imageIndex) {
|
|
|
555
475
|
}
|
|
556
476
|
return imageId ? dist_esm.metaData.get('instance', imageId) || {} : {};
|
|
557
477
|
}
|
|
558
|
-
|
|
478
|
+
const getInstanceNumber = (viewportData, viewportId, imageIndex, cornerstoneViewportService) => {
|
|
559
479
|
let instanceNumber;
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
480
|
+
switch (viewportData.viewportType) {
|
|
481
|
+
case dist_esm.Enums.ViewportType.STACK:
|
|
482
|
+
instanceNumber = _getInstanceNumberFromStack(viewportData, imageIndex);
|
|
483
|
+
break;
|
|
484
|
+
case dist_esm.Enums.ViewportType.ORTHOGRAPHIC:
|
|
485
|
+
instanceNumber = _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewportService);
|
|
486
|
+
break;
|
|
567
487
|
}
|
|
568
|
-
return instanceNumber;
|
|
569
|
-
}
|
|
488
|
+
return instanceNumber ?? null;
|
|
489
|
+
};
|
|
570
490
|
function _getInstanceNumberFromStack(viewportData, imageIndex) {
|
|
571
491
|
const imageIds = viewportData.data.imageIds;
|
|
572
492
|
const imageId = imageIds[imageIndex];
|
|
@@ -612,8 +532,8 @@ function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewp
|
|
|
612
532
|
const scanAxisNormal = direction.slice(6, 9);
|
|
613
533
|
|
|
614
534
|
// check if viewPlaneNormal is parallel to scanAxisNormal
|
|
615
|
-
const cross = gl_matrix_esm/* vec3.cross */.
|
|
616
|
-
const isAcquisitionPlane = gl_matrix_esm/* vec3.length */.
|
|
535
|
+
const cross = gl_matrix_esm/* vec3.cross */.eR.cross(gl_matrix_esm/* vec3.create */.eR.create(), viewPlaneNormal, scanAxisNormal);
|
|
536
|
+
const isAcquisitionPlane = gl_matrix_esm/* vec3.length */.eR.length(cross) < EPSILON;
|
|
617
537
|
if (isAcquisitionPlane) {
|
|
618
538
|
const imageId = imageIds[imageIndex];
|
|
619
539
|
if (!imageId) {
|
|
@@ -625,6 +545,75 @@ function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewp
|
|
|
625
545
|
return parseInt(instanceNumber);
|
|
626
546
|
}
|
|
627
547
|
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Window Level / Center Overlay item
|
|
551
|
+
*/
|
|
552
|
+
function VOIOverlayItem({
|
|
553
|
+
voi,
|
|
554
|
+
customization
|
|
555
|
+
}) {
|
|
556
|
+
const {
|
|
557
|
+
windowWidth,
|
|
558
|
+
windowCenter
|
|
559
|
+
} = voi;
|
|
560
|
+
if (typeof windowCenter !== 'number' || typeof windowWidth !== 'number') {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
564
|
+
className: "overlay-item flex flex-row",
|
|
565
|
+
style: {
|
|
566
|
+
color: customization && customization.color || undefined
|
|
567
|
+
}
|
|
568
|
+
}, /*#__PURE__*/react.createElement("span", {
|
|
569
|
+
className: "mr-1 shrink-0"
|
|
570
|
+
}, "W:"), /*#__PURE__*/react.createElement("span", {
|
|
571
|
+
className: "ml-1 mr-2 shrink-0"
|
|
572
|
+
}, windowWidth.toFixed(0)), /*#__PURE__*/react.createElement("span", {
|
|
573
|
+
className: "mr-1 shrink-0"
|
|
574
|
+
}, "L:"), /*#__PURE__*/react.createElement("span", {
|
|
575
|
+
className: "ml-1 shrink-0"
|
|
576
|
+
}, windowCenter.toFixed(0)));
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Zoom Level Overlay item
|
|
581
|
+
*/
|
|
582
|
+
function ZoomOverlayItem({
|
|
583
|
+
scale,
|
|
584
|
+
customization
|
|
585
|
+
}) {
|
|
586
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
587
|
+
className: "overlay-item flex flex-row",
|
|
588
|
+
style: {
|
|
589
|
+
color: customization && customization.color || undefined
|
|
590
|
+
}
|
|
591
|
+
}, /*#__PURE__*/react.createElement("span", {
|
|
592
|
+
className: "mr-1 shrink-0"
|
|
593
|
+
}, "Zoom:"), /*#__PURE__*/react.createElement("span", null, scale.toFixed(2), "x"));
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Instance Number Overlay Item
|
|
598
|
+
*/
|
|
599
|
+
function InstanceNumberOverlayItem({
|
|
600
|
+
instanceNumber,
|
|
601
|
+
imageSliceData,
|
|
602
|
+
customization
|
|
603
|
+
}) {
|
|
604
|
+
const {
|
|
605
|
+
imageIndex,
|
|
606
|
+
numberOfSlices
|
|
607
|
+
} = imageSliceData;
|
|
608
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
609
|
+
className: "overlay-item flex flex-row",
|
|
610
|
+
style: {
|
|
611
|
+
color: customization && customization.color || undefined
|
|
612
|
+
}
|
|
613
|
+
}, /*#__PURE__*/react.createElement("span", {
|
|
614
|
+
className: "mr-1 shrink-0"
|
|
615
|
+
}, "I:"), /*#__PURE__*/react.createElement("span", null, instanceNumber !== undefined && instanceNumber !== null ? `${instanceNumber} (${imageIndex + 1}/${numberOfSlices})` : `${imageIndex + 1}/${numberOfSlices}`));
|
|
616
|
+
}
|
|
628
617
|
CustomizableViewportOverlay.propTypes = {
|
|
629
618
|
viewportData: (prop_types_default()).object,
|
|
630
619
|
imageIndex: (prop_types_default()).number,
|
|
@@ -632,7 +621,7 @@ CustomizableViewportOverlay.propTypes = {
|
|
|
632
621
|
};
|
|
633
622
|
/* harmony default export */ const Overlays_CustomizableViewportOverlay = (CustomizableViewportOverlay);
|
|
634
623
|
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
635
|
-
var classnames = __webpack_require__(
|
|
624
|
+
var classnames = __webpack_require__(61466);
|
|
636
625
|
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
637
626
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css
|
|
638
627
|
// extracted by mini-css-extract-plugin
|
|
@@ -649,15 +638,14 @@ const {
|
|
|
649
638
|
getOrientationStringLPS,
|
|
650
639
|
invertOrientationStringLPS
|
|
651
640
|
} = esm.utilities.orientation;
|
|
652
|
-
function ViewportOrientationMarkers(
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
} = _ref;
|
|
641
|
+
function ViewportOrientationMarkers({
|
|
642
|
+
element,
|
|
643
|
+
viewportData,
|
|
644
|
+
imageSliceData,
|
|
645
|
+
viewportId,
|
|
646
|
+
servicesManager,
|
|
647
|
+
orientationMarkers = ['top', 'left']
|
|
648
|
+
}) {
|
|
661
649
|
// Rotation is in degrees
|
|
662
650
|
const [rotation, setRotation] = (0,react.useState)(0);
|
|
663
651
|
const [flipHorizontal, setFlipHorizontal] = (0,react.useState)(false);
|
|
@@ -715,8 +703,8 @@ function ViewportOrientationMarkers(_ref) {
|
|
|
715
703
|
viewUp,
|
|
716
704
|
viewPlaneNormal
|
|
717
705
|
} = viewport.getCamera();
|
|
718
|
-
const viewRight = gl_matrix_esm/* vec3.create */.
|
|
719
|
-
gl_matrix_esm/* vec3.cross */.
|
|
706
|
+
const viewRight = gl_matrix_esm/* vec3.create */.eR.create();
|
|
707
|
+
gl_matrix_esm/* vec3.cross */.eR.cross(viewRight, viewUp, viewPlaneNormal);
|
|
720
708
|
columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]];
|
|
721
709
|
rowCosines = viewRight;
|
|
722
710
|
}
|
|
@@ -729,20 +717,15 @@ function ViewportOrientationMarkers(_ref) {
|
|
|
729
717
|
console.log('ViewportOrientationMarkers::No viewport');
|
|
730
718
|
return null;
|
|
731
719
|
}
|
|
732
|
-
const backgroundColor = ohifViewport.getViewportOptions().background;
|
|
733
|
-
|
|
734
|
-
// Todo: probably this can be done in a better way in which we identify bright
|
|
735
|
-
// background
|
|
736
|
-
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
737
720
|
return orientationMarkers.map((m, index) => /*#__PURE__*/react.createElement("div", {
|
|
738
|
-
className: classnames_default()(`${m}-mid orientation-marker`,
|
|
721
|
+
className: classnames_default()('overlay-text', `${m}-mid orientation-marker`, 'text-aqua-pale', 'text-[13px]', 'leading-5'),
|
|
739
722
|
key: `${m}-mid orientation-marker`
|
|
740
723
|
}, /*#__PURE__*/react.createElement("div", {
|
|
741
724
|
className: "orientation-marker-value"
|
|
742
725
|
}, markers[m])));
|
|
743
726
|
}, [viewportData, imageSliceData, rotation, flipVertical, flipHorizontal, orientationMarkers, element]);
|
|
744
727
|
return /*#__PURE__*/react.createElement("div", {
|
|
745
|
-
className: "ViewportOrientationMarkers
|
|
728
|
+
className: "ViewportOrientationMarkers select-none"
|
|
746
729
|
}, markers);
|
|
747
730
|
}
|
|
748
731
|
ViewportOrientationMarkers.propTypes = {
|
|
@@ -818,11 +801,10 @@ function _getOrientationMarkers(rowCosines, columnCosines, rotation, flipVertica
|
|
|
818
801
|
|
|
819
802
|
|
|
820
803
|
|
|
821
|
-
function ViewportImageSliceLoadingIndicator(
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
} = _ref;
|
|
804
|
+
function ViewportImageSliceLoadingIndicator({
|
|
805
|
+
viewportData,
|
|
806
|
+
element
|
|
807
|
+
}) {
|
|
826
808
|
const [loading, setLoading] = (0,react.useState)(false);
|
|
827
809
|
const [error, setError] = (0,react.useState)(false);
|
|
828
810
|
const loadIndicatorRef = (0,react.useRef)(null);
|
|
@@ -961,48 +943,34 @@ function CornerstoneOverlays(props) {
|
|
|
961
943
|
}
|
|
962
944
|
/* harmony default export */ const Overlays_CornerstoneOverlays = (CornerstoneOverlays);
|
|
963
945
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
|
|
964
|
-
var getSOPInstanceAttributes = __webpack_require__(
|
|
946
|
+
var getSOPInstanceAttributes = __webpack_require__(1663);
|
|
965
947
|
// EXTERNAL MODULE: ./state/index.js + 1 modules
|
|
966
|
-
var state_0 = __webpack_require__(
|
|
948
|
+
var state_0 = __webpack_require__(15575);
|
|
967
949
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx
|
|
968
950
|
|
|
969
951
|
|
|
970
952
|
|
|
971
953
|
|
|
972
|
-
function WrappedCinePlayer(
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
} = _ref;
|
|
954
|
+
function WrappedCinePlayer({
|
|
955
|
+
enabledVPElement,
|
|
956
|
+
viewportId,
|
|
957
|
+
servicesManager
|
|
958
|
+
}) {
|
|
978
959
|
const {
|
|
979
|
-
toolbarService,
|
|
980
960
|
customizationService,
|
|
981
961
|
displaySetService,
|
|
982
|
-
viewportGridService
|
|
983
|
-
cineService
|
|
962
|
+
viewportGridService
|
|
984
963
|
} = servicesManager.services;
|
|
985
964
|
const [{
|
|
986
965
|
isCineEnabled,
|
|
987
966
|
cines
|
|
988
|
-
}] = (0,ui_src/* useCine */.
|
|
967
|
+
}, api] = (0,ui_src/* useCine */.tq)();
|
|
989
968
|
const [newStackFrameRate, setNewStackFrameRate] = (0,react.useState)(24);
|
|
990
|
-
const [appConfig] = (0,state_0/* useAppConfig */.
|
|
969
|
+
const [appConfig] = (0,state_0/* useAppConfig */.r)();
|
|
970
|
+
const isMountedRef = (0,react.useRef)(null);
|
|
991
971
|
const {
|
|
992
|
-
component: CinePlayerComponent = ui_src/* CinePlayer */.
|
|
972
|
+
component: CinePlayerComponent = ui_src/* CinePlayer */.F0
|
|
993
973
|
} = customizationService.get('cinePlayer') ?? {};
|
|
994
|
-
const handleCineClose = () => {
|
|
995
|
-
toolbarService.recordInteraction({
|
|
996
|
-
groupId: 'MoreTools',
|
|
997
|
-
interactionType: 'toggle',
|
|
998
|
-
commands: [{
|
|
999
|
-
commandName: 'toggleCine',
|
|
1000
|
-
commandOptions: {},
|
|
1001
|
-
toolName: 'cine',
|
|
1002
|
-
context: 'CORNERSTONE'
|
|
1003
|
-
}]
|
|
1004
|
-
});
|
|
1005
|
-
};
|
|
1006
974
|
const cineHandler = () => {
|
|
1007
975
|
if (!cines || !cines[viewportId] || !enabledVPElement) {
|
|
1008
976
|
return;
|
|
@@ -1012,11 +980,11 @@ function WrappedCinePlayer(_ref) {
|
|
|
1012
980
|
const frameRate = cine.frameRate || 24;
|
|
1013
981
|
const validFrameRate = Math.max(frameRate, 1);
|
|
1014
982
|
if (isPlaying) {
|
|
1015
|
-
|
|
983
|
+
api.playClip(enabledVPElement, {
|
|
1016
984
|
framesPerSecond: validFrameRate
|
|
1017
985
|
});
|
|
1018
986
|
} else {
|
|
1019
|
-
|
|
987
|
+
api.stopClip(enabledVPElement);
|
|
1020
988
|
}
|
|
1021
989
|
};
|
|
1022
990
|
const newStackCineHandler = (0,react.useCallback)(() => {
|
|
@@ -1038,19 +1006,22 @@ function WrappedCinePlayer(_ref) {
|
|
|
1038
1006
|
}
|
|
1039
1007
|
});
|
|
1040
1008
|
if (isPlaying) {
|
|
1041
|
-
|
|
1009
|
+
api.setIsCineEnabled(isPlaying);
|
|
1042
1010
|
}
|
|
1043
|
-
|
|
1011
|
+
api.setCine({
|
|
1044
1012
|
id: viewportId,
|
|
1045
1013
|
isPlaying,
|
|
1046
1014
|
frameRate
|
|
1047
1015
|
});
|
|
1048
1016
|
setNewStackFrameRate(frameRate);
|
|
1049
|
-
}, [
|
|
1017
|
+
}, [displaySetService, viewportId, viewportGridService, cines]);
|
|
1050
1018
|
(0,react.useEffect)(() => {
|
|
1019
|
+
isMountedRef.current = true;
|
|
1051
1020
|
dist_esm.eventTarget.addEventListener(dist_esm.Enums.Events.STACK_VIEWPORT_NEW_STACK, newStackCineHandler);
|
|
1052
1021
|
return () => {
|
|
1053
|
-
|
|
1022
|
+
isMountedRef.current = false;
|
|
1023
|
+
api.stopClip(enabledVPElement);
|
|
1024
|
+
api.setCine({
|
|
1054
1025
|
id: viewportId,
|
|
1055
1026
|
isPlaying: false
|
|
1056
1027
|
});
|
|
@@ -1058,28 +1029,35 @@ function WrappedCinePlayer(_ref) {
|
|
|
1058
1029
|
};
|
|
1059
1030
|
}, [enabledVPElement, newStackCineHandler]);
|
|
1060
1031
|
(0,react.useEffect)(() => {
|
|
1061
|
-
if (!cines || !cines[viewportId] || !enabledVPElement) {
|
|
1032
|
+
if (!cines || !cines[viewportId] || !enabledVPElement || !isMountedRef.current) {
|
|
1062
1033
|
return;
|
|
1063
1034
|
}
|
|
1064
1035
|
cineHandler();
|
|
1065
1036
|
return () => {
|
|
1066
|
-
|
|
1067
|
-
cineService.stopClip(enabledVPElement);
|
|
1068
|
-
}
|
|
1037
|
+
api.stopClip(enabledVPElement);
|
|
1069
1038
|
};
|
|
1070
|
-
}, [cines, viewportId,
|
|
1039
|
+
}, [cines, viewportId, enabledVPElement, cineHandler]);
|
|
1071
1040
|
const cine = cines[viewportId];
|
|
1072
1041
|
const isPlaying = cine && cine.isPlaying || false;
|
|
1073
1042
|
return isCineEnabled && /*#__PURE__*/react.createElement(CinePlayerComponent, {
|
|
1074
1043
|
className: "absolute left-1/2 bottom-3 -translate-x-1/2",
|
|
1075
1044
|
frameRate: newStackFrameRate,
|
|
1076
1045
|
isPlaying: isPlaying,
|
|
1077
|
-
onClose:
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1046
|
+
onClose: () => {
|
|
1047
|
+
// also stop the clip
|
|
1048
|
+
api.setCine({
|
|
1049
|
+
id: viewportId,
|
|
1050
|
+
isPlaying: false
|
|
1051
|
+
});
|
|
1052
|
+
api.setIsCineEnabled(false);
|
|
1053
|
+
},
|
|
1054
|
+
onPlayPauseChange: isPlaying => {
|
|
1055
|
+
api.setCine({
|
|
1056
|
+
id: viewportId,
|
|
1057
|
+
isPlaying
|
|
1058
|
+
});
|
|
1059
|
+
},
|
|
1060
|
+
onFrameRateChange: frameRate => api.setCine({
|
|
1083
1061
|
id: viewportId,
|
|
1084
1062
|
frameRate
|
|
1085
1063
|
})
|
|
@@ -1089,6 +1067,908 @@ function WrappedCinePlayer(_ref) {
|
|
|
1089
1067
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/CinePlayer/index.ts
|
|
1090
1068
|
|
|
1091
1069
|
/* harmony default export */ const components_CinePlayer = (CinePlayer);
|
|
1070
|
+
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/contextProviders/ViewportActionCornersProvider.tsx
|
|
1071
|
+
var ViewportActionCornersProvider = __webpack_require__(76255);
|
|
1072
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/OHIFViewportActionCorners.tsx
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
function OHIFViewportActionCorners({
|
|
1077
|
+
viewportId
|
|
1078
|
+
}) {
|
|
1079
|
+
const [viewportActionCornersState] = (0,ViewportActionCornersProvider/* useViewportActionCornersContext */.R4)();
|
|
1080
|
+
if (!viewportActionCornersState[viewportId]) {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
return /*#__PURE__*/react.createElement(ui_src/* ViewportActionCorners */.R2, {
|
|
1084
|
+
cornerComponents: viewportActionCornersState[viewportId]
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
/* harmony default export */ const components_OHIFViewportActionCorners = (OHIFViewportActionCorners);
|
|
1088
|
+
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
1089
|
+
var es = __webpack_require__(80619);
|
|
1090
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
function Colormap({
|
|
1095
|
+
colormaps,
|
|
1096
|
+
viewportId,
|
|
1097
|
+
displaySets,
|
|
1098
|
+
commandsManager,
|
|
1099
|
+
serviceManager
|
|
1100
|
+
}) {
|
|
1101
|
+
const {
|
|
1102
|
+
cornerstoneViewportService
|
|
1103
|
+
} = serviceManager.services;
|
|
1104
|
+
const [activeDisplaySet, setActiveDisplaySet] = (0,react.useState)(displaySets[0]);
|
|
1105
|
+
const [showPreview, setShowPreview] = (0,react.useState)(false);
|
|
1106
|
+
const [prePreviewColormap, setPrePreviewColormap] = (0,react.useState)(null);
|
|
1107
|
+
const showPreviewRef = (0,react.useRef)(showPreview);
|
|
1108
|
+
showPreviewRef.current = showPreview;
|
|
1109
|
+
const prePreviewColormapRef = (0,react.useRef)(prePreviewColormap);
|
|
1110
|
+
prePreviewColormapRef.current = prePreviewColormap;
|
|
1111
|
+
const activeDisplaySetRef = (0,react.useRef)(activeDisplaySet);
|
|
1112
|
+
activeDisplaySetRef.current = activeDisplaySet;
|
|
1113
|
+
const onSetColorLUT = (0,react.useCallback)(props => {
|
|
1114
|
+
// TODO: Better way to check if it's a fusion
|
|
1115
|
+
const oneOpacityColormaps = ['Grayscale', 'X Ray'];
|
|
1116
|
+
const opacity = displaySets.length > 1 && !oneOpacityColormaps.includes(props.colormap.name) ? 0.5 : 1;
|
|
1117
|
+
commandsManager.run({
|
|
1118
|
+
commandName: 'setViewportColormap',
|
|
1119
|
+
commandOptions: {
|
|
1120
|
+
...props,
|
|
1121
|
+
opacity,
|
|
1122
|
+
immediate: true
|
|
1123
|
+
},
|
|
1124
|
+
context: 'CORNERSTONE'
|
|
1125
|
+
});
|
|
1126
|
+
}, [commandsManager]);
|
|
1127
|
+
const getViewportColormap = (viewportId, displaySet) => {
|
|
1128
|
+
const {
|
|
1129
|
+
displaySetInstanceUID
|
|
1130
|
+
} = displaySet;
|
|
1131
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1132
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1133
|
+
const {
|
|
1134
|
+
colormap
|
|
1135
|
+
} = viewport.getProperties();
|
|
1136
|
+
if (!colormap) {
|
|
1137
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1138
|
+
}
|
|
1139
|
+
return colormap;
|
|
1140
|
+
}
|
|
1141
|
+
const actorEntries = viewport.getActors();
|
|
1142
|
+
const actorEntry = actorEntries.find(entry => entry.uid.includes(displaySetInstanceUID));
|
|
1143
|
+
const {
|
|
1144
|
+
colormap
|
|
1145
|
+
} = viewport.getProperties(actorEntry.uid);
|
|
1146
|
+
if (!colormap) {
|
|
1147
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1148
|
+
}
|
|
1149
|
+
return colormap;
|
|
1150
|
+
};
|
|
1151
|
+
const buttons = (0,react.useMemo)(() => {
|
|
1152
|
+
return displaySets.map((displaySet, index) => ({
|
|
1153
|
+
children: displaySet.Modality,
|
|
1154
|
+
key: index,
|
|
1155
|
+
style: {
|
|
1156
|
+
minWidth: `calc(100% / ${displaySets.length})`
|
|
1157
|
+
}
|
|
1158
|
+
}));
|
|
1159
|
+
}, [displaySets]);
|
|
1160
|
+
(0,react.useEffect)(() => {
|
|
1161
|
+
setActiveDisplaySet(displaySets[displaySets.length - 1]);
|
|
1162
|
+
}, [displaySets]);
|
|
1163
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, buttons.length > 1 && /*#__PURE__*/react.createElement("div", {
|
|
1164
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1165
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ButtonGroup */.e2, {
|
|
1166
|
+
onActiveIndexChange: index => {
|
|
1167
|
+
setActiveDisplaySet(displaySets[index]);
|
|
1168
|
+
setPrePreviewColormap(null);
|
|
1169
|
+
},
|
|
1170
|
+
activeIndex: displaySets.findIndex(ds => ds.displaySetInstanceUID === activeDisplaySetRef.current.displaySetInstanceUID) || 1,
|
|
1171
|
+
className: "w-[70%] text-[10px]"
|
|
1172
|
+
}, buttons.map(({
|
|
1173
|
+
children,
|
|
1174
|
+
key,
|
|
1175
|
+
style
|
|
1176
|
+
}) => /*#__PURE__*/react.createElement("div", {
|
|
1177
|
+
key: key,
|
|
1178
|
+
style: style
|
|
1179
|
+
}, children)))), /*#__PURE__*/react.createElement("div", {
|
|
1180
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1181
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1182
|
+
label: "Preview in viewport",
|
|
1183
|
+
checked: showPreview,
|
|
1184
|
+
onChange: checked => {
|
|
1185
|
+
setShowPreview(checked);
|
|
1186
|
+
}
|
|
1187
|
+
})), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.DividerItem */.se.VG, null), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, colormaps.map((colormap, index) => /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1188
|
+
key: index,
|
|
1189
|
+
label: colormap.description,
|
|
1190
|
+
onClick: () => {
|
|
1191
|
+
onSetColorLUT({
|
|
1192
|
+
viewportId,
|
|
1193
|
+
colormap,
|
|
1194
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1195
|
+
});
|
|
1196
|
+
setPrePreviewColormap(null);
|
|
1197
|
+
},
|
|
1198
|
+
onMouseEnter: () => {
|
|
1199
|
+
if (showPreviewRef.current) {
|
|
1200
|
+
setPrePreviewColormap(getViewportColormap(viewportId, activeDisplaySetRef.current));
|
|
1201
|
+
onSetColorLUT({
|
|
1202
|
+
viewportId,
|
|
1203
|
+
colormap,
|
|
1204
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
},
|
|
1208
|
+
onMouseLeave: () => {
|
|
1209
|
+
if (showPreviewRef.current && prePreviewColormapRef.current) {
|
|
1210
|
+
onSetColorLUT({
|
|
1211
|
+
viewportId,
|
|
1212
|
+
colormap: prePreviewColormapRef.current,
|
|
1213
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}))));
|
|
1218
|
+
}
|
|
1219
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
function setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, colorbarOptions) {
|
|
1225
|
+
const {
|
|
1226
|
+
cornerstoneViewportService
|
|
1227
|
+
} = serviceManager.services;
|
|
1228
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1229
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1230
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1231
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1232
|
+
if (isLight) {
|
|
1233
|
+
colorbarOptions.ticks = {
|
|
1234
|
+
position: 'left',
|
|
1235
|
+
style: {
|
|
1236
|
+
font: '12px Arial',
|
|
1237
|
+
color: '#000000',
|
|
1238
|
+
maxNumTicks: 8,
|
|
1239
|
+
tickSize: 5,
|
|
1240
|
+
tickWidth: 1,
|
|
1241
|
+
labelMargin: 3
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
const displaySetInstanceUIDs = [];
|
|
1246
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1247
|
+
displaySetInstanceUIDs.push(viewportId);
|
|
1248
|
+
}
|
|
1249
|
+
if (viewport instanceof dist_esm.VolumeViewport) {
|
|
1250
|
+
displaySets.forEach(ds => {
|
|
1251
|
+
displaySetInstanceUIDs.push(ds.displaySetInstanceUID);
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
commandsManager.run({
|
|
1255
|
+
commandName: 'toggleViewportColorbar',
|
|
1256
|
+
commandOptions: {
|
|
1257
|
+
viewportId,
|
|
1258
|
+
options: colorbarOptions,
|
|
1259
|
+
displaySetInstanceUIDs
|
|
1260
|
+
},
|
|
1261
|
+
context: 'CORNERSTONE'
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
function Colorbar({
|
|
1265
|
+
viewportId,
|
|
1266
|
+
displaySets,
|
|
1267
|
+
commandsManager,
|
|
1268
|
+
serviceManager,
|
|
1269
|
+
colorbarProperties
|
|
1270
|
+
}) {
|
|
1271
|
+
const {
|
|
1272
|
+
colorbarService
|
|
1273
|
+
} = serviceManager.services;
|
|
1274
|
+
const {
|
|
1275
|
+
width: colorbarWidth,
|
|
1276
|
+
colorbarTickPosition,
|
|
1277
|
+
colorbarContainerPosition,
|
|
1278
|
+
colormaps,
|
|
1279
|
+
colorbarInitialColormap
|
|
1280
|
+
} = colorbarProperties;
|
|
1281
|
+
const [showColorbar, setShowColorbar] = (0,react.useState)(colorbarService.hasColorbar(viewportId));
|
|
1282
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1283
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1284
|
+
viewportId,
|
|
1285
|
+
colormaps,
|
|
1286
|
+
ticks: {
|
|
1287
|
+
position: colorbarTickPosition
|
|
1288
|
+
},
|
|
1289
|
+
width: colorbarWidth,
|
|
1290
|
+
position: colorbarContainerPosition,
|
|
1291
|
+
activeColormapName: colorbarInitialColormap
|
|
1292
|
+
});
|
|
1293
|
+
}, [commandsManager]);
|
|
1294
|
+
(0,react.useEffect)(() => {
|
|
1295
|
+
const updateColorbarState = () => {
|
|
1296
|
+
setShowColorbar(colorbarService.hasColorbar(viewportId));
|
|
1297
|
+
};
|
|
1298
|
+
const {
|
|
1299
|
+
unsubscribe
|
|
1300
|
+
} = colorbarService.subscribe(colorbarService.EVENTS.STATE_CHANGED, updateColorbarState);
|
|
1301
|
+
return () => {
|
|
1302
|
+
unsubscribe();
|
|
1303
|
+
};
|
|
1304
|
+
}, [viewportId]);
|
|
1305
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1306
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1307
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1308
|
+
label: "Display Color bar",
|
|
1309
|
+
checked: showColorbar,
|
|
1310
|
+
onChange: () => {
|
|
1311
|
+
onSetColorbar();
|
|
1312
|
+
}
|
|
1313
|
+
}));
|
|
1314
|
+
}
|
|
1315
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevel.tsx
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
function WindowLevel({
|
|
1320
|
+
viewportId,
|
|
1321
|
+
commandsManager,
|
|
1322
|
+
presets
|
|
1323
|
+
}) {
|
|
1324
|
+
const {
|
|
1325
|
+
t
|
|
1326
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1327
|
+
const onSetWindowLevel = (0,react.useCallback)(props => {
|
|
1328
|
+
commandsManager.run({
|
|
1329
|
+
commandName: 'setViewportWindowLevel',
|
|
1330
|
+
commandOptions: {
|
|
1331
|
+
...props
|
|
1332
|
+
},
|
|
1333
|
+
context: 'CORNERSTONE'
|
|
1334
|
+
});
|
|
1335
|
+
}, [commandsManager]);
|
|
1336
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.HeaderItem */.se.N5, null, t('Modality Presets', {
|
|
1337
|
+
modality: Object.keys(presets)[0]
|
|
1338
|
+
})), Object.values(presets)[0].map((preset, index) => /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1339
|
+
key: index,
|
|
1340
|
+
label: preset.description,
|
|
1341
|
+
secondaryLabel: `${preset.window} / ${preset.level}`,
|
|
1342
|
+
onClick: () => onSetWindowLevel({
|
|
1343
|
+
...preset,
|
|
1344
|
+
viewportId
|
|
1345
|
+
})
|
|
1346
|
+
})));
|
|
1347
|
+
}
|
|
1348
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresetsContent.tsx
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
function VolumeRenderingPresetsContent({
|
|
1354
|
+
presets,
|
|
1355
|
+
viewportId,
|
|
1356
|
+
commandsManager,
|
|
1357
|
+
onClose
|
|
1358
|
+
}) {
|
|
1359
|
+
const [filteredPresets, setFilteredPresets] = (0,react.useState)(presets);
|
|
1360
|
+
const [searchValue, setSearchValue] = (0,react.useState)('');
|
|
1361
|
+
const [selectedPreset, setSelectedPreset] = (0,react.useState)(null);
|
|
1362
|
+
const handleSearchChange = (0,react.useCallback)(value => {
|
|
1363
|
+
setSearchValue(value);
|
|
1364
|
+
const filtered = value ? presets.filter(preset => preset.name.toLowerCase().includes(value.toLowerCase())) : presets;
|
|
1365
|
+
setFilteredPresets(filtered);
|
|
1366
|
+
}, [presets]);
|
|
1367
|
+
const handleApply = (0,react.useCallback)(props => {
|
|
1368
|
+
commandsManager.runCommand('setViewportPreset', {
|
|
1369
|
+
...props
|
|
1370
|
+
});
|
|
1371
|
+
}, [commandsManager]);
|
|
1372
|
+
const formatLabel = (label, maxChars) => {
|
|
1373
|
+
return label.length > maxChars ? `${label.slice(0, maxChars)}...` : label;
|
|
1374
|
+
};
|
|
1375
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1376
|
+
className: "flex min-h-full w-full flex-col justify-between"
|
|
1377
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1378
|
+
className: "border-secondary-light h-[433px] w-full overflow-hidden rounded border bg-black px-2.5"
|
|
1379
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1380
|
+
className: "flex h-[46px] w-full items-center justify-start"
|
|
1381
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1382
|
+
className: "h-[26px] w-[200px]"
|
|
1383
|
+
}, /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.Cv, {
|
|
1384
|
+
value: searchValue,
|
|
1385
|
+
onDebounceChange: handleSearchChange,
|
|
1386
|
+
placeholder: 'Search all'
|
|
1387
|
+
}))), /*#__PURE__*/react.createElement("div", {
|
|
1388
|
+
className: "ohif-scrollbar overflow h-[385px] w-full overflow-y-auto"
|
|
1389
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1390
|
+
className: "grid grid-cols-4 gap-3 pt-2 pr-3"
|
|
1391
|
+
}, filteredPresets.map((preset, index) => /*#__PURE__*/react.createElement("div", {
|
|
1392
|
+
key: index,
|
|
1393
|
+
className: "flex cursor-pointer flex-col items-start",
|
|
1394
|
+
onClick: () => {
|
|
1395
|
+
setSelectedPreset(preset);
|
|
1396
|
+
handleApply({
|
|
1397
|
+
preset: preset.name,
|
|
1398
|
+
viewportId
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1402
|
+
name: preset.name,
|
|
1403
|
+
className: selectedPreset?.name === preset.name ? 'border-primary-light h-[75px] w-[95px] max-w-none rounded border-2' : 'hover:border-primary-light h-[75px] w-[95px] max-w-none rounded border-2 border-black'
|
|
1404
|
+
}), /*#__PURE__*/react.createElement("label", {
|
|
1405
|
+
className: "text-aqua-pale mt-2 text-left text-xs"
|
|
1406
|
+
}, formatLabel(preset.name, 11))))))), /*#__PURE__*/react.createElement("footer", {
|
|
1407
|
+
className: "flex h-[60px] w-full items-center justify-end"
|
|
1408
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1409
|
+
className: "flex"
|
|
1410
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Button */.$n, {
|
|
1411
|
+
name: "Cancel",
|
|
1412
|
+
size: ui_src/* ButtonEnums.size */.Ny.Ej.medium,
|
|
1413
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.secondary,
|
|
1414
|
+
onClick: onClose
|
|
1415
|
+
}, ' ', "Cancel", ' '))));
|
|
1416
|
+
}
|
|
1417
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
function VolumeRenderingPresets({
|
|
1422
|
+
viewportId,
|
|
1423
|
+
serviceManager,
|
|
1424
|
+
commandsManager,
|
|
1425
|
+
volumeRenderingPresets
|
|
1426
|
+
}) {
|
|
1427
|
+
const {
|
|
1428
|
+
uiModalService
|
|
1429
|
+
} = serviceManager.services;
|
|
1430
|
+
const onClickPresets = () => {
|
|
1431
|
+
uiModalService.show({
|
|
1432
|
+
content: VolumeRenderingPresetsContent,
|
|
1433
|
+
title: 'Rendering Presets',
|
|
1434
|
+
movable: true,
|
|
1435
|
+
contentProps: {
|
|
1436
|
+
onClose: uiModalService.hide,
|
|
1437
|
+
presets: volumeRenderingPresets,
|
|
1438
|
+
viewportId,
|
|
1439
|
+
commandsManager
|
|
1440
|
+
},
|
|
1441
|
+
containerDimensions: 'h-[543px] w-[460px]',
|
|
1442
|
+
contentDimensions: 'h-[493px] w-[460px] pl-[12px]'
|
|
1443
|
+
});
|
|
1444
|
+
};
|
|
1445
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1446
|
+
label: "Rendering Presets",
|
|
1447
|
+
icon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1448
|
+
name: "VolumeRendering"
|
|
1449
|
+
}),
|
|
1450
|
+
rightIcon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1451
|
+
name: "action-new-dialog"
|
|
1452
|
+
}),
|
|
1453
|
+
onClick: onClickPresets
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx
|
|
1457
|
+
|
|
1458
|
+
function VolumeRenderingQuality({
|
|
1459
|
+
volumeRenderingQualityRange,
|
|
1460
|
+
commandsManager,
|
|
1461
|
+
serviceManager,
|
|
1462
|
+
viewportId
|
|
1463
|
+
}) {
|
|
1464
|
+
const {
|
|
1465
|
+
cornerstoneViewportService
|
|
1466
|
+
} = serviceManager.services;
|
|
1467
|
+
const {
|
|
1468
|
+
min,
|
|
1469
|
+
max,
|
|
1470
|
+
step
|
|
1471
|
+
} = volumeRenderingQualityRange;
|
|
1472
|
+
const [quality, setQuality] = (0,react.useState)(null);
|
|
1473
|
+
const onChange = (0,react.useCallback)(value => {
|
|
1474
|
+
commandsManager.runCommand('setVolumeRenderingQulaity', {
|
|
1475
|
+
viewportId,
|
|
1476
|
+
volumeQuality: value
|
|
1477
|
+
});
|
|
1478
|
+
setQuality(value);
|
|
1479
|
+
}, [commandsManager, viewportId]);
|
|
1480
|
+
const calculateBackground = value => {
|
|
1481
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1482
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1483
|
+
};
|
|
1484
|
+
(0,react.useEffect)(() => {
|
|
1485
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1486
|
+
const {
|
|
1487
|
+
actor
|
|
1488
|
+
} = viewport.getActors()[0];
|
|
1489
|
+
const mapper = actor.getMapper();
|
|
1490
|
+
const image = mapper.getInputData();
|
|
1491
|
+
const spacing = image.getSpacing();
|
|
1492
|
+
const sampleDistance = mapper.getSampleDistance();
|
|
1493
|
+
const averageSpacing = spacing.reduce((a, b) => a + b) / 3.0;
|
|
1494
|
+
if (sampleDistance === averageSpacing) {
|
|
1495
|
+
setQuality(1);
|
|
1496
|
+
} else {
|
|
1497
|
+
setQuality(Math.sqrt(averageSpacing / (sampleDistance * 0.5)));
|
|
1498
|
+
}
|
|
1499
|
+
}, [cornerstoneViewportService, viewportId]);
|
|
1500
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1501
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1502
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1503
|
+
className: "block text-white",
|
|
1504
|
+
htmlFor: "volume"
|
|
1505
|
+
}, "Quality"), quality !== null && /*#__PURE__*/react.createElement("input", {
|
|
1506
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1507
|
+
value: quality,
|
|
1508
|
+
id: "volume",
|
|
1509
|
+
max: max,
|
|
1510
|
+
min: min,
|
|
1511
|
+
type: "range",
|
|
1512
|
+
step: step,
|
|
1513
|
+
onChange: e => onChange(parseInt(e.target.value, 10)),
|
|
1514
|
+
style: {
|
|
1515
|
+
background: calculateBackground((quality - min) / (max - min))
|
|
1516
|
+
}
|
|
1517
|
+
})));
|
|
1518
|
+
}
|
|
1519
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx
|
|
1520
|
+
|
|
1521
|
+
function VolumeShift({
|
|
1522
|
+
viewportId,
|
|
1523
|
+
commandsManager,
|
|
1524
|
+
serviceManager
|
|
1525
|
+
}) {
|
|
1526
|
+
const {
|
|
1527
|
+
cornerstoneViewportService
|
|
1528
|
+
} = serviceManager.services;
|
|
1529
|
+
const [minShift, setMinShift] = (0,react.useState)(null);
|
|
1530
|
+
const [maxShift, setMaxShift] = (0,react.useState)(null);
|
|
1531
|
+
const [shift, setShift] = (0,react.useState)(cornerstoneViewportService.getCornerstoneViewport(viewportId)?.shiftedBy || 0);
|
|
1532
|
+
const [step, setStep] = (0,react.useState)(null);
|
|
1533
|
+
const [isBlocking, setIsBlocking] = (0,react.useState)(false);
|
|
1534
|
+
const prevShiftRef = (0,react.useRef)(shift);
|
|
1535
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1536
|
+
const {
|
|
1537
|
+
actor
|
|
1538
|
+
} = viewport.getActors()[0];
|
|
1539
|
+
const ofun = actor.getProperty().getScalarOpacity(0);
|
|
1540
|
+
(0,react.useEffect)(() => {
|
|
1541
|
+
if (isBlocking) {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
const range = ofun.getRange();
|
|
1545
|
+
const transferFunctionWidth = range[1] - range[0];
|
|
1546
|
+
const minShift = -transferFunctionWidth;
|
|
1547
|
+
const maxShift = transferFunctionWidth;
|
|
1548
|
+
setMinShift(minShift);
|
|
1549
|
+
setMaxShift(maxShift);
|
|
1550
|
+
setStep(Math.pow(10, Math.floor(Math.log10(transferFunctionWidth / 500))));
|
|
1551
|
+
}, [cornerstoneViewportService, viewportId, actor, ofun, isBlocking]);
|
|
1552
|
+
const onChangeRange = (0,react.useCallback)(newShift => {
|
|
1553
|
+
const shiftDifference = newShift - prevShiftRef.current;
|
|
1554
|
+
prevShiftRef.current = newShift;
|
|
1555
|
+
viewport.shiftedBy = newShift;
|
|
1556
|
+
commandsManager.runCommand('shiftVolumeOpacityPoints', {
|
|
1557
|
+
viewportId,
|
|
1558
|
+
shift: shiftDifference
|
|
1559
|
+
});
|
|
1560
|
+
}, [commandsManager, viewportId, viewport]);
|
|
1561
|
+
const calculateBackground = value => {
|
|
1562
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1563
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1564
|
+
};
|
|
1565
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1566
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1567
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1568
|
+
className: "block text-white",
|
|
1569
|
+
htmlFor: "shift"
|
|
1570
|
+
}, "Shift"), step !== null && /*#__PURE__*/react.createElement("input", {
|
|
1571
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1572
|
+
value: shift,
|
|
1573
|
+
onChange: e => {
|
|
1574
|
+
const shiftValue = parseInt(e.target.value, 10);
|
|
1575
|
+
setShift(shiftValue);
|
|
1576
|
+
onChangeRange(shiftValue);
|
|
1577
|
+
},
|
|
1578
|
+
id: "shift",
|
|
1579
|
+
onMouseDown: () => setIsBlocking(true),
|
|
1580
|
+
onMouseUp: () => setIsBlocking(false),
|
|
1581
|
+
max: maxShift,
|
|
1582
|
+
min: minShift,
|
|
1583
|
+
type: "range",
|
|
1584
|
+
step: step,
|
|
1585
|
+
style: {
|
|
1586
|
+
background: calculateBackground((shift - minShift) / (maxShift - minShift))
|
|
1587
|
+
}
|
|
1588
|
+
})));
|
|
1589
|
+
}
|
|
1590
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx
|
|
1591
|
+
|
|
1592
|
+
function VolumeLighting({
|
|
1593
|
+
serviceManager,
|
|
1594
|
+
commandsManager,
|
|
1595
|
+
viewportId
|
|
1596
|
+
}) {
|
|
1597
|
+
const {
|
|
1598
|
+
cornerstoneViewportService
|
|
1599
|
+
} = serviceManager.services;
|
|
1600
|
+
const [ambient, setAmbient] = (0,react.useState)(null);
|
|
1601
|
+
const [diffuse, setDiffuse] = (0,react.useState)(null);
|
|
1602
|
+
const [specular, setSpecular] = (0,react.useState)(null);
|
|
1603
|
+
const onAmbientChange = (0,react.useCallback)(() => {
|
|
1604
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1605
|
+
viewportId,
|
|
1606
|
+
options: {
|
|
1607
|
+
ambient
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1610
|
+
}, [ambient, commandsManager, viewportId]);
|
|
1611
|
+
const onDiffuseChange = (0,react.useCallback)(() => {
|
|
1612
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1613
|
+
viewportId,
|
|
1614
|
+
options: {
|
|
1615
|
+
diffuse
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
}, [diffuse, commandsManager, viewportId]);
|
|
1619
|
+
const onSpecularChange = (0,react.useCallback)(() => {
|
|
1620
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1621
|
+
viewportId,
|
|
1622
|
+
options: {
|
|
1623
|
+
specular
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
}, [specular, commandsManager, viewportId]);
|
|
1627
|
+
const calculateBackground = value => {
|
|
1628
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1629
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1630
|
+
};
|
|
1631
|
+
(0,react.useEffect)(() => {
|
|
1632
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1633
|
+
const {
|
|
1634
|
+
actor
|
|
1635
|
+
} = viewport.getActors()[0];
|
|
1636
|
+
const ambient = actor.getProperty().getAmbient();
|
|
1637
|
+
const diffuse = actor.getProperty().getDiffuse();
|
|
1638
|
+
const specular = actor.getProperty().getSpecular();
|
|
1639
|
+
setAmbient(ambient);
|
|
1640
|
+
setDiffuse(diffuse);
|
|
1641
|
+
setSpecular(specular);
|
|
1642
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1643
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1644
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1645
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1646
|
+
className: "block text-white",
|
|
1647
|
+
htmlFor: "ambient"
|
|
1648
|
+
}, "Ambient"), ambient !== null && /*#__PURE__*/react.createElement("input", {
|
|
1649
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1650
|
+
value: ambient,
|
|
1651
|
+
onChange: e => {
|
|
1652
|
+
setAmbient(e.target.value);
|
|
1653
|
+
onAmbientChange();
|
|
1654
|
+
},
|
|
1655
|
+
id: "ambient",
|
|
1656
|
+
max: 1,
|
|
1657
|
+
min: 0,
|
|
1658
|
+
type: "range",
|
|
1659
|
+
step: 0.1,
|
|
1660
|
+
style: {
|
|
1661
|
+
background: calculateBackground(ambient)
|
|
1662
|
+
}
|
|
1663
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1664
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1665
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1666
|
+
className: "block text-white",
|
|
1667
|
+
htmlFor: "diffuse"
|
|
1668
|
+
}, "Diffuse"), diffuse !== null && /*#__PURE__*/react.createElement("input", {
|
|
1669
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1670
|
+
value: diffuse,
|
|
1671
|
+
onChange: e => {
|
|
1672
|
+
setDiffuse(e.target.value);
|
|
1673
|
+
onDiffuseChange();
|
|
1674
|
+
},
|
|
1675
|
+
id: "diffuse",
|
|
1676
|
+
max: 1,
|
|
1677
|
+
min: 0,
|
|
1678
|
+
type: "range",
|
|
1679
|
+
step: 0.1,
|
|
1680
|
+
style: {
|
|
1681
|
+
background: calculateBackground(diffuse)
|
|
1682
|
+
}
|
|
1683
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1684
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1685
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1686
|
+
className: "block text-white",
|
|
1687
|
+
htmlFor: "specular"
|
|
1688
|
+
}, "Specular"), specular !== null && /*#__PURE__*/react.createElement("input", {
|
|
1689
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1690
|
+
value: specular,
|
|
1691
|
+
onChange: e => {
|
|
1692
|
+
setSpecular(e.target.value);
|
|
1693
|
+
onSpecularChange();
|
|
1694
|
+
},
|
|
1695
|
+
id: "specular",
|
|
1696
|
+
max: 1,
|
|
1697
|
+
min: 0,
|
|
1698
|
+
type: "range",
|
|
1699
|
+
step: 0.1,
|
|
1700
|
+
style: {
|
|
1701
|
+
background: calculateBackground(specular)
|
|
1702
|
+
}
|
|
1703
|
+
})));
|
|
1704
|
+
}
|
|
1705
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
function VolumeShade({
|
|
1709
|
+
commandsManager,
|
|
1710
|
+
viewportId,
|
|
1711
|
+
serviceManager
|
|
1712
|
+
}) {
|
|
1713
|
+
const {
|
|
1714
|
+
cornerstoneViewportService
|
|
1715
|
+
} = serviceManager.services;
|
|
1716
|
+
const [shade, setShade] = (0,react.useState)(true);
|
|
1717
|
+
const [key, setKey] = (0,react.useState)(0);
|
|
1718
|
+
const onShadeChange = (0,react.useCallback)(checked => {
|
|
1719
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1720
|
+
viewportId,
|
|
1721
|
+
options: {
|
|
1722
|
+
shade: checked
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
}, [commandsManager, viewportId]);
|
|
1726
|
+
(0,react.useEffect)(() => {
|
|
1727
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1728
|
+
const {
|
|
1729
|
+
actor
|
|
1730
|
+
} = viewport.getActors()[0];
|
|
1731
|
+
const shade = actor.getProperty().getShade();
|
|
1732
|
+
setShade(shade);
|
|
1733
|
+
setKey(key + 1);
|
|
1734
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1735
|
+
return /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1736
|
+
key: key,
|
|
1737
|
+
label: "Shade",
|
|
1738
|
+
checked: shade,
|
|
1739
|
+
onChange: () => {
|
|
1740
|
+
setShade(!shade);
|
|
1741
|
+
onShadeChange(!shade);
|
|
1742
|
+
}
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
function VolumeRenderingOptions({
|
|
1753
|
+
viewportId,
|
|
1754
|
+
commandsManager,
|
|
1755
|
+
volumeRenderingQualityRange,
|
|
1756
|
+
serviceManager
|
|
1757
|
+
}) {
|
|
1758
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(VolumeRenderingQuality, {
|
|
1759
|
+
viewportId: viewportId,
|
|
1760
|
+
commandsManager: commandsManager,
|
|
1761
|
+
serviceManager: serviceManager,
|
|
1762
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1763
|
+
}), /*#__PURE__*/react.createElement(VolumeShift, {
|
|
1764
|
+
viewportId: viewportId,
|
|
1765
|
+
commandsManager: commandsManager,
|
|
1766
|
+
serviceManager: serviceManager
|
|
1767
|
+
}), /*#__PURE__*/react.createElement("div", {
|
|
1768
|
+
className: "all-in-one-menu-item flex w-full justify-start"
|
|
1769
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1770
|
+
className: "text-aqua-pale text-[13px]"
|
|
1771
|
+
}, "LIGHTING")), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.DividerItem */.se.VG, null), /*#__PURE__*/react.createElement("div", {
|
|
1772
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1773
|
+
}, /*#__PURE__*/react.createElement(VolumeShade, {
|
|
1774
|
+
commandsManager: commandsManager,
|
|
1775
|
+
serviceManager: serviceManager,
|
|
1776
|
+
viewportId: viewportId
|
|
1777
|
+
})), /*#__PURE__*/react.createElement(VolumeLighting, {
|
|
1778
|
+
viewportId: viewportId,
|
|
1779
|
+
commandsManager: commandsManager,
|
|
1780
|
+
serviceManager: serviceManager
|
|
1781
|
+
}));
|
|
1782
|
+
}
|
|
1783
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
function WindowLevelActionMenu({
|
|
1797
|
+
viewportId,
|
|
1798
|
+
element,
|
|
1799
|
+
presets,
|
|
1800
|
+
verticalDirection,
|
|
1801
|
+
horizontalDirection,
|
|
1802
|
+
commandsManager,
|
|
1803
|
+
serviceManager,
|
|
1804
|
+
colorbarProperties,
|
|
1805
|
+
displaySets,
|
|
1806
|
+
volumeRenderingPresets,
|
|
1807
|
+
volumeRenderingQualityRange
|
|
1808
|
+
}) {
|
|
1809
|
+
const {
|
|
1810
|
+
colormaps,
|
|
1811
|
+
colorbarContainerPosition,
|
|
1812
|
+
colorbarInitialColormap,
|
|
1813
|
+
colorbarTickPosition,
|
|
1814
|
+
width: colorbarWidth
|
|
1815
|
+
} = colorbarProperties;
|
|
1816
|
+
const {
|
|
1817
|
+
colorbarService,
|
|
1818
|
+
cornerstoneViewportService
|
|
1819
|
+
} = serviceManager.services;
|
|
1820
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1821
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1822
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1823
|
+
const nonImageModalities = ['SR', 'SEG', 'SM', 'RTSTRUCT', 'RTPLAN', 'RTDOSE'];
|
|
1824
|
+
const {
|
|
1825
|
+
t
|
|
1826
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1827
|
+
const [viewportGrid] = (0,ui_src/* useViewportGrid */.ih)();
|
|
1828
|
+
const {
|
|
1829
|
+
activeViewportId
|
|
1830
|
+
} = viewportGrid;
|
|
1831
|
+
const [vpHeight, setVpHeight] = (0,react.useState)(element?.clientHeight);
|
|
1832
|
+
const [menuKey, setMenuKey] = (0,react.useState)(0);
|
|
1833
|
+
const [is3DVolume, setIs3DVolume] = (0,react.useState)(false);
|
|
1834
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1835
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1836
|
+
colormaps,
|
|
1837
|
+
ticks: {
|
|
1838
|
+
position: colorbarTickPosition
|
|
1839
|
+
},
|
|
1840
|
+
width: colorbarWidth,
|
|
1841
|
+
position: colorbarContainerPosition,
|
|
1842
|
+
activeColormapName: colorbarInitialColormap
|
|
1843
|
+
});
|
|
1844
|
+
}, [commandsManager]);
|
|
1845
|
+
(0,react.useEffect)(() => {
|
|
1846
|
+
const newVpHeight = element?.clientHeight;
|
|
1847
|
+
if (vpHeight !== newVpHeight) {
|
|
1848
|
+
setVpHeight(newVpHeight);
|
|
1849
|
+
}
|
|
1850
|
+
}, [element, vpHeight]);
|
|
1851
|
+
(0,react.useEffect)(() => {
|
|
1852
|
+
if (!colorbarService.hasColorbar(viewportId)) {
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1855
|
+
window.setTimeout(() => {
|
|
1856
|
+
colorbarService.removeColorbar(viewportId);
|
|
1857
|
+
onSetColorbar();
|
|
1858
|
+
}, 0);
|
|
1859
|
+
}, [viewportId]);
|
|
1860
|
+
(0,react.useEffect)(() => {
|
|
1861
|
+
if (colorbarService.hasColorbar(viewportId)) {
|
|
1862
|
+
colorbarService.removeColorbar(viewportId);
|
|
1863
|
+
}
|
|
1864
|
+
}, [displaySets]);
|
|
1865
|
+
(0,react.useEffect)(() => {
|
|
1866
|
+
setMenuKey(menuKey + 1);
|
|
1867
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1868
|
+
if (viewport instanceof dist_esm.VolumeViewport3D) {
|
|
1869
|
+
setIs3DVolume(true);
|
|
1870
|
+
} else {
|
|
1871
|
+
setIs3DVolume(false);
|
|
1872
|
+
}
|
|
1873
|
+
}, [displaySets, viewportId, presets, volumeRenderingQualityRange, volumeRenderingPresets, colorbarProperties, activeViewportId, viewportGrid]);
|
|
1874
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.IconMenu */.se.dd, {
|
|
1875
|
+
icon: "viewport-window-level",
|
|
1876
|
+
verticalDirection: verticalDirection,
|
|
1877
|
+
horizontalDirection: horizontalDirection,
|
|
1878
|
+
iconClassName: classnames_default()(
|
|
1879
|
+
// Visible on hover and for the active viewport
|
|
1880
|
+
activeViewportId === viewportId ? 'visible' : 'invisible group-hover:visible', 'flex shrink-0 cursor-pointer rounded active:text-white', isLight ? 'text-aqua-pale hover:bg-secondary-dark' : 'text-primary-light hover:bg-secondary-light/60'),
|
|
1881
|
+
menuStyle: {
|
|
1882
|
+
maxHeight: vpHeight - 32,
|
|
1883
|
+
minWidth: 218
|
|
1884
|
+
},
|
|
1885
|
+
onVisibilityChange: () => {
|
|
1886
|
+
setVpHeight(element.clientHeight);
|
|
1887
|
+
},
|
|
1888
|
+
menuKey: menuKey
|
|
1889
|
+
}, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, !is3DVolume && /*#__PURE__*/react.createElement(Colorbar, {
|
|
1890
|
+
viewportId: viewportId,
|
|
1891
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1892
|
+
commandsManager: commandsManager,
|
|
1893
|
+
serviceManager: serviceManager,
|
|
1894
|
+
colorbarProperties: colorbarProperties
|
|
1895
|
+
}), colormaps && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1896
|
+
key: "colorLUTPresets",
|
|
1897
|
+
itemLabel: "Color LUT",
|
|
1898
|
+
itemIcon: "icon-color-lut"
|
|
1899
|
+
}, /*#__PURE__*/react.createElement(Colormap, {
|
|
1900
|
+
colormaps: colormaps,
|
|
1901
|
+
viewportId: viewportId,
|
|
1902
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1903
|
+
commandsManager: commandsManager,
|
|
1904
|
+
serviceManager: serviceManager
|
|
1905
|
+
})), presets && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1906
|
+
key: "windowLevelPresets",
|
|
1907
|
+
itemLabel: t('Modality Window Presets', {
|
|
1908
|
+
modality: Object.keys(presets)[0]
|
|
1909
|
+
}),
|
|
1910
|
+
itemIcon: "viewport-window-level"
|
|
1911
|
+
}, /*#__PURE__*/react.createElement(WindowLevel, {
|
|
1912
|
+
viewportId: viewportId,
|
|
1913
|
+
commandsManager: commandsManager,
|
|
1914
|
+
presets: presets
|
|
1915
|
+
})), volumeRenderingPresets && is3DVolume && /*#__PURE__*/react.createElement(VolumeRenderingPresets, {
|
|
1916
|
+
serviceManager: serviceManager,
|
|
1917
|
+
viewportId: viewportId,
|
|
1918
|
+
commandsManager: commandsManager,
|
|
1919
|
+
volumeRenderingPresets: volumeRenderingPresets
|
|
1920
|
+
}), volumeRenderingQualityRange && is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1921
|
+
itemLabel: "Rendering Options"
|
|
1922
|
+
}, /*#__PURE__*/react.createElement(VolumeRenderingOptions, {
|
|
1923
|
+
viewportId: viewportId,
|
|
1924
|
+
commandsManager: commandsManager,
|
|
1925
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange,
|
|
1926
|
+
serviceManager: serviceManager
|
|
1927
|
+
}))));
|
|
1928
|
+
}
|
|
1929
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
function getWindowLevelActionMenu({
|
|
1933
|
+
viewportId,
|
|
1934
|
+
element,
|
|
1935
|
+
displaySets,
|
|
1936
|
+
servicesManager,
|
|
1937
|
+
commandsManager,
|
|
1938
|
+
verticalDirection,
|
|
1939
|
+
horizontalDirection
|
|
1940
|
+
}) {
|
|
1941
|
+
const {
|
|
1942
|
+
customizationService
|
|
1943
|
+
} = servicesManager.services;
|
|
1944
|
+
const {
|
|
1945
|
+
presets
|
|
1946
|
+
} = customizationService.get('cornerstone.windowLevelPresets');
|
|
1947
|
+
const colorbarProperties = customizationService.get('cornerstone.colorbar');
|
|
1948
|
+
const {
|
|
1949
|
+
volumeRenderingPresets,
|
|
1950
|
+
volumeRenderingQualityRange
|
|
1951
|
+
} = customizationService.get('cornerstone.3dVolumeRendering');
|
|
1952
|
+
const displaySetPresets = displaySets.filter(displaySet => presets[displaySet.Modality]).map(displaySet => {
|
|
1953
|
+
return {
|
|
1954
|
+
[displaySet.Modality]: presets[displaySet.Modality]
|
|
1955
|
+
};
|
|
1956
|
+
});
|
|
1957
|
+
const hasMenu = displaySetPresets.length > 0;
|
|
1958
|
+
return hasMenu ? /*#__PURE__*/react.createElement(WindowLevelActionMenu, {
|
|
1959
|
+
viewportId: viewportId,
|
|
1960
|
+
element: element,
|
|
1961
|
+
presets: displaySetPresets[0],
|
|
1962
|
+
verticalDirection: verticalDirection,
|
|
1963
|
+
horizontalDirection: horizontalDirection,
|
|
1964
|
+
commandsManager: commandsManager,
|
|
1965
|
+
serviceManager: servicesManager,
|
|
1966
|
+
colorbarProperties: colorbarProperties,
|
|
1967
|
+
displaySets: displaySets,
|
|
1968
|
+
volumeRenderingPresets: volumeRenderingPresets,
|
|
1969
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1970
|
+
}) : null;
|
|
1971
|
+
}
|
|
1092
1972
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
|
|
1093
1973
|
|
|
1094
1974
|
|
|
@@ -1102,6 +1982,9 @@ function WrappedCinePlayer(_ref) {
|
|
|
1102
1982
|
|
|
1103
1983
|
|
|
1104
1984
|
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1105
1988
|
const STACK = 'stack';
|
|
1106
1989
|
|
|
1107
1990
|
/**
|
|
@@ -1166,19 +2049,20 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1166
2049
|
viewportOptions,
|
|
1167
2050
|
displaySetOptions,
|
|
1168
2051
|
servicesManager,
|
|
1169
|
-
commandsManager,
|
|
1170
2052
|
onElementEnabled,
|
|
1171
2053
|
onElementDisabled,
|
|
1172
2054
|
isJumpToMeasurementDisabled,
|
|
1173
2055
|
// Note: you SHOULD NOT use the initialImageIdOrIndex for manipulation
|
|
1174
2056
|
// of the imageData in the OHIFCornerstoneViewport. This prop is used
|
|
1175
2057
|
// to set the initial state of the viewport's first image to render
|
|
1176
|
-
initialImageIndex
|
|
2058
|
+
initialImageIndex,
|
|
2059
|
+
onReady
|
|
1177
2060
|
} = props;
|
|
1178
2061
|
const viewportId = viewportOptions.viewportId;
|
|
1179
2062
|
const [scrollbarHeight, setScrollbarHeight] = (0,react.useState)('100px');
|
|
1180
2063
|
const [enabledVPElement, setEnabledVPElement] = (0,react.useState)(null);
|
|
1181
2064
|
const elementRef = (0,react.useRef)();
|
|
2065
|
+
const [appConfig] = (0,state_0/* useAppConfig */.r)();
|
|
1182
2066
|
const {
|
|
1183
2067
|
measurementService,
|
|
1184
2068
|
displaySetService,
|
|
@@ -1188,12 +2072,14 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1188
2072
|
cornerstoneViewportService,
|
|
1189
2073
|
cornerstoneCacheService,
|
|
1190
2074
|
viewportGridService,
|
|
1191
|
-
stateSyncService
|
|
2075
|
+
stateSyncService,
|
|
2076
|
+
viewportActionCornersService,
|
|
2077
|
+
customizationService
|
|
1192
2078
|
} = servicesManager.services;
|
|
1193
|
-
const [viewportDialogState] = (0,ui_src/* useViewportDialog */.
|
|
2079
|
+
const [viewportDialogState] = (0,ui_src/* useViewportDialog */.OR)();
|
|
1194
2080
|
// useCallback for scroll bar height calculation
|
|
1195
2081
|
const setImageScrollBarHeight = (0,react.useCallback)(() => {
|
|
1196
|
-
const scrollbarHeight = `${elementRef.current.clientHeight -
|
|
2082
|
+
const scrollbarHeight = `${elementRef.current.clientHeight - 40}px`;
|
|
1197
2083
|
setScrollbarHeight(scrollbarHeight);
|
|
1198
2084
|
}, [elementRef]);
|
|
1199
2085
|
|
|
@@ -1209,6 +2095,7 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1209
2095
|
const syncGroups = viewportInfo.getSyncGroups();
|
|
1210
2096
|
toolGroupService.removeViewportFromToolGroup(viewportId, renderingEngineId);
|
|
1211
2097
|
syncGroupService.removeViewportFromSyncGroup(viewportId, renderingEngineId, syncGroups);
|
|
2098
|
+
viewportActionCornersService.clear(viewportId);
|
|
1212
2099
|
}, [viewportId]);
|
|
1213
2100
|
const elementEnabledHandler = (0,react.useCallback)(evt => {
|
|
1214
2101
|
// check this is this element reference and return early if doesn't match
|
|
@@ -1220,15 +2107,21 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1220
2107
|
element
|
|
1221
2108
|
} = evt.detail;
|
|
1222
2109
|
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1223
|
-
(0,state/* setEnabledElement */.
|
|
2110
|
+
(0,state/* setEnabledElement */.ye)(viewportId, element);
|
|
1224
2111
|
setEnabledVPElement(element);
|
|
1225
2112
|
const renderingEngineId = viewportInfo.getRenderingEngineId();
|
|
1226
2113
|
const toolGroupId = viewportInfo.getToolGroupId();
|
|
1227
2114
|
const syncGroups = viewportInfo.getSyncGroups();
|
|
1228
2115
|
toolGroupService.addViewportToToolGroup(viewportId, renderingEngineId, toolGroupId);
|
|
1229
2116
|
syncGroupService.addViewportToSyncGroup(viewportId, renderingEngineId, syncGroups);
|
|
2117
|
+
const synchronizersStore = stateSyncService.getState().synchronizersStore;
|
|
2118
|
+
if (synchronizersStore?.[viewportId]?.length) {
|
|
2119
|
+
// If the viewport used to have a synchronizer, re apply it again
|
|
2120
|
+
_rehydrateSynchronizers(synchronizersStore, viewportId, syncGroupService);
|
|
2121
|
+
}
|
|
1230
2122
|
if (onElementEnabled) {
|
|
1231
2123
|
onElementEnabled(evt);
|
|
2124
|
+
onReady?.(evt);
|
|
1232
2125
|
}
|
|
1233
2126
|
}, [viewportId, onElementEnabled, toolGroupService]);
|
|
1234
2127
|
|
|
@@ -1242,13 +2135,17 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1242
2135
|
if (!viewportInfo) {
|
|
1243
2136
|
return;
|
|
1244
2137
|
}
|
|
1245
|
-
cleanUpServices(viewportInfo);
|
|
1246
2138
|
cornerstoneViewportService.storePresentation({
|
|
1247
2139
|
viewportId
|
|
1248
2140
|
});
|
|
2141
|
+
|
|
2142
|
+
// This should be done after the store presentation since synchronizers
|
|
2143
|
+
// will get cleaned up and they need the viewportInfo to be present
|
|
2144
|
+
cleanUpServices(viewportInfo);
|
|
1249
2145
|
if (onElementDisabled) {
|
|
1250
2146
|
onElementDisabled(viewportInfo);
|
|
1251
2147
|
}
|
|
2148
|
+
cornerstoneViewportService.disableElement(viewportId);
|
|
1252
2149
|
dist_esm.eventTarget.removeEventListener(dist_esm.Enums.Events.ELEMENT_ENABLED, elementEnabledHandler);
|
|
1253
2150
|
};
|
|
1254
2151
|
}, []);
|
|
@@ -1264,11 +2161,10 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1264
2161
|
(0,react.useEffect)(() => {
|
|
1265
2162
|
const {
|
|
1266
2163
|
unsubscribe
|
|
1267
|
-
} = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED, async
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
} = _ref;
|
|
2164
|
+
} = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED, async ({
|
|
2165
|
+
displaySetInstanceUID: invalidatedDisplaySetInstanceUID,
|
|
2166
|
+
invalidateData
|
|
2167
|
+
}) => {
|
|
1272
2168
|
if (!invalidateData) {
|
|
1273
2169
|
return;
|
|
1274
2170
|
}
|
|
@@ -1295,10 +2191,9 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1295
2191
|
// The presentation state will have been stored previously by closing
|
|
1296
2192
|
// a viewport. Otherwise, this viewport will be unchanged and the
|
|
1297
2193
|
// presentation information will be directly carried over.
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
} = stateSyncService.getState();
|
|
2194
|
+
const state = stateSyncService.getState();
|
|
2195
|
+
const lutPresentationStore = state.lutPresentationStore;
|
|
2196
|
+
const positionPresentationStore = state.positionPresentationStore;
|
|
1302
2197
|
const {
|
|
1303
2198
|
presentationIds
|
|
1304
2199
|
} = viewportOptions;
|
|
@@ -1351,12 +2246,36 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1351
2246
|
unsubscribeFromJumpToMeasurementEvents();
|
|
1352
2247
|
};
|
|
1353
2248
|
}, [displaySets, elementRef, viewportId]);
|
|
2249
|
+
|
|
2250
|
+
// Set up the window level action menu in the viewport action corners.
|
|
2251
|
+
(0,react.useEffect)(() => {
|
|
2252
|
+
// Doing an === check here because the default config value when not set is true
|
|
2253
|
+
if (appConfig.addWindowLevelActionMenu === false) {
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
// TODO: In the future we should consider using the customization service
|
|
2258
|
+
// to determine if and in which corner various action components should go.
|
|
2259
|
+
const wlActionMenu = getWindowLevelActionMenu({
|
|
2260
|
+
viewportId,
|
|
2261
|
+
element: elementRef.current,
|
|
2262
|
+
displaySets,
|
|
2263
|
+
servicesManager,
|
|
2264
|
+
commandsManager,
|
|
2265
|
+
verticalDirection: ui_src/* AllInOneMenu.VerticalDirection */.se.mq.TopToBottom,
|
|
2266
|
+
horizontalDirection: ui_src/* AllInOneMenu.HorizontalDirection */.se.Iu.RightToLeft
|
|
2267
|
+
});
|
|
2268
|
+
viewportActionCornersService.setComponent({
|
|
2269
|
+
viewportId,
|
|
2270
|
+
id: 'windowLevelActionMenu',
|
|
2271
|
+
component: wlActionMenu,
|
|
2272
|
+
location: viewportActionCornersService.LOCATIONS.topRight,
|
|
2273
|
+
indexPriority: -100
|
|
2274
|
+
});
|
|
2275
|
+
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
|
1354
2276
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1355
2277
|
className: "viewport-wrapper"
|
|
1356
|
-
}, /*#__PURE__*/react.createElement(index_esm/* default */.
|
|
1357
|
-
refreshMode: "debounce",
|
|
1358
|
-
refreshRate: 50 // Wait 50 ms after last move to render
|
|
1359
|
-
,
|
|
2278
|
+
}, /*#__PURE__*/react.createElement(index_esm/* default */.Ay, {
|
|
1360
2279
|
onResize: onResize,
|
|
1361
2280
|
targetRef: elementRef.current
|
|
1362
2281
|
}), /*#__PURE__*/react.createElement("div", {
|
|
@@ -1379,15 +2298,17 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1379
2298
|
viewportId: viewportId,
|
|
1380
2299
|
servicesManager: servicesManager
|
|
1381
2300
|
})), /*#__PURE__*/react.createElement("div", {
|
|
1382
|
-
className: "absolute w-full"
|
|
1383
|
-
}, viewportDialogState.viewportId === viewportId && /*#__PURE__*/react.createElement(ui_src/* Notification */.
|
|
2301
|
+
className: "absolute top-[24px] w-full"
|
|
2302
|
+
}, viewportDialogState.viewportId === viewportId && /*#__PURE__*/react.createElement(ui_src/* Notification */.Eg, {
|
|
1384
2303
|
id: "viewport-notification",
|
|
1385
2304
|
message: viewportDialogState.message,
|
|
1386
2305
|
type: viewportDialogState.type,
|
|
1387
2306
|
actions: viewportDialogState.actions,
|
|
1388
2307
|
onSubmit: viewportDialogState.onSubmit,
|
|
1389
2308
|
onOutsideClick: viewportDialogState.onOutsideClick
|
|
1390
|
-
}))
|
|
2309
|
+
})), /*#__PURE__*/react.createElement(components_OHIFViewportActionCorners, {
|
|
2310
|
+
viewportId: viewportId
|
|
2311
|
+
}));
|
|
1391
2312
|
}, areEqual);
|
|
1392
2313
|
function _subscribeToJumpToMeasurementEvents(measurementService, displaySetService, elementRef, viewportId, displaySets, viewportGridService, cornerstoneViewportService) {
|
|
1393
2314
|
const {
|
|
@@ -1470,7 +2391,7 @@ function _jumpToMeasurement(measurement, targetElementRef, viewportId, measureme
|
|
|
1470
2391
|
const {
|
|
1471
2392
|
SOPInstanceUID: aSOPInstanceUID,
|
|
1472
2393
|
frameNumber: aFrameNumber
|
|
1473
|
-
} = (0,getSOPInstanceAttributes/* default */.
|
|
2394
|
+
} = (0,getSOPInstanceAttributes/* default */.A)(imageId);
|
|
1474
2395
|
return aSOPInstanceUID === SOPInstanceUID && (!frameNumber || frameNumber === aFrameNumber);
|
|
1475
2396
|
});
|
|
1476
2397
|
} else {
|
|
@@ -1501,6 +2422,42 @@ function _jumpToMeasurement(measurement, targetElementRef, viewportId, measureme
|
|
|
1501
2422
|
cacheJumpToMeasurementEvent = null;
|
|
1502
2423
|
}
|
|
1503
2424
|
}
|
|
2425
|
+
function _rehydrateSynchronizers(synchronizersStore, viewportId, syncGroupService) {
|
|
2426
|
+
synchronizersStore[viewportId].forEach(synchronizerObj => {
|
|
2427
|
+
if (!synchronizerObj.id) {
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
const {
|
|
2431
|
+
id,
|
|
2432
|
+
sourceViewports,
|
|
2433
|
+
targetViewports
|
|
2434
|
+
} = synchronizerObj;
|
|
2435
|
+
const synchronizer = syncGroupService.getSynchronizer(id);
|
|
2436
|
+
if (!synchronizer) {
|
|
2437
|
+
return;
|
|
2438
|
+
}
|
|
2439
|
+
const sourceViewportInfo = sourceViewports.find(sourceViewport => sourceViewport.viewportId === viewportId);
|
|
2440
|
+
const targetViewportInfo = targetViewports.find(targetViewport => targetViewport.viewportId === viewportId);
|
|
2441
|
+
const isSourceViewportInSynchronizer = synchronizer.getSourceViewports().find(sourceViewport => sourceViewport.viewportId === viewportId);
|
|
2442
|
+
const isTargetViewportInSynchronizer = synchronizer.getTargetViewports().find(targetViewport => targetViewport.viewportId === viewportId);
|
|
2443
|
+
|
|
2444
|
+
// if the viewport was previously a source viewport, add it again
|
|
2445
|
+
if (sourceViewportInfo && !isSourceViewportInSynchronizer) {
|
|
2446
|
+
synchronizer.addSource({
|
|
2447
|
+
viewportId: sourceViewportInfo.viewportId,
|
|
2448
|
+
renderingEngineId: sourceViewportInfo.renderingEngineId
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
// if the viewport was previously a target viewport, add it again
|
|
2453
|
+
if (targetViewportInfo && !isTargetViewportInSynchronizer) {
|
|
2454
|
+
synchronizer.addTarget({
|
|
2455
|
+
viewportId: targetViewportInfo.viewportId,
|
|
2456
|
+
renderingEngineId: targetViewportInfo.renderingEngineId
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2459
|
+
});
|
|
2460
|
+
}
|
|
1504
2461
|
|
|
1505
2462
|
// Component displayName
|
|
1506
2463
|
OHIFCornerstoneViewport.displayName = 'OHIFCornerstoneViewport';
|