@ohif/app 3.8.0-beta.7 → 3.8.0-beta.71
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.091ace1591aff1f6b679.js} +334 -287
- package/dist/{687.bundle.9d0330ea5d61fe3117da.js → 164.bundle.fcc94cd4e142a409769d.js} +22 -38
- package/dist/17dd54813d5acc10bf8f.wasm +0 -0
- package/dist/{506.bundle.ab8226d3d81abe874544.js → 188.bundle.0081530bd886a18676eb.js} +23 -28
- package/dist/191.bundle.ef35ed1f90a988b3952b.js +30360 -0
- package/dist/{221.bundle.c2dc03d8fa4235dc1285.js → 2.bundle.ab8937194aad592bc7b4.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.9be178d7555a64de203a.js} +544 -860
- package/dist/41.bundle.b5a6c70f88cf565cad3e.js +874 -0
- package/dist/425.bundle.e44cfce041ba5209a878.js +2957 -0
- package/dist/425.css +2 -0
- package/dist/{126.bundle.42df2dafc9c0310da188.js → 448.bundle.599d81471e1d7f7962bc.js} +361 -427
- package/dist/{957.bundle.9ea4506963ef8b2d84ba.js → 504.bundle.5ccd6d4269fa77a0a7e7.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.fb8ac10c41eb734e2f3d.js} +151 -147
- package/dist/{181.bundle.a62b9f0ec692299acb35.js → 574.bundle.b262cbe9f2afd7275271.js} +1286 -307
- package/dist/{181.css → 574.css} +1 -1
- package/dist/{410.bundle.38c9d3820e152e89288e.js → 594.bundle.b70ca7a91d85ebd5d8c4.js} +183 -221
- package/dist/{776.bundle.004382036bdbd8ee2b95.js → 595.bundle.c25147a450c67defb3d5.js} +3157 -1029
- package/dist/{774.bundle.4b2dc46a35012b898e1a.js → 644.bundle.1e77691d2eeb96a423b0.js} +1852 -8945
- package/dist/699.bundle.02c15c3cc4c04dbf7f51.js +785 -0
- package/dist/{359.bundle.8abe0036a7bf6b5fd115.js → 724.bundle.d50ce9fb0ab01b9378b7.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.809c87a7ba9da6fb29c8.js} +77 -96
- package/dist/{236.bundle.c9e70d55e7b2574c1ecd.js → 889.bundle.1c17d0d13e157ac21d38.js} +198 -197
- package/dist/{342.bundle.d9668551811e3a88aaa4.js → 90.bundle.27637ef740946d5c8948.js} +1429 -1055
- package/dist/{281.bundle.16a2933086a57e60c96c.js → 905.bundle.206e44c3bbd1df1a900b.js} +155 -122
- package/dist/{814.bundle.a1aba9c1e3d336008351.js → 907.bundle.11700f7af989b5af8bc3.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.a1ffb667eb04cbe07210.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.d1c8b09ab30d221fddf0.js} +148259 -61821
- 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.01449e456b7d4a737d4f.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;
|
|
@@ -371,26 +295,14 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
371
295
|
const topRightCustomization = customizationService.getModeCustomization('cornerstoneOverlayTopRight');
|
|
372
296
|
const bottomLeftCustomization = customizationService.getModeCustomization('cornerstoneOverlayBottomLeft');
|
|
373
297
|
const bottomRightCustomization = customizationService.getModeCustomization('cornerstoneOverlayBottomRight');
|
|
374
|
-
const
|
|
298
|
+
const instances = (0,react.useMemo)(() => {
|
|
375
299
|
if (viewportData != null) {
|
|
376
|
-
return
|
|
300
|
+
return _getViewportInstances(viewportData);
|
|
377
301
|
} else {
|
|
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,
|
|
@@ -486,87 +383,130 @@ function CustomizableViewportOverlay(_ref4) {
|
|
|
486
383
|
formatTime: formatDICOMTime,
|
|
487
384
|
formatNumberPrecision: formatNumberPrecision
|
|
488
385
|
},
|
|
489
|
-
instance,
|
|
490
|
-
// calculated
|
|
386
|
+
instance: instances ? instances[item?.instanceIndex] : null,
|
|
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') {
|
|
504
403
|
return renderItem.content(overlayItemProps);
|
|
505
404
|
}
|
|
506
405
|
}
|
|
507
|
-
}, [element, viewportData, imageSliceData, viewportId, servicesManager, customizationService,
|
|
508
|
-
const
|
|
509
|
-
const items =
|
|
406
|
+
}, [element, viewportData, imageSliceData, viewportId, servicesManager, customizationService, instances, voi, scale, instanceNumber]);
|
|
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: instances ? instances[item?.instanceIndex] : null,
|
|
413
|
+
formatters: {
|
|
414
|
+
formatDate: formatDICOMDate
|
|
415
|
+
}
|
|
416
|
+
}) ? _renderOverlayItem(item) : null : _renderOverlayItem(item))));
|
|
417
|
+
}, [_renderOverlayItem]);
|
|
418
|
+
const studyDateItem = {
|
|
419
|
+
id: 'StudyDate',
|
|
420
|
+
customizationType: 'ohif.overlayItem',
|
|
421
|
+
label: '',
|
|
422
|
+
title: 'Study date',
|
|
423
|
+
condition: ({
|
|
424
|
+
instance
|
|
425
|
+
}) => instance && instance.StudyDate,
|
|
426
|
+
contentF: ({
|
|
427
|
+
instance,
|
|
428
|
+
formatters: {
|
|
429
|
+
formatDate
|
|
430
|
+
}
|
|
431
|
+
}) => formatDate(instance.StudyDate)
|
|
432
|
+
};
|
|
433
|
+
const seriesDescriptionItem = {
|
|
434
|
+
id: 'SeriesDescription',
|
|
435
|
+
customizationType: 'ohif.overlayItem',
|
|
436
|
+
label: '',
|
|
437
|
+
title: 'Series description',
|
|
438
|
+
attribute: 'SeriesDescription',
|
|
439
|
+
condition: ({
|
|
440
|
+
instance
|
|
441
|
+
}) => {
|
|
442
|
+
return instance && instance.SeriesDescription;
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
const topLeftItems = instances ? instances.map((instance, index) => {
|
|
446
|
+
return [{
|
|
447
|
+
...studyDateItem,
|
|
448
|
+
instanceIndex: index
|
|
449
|
+
}, {
|
|
450
|
+
...seriesDescriptionItem,
|
|
451
|
+
instanceIndex: index
|
|
452
|
+
}];
|
|
453
|
+
}).flat() : [];
|
|
454
|
+
return /*#__PURE__*/react.createElement(ui_src/* ViewportOverlay */.pU, {
|
|
455
|
+
topLeft:
|
|
456
|
+
/**
|
|
457
|
+
* Inline default overlay items for a more standard expansion
|
|
458
|
+
*/
|
|
459
|
+
getContent(topLeftCustomization, [...topLeftItems], 'topLeftOverlayItem'),
|
|
460
|
+
topRight: getContent(topRightCustomization, [], 'topRightOverlayItem'),
|
|
461
|
+
bottomLeft: getContent(bottomLeftCustomization, [{
|
|
510
462
|
id: 'WindowLevel',
|
|
511
463
|
customizationType: 'ohif.overlayItem.windowLevel'
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
464
|
+
}, {
|
|
465
|
+
id: 'ZoomLevel',
|
|
466
|
+
customizationType: 'ohif.overlayItem.zoomLevel',
|
|
467
|
+
condition: () => {
|
|
468
|
+
const activeToolName = toolGroupService.getActiveToolForViewport(viewportId);
|
|
469
|
+
return activeToolName === 'Zoom';
|
|
470
|
+
}
|
|
471
|
+
}], 'bottomLeftOverlayItem'),
|
|
472
|
+
bottomRight: getContent(bottomRightCustomization, [{
|
|
473
|
+
id: 'InstanceNumber',
|
|
520
474
|
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()
|
|
475
|
+
}], 'bottomRightOverlayItem')
|
|
543
476
|
});
|
|
544
477
|
}
|
|
545
|
-
function
|
|
546
|
-
|
|
478
|
+
function _getViewportInstances(viewportData) {
|
|
479
|
+
const imageIds = [];
|
|
547
480
|
if (viewportData.viewportType === dist_esm.Enums.ViewportType.STACK) {
|
|
548
|
-
|
|
481
|
+
imageIds.push(viewportData.data.imageIds[0]);
|
|
549
482
|
} else if (viewportData.viewportType === dist_esm.Enums.ViewportType.ORTHOGRAPHIC) {
|
|
550
483
|
const volumes = viewportData.data;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
484
|
+
volumes.forEach(volume => {
|
|
485
|
+
if (!volume?.imageIds) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
imageIds.push(volume.imageIds[0]);
|
|
489
|
+
});
|
|
555
490
|
}
|
|
556
|
-
|
|
491
|
+
const instances = [];
|
|
492
|
+
imageIds.forEach(imageId => {
|
|
493
|
+
const instance = dist_esm.metaData.get('instance', imageId) || {};
|
|
494
|
+
instances.push(instance);
|
|
495
|
+
});
|
|
496
|
+
return instances;
|
|
557
497
|
}
|
|
558
|
-
|
|
498
|
+
const getInstanceNumber = (viewportData, viewportId, imageIndex, cornerstoneViewportService) => {
|
|
559
499
|
let instanceNumber;
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
500
|
+
switch (viewportData.viewportType) {
|
|
501
|
+
case dist_esm.Enums.ViewportType.STACK:
|
|
502
|
+
instanceNumber = _getInstanceNumberFromStack(viewportData, imageIndex);
|
|
503
|
+
break;
|
|
504
|
+
case dist_esm.Enums.ViewportType.ORTHOGRAPHIC:
|
|
505
|
+
instanceNumber = _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewportService, imageIndex);
|
|
506
|
+
break;
|
|
567
507
|
}
|
|
568
|
-
return instanceNumber;
|
|
569
|
-
}
|
|
508
|
+
return instanceNumber ?? null;
|
|
509
|
+
};
|
|
570
510
|
function _getInstanceNumberFromStack(viewportData, imageIndex) {
|
|
571
511
|
const imageIds = viewportData.data.imageIds;
|
|
572
512
|
const imageId = imageIds[imageIndex];
|
|
@@ -587,14 +527,16 @@ function _getInstanceNumberFromStack(viewportData, imageIndex) {
|
|
|
587
527
|
// Since volume viewports can be in any view direction, they can render
|
|
588
528
|
// a reconstructed image which don't have imageIds; therefore, no instance and instanceNumber
|
|
589
529
|
// Here we check if viewport is in the acquisition direction and if so, we get the instanceNumber
|
|
590
|
-
function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewportService) {
|
|
591
|
-
const volumes = viewportData.
|
|
592
|
-
|
|
593
|
-
// Todo: support fusion of acquisition plane which has instanceNumber
|
|
594
|
-
if (!volumes || volumes.length > 1) {
|
|
530
|
+
function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewportService, imageIndex) {
|
|
531
|
+
const volumes = viewportData.data;
|
|
532
|
+
if (!volumes) {
|
|
595
533
|
return;
|
|
596
534
|
}
|
|
597
|
-
|
|
535
|
+
|
|
536
|
+
// Todo: support fusion of acquisition plane which has instanceNumber
|
|
537
|
+
const {
|
|
538
|
+
volume
|
|
539
|
+
} = volumes[0];
|
|
598
540
|
const {
|
|
599
541
|
direction,
|
|
600
542
|
imageIds
|
|
@@ -612,8 +554,8 @@ function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewp
|
|
|
612
554
|
const scanAxisNormal = direction.slice(6, 9);
|
|
613
555
|
|
|
614
556
|
// check if viewPlaneNormal is parallel to scanAxisNormal
|
|
615
|
-
const cross = gl_matrix_esm/* vec3.cross */.
|
|
616
|
-
const isAcquisitionPlane = gl_matrix_esm/* vec3.length */.
|
|
557
|
+
const cross = gl_matrix_esm/* vec3.cross */.eR.cross(gl_matrix_esm/* vec3.create */.eR.create(), viewPlaneNormal, scanAxisNormal);
|
|
558
|
+
const isAcquisitionPlane = gl_matrix_esm/* vec3.length */.eR.length(cross) < EPSILON;
|
|
617
559
|
if (isAcquisitionPlane) {
|
|
618
560
|
const imageId = imageIds[imageIndex];
|
|
619
561
|
if (!imageId) {
|
|
@@ -625,6 +567,75 @@ function _getInstanceNumberFromVolume(viewportData, viewportId, cornerstoneViewp
|
|
|
625
567
|
return parseInt(instanceNumber);
|
|
626
568
|
}
|
|
627
569
|
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Window Level / Center Overlay item
|
|
573
|
+
*/
|
|
574
|
+
function VOIOverlayItem({
|
|
575
|
+
voi,
|
|
576
|
+
customization
|
|
577
|
+
}) {
|
|
578
|
+
const {
|
|
579
|
+
windowWidth,
|
|
580
|
+
windowCenter
|
|
581
|
+
} = voi;
|
|
582
|
+
if (typeof windowCenter !== 'number' || typeof windowWidth !== 'number') {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
586
|
+
className: "overlay-item flex flex-row",
|
|
587
|
+
style: {
|
|
588
|
+
color: customization && customization.color || undefined
|
|
589
|
+
}
|
|
590
|
+
}, /*#__PURE__*/react.createElement("span", {
|
|
591
|
+
className: "mr-1 shrink-0"
|
|
592
|
+
}, "W:"), /*#__PURE__*/react.createElement("span", {
|
|
593
|
+
className: "ml-1 mr-2 shrink-0"
|
|
594
|
+
}, windowWidth.toFixed(0)), /*#__PURE__*/react.createElement("span", {
|
|
595
|
+
className: "mr-1 shrink-0"
|
|
596
|
+
}, "L:"), /*#__PURE__*/react.createElement("span", {
|
|
597
|
+
className: "ml-1 shrink-0"
|
|
598
|
+
}, windowCenter.toFixed(0)));
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Zoom Level Overlay item
|
|
603
|
+
*/
|
|
604
|
+
function ZoomOverlayItem({
|
|
605
|
+
scale,
|
|
606
|
+
customization
|
|
607
|
+
}) {
|
|
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
|
+
}, "Zoom:"), /*#__PURE__*/react.createElement("span", null, scale.toFixed(2), "x"));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Instance Number Overlay Item
|
|
620
|
+
*/
|
|
621
|
+
function InstanceNumberOverlayItem({
|
|
622
|
+
instanceNumber,
|
|
623
|
+
imageSliceData,
|
|
624
|
+
customization
|
|
625
|
+
}) {
|
|
626
|
+
const {
|
|
627
|
+
imageIndex,
|
|
628
|
+
numberOfSlices
|
|
629
|
+
} = imageSliceData;
|
|
630
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
631
|
+
className: "overlay-item flex flex-row",
|
|
632
|
+
style: {
|
|
633
|
+
color: customization && customization.color || undefined
|
|
634
|
+
}
|
|
635
|
+
}, /*#__PURE__*/react.createElement("span", null, instanceNumber !== undefined && instanceNumber !== null ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("span", {
|
|
636
|
+
className: "mr-1 shrink-0"
|
|
637
|
+
}, "I:"), /*#__PURE__*/react.createElement("span", null, `${instanceNumber} (${imageIndex + 1}/${numberOfSlices})`)) : `${imageIndex + 1}/${numberOfSlices}`));
|
|
638
|
+
}
|
|
628
639
|
CustomizableViewportOverlay.propTypes = {
|
|
629
640
|
viewportData: (prop_types_default()).object,
|
|
630
641
|
imageIndex: (prop_types_default()).number,
|
|
@@ -632,7 +643,7 @@ CustomizableViewportOverlay.propTypes = {
|
|
|
632
643
|
};
|
|
633
644
|
/* harmony default export */ const Overlays_CustomizableViewportOverlay = (CustomizableViewportOverlay);
|
|
634
645
|
// EXTERNAL MODULE: ../../../node_modules/classnames/index.js
|
|
635
|
-
var classnames = __webpack_require__(
|
|
646
|
+
var classnames = __webpack_require__(61466);
|
|
636
647
|
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
|
|
637
648
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/Overlays/ViewportOrientationMarkers.css
|
|
638
649
|
// extracted by mini-css-extract-plugin
|
|
@@ -649,15 +660,14 @@ const {
|
|
|
649
660
|
getOrientationStringLPS,
|
|
650
661
|
invertOrientationStringLPS
|
|
651
662
|
} = esm.utilities.orientation;
|
|
652
|
-
function ViewportOrientationMarkers(
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
} = _ref;
|
|
663
|
+
function ViewportOrientationMarkers({
|
|
664
|
+
element,
|
|
665
|
+
viewportData,
|
|
666
|
+
imageSliceData,
|
|
667
|
+
viewportId,
|
|
668
|
+
servicesManager,
|
|
669
|
+
orientationMarkers = ['top', 'left']
|
|
670
|
+
}) {
|
|
661
671
|
// Rotation is in degrees
|
|
662
672
|
const [rotation, setRotation] = (0,react.useState)(0);
|
|
663
673
|
const [flipHorizontal, setFlipHorizontal] = (0,react.useState)(false);
|
|
@@ -715,8 +725,8 @@ function ViewportOrientationMarkers(_ref) {
|
|
|
715
725
|
viewUp,
|
|
716
726
|
viewPlaneNormal
|
|
717
727
|
} = viewport.getCamera();
|
|
718
|
-
const viewRight = gl_matrix_esm/* vec3.create */.
|
|
719
|
-
gl_matrix_esm/* vec3.cross */.
|
|
728
|
+
const viewRight = gl_matrix_esm/* vec3.create */.eR.create();
|
|
729
|
+
gl_matrix_esm/* vec3.cross */.eR.cross(viewRight, viewUp, viewPlaneNormal);
|
|
720
730
|
columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]];
|
|
721
731
|
rowCosines = viewRight;
|
|
722
732
|
}
|
|
@@ -729,20 +739,15 @@ function ViewportOrientationMarkers(_ref) {
|
|
|
729
739
|
console.log('ViewportOrientationMarkers::No viewport');
|
|
730
740
|
return null;
|
|
731
741
|
}
|
|
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
742
|
return orientationMarkers.map((m, index) => /*#__PURE__*/react.createElement("div", {
|
|
738
|
-
className: classnames_default()(`${m}-mid orientation-marker`,
|
|
743
|
+
className: classnames_default()('overlay-text', `${m}-mid orientation-marker`, 'text-aqua-pale', 'text-[13px]', 'leading-5'),
|
|
739
744
|
key: `${m}-mid orientation-marker`
|
|
740
745
|
}, /*#__PURE__*/react.createElement("div", {
|
|
741
746
|
className: "orientation-marker-value"
|
|
742
747
|
}, markers[m])));
|
|
743
748
|
}, [viewportData, imageSliceData, rotation, flipVertical, flipHorizontal, orientationMarkers, element]);
|
|
744
749
|
return /*#__PURE__*/react.createElement("div", {
|
|
745
|
-
className: "ViewportOrientationMarkers
|
|
750
|
+
className: "ViewportOrientationMarkers select-none"
|
|
746
751
|
}, markers);
|
|
747
752
|
}
|
|
748
753
|
ViewportOrientationMarkers.propTypes = {
|
|
@@ -818,11 +823,10 @@ function _getOrientationMarkers(rowCosines, columnCosines, rotation, flipVertica
|
|
|
818
823
|
|
|
819
824
|
|
|
820
825
|
|
|
821
|
-
function ViewportImageSliceLoadingIndicator(
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
} = _ref;
|
|
826
|
+
function ViewportImageSliceLoadingIndicator({
|
|
827
|
+
viewportData,
|
|
828
|
+
element
|
|
829
|
+
}) {
|
|
826
830
|
const [loading, setLoading] = (0,react.useState)(false);
|
|
827
831
|
const [error, setError] = (0,react.useState)(false);
|
|
828
832
|
const loadIndicatorRef = (0,react.useRef)(null);
|
|
@@ -961,48 +965,34 @@ function CornerstoneOverlays(props) {
|
|
|
961
965
|
}
|
|
962
966
|
/* harmony default export */ const Overlays_CornerstoneOverlays = (CornerstoneOverlays);
|
|
963
967
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
|
|
964
|
-
var getSOPInstanceAttributes = __webpack_require__(
|
|
968
|
+
var getSOPInstanceAttributes = __webpack_require__(1663);
|
|
965
969
|
// EXTERNAL MODULE: ./state/index.js + 1 modules
|
|
966
|
-
var state_0 = __webpack_require__(
|
|
970
|
+
var state_0 = __webpack_require__(15575);
|
|
967
971
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx
|
|
968
972
|
|
|
969
973
|
|
|
970
974
|
|
|
971
975
|
|
|
972
|
-
function WrappedCinePlayer(
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
} = _ref;
|
|
976
|
+
function WrappedCinePlayer({
|
|
977
|
+
enabledVPElement,
|
|
978
|
+
viewportId,
|
|
979
|
+
servicesManager
|
|
980
|
+
}) {
|
|
978
981
|
const {
|
|
979
|
-
toolbarService,
|
|
980
982
|
customizationService,
|
|
981
983
|
displaySetService,
|
|
982
|
-
viewportGridService
|
|
983
|
-
cineService
|
|
984
|
+
viewportGridService
|
|
984
985
|
} = servicesManager.services;
|
|
985
986
|
const [{
|
|
986
987
|
isCineEnabled,
|
|
987
988
|
cines
|
|
988
|
-
}] = (0,ui_src/* useCine */.
|
|
989
|
+
}, api] = (0,ui_src/* useCine */.tq)();
|
|
989
990
|
const [newStackFrameRate, setNewStackFrameRate] = (0,react.useState)(24);
|
|
990
|
-
const [appConfig] = (0,state_0/* useAppConfig */.
|
|
991
|
+
const [appConfig] = (0,state_0/* useAppConfig */.r)();
|
|
992
|
+
const isMountedRef = (0,react.useRef)(null);
|
|
991
993
|
const {
|
|
992
|
-
component: CinePlayerComponent = ui_src/* CinePlayer */.
|
|
994
|
+
component: CinePlayerComponent = ui_src/* CinePlayer */.F0
|
|
993
995
|
} = 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
996
|
const cineHandler = () => {
|
|
1007
997
|
if (!cines || !cines[viewportId] || !enabledVPElement) {
|
|
1008
998
|
return;
|
|
@@ -1012,11 +1002,11 @@ function WrappedCinePlayer(_ref) {
|
|
|
1012
1002
|
const frameRate = cine.frameRate || 24;
|
|
1013
1003
|
const validFrameRate = Math.max(frameRate, 1);
|
|
1014
1004
|
if (isPlaying) {
|
|
1015
|
-
|
|
1005
|
+
api.playClip(enabledVPElement, {
|
|
1016
1006
|
framesPerSecond: validFrameRate
|
|
1017
1007
|
});
|
|
1018
1008
|
} else {
|
|
1019
|
-
|
|
1009
|
+
api.stopClip(enabledVPElement);
|
|
1020
1010
|
}
|
|
1021
1011
|
};
|
|
1022
1012
|
const newStackCineHandler = (0,react.useCallback)(() => {
|
|
@@ -1038,19 +1028,22 @@ function WrappedCinePlayer(_ref) {
|
|
|
1038
1028
|
}
|
|
1039
1029
|
});
|
|
1040
1030
|
if (isPlaying) {
|
|
1041
|
-
|
|
1031
|
+
api.setIsCineEnabled(isPlaying);
|
|
1042
1032
|
}
|
|
1043
|
-
|
|
1033
|
+
api.setCine({
|
|
1044
1034
|
id: viewportId,
|
|
1045
1035
|
isPlaying,
|
|
1046
1036
|
frameRate
|
|
1047
1037
|
});
|
|
1048
1038
|
setNewStackFrameRate(frameRate);
|
|
1049
|
-
}, [
|
|
1039
|
+
}, [displaySetService, viewportId, viewportGridService, cines]);
|
|
1050
1040
|
(0,react.useEffect)(() => {
|
|
1041
|
+
isMountedRef.current = true;
|
|
1051
1042
|
dist_esm.eventTarget.addEventListener(dist_esm.Enums.Events.STACK_VIEWPORT_NEW_STACK, newStackCineHandler);
|
|
1052
1043
|
return () => {
|
|
1053
|
-
|
|
1044
|
+
isMountedRef.current = false;
|
|
1045
|
+
api.stopClip(enabledVPElement);
|
|
1046
|
+
api.setCine({
|
|
1054
1047
|
id: viewportId,
|
|
1055
1048
|
isPlaying: false
|
|
1056
1049
|
});
|
|
@@ -1058,28 +1051,35 @@ function WrappedCinePlayer(_ref) {
|
|
|
1058
1051
|
};
|
|
1059
1052
|
}, [enabledVPElement, newStackCineHandler]);
|
|
1060
1053
|
(0,react.useEffect)(() => {
|
|
1061
|
-
if (!cines || !cines[viewportId] || !enabledVPElement) {
|
|
1054
|
+
if (!cines || !cines[viewportId] || !enabledVPElement || !isMountedRef.current) {
|
|
1062
1055
|
return;
|
|
1063
1056
|
}
|
|
1064
1057
|
cineHandler();
|
|
1065
1058
|
return () => {
|
|
1066
|
-
|
|
1067
|
-
cineService.stopClip(enabledVPElement);
|
|
1068
|
-
}
|
|
1059
|
+
api.stopClip(enabledVPElement);
|
|
1069
1060
|
};
|
|
1070
|
-
}, [cines, viewportId,
|
|
1061
|
+
}, [cines, viewportId, enabledVPElement, cineHandler]);
|
|
1071
1062
|
const cine = cines[viewportId];
|
|
1072
1063
|
const isPlaying = cine && cine.isPlaying || false;
|
|
1073
1064
|
return isCineEnabled && /*#__PURE__*/react.createElement(CinePlayerComponent, {
|
|
1074
1065
|
className: "absolute left-1/2 bottom-3 -translate-x-1/2",
|
|
1075
1066
|
frameRate: newStackFrameRate,
|
|
1076
1067
|
isPlaying: isPlaying,
|
|
1077
|
-
onClose:
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1068
|
+
onClose: () => {
|
|
1069
|
+
// also stop the clip
|
|
1070
|
+
api.setCine({
|
|
1071
|
+
id: viewportId,
|
|
1072
|
+
isPlaying: false
|
|
1073
|
+
});
|
|
1074
|
+
api.setIsCineEnabled(false);
|
|
1075
|
+
},
|
|
1076
|
+
onPlayPauseChange: isPlaying => {
|
|
1077
|
+
api.setCine({
|
|
1078
|
+
id: viewportId,
|
|
1079
|
+
isPlaying
|
|
1080
|
+
});
|
|
1081
|
+
},
|
|
1082
|
+
onFrameRateChange: frameRate => api.setCine({
|
|
1083
1083
|
id: viewportId,
|
|
1084
1084
|
frameRate
|
|
1085
1085
|
})
|
|
@@ -1089,6 +1089,908 @@ function WrappedCinePlayer(_ref) {
|
|
|
1089
1089
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/CinePlayer/index.ts
|
|
1090
1090
|
|
|
1091
1091
|
/* harmony default export */ const components_CinePlayer = (CinePlayer);
|
|
1092
|
+
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/contextProviders/ViewportActionCornersProvider.tsx
|
|
1093
|
+
var ViewportActionCornersProvider = __webpack_require__(76255);
|
|
1094
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/OHIFViewportActionCorners.tsx
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
function OHIFViewportActionCorners({
|
|
1099
|
+
viewportId
|
|
1100
|
+
}) {
|
|
1101
|
+
const [viewportActionCornersState] = (0,ViewportActionCornersProvider/* useViewportActionCornersContext */.R4)();
|
|
1102
|
+
if (!viewportActionCornersState[viewportId]) {
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
return /*#__PURE__*/react.createElement(ui_src/* ViewportActionCorners */.R2, {
|
|
1106
|
+
cornerComponents: viewportActionCornersState[viewportId]
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
/* harmony default export */ const components_OHIFViewportActionCorners = (OHIFViewportActionCorners);
|
|
1110
|
+
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
1111
|
+
var es = __webpack_require__(80619);
|
|
1112
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
function Colormap({
|
|
1117
|
+
colormaps,
|
|
1118
|
+
viewportId,
|
|
1119
|
+
displaySets,
|
|
1120
|
+
commandsManager,
|
|
1121
|
+
serviceManager
|
|
1122
|
+
}) {
|
|
1123
|
+
const {
|
|
1124
|
+
cornerstoneViewportService
|
|
1125
|
+
} = serviceManager.services;
|
|
1126
|
+
const [activeDisplaySet, setActiveDisplaySet] = (0,react.useState)(displaySets[0]);
|
|
1127
|
+
const [showPreview, setShowPreview] = (0,react.useState)(false);
|
|
1128
|
+
const [prePreviewColormap, setPrePreviewColormap] = (0,react.useState)(null);
|
|
1129
|
+
const showPreviewRef = (0,react.useRef)(showPreview);
|
|
1130
|
+
showPreviewRef.current = showPreview;
|
|
1131
|
+
const prePreviewColormapRef = (0,react.useRef)(prePreviewColormap);
|
|
1132
|
+
prePreviewColormapRef.current = prePreviewColormap;
|
|
1133
|
+
const activeDisplaySetRef = (0,react.useRef)(activeDisplaySet);
|
|
1134
|
+
activeDisplaySetRef.current = activeDisplaySet;
|
|
1135
|
+
const onSetColorLUT = (0,react.useCallback)(props => {
|
|
1136
|
+
// TODO: Better way to check if it's a fusion
|
|
1137
|
+
const oneOpacityColormaps = ['Grayscale', 'X Ray'];
|
|
1138
|
+
const opacity = displaySets.length > 1 && !oneOpacityColormaps.includes(props.colormap.name) ? 0.5 : 1;
|
|
1139
|
+
commandsManager.run({
|
|
1140
|
+
commandName: 'setViewportColormap',
|
|
1141
|
+
commandOptions: {
|
|
1142
|
+
...props,
|
|
1143
|
+
opacity,
|
|
1144
|
+
immediate: true
|
|
1145
|
+
},
|
|
1146
|
+
context: 'CORNERSTONE'
|
|
1147
|
+
});
|
|
1148
|
+
}, [commandsManager]);
|
|
1149
|
+
const getViewportColormap = (viewportId, displaySet) => {
|
|
1150
|
+
const {
|
|
1151
|
+
displaySetInstanceUID
|
|
1152
|
+
} = displaySet;
|
|
1153
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1154
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1155
|
+
const {
|
|
1156
|
+
colormap
|
|
1157
|
+
} = viewport.getProperties();
|
|
1158
|
+
if (!colormap) {
|
|
1159
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1160
|
+
}
|
|
1161
|
+
return colormap;
|
|
1162
|
+
}
|
|
1163
|
+
const actorEntries = viewport.getActors();
|
|
1164
|
+
const actorEntry = actorEntries.find(entry => entry.uid.includes(displaySetInstanceUID));
|
|
1165
|
+
const {
|
|
1166
|
+
colormap
|
|
1167
|
+
} = viewport.getProperties(actorEntry.uid);
|
|
1168
|
+
if (!colormap) {
|
|
1169
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1170
|
+
}
|
|
1171
|
+
return colormap;
|
|
1172
|
+
};
|
|
1173
|
+
const buttons = (0,react.useMemo)(() => {
|
|
1174
|
+
return displaySets.map((displaySet, index) => ({
|
|
1175
|
+
children: displaySet.Modality,
|
|
1176
|
+
key: index,
|
|
1177
|
+
style: {
|
|
1178
|
+
minWidth: `calc(100% / ${displaySets.length})`
|
|
1179
|
+
}
|
|
1180
|
+
}));
|
|
1181
|
+
}, [displaySets]);
|
|
1182
|
+
(0,react.useEffect)(() => {
|
|
1183
|
+
setActiveDisplaySet(displaySets[displaySets.length - 1]);
|
|
1184
|
+
}, [displaySets]);
|
|
1185
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, buttons.length > 1 && /*#__PURE__*/react.createElement("div", {
|
|
1186
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1187
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ButtonGroup */.e2, {
|
|
1188
|
+
onActiveIndexChange: index => {
|
|
1189
|
+
setActiveDisplaySet(displaySets[index]);
|
|
1190
|
+
setPrePreviewColormap(null);
|
|
1191
|
+
},
|
|
1192
|
+
activeIndex: displaySets.findIndex(ds => ds.displaySetInstanceUID === activeDisplaySetRef.current.displaySetInstanceUID) || 1,
|
|
1193
|
+
className: "w-[70%] text-[10px]"
|
|
1194
|
+
}, buttons.map(({
|
|
1195
|
+
children,
|
|
1196
|
+
key,
|
|
1197
|
+
style
|
|
1198
|
+
}) => /*#__PURE__*/react.createElement("div", {
|
|
1199
|
+
key: key,
|
|
1200
|
+
style: style
|
|
1201
|
+
}, children)))), /*#__PURE__*/react.createElement("div", {
|
|
1202
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1203
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1204
|
+
label: "Preview in viewport",
|
|
1205
|
+
checked: showPreview,
|
|
1206
|
+
onChange: checked => {
|
|
1207
|
+
setShowPreview(checked);
|
|
1208
|
+
}
|
|
1209
|
+
})), /*#__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, {
|
|
1210
|
+
key: index,
|
|
1211
|
+
label: colormap.description,
|
|
1212
|
+
onClick: () => {
|
|
1213
|
+
onSetColorLUT({
|
|
1214
|
+
viewportId,
|
|
1215
|
+
colormap,
|
|
1216
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1217
|
+
});
|
|
1218
|
+
setPrePreviewColormap(null);
|
|
1219
|
+
},
|
|
1220
|
+
onMouseEnter: () => {
|
|
1221
|
+
if (showPreviewRef.current) {
|
|
1222
|
+
setPrePreviewColormap(getViewportColormap(viewportId, activeDisplaySetRef.current));
|
|
1223
|
+
onSetColorLUT({
|
|
1224
|
+
viewportId,
|
|
1225
|
+
colormap,
|
|
1226
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
1230
|
+
onMouseLeave: () => {
|
|
1231
|
+
if (showPreviewRef.current && prePreviewColormapRef.current) {
|
|
1232
|
+
onSetColorLUT({
|
|
1233
|
+
viewportId,
|
|
1234
|
+
colormap: prePreviewColormapRef.current,
|
|
1235
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}))));
|
|
1240
|
+
}
|
|
1241
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
function setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, colorbarOptions) {
|
|
1247
|
+
const {
|
|
1248
|
+
cornerstoneViewportService
|
|
1249
|
+
} = serviceManager.services;
|
|
1250
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1251
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1252
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1253
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1254
|
+
if (isLight) {
|
|
1255
|
+
colorbarOptions.ticks = {
|
|
1256
|
+
position: 'left',
|
|
1257
|
+
style: {
|
|
1258
|
+
font: '12px Arial',
|
|
1259
|
+
color: '#000000',
|
|
1260
|
+
maxNumTicks: 8,
|
|
1261
|
+
tickSize: 5,
|
|
1262
|
+
tickWidth: 1,
|
|
1263
|
+
labelMargin: 3
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
const displaySetInstanceUIDs = [];
|
|
1268
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1269
|
+
displaySetInstanceUIDs.push(viewportId);
|
|
1270
|
+
}
|
|
1271
|
+
if (viewport instanceof dist_esm.VolumeViewport) {
|
|
1272
|
+
displaySets.forEach(ds => {
|
|
1273
|
+
displaySetInstanceUIDs.push(ds.displaySetInstanceUID);
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
commandsManager.run({
|
|
1277
|
+
commandName: 'toggleViewportColorbar',
|
|
1278
|
+
commandOptions: {
|
|
1279
|
+
viewportId,
|
|
1280
|
+
options: colorbarOptions,
|
|
1281
|
+
displaySetInstanceUIDs
|
|
1282
|
+
},
|
|
1283
|
+
context: 'CORNERSTONE'
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
function Colorbar({
|
|
1287
|
+
viewportId,
|
|
1288
|
+
displaySets,
|
|
1289
|
+
commandsManager,
|
|
1290
|
+
serviceManager,
|
|
1291
|
+
colorbarProperties
|
|
1292
|
+
}) {
|
|
1293
|
+
const {
|
|
1294
|
+
colorbarService
|
|
1295
|
+
} = serviceManager.services;
|
|
1296
|
+
const {
|
|
1297
|
+
width: colorbarWidth,
|
|
1298
|
+
colorbarTickPosition,
|
|
1299
|
+
colorbarContainerPosition,
|
|
1300
|
+
colormaps,
|
|
1301
|
+
colorbarInitialColormap
|
|
1302
|
+
} = colorbarProperties;
|
|
1303
|
+
const [showColorbar, setShowColorbar] = (0,react.useState)(colorbarService.hasColorbar(viewportId));
|
|
1304
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1305
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1306
|
+
viewportId,
|
|
1307
|
+
colormaps,
|
|
1308
|
+
ticks: {
|
|
1309
|
+
position: colorbarTickPosition
|
|
1310
|
+
},
|
|
1311
|
+
width: colorbarWidth,
|
|
1312
|
+
position: colorbarContainerPosition,
|
|
1313
|
+
activeColormapName: colorbarInitialColormap
|
|
1314
|
+
});
|
|
1315
|
+
}, [commandsManager]);
|
|
1316
|
+
(0,react.useEffect)(() => {
|
|
1317
|
+
const updateColorbarState = () => {
|
|
1318
|
+
setShowColorbar(colorbarService.hasColorbar(viewportId));
|
|
1319
|
+
};
|
|
1320
|
+
const {
|
|
1321
|
+
unsubscribe
|
|
1322
|
+
} = colorbarService.subscribe(colorbarService.EVENTS.STATE_CHANGED, updateColorbarState);
|
|
1323
|
+
return () => {
|
|
1324
|
+
unsubscribe();
|
|
1325
|
+
};
|
|
1326
|
+
}, [viewportId]);
|
|
1327
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1328
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1329
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1330
|
+
label: "Display Color bar",
|
|
1331
|
+
checked: showColorbar,
|
|
1332
|
+
onChange: () => {
|
|
1333
|
+
onSetColorbar();
|
|
1334
|
+
}
|
|
1335
|
+
}));
|
|
1336
|
+
}
|
|
1337
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevel.tsx
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
function WindowLevel({
|
|
1342
|
+
viewportId,
|
|
1343
|
+
commandsManager,
|
|
1344
|
+
presets
|
|
1345
|
+
}) {
|
|
1346
|
+
const {
|
|
1347
|
+
t
|
|
1348
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1349
|
+
const onSetWindowLevel = (0,react.useCallback)(props => {
|
|
1350
|
+
commandsManager.run({
|
|
1351
|
+
commandName: 'setViewportWindowLevel',
|
|
1352
|
+
commandOptions: {
|
|
1353
|
+
...props
|
|
1354
|
+
},
|
|
1355
|
+
context: 'CORNERSTONE'
|
|
1356
|
+
});
|
|
1357
|
+
}, [commandsManager]);
|
|
1358
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.HeaderItem */.se.N5, null, t('Modality Presets', {
|
|
1359
|
+
modality: Object.keys(presets)[0]
|
|
1360
|
+
})), Object.values(presets)[0].map((preset, index) => /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1361
|
+
key: index,
|
|
1362
|
+
label: preset.description,
|
|
1363
|
+
secondaryLabel: `${preset.window} / ${preset.level}`,
|
|
1364
|
+
onClick: () => onSetWindowLevel({
|
|
1365
|
+
...preset,
|
|
1366
|
+
viewportId
|
|
1367
|
+
})
|
|
1368
|
+
})));
|
|
1369
|
+
}
|
|
1370
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresetsContent.tsx
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
function VolumeRenderingPresetsContent({
|
|
1376
|
+
presets,
|
|
1377
|
+
viewportId,
|
|
1378
|
+
commandsManager,
|
|
1379
|
+
onClose
|
|
1380
|
+
}) {
|
|
1381
|
+
const [filteredPresets, setFilteredPresets] = (0,react.useState)(presets);
|
|
1382
|
+
const [searchValue, setSearchValue] = (0,react.useState)('');
|
|
1383
|
+
const [selectedPreset, setSelectedPreset] = (0,react.useState)(null);
|
|
1384
|
+
const handleSearchChange = (0,react.useCallback)(value => {
|
|
1385
|
+
setSearchValue(value);
|
|
1386
|
+
const filtered = value ? presets.filter(preset => preset.name.toLowerCase().includes(value.toLowerCase())) : presets;
|
|
1387
|
+
setFilteredPresets(filtered);
|
|
1388
|
+
}, [presets]);
|
|
1389
|
+
const handleApply = (0,react.useCallback)(props => {
|
|
1390
|
+
commandsManager.runCommand('setViewportPreset', {
|
|
1391
|
+
...props
|
|
1392
|
+
});
|
|
1393
|
+
}, [commandsManager]);
|
|
1394
|
+
const formatLabel = (label, maxChars) => {
|
|
1395
|
+
return label.length > maxChars ? `${label.slice(0, maxChars)}...` : label;
|
|
1396
|
+
};
|
|
1397
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1398
|
+
className: "flex min-h-full w-full flex-col justify-between"
|
|
1399
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1400
|
+
className: "border-secondary-light h-[433px] w-full overflow-hidden rounded border bg-black px-2.5"
|
|
1401
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1402
|
+
className: "flex h-[46px] w-full items-center justify-start"
|
|
1403
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1404
|
+
className: "h-[26px] w-[200px]"
|
|
1405
|
+
}, /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.Cv, {
|
|
1406
|
+
value: searchValue,
|
|
1407
|
+
onDebounceChange: handleSearchChange,
|
|
1408
|
+
placeholder: 'Search all'
|
|
1409
|
+
}))), /*#__PURE__*/react.createElement("div", {
|
|
1410
|
+
className: "ohif-scrollbar overflow h-[385px] w-full overflow-y-auto"
|
|
1411
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1412
|
+
className: "grid grid-cols-4 gap-3 pt-2 pr-3"
|
|
1413
|
+
}, filteredPresets.map((preset, index) => /*#__PURE__*/react.createElement("div", {
|
|
1414
|
+
key: index,
|
|
1415
|
+
className: "flex cursor-pointer flex-col items-start",
|
|
1416
|
+
onClick: () => {
|
|
1417
|
+
setSelectedPreset(preset);
|
|
1418
|
+
handleApply({
|
|
1419
|
+
preset: preset.name,
|
|
1420
|
+
viewportId
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1424
|
+
name: preset.name,
|
|
1425
|
+
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'
|
|
1426
|
+
}), /*#__PURE__*/react.createElement("label", {
|
|
1427
|
+
className: "text-aqua-pale mt-2 text-left text-xs"
|
|
1428
|
+
}, formatLabel(preset.name, 11))))))), /*#__PURE__*/react.createElement("footer", {
|
|
1429
|
+
className: "flex h-[60px] w-full items-center justify-end"
|
|
1430
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1431
|
+
className: "flex"
|
|
1432
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Button */.$n, {
|
|
1433
|
+
name: "Cancel",
|
|
1434
|
+
size: ui_src/* ButtonEnums.size */.Ny.Ej.medium,
|
|
1435
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.secondary,
|
|
1436
|
+
onClick: onClose
|
|
1437
|
+
}, ' ', "Cancel", ' '))));
|
|
1438
|
+
}
|
|
1439
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
function VolumeRenderingPresets({
|
|
1444
|
+
viewportId,
|
|
1445
|
+
serviceManager,
|
|
1446
|
+
commandsManager,
|
|
1447
|
+
volumeRenderingPresets
|
|
1448
|
+
}) {
|
|
1449
|
+
const {
|
|
1450
|
+
uiModalService
|
|
1451
|
+
} = serviceManager.services;
|
|
1452
|
+
const onClickPresets = () => {
|
|
1453
|
+
uiModalService.show({
|
|
1454
|
+
content: VolumeRenderingPresetsContent,
|
|
1455
|
+
title: 'Rendering Presets',
|
|
1456
|
+
movable: true,
|
|
1457
|
+
contentProps: {
|
|
1458
|
+
onClose: uiModalService.hide,
|
|
1459
|
+
presets: volumeRenderingPresets,
|
|
1460
|
+
viewportId,
|
|
1461
|
+
commandsManager
|
|
1462
|
+
},
|
|
1463
|
+
containerDimensions: 'h-[543px] w-[460px]',
|
|
1464
|
+
contentDimensions: 'h-[493px] w-[460px] pl-[12px]'
|
|
1465
|
+
});
|
|
1466
|
+
};
|
|
1467
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1468
|
+
label: "Rendering Presets",
|
|
1469
|
+
icon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1470
|
+
name: "VolumeRendering"
|
|
1471
|
+
}),
|
|
1472
|
+
rightIcon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1473
|
+
name: "action-new-dialog"
|
|
1474
|
+
}),
|
|
1475
|
+
onClick: onClickPresets
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx
|
|
1479
|
+
|
|
1480
|
+
function VolumeRenderingQuality({
|
|
1481
|
+
volumeRenderingQualityRange,
|
|
1482
|
+
commandsManager,
|
|
1483
|
+
serviceManager,
|
|
1484
|
+
viewportId
|
|
1485
|
+
}) {
|
|
1486
|
+
const {
|
|
1487
|
+
cornerstoneViewportService
|
|
1488
|
+
} = serviceManager.services;
|
|
1489
|
+
const {
|
|
1490
|
+
min,
|
|
1491
|
+
max,
|
|
1492
|
+
step
|
|
1493
|
+
} = volumeRenderingQualityRange;
|
|
1494
|
+
const [quality, setQuality] = (0,react.useState)(null);
|
|
1495
|
+
const onChange = (0,react.useCallback)(value => {
|
|
1496
|
+
commandsManager.runCommand('setVolumeRenderingQulaity', {
|
|
1497
|
+
viewportId,
|
|
1498
|
+
volumeQuality: value
|
|
1499
|
+
});
|
|
1500
|
+
setQuality(value);
|
|
1501
|
+
}, [commandsManager, viewportId]);
|
|
1502
|
+
const calculateBackground = value => {
|
|
1503
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1504
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1505
|
+
};
|
|
1506
|
+
(0,react.useEffect)(() => {
|
|
1507
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1508
|
+
const {
|
|
1509
|
+
actor
|
|
1510
|
+
} = viewport.getActors()[0];
|
|
1511
|
+
const mapper = actor.getMapper();
|
|
1512
|
+
const image = mapper.getInputData();
|
|
1513
|
+
const spacing = image.getSpacing();
|
|
1514
|
+
const sampleDistance = mapper.getSampleDistance();
|
|
1515
|
+
const averageSpacing = spacing.reduce((a, b) => a + b) / 3.0;
|
|
1516
|
+
if (sampleDistance === averageSpacing) {
|
|
1517
|
+
setQuality(1);
|
|
1518
|
+
} else {
|
|
1519
|
+
setQuality(Math.sqrt(averageSpacing / (sampleDistance * 0.5)));
|
|
1520
|
+
}
|
|
1521
|
+
}, [cornerstoneViewportService, viewportId]);
|
|
1522
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1523
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1524
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1525
|
+
className: "block text-white",
|
|
1526
|
+
htmlFor: "volume"
|
|
1527
|
+
}, "Quality"), quality !== null && /*#__PURE__*/react.createElement("input", {
|
|
1528
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1529
|
+
value: quality,
|
|
1530
|
+
id: "volume",
|
|
1531
|
+
max: max,
|
|
1532
|
+
min: min,
|
|
1533
|
+
type: "range",
|
|
1534
|
+
step: step,
|
|
1535
|
+
onChange: e => onChange(parseInt(e.target.value, 10)),
|
|
1536
|
+
style: {
|
|
1537
|
+
background: calculateBackground((quality - min) / (max - min))
|
|
1538
|
+
}
|
|
1539
|
+
})));
|
|
1540
|
+
}
|
|
1541
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx
|
|
1542
|
+
|
|
1543
|
+
function VolumeShift({
|
|
1544
|
+
viewportId,
|
|
1545
|
+
commandsManager,
|
|
1546
|
+
serviceManager
|
|
1547
|
+
}) {
|
|
1548
|
+
const {
|
|
1549
|
+
cornerstoneViewportService
|
|
1550
|
+
} = serviceManager.services;
|
|
1551
|
+
const [minShift, setMinShift] = (0,react.useState)(null);
|
|
1552
|
+
const [maxShift, setMaxShift] = (0,react.useState)(null);
|
|
1553
|
+
const [shift, setShift] = (0,react.useState)(cornerstoneViewportService.getCornerstoneViewport(viewportId)?.shiftedBy || 0);
|
|
1554
|
+
const [step, setStep] = (0,react.useState)(null);
|
|
1555
|
+
const [isBlocking, setIsBlocking] = (0,react.useState)(false);
|
|
1556
|
+
const prevShiftRef = (0,react.useRef)(shift);
|
|
1557
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1558
|
+
const {
|
|
1559
|
+
actor
|
|
1560
|
+
} = viewport.getActors()[0];
|
|
1561
|
+
const ofun = actor.getProperty().getScalarOpacity(0);
|
|
1562
|
+
(0,react.useEffect)(() => {
|
|
1563
|
+
if (isBlocking) {
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
const range = ofun.getRange();
|
|
1567
|
+
const transferFunctionWidth = range[1] - range[0];
|
|
1568
|
+
const minShift = -transferFunctionWidth;
|
|
1569
|
+
const maxShift = transferFunctionWidth;
|
|
1570
|
+
setMinShift(minShift);
|
|
1571
|
+
setMaxShift(maxShift);
|
|
1572
|
+
setStep(Math.pow(10, Math.floor(Math.log10(transferFunctionWidth / 500))));
|
|
1573
|
+
}, [cornerstoneViewportService, viewportId, actor, ofun, isBlocking]);
|
|
1574
|
+
const onChangeRange = (0,react.useCallback)(newShift => {
|
|
1575
|
+
const shiftDifference = newShift - prevShiftRef.current;
|
|
1576
|
+
prevShiftRef.current = newShift;
|
|
1577
|
+
viewport.shiftedBy = newShift;
|
|
1578
|
+
commandsManager.runCommand('shiftVolumeOpacityPoints', {
|
|
1579
|
+
viewportId,
|
|
1580
|
+
shift: shiftDifference
|
|
1581
|
+
});
|
|
1582
|
+
}, [commandsManager, viewportId, viewport]);
|
|
1583
|
+
const calculateBackground = value => {
|
|
1584
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1585
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1586
|
+
};
|
|
1587
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1588
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1589
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1590
|
+
className: "block text-white",
|
|
1591
|
+
htmlFor: "shift"
|
|
1592
|
+
}, "Shift"), step !== null && /*#__PURE__*/react.createElement("input", {
|
|
1593
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1594
|
+
value: shift,
|
|
1595
|
+
onChange: e => {
|
|
1596
|
+
const shiftValue = parseInt(e.target.value, 10);
|
|
1597
|
+
setShift(shiftValue);
|
|
1598
|
+
onChangeRange(shiftValue);
|
|
1599
|
+
},
|
|
1600
|
+
id: "shift",
|
|
1601
|
+
onMouseDown: () => setIsBlocking(true),
|
|
1602
|
+
onMouseUp: () => setIsBlocking(false),
|
|
1603
|
+
max: maxShift,
|
|
1604
|
+
min: minShift,
|
|
1605
|
+
type: "range",
|
|
1606
|
+
step: step,
|
|
1607
|
+
style: {
|
|
1608
|
+
background: calculateBackground((shift - minShift) / (maxShift - minShift))
|
|
1609
|
+
}
|
|
1610
|
+
})));
|
|
1611
|
+
}
|
|
1612
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx
|
|
1613
|
+
|
|
1614
|
+
function VolumeLighting({
|
|
1615
|
+
serviceManager,
|
|
1616
|
+
commandsManager,
|
|
1617
|
+
viewportId
|
|
1618
|
+
}) {
|
|
1619
|
+
const {
|
|
1620
|
+
cornerstoneViewportService
|
|
1621
|
+
} = serviceManager.services;
|
|
1622
|
+
const [ambient, setAmbient] = (0,react.useState)(null);
|
|
1623
|
+
const [diffuse, setDiffuse] = (0,react.useState)(null);
|
|
1624
|
+
const [specular, setSpecular] = (0,react.useState)(null);
|
|
1625
|
+
const onAmbientChange = (0,react.useCallback)(() => {
|
|
1626
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1627
|
+
viewportId,
|
|
1628
|
+
options: {
|
|
1629
|
+
ambient
|
|
1630
|
+
}
|
|
1631
|
+
});
|
|
1632
|
+
}, [ambient, commandsManager, viewportId]);
|
|
1633
|
+
const onDiffuseChange = (0,react.useCallback)(() => {
|
|
1634
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1635
|
+
viewportId,
|
|
1636
|
+
options: {
|
|
1637
|
+
diffuse
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1640
|
+
}, [diffuse, commandsManager, viewportId]);
|
|
1641
|
+
const onSpecularChange = (0,react.useCallback)(() => {
|
|
1642
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1643
|
+
viewportId,
|
|
1644
|
+
options: {
|
|
1645
|
+
specular
|
|
1646
|
+
}
|
|
1647
|
+
});
|
|
1648
|
+
}, [specular, commandsManager, viewportId]);
|
|
1649
|
+
const calculateBackground = value => {
|
|
1650
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1651
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1652
|
+
};
|
|
1653
|
+
(0,react.useEffect)(() => {
|
|
1654
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1655
|
+
const {
|
|
1656
|
+
actor
|
|
1657
|
+
} = viewport.getActors()[0];
|
|
1658
|
+
const ambient = actor.getProperty().getAmbient();
|
|
1659
|
+
const diffuse = actor.getProperty().getDiffuse();
|
|
1660
|
+
const specular = actor.getProperty().getSpecular();
|
|
1661
|
+
setAmbient(ambient);
|
|
1662
|
+
setDiffuse(diffuse);
|
|
1663
|
+
setSpecular(specular);
|
|
1664
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1665
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1666
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1667
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1668
|
+
className: "block text-white",
|
|
1669
|
+
htmlFor: "ambient"
|
|
1670
|
+
}, "Ambient"), ambient !== null && /*#__PURE__*/react.createElement("input", {
|
|
1671
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1672
|
+
value: ambient,
|
|
1673
|
+
onChange: e => {
|
|
1674
|
+
setAmbient(e.target.value);
|
|
1675
|
+
onAmbientChange();
|
|
1676
|
+
},
|
|
1677
|
+
id: "ambient",
|
|
1678
|
+
max: 1,
|
|
1679
|
+
min: 0,
|
|
1680
|
+
type: "range",
|
|
1681
|
+
step: 0.1,
|
|
1682
|
+
style: {
|
|
1683
|
+
background: calculateBackground(ambient)
|
|
1684
|
+
}
|
|
1685
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1686
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1687
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1688
|
+
className: "block text-white",
|
|
1689
|
+
htmlFor: "diffuse"
|
|
1690
|
+
}, "Diffuse"), diffuse !== null && /*#__PURE__*/react.createElement("input", {
|
|
1691
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1692
|
+
value: diffuse,
|
|
1693
|
+
onChange: e => {
|
|
1694
|
+
setDiffuse(e.target.value);
|
|
1695
|
+
onDiffuseChange();
|
|
1696
|
+
},
|
|
1697
|
+
id: "diffuse",
|
|
1698
|
+
max: 1,
|
|
1699
|
+
min: 0,
|
|
1700
|
+
type: "range",
|
|
1701
|
+
step: 0.1,
|
|
1702
|
+
style: {
|
|
1703
|
+
background: calculateBackground(diffuse)
|
|
1704
|
+
}
|
|
1705
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1706
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1707
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1708
|
+
className: "block text-white",
|
|
1709
|
+
htmlFor: "specular"
|
|
1710
|
+
}, "Specular"), specular !== null && /*#__PURE__*/react.createElement("input", {
|
|
1711
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1712
|
+
value: specular,
|
|
1713
|
+
onChange: e => {
|
|
1714
|
+
setSpecular(e.target.value);
|
|
1715
|
+
onSpecularChange();
|
|
1716
|
+
},
|
|
1717
|
+
id: "specular",
|
|
1718
|
+
max: 1,
|
|
1719
|
+
min: 0,
|
|
1720
|
+
type: "range",
|
|
1721
|
+
step: 0.1,
|
|
1722
|
+
style: {
|
|
1723
|
+
background: calculateBackground(specular)
|
|
1724
|
+
}
|
|
1725
|
+
})));
|
|
1726
|
+
}
|
|
1727
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
function VolumeShade({
|
|
1731
|
+
commandsManager,
|
|
1732
|
+
viewportId,
|
|
1733
|
+
serviceManager
|
|
1734
|
+
}) {
|
|
1735
|
+
const {
|
|
1736
|
+
cornerstoneViewportService
|
|
1737
|
+
} = serviceManager.services;
|
|
1738
|
+
const [shade, setShade] = (0,react.useState)(true);
|
|
1739
|
+
const [key, setKey] = (0,react.useState)(0);
|
|
1740
|
+
const onShadeChange = (0,react.useCallback)(checked => {
|
|
1741
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1742
|
+
viewportId,
|
|
1743
|
+
options: {
|
|
1744
|
+
shade: checked
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
}, [commandsManager, viewportId]);
|
|
1748
|
+
(0,react.useEffect)(() => {
|
|
1749
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1750
|
+
const {
|
|
1751
|
+
actor
|
|
1752
|
+
} = viewport.getActors()[0];
|
|
1753
|
+
const shade = actor.getProperty().getShade();
|
|
1754
|
+
setShade(shade);
|
|
1755
|
+
setKey(key + 1);
|
|
1756
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1757
|
+
return /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1758
|
+
key: key,
|
|
1759
|
+
label: "Shade",
|
|
1760
|
+
checked: shade,
|
|
1761
|
+
onChange: () => {
|
|
1762
|
+
setShade(!shade);
|
|
1763
|
+
onShadeChange(!shade);
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx
|
|
1768
|
+
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
function VolumeRenderingOptions({
|
|
1775
|
+
viewportId,
|
|
1776
|
+
commandsManager,
|
|
1777
|
+
volumeRenderingQualityRange,
|
|
1778
|
+
serviceManager
|
|
1779
|
+
}) {
|
|
1780
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(VolumeRenderingQuality, {
|
|
1781
|
+
viewportId: viewportId,
|
|
1782
|
+
commandsManager: commandsManager,
|
|
1783
|
+
serviceManager: serviceManager,
|
|
1784
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1785
|
+
}), /*#__PURE__*/react.createElement(VolumeShift, {
|
|
1786
|
+
viewportId: viewportId,
|
|
1787
|
+
commandsManager: commandsManager,
|
|
1788
|
+
serviceManager: serviceManager
|
|
1789
|
+
}), /*#__PURE__*/react.createElement("div", {
|
|
1790
|
+
className: "all-in-one-menu-item flex w-full justify-start"
|
|
1791
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1792
|
+
className: "text-aqua-pale text-[13px]"
|
|
1793
|
+
}, "LIGHTING")), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.DividerItem */.se.VG, null), /*#__PURE__*/react.createElement("div", {
|
|
1794
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1795
|
+
}, /*#__PURE__*/react.createElement(VolumeShade, {
|
|
1796
|
+
commandsManager: commandsManager,
|
|
1797
|
+
serviceManager: serviceManager,
|
|
1798
|
+
viewportId: viewportId
|
|
1799
|
+
})), /*#__PURE__*/react.createElement(VolumeLighting, {
|
|
1800
|
+
viewportId: viewportId,
|
|
1801
|
+
commandsManager: commandsManager,
|
|
1802
|
+
serviceManager: serviceManager
|
|
1803
|
+
}));
|
|
1804
|
+
}
|
|
1805
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
|
|
1818
|
+
function WindowLevelActionMenu({
|
|
1819
|
+
viewportId,
|
|
1820
|
+
element,
|
|
1821
|
+
presets,
|
|
1822
|
+
verticalDirection,
|
|
1823
|
+
horizontalDirection,
|
|
1824
|
+
commandsManager,
|
|
1825
|
+
serviceManager,
|
|
1826
|
+
colorbarProperties,
|
|
1827
|
+
displaySets,
|
|
1828
|
+
volumeRenderingPresets,
|
|
1829
|
+
volumeRenderingQualityRange
|
|
1830
|
+
}) {
|
|
1831
|
+
const {
|
|
1832
|
+
colormaps,
|
|
1833
|
+
colorbarContainerPosition,
|
|
1834
|
+
colorbarInitialColormap,
|
|
1835
|
+
colorbarTickPosition,
|
|
1836
|
+
width: colorbarWidth
|
|
1837
|
+
} = colorbarProperties;
|
|
1838
|
+
const {
|
|
1839
|
+
colorbarService,
|
|
1840
|
+
cornerstoneViewportService
|
|
1841
|
+
} = serviceManager.services;
|
|
1842
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1843
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1844
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1845
|
+
const nonImageModalities = ['SR', 'SEG', 'SM', 'RTSTRUCT', 'RTPLAN', 'RTDOSE'];
|
|
1846
|
+
const {
|
|
1847
|
+
t
|
|
1848
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1849
|
+
const [viewportGrid] = (0,ui_src/* useViewportGrid */.ih)();
|
|
1850
|
+
const {
|
|
1851
|
+
activeViewportId
|
|
1852
|
+
} = viewportGrid;
|
|
1853
|
+
const [vpHeight, setVpHeight] = (0,react.useState)(element?.clientHeight);
|
|
1854
|
+
const [menuKey, setMenuKey] = (0,react.useState)(0);
|
|
1855
|
+
const [is3DVolume, setIs3DVolume] = (0,react.useState)(false);
|
|
1856
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1857
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1858
|
+
colormaps,
|
|
1859
|
+
ticks: {
|
|
1860
|
+
position: colorbarTickPosition
|
|
1861
|
+
},
|
|
1862
|
+
width: colorbarWidth,
|
|
1863
|
+
position: colorbarContainerPosition,
|
|
1864
|
+
activeColormapName: colorbarInitialColormap
|
|
1865
|
+
});
|
|
1866
|
+
}, [commandsManager]);
|
|
1867
|
+
(0,react.useEffect)(() => {
|
|
1868
|
+
const newVpHeight = element?.clientHeight;
|
|
1869
|
+
if (vpHeight !== newVpHeight) {
|
|
1870
|
+
setVpHeight(newVpHeight);
|
|
1871
|
+
}
|
|
1872
|
+
}, [element, vpHeight]);
|
|
1873
|
+
(0,react.useEffect)(() => {
|
|
1874
|
+
if (!colorbarService.hasColorbar(viewportId)) {
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
window.setTimeout(() => {
|
|
1878
|
+
colorbarService.removeColorbar(viewportId);
|
|
1879
|
+
onSetColorbar();
|
|
1880
|
+
}, 0);
|
|
1881
|
+
}, [viewportId]);
|
|
1882
|
+
(0,react.useEffect)(() => {
|
|
1883
|
+
if (colorbarService.hasColorbar(viewportId)) {
|
|
1884
|
+
colorbarService.removeColorbar(viewportId);
|
|
1885
|
+
}
|
|
1886
|
+
}, [displaySets]);
|
|
1887
|
+
(0,react.useEffect)(() => {
|
|
1888
|
+
setMenuKey(menuKey + 1);
|
|
1889
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1890
|
+
if (viewport instanceof dist_esm.VolumeViewport3D) {
|
|
1891
|
+
setIs3DVolume(true);
|
|
1892
|
+
} else {
|
|
1893
|
+
setIs3DVolume(false);
|
|
1894
|
+
}
|
|
1895
|
+
}, [displaySets, viewportId, presets, volumeRenderingQualityRange, volumeRenderingPresets, colorbarProperties, activeViewportId, viewportGrid]);
|
|
1896
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.IconMenu */.se.dd, {
|
|
1897
|
+
icon: "viewport-window-level",
|
|
1898
|
+
verticalDirection: verticalDirection,
|
|
1899
|
+
horizontalDirection: horizontalDirection,
|
|
1900
|
+
iconClassName: classnames_default()(
|
|
1901
|
+
// Visible on hover and for the active viewport
|
|
1902
|
+
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'),
|
|
1903
|
+
menuStyle: {
|
|
1904
|
+
maxHeight: vpHeight - 32,
|
|
1905
|
+
minWidth: 218
|
|
1906
|
+
},
|
|
1907
|
+
onVisibilityChange: () => {
|
|
1908
|
+
setVpHeight(element.clientHeight);
|
|
1909
|
+
},
|
|
1910
|
+
menuKey: menuKey
|
|
1911
|
+
}, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, !is3DVolume && /*#__PURE__*/react.createElement(Colorbar, {
|
|
1912
|
+
viewportId: viewportId,
|
|
1913
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1914
|
+
commandsManager: commandsManager,
|
|
1915
|
+
serviceManager: serviceManager,
|
|
1916
|
+
colorbarProperties: colorbarProperties
|
|
1917
|
+
}), colormaps && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1918
|
+
key: "colorLUTPresets",
|
|
1919
|
+
itemLabel: "Color LUT",
|
|
1920
|
+
itemIcon: "icon-color-lut"
|
|
1921
|
+
}, /*#__PURE__*/react.createElement(Colormap, {
|
|
1922
|
+
colormaps: colormaps,
|
|
1923
|
+
viewportId: viewportId,
|
|
1924
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1925
|
+
commandsManager: commandsManager,
|
|
1926
|
+
serviceManager: serviceManager
|
|
1927
|
+
})), presets && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1928
|
+
key: "windowLevelPresets",
|
|
1929
|
+
itemLabel: t('Modality Window Presets', {
|
|
1930
|
+
modality: Object.keys(presets)[0]
|
|
1931
|
+
}),
|
|
1932
|
+
itemIcon: "viewport-window-level"
|
|
1933
|
+
}, /*#__PURE__*/react.createElement(WindowLevel, {
|
|
1934
|
+
viewportId: viewportId,
|
|
1935
|
+
commandsManager: commandsManager,
|
|
1936
|
+
presets: presets
|
|
1937
|
+
})), volumeRenderingPresets && is3DVolume && /*#__PURE__*/react.createElement(VolumeRenderingPresets, {
|
|
1938
|
+
serviceManager: serviceManager,
|
|
1939
|
+
viewportId: viewportId,
|
|
1940
|
+
commandsManager: commandsManager,
|
|
1941
|
+
volumeRenderingPresets: volumeRenderingPresets
|
|
1942
|
+
}), volumeRenderingQualityRange && is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1943
|
+
itemLabel: "Rendering Options"
|
|
1944
|
+
}, /*#__PURE__*/react.createElement(VolumeRenderingOptions, {
|
|
1945
|
+
viewportId: viewportId,
|
|
1946
|
+
commandsManager: commandsManager,
|
|
1947
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange,
|
|
1948
|
+
serviceManager: serviceManager
|
|
1949
|
+
}))));
|
|
1950
|
+
}
|
|
1951
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx
|
|
1952
|
+
|
|
1953
|
+
|
|
1954
|
+
function getWindowLevelActionMenu({
|
|
1955
|
+
viewportId,
|
|
1956
|
+
element,
|
|
1957
|
+
displaySets,
|
|
1958
|
+
servicesManager,
|
|
1959
|
+
commandsManager,
|
|
1960
|
+
verticalDirection,
|
|
1961
|
+
horizontalDirection
|
|
1962
|
+
}) {
|
|
1963
|
+
const {
|
|
1964
|
+
customizationService
|
|
1965
|
+
} = servicesManager.services;
|
|
1966
|
+
const {
|
|
1967
|
+
presets
|
|
1968
|
+
} = customizationService.get('cornerstone.windowLevelPresets');
|
|
1969
|
+
const colorbarProperties = customizationService.get('cornerstone.colorbar');
|
|
1970
|
+
const {
|
|
1971
|
+
volumeRenderingPresets,
|
|
1972
|
+
volumeRenderingQualityRange
|
|
1973
|
+
} = customizationService.get('cornerstone.3dVolumeRendering');
|
|
1974
|
+
const displaySetPresets = displaySets.filter(displaySet => presets[displaySet.Modality]).map(displaySet => {
|
|
1975
|
+
return {
|
|
1976
|
+
[displaySet.Modality]: presets[displaySet.Modality]
|
|
1977
|
+
};
|
|
1978
|
+
});
|
|
1979
|
+
const hasMenu = displaySetPresets.length > 0;
|
|
1980
|
+
return hasMenu ? /*#__PURE__*/react.createElement(WindowLevelActionMenu, {
|
|
1981
|
+
viewportId: viewportId,
|
|
1982
|
+
element: element,
|
|
1983
|
+
presets: displaySetPresets[0],
|
|
1984
|
+
verticalDirection: verticalDirection,
|
|
1985
|
+
horizontalDirection: horizontalDirection,
|
|
1986
|
+
commandsManager: commandsManager,
|
|
1987
|
+
serviceManager: servicesManager,
|
|
1988
|
+
colorbarProperties: colorbarProperties,
|
|
1989
|
+
displaySets: displaySets,
|
|
1990
|
+
volumeRenderingPresets: volumeRenderingPresets,
|
|
1991
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1992
|
+
}) : null;
|
|
1993
|
+
}
|
|
1092
1994
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
|
|
1093
1995
|
|
|
1094
1996
|
|
|
@@ -1102,6 +2004,9 @@ function WrappedCinePlayer(_ref) {
|
|
|
1102
2004
|
|
|
1103
2005
|
|
|
1104
2006
|
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
|
|
1105
2010
|
const STACK = 'stack';
|
|
1106
2011
|
|
|
1107
2012
|
/**
|
|
@@ -1166,19 +2071,20 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1166
2071
|
viewportOptions,
|
|
1167
2072
|
displaySetOptions,
|
|
1168
2073
|
servicesManager,
|
|
1169
|
-
commandsManager,
|
|
1170
2074
|
onElementEnabled,
|
|
1171
2075
|
onElementDisabled,
|
|
1172
2076
|
isJumpToMeasurementDisabled,
|
|
1173
2077
|
// Note: you SHOULD NOT use the initialImageIdOrIndex for manipulation
|
|
1174
2078
|
// of the imageData in the OHIFCornerstoneViewport. This prop is used
|
|
1175
2079
|
// to set the initial state of the viewport's first image to render
|
|
1176
|
-
initialImageIndex
|
|
2080
|
+
initialImageIndex,
|
|
2081
|
+
onReady
|
|
1177
2082
|
} = props;
|
|
1178
2083
|
const viewportId = viewportOptions.viewportId;
|
|
1179
2084
|
const [scrollbarHeight, setScrollbarHeight] = (0,react.useState)('100px');
|
|
1180
2085
|
const [enabledVPElement, setEnabledVPElement] = (0,react.useState)(null);
|
|
1181
2086
|
const elementRef = (0,react.useRef)();
|
|
2087
|
+
const [appConfig] = (0,state_0/* useAppConfig */.r)();
|
|
1182
2088
|
const {
|
|
1183
2089
|
measurementService,
|
|
1184
2090
|
displaySetService,
|
|
@@ -1188,12 +2094,14 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1188
2094
|
cornerstoneViewportService,
|
|
1189
2095
|
cornerstoneCacheService,
|
|
1190
2096
|
viewportGridService,
|
|
1191
|
-
stateSyncService
|
|
2097
|
+
stateSyncService,
|
|
2098
|
+
viewportActionCornersService,
|
|
2099
|
+
customizationService
|
|
1192
2100
|
} = servicesManager.services;
|
|
1193
|
-
const [viewportDialogState] = (0,ui_src/* useViewportDialog */.
|
|
2101
|
+
const [viewportDialogState] = (0,ui_src/* useViewportDialog */.OR)();
|
|
1194
2102
|
// useCallback for scroll bar height calculation
|
|
1195
2103
|
const setImageScrollBarHeight = (0,react.useCallback)(() => {
|
|
1196
|
-
const scrollbarHeight = `${elementRef.current.clientHeight -
|
|
2104
|
+
const scrollbarHeight = `${elementRef.current.clientHeight - 40}px`;
|
|
1197
2105
|
setScrollbarHeight(scrollbarHeight);
|
|
1198
2106
|
}, [elementRef]);
|
|
1199
2107
|
|
|
@@ -1209,6 +2117,7 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1209
2117
|
const syncGroups = viewportInfo.getSyncGroups();
|
|
1210
2118
|
toolGroupService.removeViewportFromToolGroup(viewportId, renderingEngineId);
|
|
1211
2119
|
syncGroupService.removeViewportFromSyncGroup(viewportId, renderingEngineId, syncGroups);
|
|
2120
|
+
viewportActionCornersService.clear(viewportId);
|
|
1212
2121
|
}, [viewportId]);
|
|
1213
2122
|
const elementEnabledHandler = (0,react.useCallback)(evt => {
|
|
1214
2123
|
// check this is this element reference and return early if doesn't match
|
|
@@ -1220,15 +2129,21 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1220
2129
|
element
|
|
1221
2130
|
} = evt.detail;
|
|
1222
2131
|
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1223
|
-
(0,state/* setEnabledElement */.
|
|
2132
|
+
(0,state/* setEnabledElement */.ye)(viewportId, element);
|
|
1224
2133
|
setEnabledVPElement(element);
|
|
1225
2134
|
const renderingEngineId = viewportInfo.getRenderingEngineId();
|
|
1226
2135
|
const toolGroupId = viewportInfo.getToolGroupId();
|
|
1227
2136
|
const syncGroups = viewportInfo.getSyncGroups();
|
|
1228
2137
|
toolGroupService.addViewportToToolGroup(viewportId, renderingEngineId, toolGroupId);
|
|
1229
2138
|
syncGroupService.addViewportToSyncGroup(viewportId, renderingEngineId, syncGroups);
|
|
2139
|
+
const synchronizersStore = stateSyncService.getState().synchronizersStore;
|
|
2140
|
+
if (synchronizersStore?.[viewportId]?.length) {
|
|
2141
|
+
// If the viewport used to have a synchronizer, re apply it again
|
|
2142
|
+
_rehydrateSynchronizers(synchronizersStore, viewportId, syncGroupService);
|
|
2143
|
+
}
|
|
1230
2144
|
if (onElementEnabled) {
|
|
1231
2145
|
onElementEnabled(evt);
|
|
2146
|
+
onReady?.(evt);
|
|
1232
2147
|
}
|
|
1233
2148
|
}, [viewportId, onElementEnabled, toolGroupService]);
|
|
1234
2149
|
|
|
@@ -1242,13 +2157,17 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1242
2157
|
if (!viewportInfo) {
|
|
1243
2158
|
return;
|
|
1244
2159
|
}
|
|
1245
|
-
cleanUpServices(viewportInfo);
|
|
1246
2160
|
cornerstoneViewportService.storePresentation({
|
|
1247
2161
|
viewportId
|
|
1248
2162
|
});
|
|
2163
|
+
|
|
2164
|
+
// This should be done after the store presentation since synchronizers
|
|
2165
|
+
// will get cleaned up and they need the viewportInfo to be present
|
|
2166
|
+
cleanUpServices(viewportInfo);
|
|
1249
2167
|
if (onElementDisabled) {
|
|
1250
2168
|
onElementDisabled(viewportInfo);
|
|
1251
2169
|
}
|
|
2170
|
+
cornerstoneViewportService.disableElement(viewportId);
|
|
1252
2171
|
dist_esm.eventTarget.removeEventListener(dist_esm.Enums.Events.ELEMENT_ENABLED, elementEnabledHandler);
|
|
1253
2172
|
};
|
|
1254
2173
|
}, []);
|
|
@@ -1264,11 +2183,10 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1264
2183
|
(0,react.useEffect)(() => {
|
|
1265
2184
|
const {
|
|
1266
2185
|
unsubscribe
|
|
1267
|
-
} = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED, async
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
} = _ref;
|
|
2186
|
+
} = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SET_SERIES_METADATA_INVALIDATED, async ({
|
|
2187
|
+
displaySetInstanceUID: invalidatedDisplaySetInstanceUID,
|
|
2188
|
+
invalidateData
|
|
2189
|
+
}) => {
|
|
1272
2190
|
if (!invalidateData) {
|
|
1273
2191
|
return;
|
|
1274
2192
|
}
|
|
@@ -1295,10 +2213,9 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1295
2213
|
// The presentation state will have been stored previously by closing
|
|
1296
2214
|
// a viewport. Otherwise, this viewport will be unchanged and the
|
|
1297
2215
|
// presentation information will be directly carried over.
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
} = stateSyncService.getState();
|
|
2216
|
+
const state = stateSyncService.getState();
|
|
2217
|
+
const lutPresentationStore = state.lutPresentationStore;
|
|
2218
|
+
const positionPresentationStore = state.positionPresentationStore;
|
|
1302
2219
|
const {
|
|
1303
2220
|
presentationIds
|
|
1304
2221
|
} = viewportOptions;
|
|
@@ -1351,12 +2268,36 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1351
2268
|
unsubscribeFromJumpToMeasurementEvents();
|
|
1352
2269
|
};
|
|
1353
2270
|
}, [displaySets, elementRef, viewportId]);
|
|
2271
|
+
|
|
2272
|
+
// Set up the window level action menu in the viewport action corners.
|
|
2273
|
+
(0,react.useEffect)(() => {
|
|
2274
|
+
// Doing an === check here because the default config value when not set is true
|
|
2275
|
+
if (appConfig.addWindowLevelActionMenu === false) {
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
// TODO: In the future we should consider using the customization service
|
|
2280
|
+
// to determine if and in which corner various action components should go.
|
|
2281
|
+
const wlActionMenu = getWindowLevelActionMenu({
|
|
2282
|
+
viewportId,
|
|
2283
|
+
element: elementRef.current,
|
|
2284
|
+
displaySets,
|
|
2285
|
+
servicesManager,
|
|
2286
|
+
commandsManager,
|
|
2287
|
+
verticalDirection: ui_src/* AllInOneMenu.VerticalDirection */.se.mq.TopToBottom,
|
|
2288
|
+
horizontalDirection: ui_src/* AllInOneMenu.HorizontalDirection */.se.Iu.RightToLeft
|
|
2289
|
+
});
|
|
2290
|
+
viewportActionCornersService.setComponent({
|
|
2291
|
+
viewportId,
|
|
2292
|
+
id: 'windowLevelActionMenu',
|
|
2293
|
+
component: wlActionMenu,
|
|
2294
|
+
location: viewportActionCornersService.LOCATIONS.topRight,
|
|
2295
|
+
indexPriority: -100
|
|
2296
|
+
});
|
|
2297
|
+
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
|
1354
2298
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1355
2299
|
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
|
-
,
|
|
2300
|
+
}, /*#__PURE__*/react.createElement(index_esm/* default */.Ay, {
|
|
1360
2301
|
onResize: onResize,
|
|
1361
2302
|
targetRef: elementRef.current
|
|
1362
2303
|
}), /*#__PURE__*/react.createElement("div", {
|
|
@@ -1379,15 +2320,17 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1379
2320
|
viewportId: viewportId,
|
|
1380
2321
|
servicesManager: servicesManager
|
|
1381
2322
|
})), /*#__PURE__*/react.createElement("div", {
|
|
1382
|
-
className: "absolute w-full"
|
|
1383
|
-
}, viewportDialogState.viewportId === viewportId && /*#__PURE__*/react.createElement(ui_src/* Notification */.
|
|
2323
|
+
className: "absolute top-[24px] w-full"
|
|
2324
|
+
}, viewportDialogState.viewportId === viewportId && /*#__PURE__*/react.createElement(ui_src/* Notification */.Eg, {
|
|
1384
2325
|
id: "viewport-notification",
|
|
1385
2326
|
message: viewportDialogState.message,
|
|
1386
2327
|
type: viewportDialogState.type,
|
|
1387
2328
|
actions: viewportDialogState.actions,
|
|
1388
2329
|
onSubmit: viewportDialogState.onSubmit,
|
|
1389
2330
|
onOutsideClick: viewportDialogState.onOutsideClick
|
|
1390
|
-
}))
|
|
2331
|
+
})), /*#__PURE__*/react.createElement(components_OHIFViewportActionCorners, {
|
|
2332
|
+
viewportId: viewportId
|
|
2333
|
+
}));
|
|
1391
2334
|
}, areEqual);
|
|
1392
2335
|
function _subscribeToJumpToMeasurementEvents(measurementService, displaySetService, elementRef, viewportId, displaySets, viewportGridService, cornerstoneViewportService) {
|
|
1393
2336
|
const {
|
|
@@ -1470,7 +2413,7 @@ function _jumpToMeasurement(measurement, targetElementRef, viewportId, measureme
|
|
|
1470
2413
|
const {
|
|
1471
2414
|
SOPInstanceUID: aSOPInstanceUID,
|
|
1472
2415
|
frameNumber: aFrameNumber
|
|
1473
|
-
} = (0,getSOPInstanceAttributes/* default */.
|
|
2416
|
+
} = (0,getSOPInstanceAttributes/* default */.A)(imageId);
|
|
1474
2417
|
return aSOPInstanceUID === SOPInstanceUID && (!frameNumber || frameNumber === aFrameNumber);
|
|
1475
2418
|
});
|
|
1476
2419
|
} else {
|
|
@@ -1501,6 +2444,42 @@ function _jumpToMeasurement(measurement, targetElementRef, viewportId, measureme
|
|
|
1501
2444
|
cacheJumpToMeasurementEvent = null;
|
|
1502
2445
|
}
|
|
1503
2446
|
}
|
|
2447
|
+
function _rehydrateSynchronizers(synchronizersStore, viewportId, syncGroupService) {
|
|
2448
|
+
synchronizersStore[viewportId].forEach(synchronizerObj => {
|
|
2449
|
+
if (!synchronizerObj.id) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
const {
|
|
2453
|
+
id,
|
|
2454
|
+
sourceViewports,
|
|
2455
|
+
targetViewports
|
|
2456
|
+
} = synchronizerObj;
|
|
2457
|
+
const synchronizer = syncGroupService.getSynchronizer(id);
|
|
2458
|
+
if (!synchronizer) {
|
|
2459
|
+
return;
|
|
2460
|
+
}
|
|
2461
|
+
const sourceViewportInfo = sourceViewports.find(sourceViewport => sourceViewport.viewportId === viewportId);
|
|
2462
|
+
const targetViewportInfo = targetViewports.find(targetViewport => targetViewport.viewportId === viewportId);
|
|
2463
|
+
const isSourceViewportInSynchronizer = synchronizer.getSourceViewports().find(sourceViewport => sourceViewport.viewportId === viewportId);
|
|
2464
|
+
const isTargetViewportInSynchronizer = synchronizer.getTargetViewports().find(targetViewport => targetViewport.viewportId === viewportId);
|
|
2465
|
+
|
|
2466
|
+
// if the viewport was previously a source viewport, add it again
|
|
2467
|
+
if (sourceViewportInfo && !isSourceViewportInSynchronizer) {
|
|
2468
|
+
synchronizer.addSource({
|
|
2469
|
+
viewportId: sourceViewportInfo.viewportId,
|
|
2470
|
+
renderingEngineId: sourceViewportInfo.renderingEngineId
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
// if the viewport was previously a target viewport, add it again
|
|
2475
|
+
if (targetViewportInfo && !isTargetViewportInSynchronizer) {
|
|
2476
|
+
synchronizer.addTarget({
|
|
2477
|
+
viewportId: targetViewportInfo.viewportId,
|
|
2478
|
+
renderingEngineId: targetViewportInfo.renderingEngineId
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
1504
2483
|
|
|
1505
2484
|
// Component displayName
|
|
1506
2485
|
OHIFCornerstoneViewport.displayName = 'OHIFCornerstoneViewport';
|