@ohif/app 3.8.0-beta.66 → 3.8.0-beta.68
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/{121.bundle.fda405f29003c308ce09.js → 121.bundle.a8fc45e3d88d0a8b82a8.js} +52 -75
- package/dist/{155.bundle.e9fdaa40010cc784f389.js → 155.bundle.7b87a2dbfaf2c36326bd.js} +7 -16
- package/dist/{188.bundle.67df9790c453b185fe1d.js → 188.bundle.022af4c804b855ca2f60.js} +2 -2
- package/dist/{638.bundle.4d7da6fe507df0000718.js → 2.bundle.962c8d8b57c4f94324b4.js} +46 -15
- package/dist/{295.bundle.57700cd41fd87e1521b4.js → 295.bundle.41d7b63be6a7d726b87e.js} +75 -86
- package/dist/{41.bundle.b7bf03502ac3e2ddca35.js → 41.bundle.ad4a012883642620e839.js} +16 -45
- package/dist/425.bundle.057226d5a1a2d7dcc391.js +2957 -0
- package/dist/425.css +2 -0
- package/dist/{448.bundle.0061f5280490e1a1aa88.js → 448.bundle.1d9b1b7379fba9b8e70b.js} +5 -5
- package/dist/{530.bundle.72d9812f117036615a38.js → 530.bundle.632dcb0d4f5266058c8b.js} +41 -67
- package/dist/{544.bundle.c3009e245ceb1554c70a.js → 544.bundle.df7870b43d7aa1faed39.js} +4 -4
- package/dist/{559.bundle.bb2c52834fb372399002.js → 559.bundle.54fea45a10d3aa002764.js} +4 -4
- package/dist/{889.bundle.edf546d8738c22b94be5.js → 574.bundle.3020ab733b8f07ec50a5.js} +1005 -49
- package/dist/{594.bundle.483843d38640164a9aca.js → 594.bundle.fad610af7dae0c2fb048.js} +4 -4
- package/dist/{701.bundle.285943aebfc0efe2b4f1.js → 595.bundle.dc733f6e58d41260ba40.js} +960 -61
- package/dist/{699.bundle.62990e46c235ab4785db.js → 699.bundle.78297d5204cdd274d097.js} +18 -25
- package/dist/{724.bundle.83a4176860f750353c0b.js → 724.bundle.171eb7665e96ac0ad109.js} +13 -71
- package/dist/{862.bundle.999931264956ced59b33.js → 862.bundle.27cb716917daad6afddc.js} +64 -83
- package/dist/{270.bundle.d7d6957c20f95c675b32.js → 889.bundle.43bac729645dcd445d23.js} +5 -5
- package/dist/{90.bundle.49b20161b4f864100085.js → 90.bundle.5e1e4b60b575b5be1369.js} +15 -25
- package/dist/{905.bundle.88010c612e910657883d.js → 905.bundle.a18b495f0a6769c5aff6.js} +2 -2
- package/dist/{907.bundle.1206d58ae62d26beaf30.js → 907.bundle.bec0deb8a4af3b4885a4.js} +2 -2
- package/dist/{961.bundle.b4d84dd80e4e1113de27.js → 961.bundle.2dd02c92ec591fec7924.js} +2 -2
- package/dist/{app.bundle.81c01fc2e11fa9b6ccb8.js → app.bundle.b36fed4fdc5235c8fd31.js} +2446 -745
- package/dist/app.bundle.css +6 -4
- 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/index.html +1 -1
- package/dist/{polySeg.bundle.a97fc68de7599f9a9fdc.js → polySeg.bundle.e7b4c29fb9173e8567b8.js} +1 -1
- package/dist/sw.js +1 -1
- package/package.json +17 -17
- package/dist/339.bundle.526cede81f0a9bb248e6.js +0 -2591
- /package/dist/{164.bundle.3f877a2272b773332317.js → 164.bundle.6a75d9824ed0e87afd36.js} +0 -0
- /package/dist/{191.bundle.509480b6972209d2567c.js → 191.bundle.7d89c921abefd1140d50.js} +0 -0
- /package/dist/{638.css → 2.css} +0 -0
- /package/dist/{290.bundle.8b4d7dfbc7cfe418a0f1.js → 290.bundle.952de53057f98e2c5ef0.js} +0 -0
- /package/dist/{342.bundle.17ec05907f93624fd494.js → 342.bundle.6e49f63ea7cea4645c0a.js} +0 -0
- /package/dist/{504.bundle.6d203e80d4bd8a823059.js → 504.bundle.993d7e2dec36257d4ce4.js} +0 -0
- /package/dist/{889.css → 574.css} +0 -0
- /package/dist/{701.css → 595.css} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[
|
|
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
|
|
@@ -23,10 +23,10 @@ var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
|
23
23
|
var esm = __webpack_require__(20767);
|
|
24
24
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 383 modules
|
|
25
25
|
var dist_esm = __webpack_require__(50719);
|
|
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__(
|
|
26
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 68 modules
|
|
27
|
+
var src = __webpack_require__(85073);
|
|
28
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 521 modules
|
|
29
|
+
var ui_src = __webpack_require__(59134);
|
|
30
30
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/state.ts
|
|
31
31
|
var state = __webpack_require__(71353);
|
|
32
32
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.css
|
|
@@ -295,7 +295,13 @@ function CustomizableViewportOverlay({
|
|
|
295
295
|
const topRightCustomization = customizationService.getModeCustomization('cornerstoneOverlayTopRight');
|
|
296
296
|
const bottomLeftCustomization = customizationService.getModeCustomization('cornerstoneOverlayBottomLeft');
|
|
297
297
|
const bottomRightCustomization = customizationService.getModeCustomization('cornerstoneOverlayBottomRight');
|
|
298
|
-
const instance = (0,react.useMemo)(() =>
|
|
298
|
+
const instance = (0,react.useMemo)(() => {
|
|
299
|
+
if (viewportData != null) {
|
|
300
|
+
return _getViewportInstance(viewportData, imageIndex);
|
|
301
|
+
} else {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
}, [viewportData, imageIndex]);
|
|
299
305
|
const instanceNumber = (0,react.useMemo)(() => viewportData ? getInstanceNumber(viewportData, viewportId, imageIndex, cornerstoneViewportService) : null, [viewportData, viewportId, imageIndex, cornerstoneViewportService]);
|
|
300
306
|
|
|
301
307
|
/**
|
|
@@ -402,7 +408,12 @@ function CustomizableViewportOverlay({
|
|
|
402
408
|
const items = customization?.items ?? defaultItems;
|
|
403
409
|
return /*#__PURE__*/react.createElement(react.Fragment, null, items.map((item, index) => /*#__PURE__*/react.createElement("div", {
|
|
404
410
|
key: `${keyPrefix}_${index}`
|
|
405
|
-
}, item?.condition ? item.condition(
|
|
411
|
+
}, item?.condition ? item.condition({
|
|
412
|
+
instance,
|
|
413
|
+
formatters: {
|
|
414
|
+
formatDate: formatDICOMDate
|
|
415
|
+
}
|
|
416
|
+
}) ? _renderOverlayItem(item) : null : _renderOverlayItem(item))));
|
|
406
417
|
}, [_renderOverlayItem]);
|
|
407
418
|
return /*#__PURE__*/react.createElement(ui_src/* ViewportOverlay */.pU, {
|
|
408
419
|
topLeft:
|
|
@@ -410,6 +421,31 @@ function CustomizableViewportOverlay({
|
|
|
410
421
|
* Inline default overlay items for a more standard expansion
|
|
411
422
|
*/
|
|
412
423
|
getContent(topLeftCustomization, [{
|
|
424
|
+
id: 'StudyDate',
|
|
425
|
+
customizationType: 'ohif.overlayItem',
|
|
426
|
+
label: '',
|
|
427
|
+
title: 'Study date',
|
|
428
|
+
condition: ({
|
|
429
|
+
instance
|
|
430
|
+
}) => instance && instance.StudyDate,
|
|
431
|
+
contentF: ({
|
|
432
|
+
instance,
|
|
433
|
+
formatters: {
|
|
434
|
+
formatDate
|
|
435
|
+
}
|
|
436
|
+
}) => formatDate(instance.StudyDate)
|
|
437
|
+
}, {
|
|
438
|
+
id: 'SeriesDescription',
|
|
439
|
+
customizationType: 'ohif.overlayItem',
|
|
440
|
+
label: '',
|
|
441
|
+
title: 'Series description',
|
|
442
|
+
attribute: 'SeriesDescription',
|
|
443
|
+
condition: ({
|
|
444
|
+
instance
|
|
445
|
+
}) => instance && instance.SeriesDescription
|
|
446
|
+
}], 'topLeftOverlayItem'),
|
|
447
|
+
topRight: getContent(topRightCustomization, [], 'topRightOverlayItem'),
|
|
448
|
+
bottomLeft: getContent(bottomLeftCustomization, [{
|
|
413
449
|
id: 'WindowLevel',
|
|
414
450
|
customizationType: 'ohif.overlayItem.windowLevel'
|
|
415
451
|
}, {
|
|
@@ -419,35 +455,26 @@ function CustomizableViewportOverlay({
|
|
|
419
455
|
const activeToolName = toolGroupService.getActiveToolForViewport(viewportId);
|
|
420
456
|
return activeToolName === 'Zoom';
|
|
421
457
|
}
|
|
422
|
-
}], '
|
|
423
|
-
|
|
458
|
+
}], 'bottomLeftOverlayItem'),
|
|
459
|
+
bottomRight: getContent(bottomRightCustomization, [{
|
|
424
460
|
id: 'InstanceNumber',
|
|
425
461
|
customizationType: 'ohif.overlayItem.instanceNumber'
|
|
426
|
-
}], '
|
|
427
|
-
bottomLeft: getContent(bottomLeftCustomization, [null], 'bottomLeftOverlayItem'),
|
|
428
|
-
bottomRight: getContent(bottomRightCustomization, [null], 'bottomRightOverlayItem')
|
|
462
|
+
}], 'bottomRightOverlayItem')
|
|
429
463
|
});
|
|
430
464
|
}
|
|
431
|
-
|
|
432
|
-
const {
|
|
433
|
-
viewportType,
|
|
434
|
-
data
|
|
435
|
-
} = viewportData;
|
|
465
|
+
function _getViewportInstance(viewportData, imageIndex) {
|
|
436
466
|
let imageId = null;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
break;
|
|
446
|
-
default:
|
|
447
|
-
break;
|
|
467
|
+
if (viewportData.viewportType === dist_esm.Enums.ViewportType.STACK) {
|
|
468
|
+
imageId = viewportData.data.imageIds[imageIndex];
|
|
469
|
+
} else if (viewportData.viewportType === dist_esm.Enums.ViewportType.ORTHOGRAPHIC) {
|
|
470
|
+
const volumes = viewportData.data;
|
|
471
|
+
if (volumes && volumes.length == 1) {
|
|
472
|
+
const volume = volumes[0];
|
|
473
|
+
imageId = volume.imageIds[imageIndex];
|
|
474
|
+
}
|
|
448
475
|
}
|
|
449
476
|
return imageId ? dist_esm.metaData.get('instance', imageId) || {} : {};
|
|
450
|
-
}
|
|
477
|
+
}
|
|
451
478
|
const getInstanceNumber = (viewportData, viewportId, imageIndex, cornerstoneViewportService) => {
|
|
452
479
|
let instanceNumber;
|
|
453
480
|
switch (viewportData.viewportType) {
|
|
@@ -541,11 +568,11 @@ function VOIOverlayItem({
|
|
|
541
568
|
}, /*#__PURE__*/react.createElement("span", {
|
|
542
569
|
className: "mr-1 shrink-0"
|
|
543
570
|
}, "W:"), /*#__PURE__*/react.createElement("span", {
|
|
544
|
-
className: "ml-1 mr-2 shrink-0
|
|
571
|
+
className: "ml-1 mr-2 shrink-0"
|
|
545
572
|
}, windowWidth.toFixed(0)), /*#__PURE__*/react.createElement("span", {
|
|
546
573
|
className: "mr-1 shrink-0"
|
|
547
574
|
}, "L:"), /*#__PURE__*/react.createElement("span", {
|
|
548
|
-
className: "ml-1 shrink-0
|
|
575
|
+
className: "ml-1 shrink-0"
|
|
549
576
|
}, windowCenter.toFixed(0)));
|
|
550
577
|
}
|
|
551
578
|
|
|
@@ -563,9 +590,7 @@ function ZoomOverlayItem({
|
|
|
563
590
|
}
|
|
564
591
|
}, /*#__PURE__*/react.createElement("span", {
|
|
565
592
|
className: "mr-1 shrink-0"
|
|
566
|
-
}, "Zoom:"), /*#__PURE__*/react.createElement("span",
|
|
567
|
-
className: "font-light"
|
|
568
|
-
}, scale.toFixed(2), "x"));
|
|
593
|
+
}, "Zoom:"), /*#__PURE__*/react.createElement("span", null, scale.toFixed(2), "x"));
|
|
569
594
|
}
|
|
570
595
|
|
|
571
596
|
/**
|
|
@@ -587,9 +612,7 @@ function InstanceNumberOverlayItem({
|
|
|
587
612
|
}
|
|
588
613
|
}, /*#__PURE__*/react.createElement("span", {
|
|
589
614
|
className: "mr-1 shrink-0"
|
|
590
|
-
}, "I:"), /*#__PURE__*/react.createElement("span", {
|
|
591
|
-
className: "font-light"
|
|
592
|
-
}, instanceNumber !== undefined && instanceNumber !== null ? `${instanceNumber} (${imageIndex + 1}/${numberOfSlices})` : `${imageIndex + 1}/${numberOfSlices}`));
|
|
615
|
+
}, "I:"), /*#__PURE__*/react.createElement("span", null, instanceNumber !== undefined && instanceNumber !== null ? `${instanceNumber} (${imageIndex + 1}/${numberOfSlices})` : `${imageIndex + 1}/${numberOfSlices}`));
|
|
593
616
|
}
|
|
594
617
|
CustomizableViewportOverlay.propTypes = {
|
|
595
618
|
viewportData: (prop_types_default()).object,
|
|
@@ -694,20 +717,15 @@ function ViewportOrientationMarkers({
|
|
|
694
717
|
console.log('ViewportOrientationMarkers::No viewport');
|
|
695
718
|
return null;
|
|
696
719
|
}
|
|
697
|
-
const backgroundColor = ohifViewport.getViewportOptions().background;
|
|
698
|
-
|
|
699
|
-
// Todo: probably this can be done in a better way in which we identify bright
|
|
700
|
-
// background
|
|
701
|
-
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
702
720
|
return orientationMarkers.map((m, index) => /*#__PURE__*/react.createElement("div", {
|
|
703
|
-
className: classnames_default()(`${m}-mid orientation-marker`,
|
|
721
|
+
className: classnames_default()('overlay-text', `${m}-mid orientation-marker`, 'text-aqua-pale', 'text-[13px]', 'leading-5'),
|
|
704
722
|
key: `${m}-mid orientation-marker`
|
|
705
723
|
}, /*#__PURE__*/react.createElement("div", {
|
|
706
724
|
className: "orientation-marker-value"
|
|
707
725
|
}, markers[m])));
|
|
708
726
|
}, [viewportData, imageSliceData, rotation, flipVertical, flipHorizontal, orientationMarkers, element]);
|
|
709
727
|
return /*#__PURE__*/react.createElement("div", {
|
|
710
|
-
className: "ViewportOrientationMarkers
|
|
728
|
+
className: "ViewportOrientationMarkers select-none"
|
|
711
729
|
}, markers);
|
|
712
730
|
}
|
|
713
731
|
ViewportOrientationMarkers.propTypes = {
|
|
@@ -1049,6 +1067,908 @@ function WrappedCinePlayer({
|
|
|
1049
1067
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/CinePlayer/index.ts
|
|
1050
1068
|
|
|
1051
1069
|
/* harmony default export */ const components_CinePlayer = (CinePlayer);
|
|
1070
|
+
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/contextProviders/ViewportActionCornersProvider.tsx
|
|
1071
|
+
var ViewportActionCornersProvider = __webpack_require__(76255);
|
|
1072
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/OHIFViewportActionCorners.tsx
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
function OHIFViewportActionCorners({
|
|
1077
|
+
viewportId
|
|
1078
|
+
}) {
|
|
1079
|
+
const [viewportActionCornersState] = (0,ViewportActionCornersProvider/* useViewportActionCornersContext */.R4)();
|
|
1080
|
+
if (!viewportActionCornersState[viewportId]) {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
return /*#__PURE__*/react.createElement(ui_src/* ViewportActionCorners */.R2, {
|
|
1084
|
+
cornerComponents: viewportActionCornersState[viewportId]
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
/* harmony default export */ const components_OHIFViewportActionCorners = (OHIFViewportActionCorners);
|
|
1088
|
+
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
1089
|
+
var es = __webpack_require__(80619);
|
|
1090
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colormap.tsx
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
function Colormap({
|
|
1095
|
+
colormaps,
|
|
1096
|
+
viewportId,
|
|
1097
|
+
displaySets,
|
|
1098
|
+
commandsManager,
|
|
1099
|
+
serviceManager
|
|
1100
|
+
}) {
|
|
1101
|
+
const {
|
|
1102
|
+
cornerstoneViewportService
|
|
1103
|
+
} = serviceManager.services;
|
|
1104
|
+
const [activeDisplaySet, setActiveDisplaySet] = (0,react.useState)(displaySets[0]);
|
|
1105
|
+
const [showPreview, setShowPreview] = (0,react.useState)(false);
|
|
1106
|
+
const [prePreviewColormap, setPrePreviewColormap] = (0,react.useState)(null);
|
|
1107
|
+
const showPreviewRef = (0,react.useRef)(showPreview);
|
|
1108
|
+
showPreviewRef.current = showPreview;
|
|
1109
|
+
const prePreviewColormapRef = (0,react.useRef)(prePreviewColormap);
|
|
1110
|
+
prePreviewColormapRef.current = prePreviewColormap;
|
|
1111
|
+
const activeDisplaySetRef = (0,react.useRef)(activeDisplaySet);
|
|
1112
|
+
activeDisplaySetRef.current = activeDisplaySet;
|
|
1113
|
+
const onSetColorLUT = (0,react.useCallback)(props => {
|
|
1114
|
+
// TODO: Better way to check if it's a fusion
|
|
1115
|
+
const oneOpacityColormaps = ['Grayscale', 'X Ray'];
|
|
1116
|
+
const opacity = displaySets.length > 1 && !oneOpacityColormaps.includes(props.colormap.name) ? 0.5 : 1;
|
|
1117
|
+
commandsManager.run({
|
|
1118
|
+
commandName: 'setViewportColormap',
|
|
1119
|
+
commandOptions: {
|
|
1120
|
+
...props,
|
|
1121
|
+
opacity,
|
|
1122
|
+
immediate: true
|
|
1123
|
+
},
|
|
1124
|
+
context: 'CORNERSTONE'
|
|
1125
|
+
});
|
|
1126
|
+
}, [commandsManager]);
|
|
1127
|
+
const getViewportColormap = (viewportId, displaySet) => {
|
|
1128
|
+
const {
|
|
1129
|
+
displaySetInstanceUID
|
|
1130
|
+
} = displaySet;
|
|
1131
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1132
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1133
|
+
const {
|
|
1134
|
+
colormap
|
|
1135
|
+
} = viewport.getProperties();
|
|
1136
|
+
if (!colormap) {
|
|
1137
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1138
|
+
}
|
|
1139
|
+
return colormap;
|
|
1140
|
+
}
|
|
1141
|
+
const actorEntries = viewport.getActors();
|
|
1142
|
+
const actorEntry = actorEntries.find(entry => entry.uid.includes(displaySetInstanceUID));
|
|
1143
|
+
const {
|
|
1144
|
+
colormap
|
|
1145
|
+
} = viewport.getProperties(actorEntry.uid);
|
|
1146
|
+
if (!colormap) {
|
|
1147
|
+
return colormaps.find(c => c.Name === 'Grayscale') || colormaps[0];
|
|
1148
|
+
}
|
|
1149
|
+
return colormap;
|
|
1150
|
+
};
|
|
1151
|
+
const buttons = (0,react.useMemo)(() => {
|
|
1152
|
+
return displaySets.map((displaySet, index) => ({
|
|
1153
|
+
children: displaySet.Modality,
|
|
1154
|
+
key: index,
|
|
1155
|
+
style: {
|
|
1156
|
+
minWidth: `calc(100% / ${displaySets.length})`
|
|
1157
|
+
}
|
|
1158
|
+
}));
|
|
1159
|
+
}, [displaySets]);
|
|
1160
|
+
(0,react.useEffect)(() => {
|
|
1161
|
+
setActiveDisplaySet(displaySets[displaySets.length - 1]);
|
|
1162
|
+
}, [displaySets]);
|
|
1163
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, buttons.length > 1 && /*#__PURE__*/react.createElement("div", {
|
|
1164
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1165
|
+
}, /*#__PURE__*/react.createElement(ui_src/* ButtonGroup */.e2, {
|
|
1166
|
+
onActiveIndexChange: index => {
|
|
1167
|
+
setActiveDisplaySet(displaySets[index]);
|
|
1168
|
+
setPrePreviewColormap(null);
|
|
1169
|
+
},
|
|
1170
|
+
activeIndex: displaySets.findIndex(ds => ds.displaySetInstanceUID === activeDisplaySetRef.current.displaySetInstanceUID) || 1,
|
|
1171
|
+
className: "w-[70%] text-[10px]"
|
|
1172
|
+
}, buttons.map(({
|
|
1173
|
+
children,
|
|
1174
|
+
key,
|
|
1175
|
+
style
|
|
1176
|
+
}) => /*#__PURE__*/react.createElement("div", {
|
|
1177
|
+
key: key,
|
|
1178
|
+
style: style
|
|
1179
|
+
}, children)))), /*#__PURE__*/react.createElement("div", {
|
|
1180
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1181
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1182
|
+
label: "Preview in viewport",
|
|
1183
|
+
checked: showPreview,
|
|
1184
|
+
onChange: checked => {
|
|
1185
|
+
setShowPreview(checked);
|
|
1186
|
+
}
|
|
1187
|
+
})), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.DividerItem */.se.VG, null), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, colormaps.map((colormap, index) => /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1188
|
+
key: index,
|
|
1189
|
+
label: colormap.description,
|
|
1190
|
+
onClick: () => {
|
|
1191
|
+
onSetColorLUT({
|
|
1192
|
+
viewportId,
|
|
1193
|
+
colormap,
|
|
1194
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1195
|
+
});
|
|
1196
|
+
setPrePreviewColormap(null);
|
|
1197
|
+
},
|
|
1198
|
+
onMouseEnter: () => {
|
|
1199
|
+
if (showPreviewRef.current) {
|
|
1200
|
+
setPrePreviewColormap(getViewportColormap(viewportId, activeDisplaySetRef.current));
|
|
1201
|
+
onSetColorLUT({
|
|
1202
|
+
viewportId,
|
|
1203
|
+
colormap,
|
|
1204
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
},
|
|
1208
|
+
onMouseLeave: () => {
|
|
1209
|
+
if (showPreviewRef.current && prePreviewColormapRef.current) {
|
|
1210
|
+
onSetColorLUT({
|
|
1211
|
+
viewportId,
|
|
1212
|
+
colormap: prePreviewColormapRef.current,
|
|
1213
|
+
displaySetInstanceUID: activeDisplaySetRef.current.displaySetInstanceUID
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}))));
|
|
1218
|
+
}
|
|
1219
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/Colorbar.tsx
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
function setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, colorbarOptions) {
|
|
1225
|
+
const {
|
|
1226
|
+
cornerstoneViewportService
|
|
1227
|
+
} = serviceManager.services;
|
|
1228
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1229
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1230
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1231
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1232
|
+
if (isLight) {
|
|
1233
|
+
colorbarOptions.ticks = {
|
|
1234
|
+
position: 'left',
|
|
1235
|
+
style: {
|
|
1236
|
+
font: '12px Arial',
|
|
1237
|
+
color: '#000000',
|
|
1238
|
+
maxNumTicks: 8,
|
|
1239
|
+
tickSize: 5,
|
|
1240
|
+
tickWidth: 1,
|
|
1241
|
+
labelMargin: 3
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
const displaySetInstanceUIDs = [];
|
|
1246
|
+
if (viewport instanceof dist_esm.StackViewport) {
|
|
1247
|
+
displaySetInstanceUIDs.push(viewportId);
|
|
1248
|
+
}
|
|
1249
|
+
if (viewport instanceof dist_esm.VolumeViewport) {
|
|
1250
|
+
displaySets.forEach(ds => {
|
|
1251
|
+
displaySetInstanceUIDs.push(ds.displaySetInstanceUID);
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
commandsManager.run({
|
|
1255
|
+
commandName: 'toggleViewportColorbar',
|
|
1256
|
+
commandOptions: {
|
|
1257
|
+
viewportId,
|
|
1258
|
+
options: colorbarOptions,
|
|
1259
|
+
displaySetInstanceUIDs
|
|
1260
|
+
},
|
|
1261
|
+
context: 'CORNERSTONE'
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
function Colorbar({
|
|
1265
|
+
viewportId,
|
|
1266
|
+
displaySets,
|
|
1267
|
+
commandsManager,
|
|
1268
|
+
serviceManager,
|
|
1269
|
+
colorbarProperties
|
|
1270
|
+
}) {
|
|
1271
|
+
const {
|
|
1272
|
+
colorbarService
|
|
1273
|
+
} = serviceManager.services;
|
|
1274
|
+
const {
|
|
1275
|
+
width: colorbarWidth,
|
|
1276
|
+
colorbarTickPosition,
|
|
1277
|
+
colorbarContainerPosition,
|
|
1278
|
+
colormaps,
|
|
1279
|
+
colorbarInitialColormap
|
|
1280
|
+
} = colorbarProperties;
|
|
1281
|
+
const [showColorbar, setShowColorbar] = (0,react.useState)(colorbarService.hasColorbar(viewportId));
|
|
1282
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1283
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1284
|
+
viewportId,
|
|
1285
|
+
colormaps,
|
|
1286
|
+
ticks: {
|
|
1287
|
+
position: colorbarTickPosition
|
|
1288
|
+
},
|
|
1289
|
+
width: colorbarWidth,
|
|
1290
|
+
position: colorbarContainerPosition,
|
|
1291
|
+
activeColormapName: colorbarInitialColormap
|
|
1292
|
+
});
|
|
1293
|
+
}, [commandsManager]);
|
|
1294
|
+
(0,react.useEffect)(() => {
|
|
1295
|
+
const updateColorbarState = () => {
|
|
1296
|
+
setShowColorbar(colorbarService.hasColorbar(viewportId));
|
|
1297
|
+
};
|
|
1298
|
+
const {
|
|
1299
|
+
unsubscribe
|
|
1300
|
+
} = colorbarService.subscribe(colorbarService.EVENTS.STATE_CHANGED, updateColorbarState);
|
|
1301
|
+
return () => {
|
|
1302
|
+
unsubscribe();
|
|
1303
|
+
};
|
|
1304
|
+
}, [viewportId]);
|
|
1305
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1306
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1307
|
+
}, /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1308
|
+
label: "Display Color bar",
|
|
1309
|
+
checked: showColorbar,
|
|
1310
|
+
onChange: () => {
|
|
1311
|
+
onSetColorbar();
|
|
1312
|
+
}
|
|
1313
|
+
}));
|
|
1314
|
+
}
|
|
1315
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevel.tsx
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
function WindowLevel({
|
|
1320
|
+
viewportId,
|
|
1321
|
+
commandsManager,
|
|
1322
|
+
presets
|
|
1323
|
+
}) {
|
|
1324
|
+
const {
|
|
1325
|
+
t
|
|
1326
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1327
|
+
const onSetWindowLevel = (0,react.useCallback)(props => {
|
|
1328
|
+
commandsManager.run({
|
|
1329
|
+
commandName: 'setViewportWindowLevel',
|
|
1330
|
+
commandOptions: {
|
|
1331
|
+
...props
|
|
1332
|
+
},
|
|
1333
|
+
context: 'CORNERSTONE'
|
|
1334
|
+
});
|
|
1335
|
+
}, [commandsManager]);
|
|
1336
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.HeaderItem */.se.N5, null, t('Modality Presets', {
|
|
1337
|
+
modality: Object.keys(presets)[0]
|
|
1338
|
+
})), Object.values(presets)[0].map((preset, index) => /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1339
|
+
key: index,
|
|
1340
|
+
label: preset.description,
|
|
1341
|
+
secondaryLabel: `${preset.window} / ${preset.level}`,
|
|
1342
|
+
onClick: () => onSetWindowLevel({
|
|
1343
|
+
...preset,
|
|
1344
|
+
viewportId
|
|
1345
|
+
})
|
|
1346
|
+
})));
|
|
1347
|
+
}
|
|
1348
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresetsContent.tsx
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
function VolumeRenderingPresetsContent({
|
|
1354
|
+
presets,
|
|
1355
|
+
viewportId,
|
|
1356
|
+
commandsManager,
|
|
1357
|
+
onClose
|
|
1358
|
+
}) {
|
|
1359
|
+
const [filteredPresets, setFilteredPresets] = (0,react.useState)(presets);
|
|
1360
|
+
const [searchValue, setSearchValue] = (0,react.useState)('');
|
|
1361
|
+
const [selectedPreset, setSelectedPreset] = (0,react.useState)(null);
|
|
1362
|
+
const handleSearchChange = (0,react.useCallback)(value => {
|
|
1363
|
+
setSearchValue(value);
|
|
1364
|
+
const filtered = value ? presets.filter(preset => preset.name.toLowerCase().includes(value.toLowerCase())) : presets;
|
|
1365
|
+
setFilteredPresets(filtered);
|
|
1366
|
+
}, [presets]);
|
|
1367
|
+
const handleApply = (0,react.useCallback)(props => {
|
|
1368
|
+
commandsManager.runCommand('setViewportPreset', {
|
|
1369
|
+
...props
|
|
1370
|
+
});
|
|
1371
|
+
}, [commandsManager]);
|
|
1372
|
+
const formatLabel = (label, maxChars) => {
|
|
1373
|
+
return label.length > maxChars ? `${label.slice(0, maxChars)}...` : label;
|
|
1374
|
+
};
|
|
1375
|
+
return /*#__PURE__*/react.createElement("div", {
|
|
1376
|
+
className: "flex min-h-full w-full flex-col justify-between"
|
|
1377
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1378
|
+
className: "border-secondary-light h-[433px] w-full overflow-hidden rounded border bg-black px-2.5"
|
|
1379
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1380
|
+
className: "flex h-[46px] w-full items-center justify-start"
|
|
1381
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1382
|
+
className: "h-[26px] w-[200px]"
|
|
1383
|
+
}, /*#__PURE__*/react.createElement(ui_src/* InputFilterText */.Cv, {
|
|
1384
|
+
value: searchValue,
|
|
1385
|
+
onDebounceChange: handleSearchChange,
|
|
1386
|
+
placeholder: 'Search all'
|
|
1387
|
+
}))), /*#__PURE__*/react.createElement("div", {
|
|
1388
|
+
className: "ohif-scrollbar overflow h-[385px] w-full overflow-y-auto"
|
|
1389
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1390
|
+
className: "grid grid-cols-4 gap-3 pt-2 pr-3"
|
|
1391
|
+
}, filteredPresets.map((preset, index) => /*#__PURE__*/react.createElement("div", {
|
|
1392
|
+
key: index,
|
|
1393
|
+
className: "flex cursor-pointer flex-col items-start",
|
|
1394
|
+
onClick: () => {
|
|
1395
|
+
setSelectedPreset(preset);
|
|
1396
|
+
handleApply({
|
|
1397
|
+
preset: preset.name,
|
|
1398
|
+
viewportId
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1402
|
+
name: preset.name,
|
|
1403
|
+
className: selectedPreset?.name === preset.name ? 'border-primary-light h-[75px] w-[95px] max-w-none rounded border-2' : 'hover:border-primary-light h-[75px] w-[95px] max-w-none rounded border-2 border-black'
|
|
1404
|
+
}), /*#__PURE__*/react.createElement("label", {
|
|
1405
|
+
className: "text-aqua-pale mt-2 text-left text-xs"
|
|
1406
|
+
}, formatLabel(preset.name, 11))))))), /*#__PURE__*/react.createElement("footer", {
|
|
1407
|
+
className: "flex h-[60px] w-full items-center justify-end"
|
|
1408
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1409
|
+
className: "flex"
|
|
1410
|
+
}, /*#__PURE__*/react.createElement(ui_src/* Button */.$n, {
|
|
1411
|
+
name: "Cancel",
|
|
1412
|
+
size: ui_src/* ButtonEnums.size */.Ny.Ej.medium,
|
|
1413
|
+
type: ui_src/* ButtonEnums.type */.Ny.NW.secondary,
|
|
1414
|
+
onClick: onClose
|
|
1415
|
+
}, ' ', "Cancel", ' '))));
|
|
1416
|
+
}
|
|
1417
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
function VolumeRenderingPresets({
|
|
1422
|
+
viewportId,
|
|
1423
|
+
serviceManager,
|
|
1424
|
+
commandsManager,
|
|
1425
|
+
volumeRenderingPresets
|
|
1426
|
+
}) {
|
|
1427
|
+
const {
|
|
1428
|
+
uiModalService
|
|
1429
|
+
} = serviceManager.services;
|
|
1430
|
+
const onClickPresets = () => {
|
|
1431
|
+
uiModalService.show({
|
|
1432
|
+
content: VolumeRenderingPresetsContent,
|
|
1433
|
+
title: 'Rendering Presets',
|
|
1434
|
+
movable: true,
|
|
1435
|
+
contentProps: {
|
|
1436
|
+
onClose: uiModalService.hide,
|
|
1437
|
+
presets: volumeRenderingPresets,
|
|
1438
|
+
viewportId,
|
|
1439
|
+
commandsManager
|
|
1440
|
+
},
|
|
1441
|
+
containerDimensions: 'h-[543px] w-[460px]',
|
|
1442
|
+
contentDimensions: 'h-[493px] w-[460px] pl-[12px]'
|
|
1443
|
+
});
|
|
1444
|
+
};
|
|
1445
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.Item */.se.q7, {
|
|
1446
|
+
label: "Rendering Presets",
|
|
1447
|
+
icon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1448
|
+
name: "VolumeRendering"
|
|
1449
|
+
}),
|
|
1450
|
+
rightIcon: /*#__PURE__*/react.createElement(ui_src/* Icon */.In, {
|
|
1451
|
+
name: "action-new-dialog"
|
|
1452
|
+
}),
|
|
1453
|
+
onClick: onClickPresets
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingQuality.tsx
|
|
1457
|
+
|
|
1458
|
+
function VolumeRenderingQuality({
|
|
1459
|
+
volumeRenderingQualityRange,
|
|
1460
|
+
commandsManager,
|
|
1461
|
+
serviceManager,
|
|
1462
|
+
viewportId
|
|
1463
|
+
}) {
|
|
1464
|
+
const {
|
|
1465
|
+
cornerstoneViewportService
|
|
1466
|
+
} = serviceManager.services;
|
|
1467
|
+
const {
|
|
1468
|
+
min,
|
|
1469
|
+
max,
|
|
1470
|
+
step
|
|
1471
|
+
} = volumeRenderingQualityRange;
|
|
1472
|
+
const [quality, setQuality] = (0,react.useState)(null);
|
|
1473
|
+
const onChange = (0,react.useCallback)(value => {
|
|
1474
|
+
commandsManager.runCommand('setVolumeRenderingQulaity', {
|
|
1475
|
+
viewportId,
|
|
1476
|
+
volumeQuality: value
|
|
1477
|
+
});
|
|
1478
|
+
setQuality(value);
|
|
1479
|
+
}, [commandsManager, viewportId]);
|
|
1480
|
+
const calculateBackground = value => {
|
|
1481
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1482
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1483
|
+
};
|
|
1484
|
+
(0,react.useEffect)(() => {
|
|
1485
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1486
|
+
const {
|
|
1487
|
+
actor
|
|
1488
|
+
} = viewport.getActors()[0];
|
|
1489
|
+
const mapper = actor.getMapper();
|
|
1490
|
+
const image = mapper.getInputData();
|
|
1491
|
+
const spacing = image.getSpacing();
|
|
1492
|
+
const sampleDistance = mapper.getSampleDistance();
|
|
1493
|
+
const averageSpacing = spacing.reduce((a, b) => a + b) / 3.0;
|
|
1494
|
+
if (sampleDistance === averageSpacing) {
|
|
1495
|
+
setQuality(1);
|
|
1496
|
+
} else {
|
|
1497
|
+
setQuality(Math.sqrt(averageSpacing / (sampleDistance * 0.5)));
|
|
1498
|
+
}
|
|
1499
|
+
}, [cornerstoneViewportService, viewportId]);
|
|
1500
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1501
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1502
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1503
|
+
className: "block text-white",
|
|
1504
|
+
htmlFor: "volume"
|
|
1505
|
+
}, "Quality"), quality !== null && /*#__PURE__*/react.createElement("input", {
|
|
1506
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1507
|
+
value: quality,
|
|
1508
|
+
id: "volume",
|
|
1509
|
+
max: max,
|
|
1510
|
+
min: min,
|
|
1511
|
+
type: "range",
|
|
1512
|
+
step: step,
|
|
1513
|
+
onChange: e => onChange(parseInt(e.target.value, 10)),
|
|
1514
|
+
style: {
|
|
1515
|
+
background: calculateBackground((quality - min) / (max - min))
|
|
1516
|
+
}
|
|
1517
|
+
})));
|
|
1518
|
+
}
|
|
1519
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShift.tsx
|
|
1520
|
+
|
|
1521
|
+
function VolumeShift({
|
|
1522
|
+
viewportId,
|
|
1523
|
+
commandsManager,
|
|
1524
|
+
serviceManager
|
|
1525
|
+
}) {
|
|
1526
|
+
const {
|
|
1527
|
+
cornerstoneViewportService
|
|
1528
|
+
} = serviceManager.services;
|
|
1529
|
+
const [minShift, setMinShift] = (0,react.useState)(null);
|
|
1530
|
+
const [maxShift, setMaxShift] = (0,react.useState)(null);
|
|
1531
|
+
const [shift, setShift] = (0,react.useState)(cornerstoneViewportService.getCornerstoneViewport(viewportId)?.shiftedBy || 0);
|
|
1532
|
+
const [step, setStep] = (0,react.useState)(null);
|
|
1533
|
+
const [isBlocking, setIsBlocking] = (0,react.useState)(false);
|
|
1534
|
+
const prevShiftRef = (0,react.useRef)(shift);
|
|
1535
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1536
|
+
const {
|
|
1537
|
+
actor
|
|
1538
|
+
} = viewport.getActors()[0];
|
|
1539
|
+
const ofun = actor.getProperty().getScalarOpacity(0);
|
|
1540
|
+
(0,react.useEffect)(() => {
|
|
1541
|
+
if (isBlocking) {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
const range = ofun.getRange();
|
|
1545
|
+
const transferFunctionWidth = range[1] - range[0];
|
|
1546
|
+
const minShift = -transferFunctionWidth;
|
|
1547
|
+
const maxShift = transferFunctionWidth;
|
|
1548
|
+
setMinShift(minShift);
|
|
1549
|
+
setMaxShift(maxShift);
|
|
1550
|
+
setStep(Math.pow(10, Math.floor(Math.log10(transferFunctionWidth / 500))));
|
|
1551
|
+
}, [cornerstoneViewportService, viewportId, actor, ofun, isBlocking]);
|
|
1552
|
+
const onChangeRange = (0,react.useCallback)(newShift => {
|
|
1553
|
+
const shiftDifference = newShift - prevShiftRef.current;
|
|
1554
|
+
prevShiftRef.current = newShift;
|
|
1555
|
+
viewport.shiftedBy = newShift;
|
|
1556
|
+
commandsManager.runCommand('shiftVolumeOpacityPoints', {
|
|
1557
|
+
viewportId,
|
|
1558
|
+
shift: shiftDifference
|
|
1559
|
+
});
|
|
1560
|
+
}, [commandsManager, viewportId, viewport]);
|
|
1561
|
+
const calculateBackground = value => {
|
|
1562
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1563
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1564
|
+
};
|
|
1565
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1566
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1567
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1568
|
+
className: "block text-white",
|
|
1569
|
+
htmlFor: "shift"
|
|
1570
|
+
}, "Shift"), step !== null && /*#__PURE__*/react.createElement("input", {
|
|
1571
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1572
|
+
value: shift,
|
|
1573
|
+
onChange: e => {
|
|
1574
|
+
const shiftValue = parseInt(e.target.value, 10);
|
|
1575
|
+
setShift(shiftValue);
|
|
1576
|
+
onChangeRange(shiftValue);
|
|
1577
|
+
},
|
|
1578
|
+
id: "shift",
|
|
1579
|
+
onMouseDown: () => setIsBlocking(true),
|
|
1580
|
+
onMouseUp: () => setIsBlocking(false),
|
|
1581
|
+
max: maxShift,
|
|
1582
|
+
min: minShift,
|
|
1583
|
+
type: "range",
|
|
1584
|
+
step: step,
|
|
1585
|
+
style: {
|
|
1586
|
+
background: calculateBackground((shift - minShift) / (maxShift - minShift))
|
|
1587
|
+
}
|
|
1588
|
+
})));
|
|
1589
|
+
}
|
|
1590
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeLighting.tsx
|
|
1591
|
+
|
|
1592
|
+
function VolumeLighting({
|
|
1593
|
+
serviceManager,
|
|
1594
|
+
commandsManager,
|
|
1595
|
+
viewportId
|
|
1596
|
+
}) {
|
|
1597
|
+
const {
|
|
1598
|
+
cornerstoneViewportService
|
|
1599
|
+
} = serviceManager.services;
|
|
1600
|
+
const [ambient, setAmbient] = (0,react.useState)(null);
|
|
1601
|
+
const [diffuse, setDiffuse] = (0,react.useState)(null);
|
|
1602
|
+
const [specular, setSpecular] = (0,react.useState)(null);
|
|
1603
|
+
const onAmbientChange = (0,react.useCallback)(() => {
|
|
1604
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1605
|
+
viewportId,
|
|
1606
|
+
options: {
|
|
1607
|
+
ambient
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1610
|
+
}, [ambient, commandsManager, viewportId]);
|
|
1611
|
+
const onDiffuseChange = (0,react.useCallback)(() => {
|
|
1612
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1613
|
+
viewportId,
|
|
1614
|
+
options: {
|
|
1615
|
+
diffuse
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
}, [diffuse, commandsManager, viewportId]);
|
|
1619
|
+
const onSpecularChange = (0,react.useCallback)(() => {
|
|
1620
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1621
|
+
viewportId,
|
|
1622
|
+
options: {
|
|
1623
|
+
specular
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
}, [specular, commandsManager, viewportId]);
|
|
1627
|
+
const calculateBackground = value => {
|
|
1628
|
+
const percentage = (value - 0) / (1 - 0) * 100;
|
|
1629
|
+
return `linear-gradient(to right, #5acce6 0%, #5acce6 ${percentage}%, #3a3f99 ${percentage}%, #3a3f99 100%)`;
|
|
1630
|
+
};
|
|
1631
|
+
(0,react.useEffect)(() => {
|
|
1632
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1633
|
+
const {
|
|
1634
|
+
actor
|
|
1635
|
+
} = viewport.getActors()[0];
|
|
1636
|
+
const ambient = actor.getProperty().getAmbient();
|
|
1637
|
+
const diffuse = actor.getProperty().getDiffuse();
|
|
1638
|
+
const specular = actor.getProperty().getSpecular();
|
|
1639
|
+
setAmbient(ambient);
|
|
1640
|
+
setDiffuse(diffuse);
|
|
1641
|
+
setSpecular(specular);
|
|
1642
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1643
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1644
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1645
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1646
|
+
className: "block text-white",
|
|
1647
|
+
htmlFor: "ambient"
|
|
1648
|
+
}, "Ambient"), ambient !== null && /*#__PURE__*/react.createElement("input", {
|
|
1649
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1650
|
+
value: ambient,
|
|
1651
|
+
onChange: e => {
|
|
1652
|
+
setAmbient(e.target.value);
|
|
1653
|
+
onAmbientChange();
|
|
1654
|
+
},
|
|
1655
|
+
id: "ambient",
|
|
1656
|
+
max: 1,
|
|
1657
|
+
min: 0,
|
|
1658
|
+
type: "range",
|
|
1659
|
+
step: 0.1,
|
|
1660
|
+
style: {
|
|
1661
|
+
background: calculateBackground(ambient)
|
|
1662
|
+
}
|
|
1663
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1664
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1665
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1666
|
+
className: "block text-white",
|
|
1667
|
+
htmlFor: "diffuse"
|
|
1668
|
+
}, "Diffuse"), diffuse !== null && /*#__PURE__*/react.createElement("input", {
|
|
1669
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1670
|
+
value: diffuse,
|
|
1671
|
+
onChange: e => {
|
|
1672
|
+
setDiffuse(e.target.value);
|
|
1673
|
+
onDiffuseChange();
|
|
1674
|
+
},
|
|
1675
|
+
id: "diffuse",
|
|
1676
|
+
max: 1,
|
|
1677
|
+
min: 0,
|
|
1678
|
+
type: "range",
|
|
1679
|
+
step: 0.1,
|
|
1680
|
+
style: {
|
|
1681
|
+
background: calculateBackground(diffuse)
|
|
1682
|
+
}
|
|
1683
|
+
})), /*#__PURE__*/react.createElement("div", {
|
|
1684
|
+
className: "all-in-one-menu-item flex w-full flex-row !items-center justify-between gap-[10px]"
|
|
1685
|
+
}, /*#__PURE__*/react.createElement("label", {
|
|
1686
|
+
className: "block text-white",
|
|
1687
|
+
htmlFor: "specular"
|
|
1688
|
+
}, "Specular"), specular !== null && /*#__PURE__*/react.createElement("input", {
|
|
1689
|
+
className: "bg-inputfield-main h-2 w-[120px] cursor-pointer appearance-none rounded-lg",
|
|
1690
|
+
value: specular,
|
|
1691
|
+
onChange: e => {
|
|
1692
|
+
setSpecular(e.target.value);
|
|
1693
|
+
onSpecularChange();
|
|
1694
|
+
},
|
|
1695
|
+
id: "specular",
|
|
1696
|
+
max: 1,
|
|
1697
|
+
min: 0,
|
|
1698
|
+
type: "range",
|
|
1699
|
+
step: 0.1,
|
|
1700
|
+
style: {
|
|
1701
|
+
background: calculateBackground(specular)
|
|
1702
|
+
}
|
|
1703
|
+
})));
|
|
1704
|
+
}
|
|
1705
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeShade.tsx
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
function VolumeShade({
|
|
1709
|
+
commandsManager,
|
|
1710
|
+
viewportId,
|
|
1711
|
+
serviceManager
|
|
1712
|
+
}) {
|
|
1713
|
+
const {
|
|
1714
|
+
cornerstoneViewportService
|
|
1715
|
+
} = serviceManager.services;
|
|
1716
|
+
const [shade, setShade] = (0,react.useState)(true);
|
|
1717
|
+
const [key, setKey] = (0,react.useState)(0);
|
|
1718
|
+
const onShadeChange = (0,react.useCallback)(checked => {
|
|
1719
|
+
commandsManager.runCommand('setVolumeLighting', {
|
|
1720
|
+
viewportId,
|
|
1721
|
+
options: {
|
|
1722
|
+
shade: checked
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
}, [commandsManager, viewportId]);
|
|
1726
|
+
(0,react.useEffect)(() => {
|
|
1727
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1728
|
+
const {
|
|
1729
|
+
actor
|
|
1730
|
+
} = viewport.getActors()[0];
|
|
1731
|
+
const shade = actor.getProperty().getShade();
|
|
1732
|
+
setShade(shade);
|
|
1733
|
+
setKey(key + 1);
|
|
1734
|
+
}, [viewportId, cornerstoneViewportService]);
|
|
1735
|
+
return /*#__PURE__*/react.createElement(ui_src/* SwitchButton */.L$, {
|
|
1736
|
+
key: key,
|
|
1737
|
+
label: "Shade",
|
|
1738
|
+
checked: shade,
|
|
1739
|
+
onChange: () => {
|
|
1740
|
+
setShade(!shade);
|
|
1741
|
+
onShadeChange(!shade);
|
|
1742
|
+
}
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingOptions.tsx
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
function VolumeRenderingOptions({
|
|
1753
|
+
viewportId,
|
|
1754
|
+
commandsManager,
|
|
1755
|
+
volumeRenderingQualityRange,
|
|
1756
|
+
serviceManager
|
|
1757
|
+
}) {
|
|
1758
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, /*#__PURE__*/react.createElement(VolumeRenderingQuality, {
|
|
1759
|
+
viewportId: viewportId,
|
|
1760
|
+
commandsManager: commandsManager,
|
|
1761
|
+
serviceManager: serviceManager,
|
|
1762
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1763
|
+
}), /*#__PURE__*/react.createElement(VolumeShift, {
|
|
1764
|
+
viewportId: viewportId,
|
|
1765
|
+
commandsManager: commandsManager,
|
|
1766
|
+
serviceManager: serviceManager
|
|
1767
|
+
}), /*#__PURE__*/react.createElement("div", {
|
|
1768
|
+
className: "all-in-one-menu-item flex w-full justify-start"
|
|
1769
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1770
|
+
className: "text-aqua-pale text-[13px]"
|
|
1771
|
+
}, "LIGHTING")), /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.DividerItem */.se.VG, null), /*#__PURE__*/react.createElement("div", {
|
|
1772
|
+
className: "all-in-one-menu-item flex w-full justify-center"
|
|
1773
|
+
}, /*#__PURE__*/react.createElement(VolumeShade, {
|
|
1774
|
+
commandsManager: commandsManager,
|
|
1775
|
+
serviceManager: serviceManager,
|
|
1776
|
+
viewportId: viewportId
|
|
1777
|
+
})), /*#__PURE__*/react.createElement(VolumeLighting, {
|
|
1778
|
+
viewportId: viewportId,
|
|
1779
|
+
commandsManager: commandsManager,
|
|
1780
|
+
serviceManager: serviceManager
|
|
1781
|
+
}));
|
|
1782
|
+
}
|
|
1783
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/WindowLevelActionMenu.tsx
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
function WindowLevelActionMenu({
|
|
1797
|
+
viewportId,
|
|
1798
|
+
element,
|
|
1799
|
+
presets,
|
|
1800
|
+
verticalDirection,
|
|
1801
|
+
horizontalDirection,
|
|
1802
|
+
commandsManager,
|
|
1803
|
+
serviceManager,
|
|
1804
|
+
colorbarProperties,
|
|
1805
|
+
displaySets,
|
|
1806
|
+
volumeRenderingPresets,
|
|
1807
|
+
volumeRenderingQualityRange
|
|
1808
|
+
}) {
|
|
1809
|
+
const {
|
|
1810
|
+
colormaps,
|
|
1811
|
+
colorbarContainerPosition,
|
|
1812
|
+
colorbarInitialColormap,
|
|
1813
|
+
colorbarTickPosition,
|
|
1814
|
+
width: colorbarWidth
|
|
1815
|
+
} = colorbarProperties;
|
|
1816
|
+
const {
|
|
1817
|
+
colorbarService,
|
|
1818
|
+
cornerstoneViewportService
|
|
1819
|
+
} = serviceManager.services;
|
|
1820
|
+
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
1821
|
+
const backgroundColor = viewportInfo.getViewportOptions().background;
|
|
1822
|
+
const isLight = backgroundColor ? dist_esm.utilities.isEqual(backgroundColor, [1, 1, 1]) : false;
|
|
1823
|
+
const nonImageModalities = ['SR', 'SEG', 'SM', 'RTSTRUCT', 'RTPLAN', 'RTDOSE'];
|
|
1824
|
+
const {
|
|
1825
|
+
t
|
|
1826
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
1827
|
+
const [viewportGrid] = (0,ui_src/* useViewportGrid */.ih)();
|
|
1828
|
+
const {
|
|
1829
|
+
activeViewportId
|
|
1830
|
+
} = viewportGrid;
|
|
1831
|
+
const [vpHeight, setVpHeight] = (0,react.useState)(element?.clientHeight);
|
|
1832
|
+
const [menuKey, setMenuKey] = (0,react.useState)(0);
|
|
1833
|
+
const [is3DVolume, setIs3DVolume] = (0,react.useState)(false);
|
|
1834
|
+
const onSetColorbar = (0,react.useCallback)(() => {
|
|
1835
|
+
setViewportColorbar(viewportId, displaySets, commandsManager, serviceManager, {
|
|
1836
|
+
colormaps,
|
|
1837
|
+
ticks: {
|
|
1838
|
+
position: colorbarTickPosition
|
|
1839
|
+
},
|
|
1840
|
+
width: colorbarWidth,
|
|
1841
|
+
position: colorbarContainerPosition,
|
|
1842
|
+
activeColormapName: colorbarInitialColormap
|
|
1843
|
+
});
|
|
1844
|
+
}, [commandsManager]);
|
|
1845
|
+
(0,react.useEffect)(() => {
|
|
1846
|
+
const newVpHeight = element?.clientHeight;
|
|
1847
|
+
if (vpHeight !== newVpHeight) {
|
|
1848
|
+
setVpHeight(newVpHeight);
|
|
1849
|
+
}
|
|
1850
|
+
}, [element, vpHeight]);
|
|
1851
|
+
(0,react.useEffect)(() => {
|
|
1852
|
+
if (!colorbarService.hasColorbar(viewportId)) {
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1855
|
+
window.setTimeout(() => {
|
|
1856
|
+
colorbarService.removeColorbar(viewportId);
|
|
1857
|
+
onSetColorbar();
|
|
1858
|
+
}, 0);
|
|
1859
|
+
}, [viewportId]);
|
|
1860
|
+
(0,react.useEffect)(() => {
|
|
1861
|
+
if (colorbarService.hasColorbar(viewportId)) {
|
|
1862
|
+
colorbarService.removeColorbar(viewportId);
|
|
1863
|
+
}
|
|
1864
|
+
}, [displaySets]);
|
|
1865
|
+
(0,react.useEffect)(() => {
|
|
1866
|
+
setMenuKey(menuKey + 1);
|
|
1867
|
+
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
1868
|
+
if (viewport instanceof dist_esm.VolumeViewport3D) {
|
|
1869
|
+
setIs3DVolume(true);
|
|
1870
|
+
} else {
|
|
1871
|
+
setIs3DVolume(false);
|
|
1872
|
+
}
|
|
1873
|
+
}, [displaySets, viewportId, presets, volumeRenderingQualityRange, volumeRenderingPresets, colorbarProperties, activeViewportId, viewportGrid]);
|
|
1874
|
+
return /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.IconMenu */.se.dd, {
|
|
1875
|
+
icon: "viewport-window-level",
|
|
1876
|
+
verticalDirection: verticalDirection,
|
|
1877
|
+
horizontalDirection: horizontalDirection,
|
|
1878
|
+
iconClassName: classnames_default()(
|
|
1879
|
+
// Visible on hover and for the active viewport
|
|
1880
|
+
activeViewportId === viewportId ? 'visible' : 'invisible group-hover:visible', 'flex shrink-0 cursor-pointer rounded active:text-white', isLight ? 'text-aqua-pale hover:bg-secondary-dark' : 'text-primary-light hover:bg-secondary-light/60'),
|
|
1881
|
+
menuStyle: {
|
|
1882
|
+
maxHeight: vpHeight - 32,
|
|
1883
|
+
minWidth: 218
|
|
1884
|
+
},
|
|
1885
|
+
onVisibilityChange: () => {
|
|
1886
|
+
setVpHeight(element.clientHeight);
|
|
1887
|
+
},
|
|
1888
|
+
menuKey: menuKey
|
|
1889
|
+
}, /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.ItemPanel */.se.cV, null, !is3DVolume && /*#__PURE__*/react.createElement(Colorbar, {
|
|
1890
|
+
viewportId: viewportId,
|
|
1891
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1892
|
+
commandsManager: commandsManager,
|
|
1893
|
+
serviceManager: serviceManager,
|
|
1894
|
+
colorbarProperties: colorbarProperties
|
|
1895
|
+
}), colormaps && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1896
|
+
key: "colorLUTPresets",
|
|
1897
|
+
itemLabel: "Color LUT",
|
|
1898
|
+
itemIcon: "icon-color-lut"
|
|
1899
|
+
}, /*#__PURE__*/react.createElement(Colormap, {
|
|
1900
|
+
colormaps: colormaps,
|
|
1901
|
+
viewportId: viewportId,
|
|
1902
|
+
displaySets: displaySets.filter(ds => !nonImageModalities.includes(ds.Modality)),
|
|
1903
|
+
commandsManager: commandsManager,
|
|
1904
|
+
serviceManager: serviceManager
|
|
1905
|
+
})), presets && !is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1906
|
+
key: "windowLevelPresets",
|
|
1907
|
+
itemLabel: t('Modality Window Presets', {
|
|
1908
|
+
modality: Object.keys(presets)[0]
|
|
1909
|
+
}),
|
|
1910
|
+
itemIcon: "viewport-window-level"
|
|
1911
|
+
}, /*#__PURE__*/react.createElement(WindowLevel, {
|
|
1912
|
+
viewportId: viewportId,
|
|
1913
|
+
commandsManager: commandsManager,
|
|
1914
|
+
presets: presets
|
|
1915
|
+
})), volumeRenderingPresets && is3DVolume && /*#__PURE__*/react.createElement(VolumeRenderingPresets, {
|
|
1916
|
+
serviceManager: serviceManager,
|
|
1917
|
+
viewportId: viewportId,
|
|
1918
|
+
commandsManager: commandsManager,
|
|
1919
|
+
volumeRenderingPresets: volumeRenderingPresets
|
|
1920
|
+
}), volumeRenderingQualityRange && is3DVolume && /*#__PURE__*/react.createElement(ui_src/* AllInOneMenu.SubMenu */.se.g8, {
|
|
1921
|
+
itemLabel: "Rendering Options"
|
|
1922
|
+
}, /*#__PURE__*/react.createElement(VolumeRenderingOptions, {
|
|
1923
|
+
viewportId: viewportId,
|
|
1924
|
+
commandsManager: commandsManager,
|
|
1925
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange,
|
|
1926
|
+
serviceManager: serviceManager
|
|
1927
|
+
}))));
|
|
1928
|
+
}
|
|
1929
|
+
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/getWindowLevelActionMenu.tsx
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
function getWindowLevelActionMenu({
|
|
1933
|
+
viewportId,
|
|
1934
|
+
element,
|
|
1935
|
+
displaySets,
|
|
1936
|
+
servicesManager,
|
|
1937
|
+
commandsManager,
|
|
1938
|
+
verticalDirection,
|
|
1939
|
+
horizontalDirection
|
|
1940
|
+
}) {
|
|
1941
|
+
const {
|
|
1942
|
+
customizationService
|
|
1943
|
+
} = servicesManager.services;
|
|
1944
|
+
const {
|
|
1945
|
+
presets
|
|
1946
|
+
} = customizationService.get('cornerstone.windowLevelPresets');
|
|
1947
|
+
const colorbarProperties = customizationService.get('cornerstone.colorbar');
|
|
1948
|
+
const {
|
|
1949
|
+
volumeRenderingPresets,
|
|
1950
|
+
volumeRenderingQualityRange
|
|
1951
|
+
} = customizationService.get('cornerstone.3dVolumeRendering');
|
|
1952
|
+
const displaySetPresets = displaySets.filter(displaySet => presets[displaySet.Modality]).map(displaySet => {
|
|
1953
|
+
return {
|
|
1954
|
+
[displaySet.Modality]: presets[displaySet.Modality]
|
|
1955
|
+
};
|
|
1956
|
+
});
|
|
1957
|
+
const hasMenu = displaySetPresets.length > 0;
|
|
1958
|
+
return hasMenu ? /*#__PURE__*/react.createElement(WindowLevelActionMenu, {
|
|
1959
|
+
viewportId: viewportId,
|
|
1960
|
+
element: element,
|
|
1961
|
+
presets: displaySetPresets[0],
|
|
1962
|
+
verticalDirection: verticalDirection,
|
|
1963
|
+
horizontalDirection: horizontalDirection,
|
|
1964
|
+
commandsManager: commandsManager,
|
|
1965
|
+
serviceManager: servicesManager,
|
|
1966
|
+
colorbarProperties: colorbarProperties,
|
|
1967
|
+
displaySets: displaySets,
|
|
1968
|
+
volumeRenderingPresets: volumeRenderingPresets,
|
|
1969
|
+
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
1970
|
+
}) : null;
|
|
1971
|
+
}
|
|
1052
1972
|
;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx
|
|
1053
1973
|
|
|
1054
1974
|
|
|
@@ -1062,6 +1982,9 @@ function WrappedCinePlayer({
|
|
|
1062
1982
|
|
|
1063
1983
|
|
|
1064
1984
|
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1065
1988
|
const STACK = 'stack';
|
|
1066
1989
|
|
|
1067
1990
|
/**
|
|
@@ -1139,6 +2062,7 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1139
2062
|
const [scrollbarHeight, setScrollbarHeight] = (0,react.useState)('100px');
|
|
1140
2063
|
const [enabledVPElement, setEnabledVPElement] = (0,react.useState)(null);
|
|
1141
2064
|
const elementRef = (0,react.useRef)();
|
|
2065
|
+
const [appConfig] = (0,state_0/* useAppConfig */.r)();
|
|
1142
2066
|
const {
|
|
1143
2067
|
measurementService,
|
|
1144
2068
|
displaySetService,
|
|
@@ -1148,12 +2072,14 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1148
2072
|
cornerstoneViewportService,
|
|
1149
2073
|
cornerstoneCacheService,
|
|
1150
2074
|
viewportGridService,
|
|
1151
|
-
stateSyncService
|
|
2075
|
+
stateSyncService,
|
|
2076
|
+
viewportActionCornersService,
|
|
2077
|
+
customizationService
|
|
1152
2078
|
} = servicesManager.services;
|
|
1153
2079
|
const [viewportDialogState] = (0,ui_src/* useViewportDialog */.OR)();
|
|
1154
2080
|
// useCallback for scroll bar height calculation
|
|
1155
2081
|
const setImageScrollBarHeight = (0,react.useCallback)(() => {
|
|
1156
|
-
const scrollbarHeight = `${elementRef.current.clientHeight -
|
|
2082
|
+
const scrollbarHeight = `${elementRef.current.clientHeight - 40}px`;
|
|
1157
2083
|
setScrollbarHeight(scrollbarHeight);
|
|
1158
2084
|
}, [elementRef]);
|
|
1159
2085
|
|
|
@@ -1169,6 +2095,7 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1169
2095
|
const syncGroups = viewportInfo.getSyncGroups();
|
|
1170
2096
|
toolGroupService.removeViewportFromToolGroup(viewportId, renderingEngineId);
|
|
1171
2097
|
syncGroupService.removeViewportFromSyncGroup(viewportId, renderingEngineId, syncGroups);
|
|
2098
|
+
viewportActionCornersService.clear(viewportId);
|
|
1172
2099
|
}, [viewportId]);
|
|
1173
2100
|
const elementEnabledHandler = (0,react.useCallback)(evt => {
|
|
1174
2101
|
// check this is this element reference and return early if doesn't match
|
|
@@ -1319,6 +2246,33 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1319
2246
|
unsubscribeFromJumpToMeasurementEvents();
|
|
1320
2247
|
};
|
|
1321
2248
|
}, [displaySets, elementRef, viewportId]);
|
|
2249
|
+
|
|
2250
|
+
// Set up the window level action menu in the viewport action corners.
|
|
2251
|
+
(0,react.useEffect)(() => {
|
|
2252
|
+
// Doing an === check here because the default config value when not set is true
|
|
2253
|
+
if (appConfig.addWindowLevelActionMenu === false) {
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
// TODO: In the future we should consider using the customization service
|
|
2258
|
+
// to determine if and in which corner various action components should go.
|
|
2259
|
+
const wlActionMenu = getWindowLevelActionMenu({
|
|
2260
|
+
viewportId,
|
|
2261
|
+
element: elementRef.current,
|
|
2262
|
+
displaySets,
|
|
2263
|
+
servicesManager,
|
|
2264
|
+
commandsManager,
|
|
2265
|
+
verticalDirection: ui_src/* AllInOneMenu.VerticalDirection */.se.mq.TopToBottom,
|
|
2266
|
+
horizontalDirection: ui_src/* AllInOneMenu.HorizontalDirection */.se.Iu.RightToLeft
|
|
2267
|
+
});
|
|
2268
|
+
viewportActionCornersService.setComponent({
|
|
2269
|
+
viewportId,
|
|
2270
|
+
id: 'windowLevelActionMenu',
|
|
2271
|
+
component: wlActionMenu,
|
|
2272
|
+
location: viewportActionCornersService.LOCATIONS.topRight,
|
|
2273
|
+
indexPriority: -100
|
|
2274
|
+
});
|
|
2275
|
+
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
|
1322
2276
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1323
2277
|
className: "viewport-wrapper"
|
|
1324
2278
|
}, /*#__PURE__*/react.createElement(index_esm/* default */.Ay, {
|
|
@@ -1344,7 +2298,7 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1344
2298
|
viewportId: viewportId,
|
|
1345
2299
|
servicesManager: servicesManager
|
|
1346
2300
|
})), /*#__PURE__*/react.createElement("div", {
|
|
1347
|
-
className: "absolute w-full"
|
|
2301
|
+
className: "absolute top-[24px] w-full"
|
|
1348
2302
|
}, viewportDialogState.viewportId === viewportId && /*#__PURE__*/react.createElement(ui_src/* Notification */.Eg, {
|
|
1349
2303
|
id: "viewport-notification",
|
|
1350
2304
|
message: viewportDialogState.message,
|
|
@@ -1352,7 +2306,9 @@ const OHIFCornerstoneViewport = /*#__PURE__*/react.memo(props => {
|
|
|
1352
2306
|
actions: viewportDialogState.actions,
|
|
1353
2307
|
onSubmit: viewportDialogState.onSubmit,
|
|
1354
2308
|
onOutsideClick: viewportDialogState.onOutsideClick
|
|
1355
|
-
}))
|
|
2309
|
+
})), /*#__PURE__*/react.createElement(components_OHIFViewportActionCorners, {
|
|
2310
|
+
viewportId: viewportId
|
|
2311
|
+
}));
|
|
1356
2312
|
}, areEqual);
|
|
1357
2313
|
function _subscribeToJumpToMeasurementEvents(measurementService, displaySetService, elementRef, viewportId, displaySets, viewportGridService, cornerstoneViewportService) {
|
|
1358
2314
|
const {
|