@3cr/viewer-browser 0.0.53 → 0.0.57
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/__tests__/index.spec.ts +31 -0
- package/components.d.ts +3 -2
- package/coverage/3cr-viewer-browser/index.html +116 -0
- package/coverage/3cr-viewer-browser/index.ts.html +211 -0
- package/coverage/3cr-viewer-browser/src/App.vue.html +313 -0
- package/coverage/3cr-viewer-browser/src/components/WebGL3DR.vue.html +442 -0
- package/coverage/3cr-viewer-browser/src/components/icons/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/icons/liver.vue.html +148 -0
- package/coverage/3cr-viewer-browser/src/components/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/loading/LoadingSpinner.vue.html +556 -0
- package/coverage/3cr-viewer-browser/src/components/loading/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/modal/MftpWebGL3DRModal.vue.html +4126 -0
- package/coverage/3cr-viewer-browser/src/components/modal/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/selectors/ValueSelector.vue.html +331 -0
- package/coverage/3cr-viewer-browser/src/components/selectors/index.html +116 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/DoubleSliderSelector.vue.html +445 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/VerticalSliderSelector.vue.html +349 -0
- package/coverage/3cr-viewer-browser/src/components/sliders/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/helpers/index.html +146 -0
- package/coverage/3cr-viewer-browser/src/helpers/layoutOverlayStyle.ts.html +406 -0
- package/coverage/3cr-viewer-browser/src/helpers/modelHelper.ts.html +412 -0
- package/coverage/3cr-viewer-browser/src/helpers/utils.ts.html +133 -0
- package/coverage/3cr-viewer-browser/src/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/main.ts.html +124 -0
- package/coverage/3cr-viewer-browser/src/plugins/index.html +131 -0
- package/coverage/3cr-viewer-browser/src/plugins/index.ts.html +130 -0
- package/coverage/3cr-viewer-browser/src/plugins/vuetify.ts.html +220 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +251 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/dist/Viewer3CR.js +17 -11
- package/dist/Viewer3CR.mjs +11911 -11157
- package/dist/Viewer3CR.umd.js +17 -11
- package/index.html +4 -1
- package/index.ts +46 -11
- package/package.json +9 -3
- package/src/App.vue +34 -45
- package/src/__tests__/app.spec.ts +27 -0
- package/src/components/WebGL3DR.vue +49 -37
- package/src/components/__tests__/webgl3dr.spec.ts +56 -0
- package/src/components/icons/liver.vue +21 -0
- package/src/components/loading/LoadingSpinner.vue +34 -12
- package/src/components/loading/__tests__/loading-spinner.spec.ts +11 -0
- package/src/components/modal/DemoModal.vue +44 -0
- package/src/components/modal/MftpWebGL3DRModal.vue +763 -410
- package/src/components/modal/__tests__/mftp-webgl-3dr-modal.spec.ts +690 -0
- package/src/components/selectors/__tests__/value-selector.spec.ts +35 -0
- package/src/components/sliders/DoubleSliderSelector.vue +30 -24
- package/src/components/sliders/VerticalSliderSelector.vue +25 -21
- package/src/components/sliders/__tests__/double-slider-selector.spec.ts +72 -0
- package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +61 -0
- package/src/helpers/__tests__/layout-overlay-style.spec.ts +288 -0
- package/src/helpers/__tests__/model-helper.spec.ts +118 -0
- package/src/helpers/__tests__/utils.spec.ts +70 -0
- package/src/helpers/layoutOverlayStyle.ts +50 -30
- package/src/plugins/__tests__/index.spec.ts +19 -0
- package/src/plugins/__tests__/vuetify.spec.ts +8 -0
- package/src/plugins/index.ts +6 -4
- package/src/plugins/vuetify.ts +25 -8
- package/test/helper.ts +35 -0
- package/test/setup.ts +1 -0
- package/tsconfig.json +5 -2
- package/vite.config.mts +1 -0
- package/vitest.config.mts +44 -0
- package/src/components/expansion-panels/ExpansionHeaderMiniMenu.vue +0 -19
- package/src/helpers/models.ts +0 -69
- /package/src/components/{sliders/SliderSelector.vue → selectors/ValueSelector.vue} +0 -0
|
@@ -1,22 +1,34 @@
|
|
|
1
|
+
<!-- /* c8 ignore start */ -->
|
|
1
2
|
<template>
|
|
3
|
+
<DemoModal v-model:modal="m_demo" />
|
|
2
4
|
<v-dialog
|
|
5
|
+
id="cr-viewer"
|
|
3
6
|
class="pa-0 ma-0 overflow-y-auto overflow-x-hidden"
|
|
4
7
|
:modelValue="value"
|
|
5
8
|
style="max-height: unset"
|
|
6
9
|
:scrollable="false"
|
|
7
10
|
fullscreen
|
|
8
11
|
persistent
|
|
9
|
-
@click:outside.prevent.stop="alterValue(false)"
|
|
10
12
|
@input="alterValue"
|
|
11
13
|
>
|
|
12
|
-
<v-dialog
|
|
14
|
+
<v-dialog
|
|
15
|
+
v-model:model-value="m_closeDialog"
|
|
16
|
+
id="close-dialog-prompt"
|
|
17
|
+
data-test="closemodal"
|
|
18
|
+
>
|
|
13
19
|
<v-card class="pa-1 ma-auto position-relative" max-width="450">
|
|
14
20
|
<v-card-title>Close Viewer?</v-card-title>
|
|
15
|
-
<v-card-text
|
|
21
|
+
<v-card-text
|
|
22
|
+
>Are you sure you want to close the Online Viewer?</v-card-text
|
|
23
|
+
>
|
|
16
24
|
<v-card-actions>
|
|
17
|
-
<v-btn variant="text" color="red" @click="m_closeDialog = false">
|
|
25
|
+
<v-btn variant="text" color="red" @click="m_closeDialog = false">
|
|
26
|
+
Cancel
|
|
27
|
+
</v-btn>
|
|
18
28
|
<v-spacer />
|
|
19
|
-
<v-btn color="primary" @click="closeModal">
|
|
29
|
+
<v-btn color="primary" @click="closeModal">
|
|
30
|
+
Close without saving
|
|
31
|
+
</v-btn>
|
|
20
32
|
<v-btn color="primary" @click="closeModal"> Save Session </v-btn>
|
|
21
33
|
</v-card-actions>
|
|
22
34
|
</v-card>
|
|
@@ -27,7 +39,12 @@
|
|
|
27
39
|
height="100vh"
|
|
28
40
|
>
|
|
29
41
|
<v-toolbar dense height="48">
|
|
30
|
-
<v-menu
|
|
42
|
+
<v-menu
|
|
43
|
+
:close-on-content-click="false"
|
|
44
|
+
:close-on-click="true"
|
|
45
|
+
open-on-hover
|
|
46
|
+
offset-y
|
|
47
|
+
>
|
|
31
48
|
<template #activator="{ props, isActive }">
|
|
32
49
|
<v-btn
|
|
33
50
|
v-bind="props"
|
|
@@ -38,61 +55,80 @@
|
|
|
38
55
|
<template #prepend>
|
|
39
56
|
<v-icon>description</v-icon>
|
|
40
57
|
</template>
|
|
41
|
-
|
|
58
|
+
File
|
|
42
59
|
</v-btn>
|
|
43
60
|
</template>
|
|
44
61
|
<v-card class="">
|
|
45
62
|
<v-list>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
<v-list-item @click="executeOption('OnLoadNewDicomSeries')">
|
|
64
|
+
<template v-slot:prepend>
|
|
65
|
+
<v-icon> upload </v-icon>
|
|
66
|
+
</template>
|
|
67
|
+
<v-list-item-title>Load New DICOM Series</v-list-item-title>
|
|
68
|
+
</v-list-item>
|
|
69
|
+
<v-list-item @click="executeOption('OnDownloadDicomSeries')">
|
|
70
|
+
<template v-slot:prepend>
|
|
71
|
+
<v-icon> download </v-icon>
|
|
72
|
+
</template>
|
|
73
|
+
<v-list-item-title>Download DICOM Series</v-list-item-title>
|
|
74
|
+
</v-list-item>
|
|
75
|
+
<v-list-item @click="executeOption('OnLoadSavedSession')">
|
|
76
|
+
<template v-slot:prepend>
|
|
77
|
+
<v-icon> sync </v-icon>
|
|
78
|
+
</template>
|
|
79
|
+
<v-list-item-title> Load Saved Session </v-list-item-title>
|
|
80
|
+
</v-list-item>
|
|
81
|
+
<v-list-item @click="executeOption('OnShare')">
|
|
82
|
+
<template v-slot:prepend>
|
|
83
|
+
<v-icon> share </v-icon>
|
|
84
|
+
</template>
|
|
85
|
+
<v-list-item-title>Share</v-list-item-title>
|
|
86
|
+
</v-list-item>
|
|
87
|
+
<v-list-item
|
|
88
|
+
@click="
|
|
89
|
+
executeOption('OnClosePopup');
|
|
90
|
+
alterValue(false);
|
|
91
|
+
"
|
|
92
|
+
>
|
|
93
|
+
<template v-slot:prepend>
|
|
94
|
+
<v-icon> close </v-icon>
|
|
95
|
+
</template>
|
|
96
|
+
<v-list-item-title>Close Viewer</v-list-item-title>
|
|
97
|
+
</v-list-item>
|
|
78
98
|
</v-list>
|
|
79
99
|
</v-card>
|
|
80
100
|
</v-menu>
|
|
81
|
-
<v-menu
|
|
101
|
+
<v-menu
|
|
102
|
+
:close-on-content-click="false"
|
|
103
|
+
:close-on-click="true"
|
|
104
|
+
open-on-hover
|
|
105
|
+
offset-y
|
|
106
|
+
>
|
|
82
107
|
<template #activator="{ props, isActive }">
|
|
83
108
|
<v-btn
|
|
84
109
|
variant="flat"
|
|
85
|
-
v-bind="props"
|
|
110
|
+
v-bind="props"
|
|
111
|
+
:color="isActive ? 'secondary' : 'primary'"
|
|
112
|
+
>
|
|
86
113
|
<template #prepend>
|
|
87
114
|
<v-icon>settings</v-icon>
|
|
88
115
|
</template>
|
|
89
|
-
|
|
116
|
+
Settings
|
|
90
117
|
</v-btn>
|
|
91
118
|
</template>
|
|
92
|
-
<v-card min-width="400" class="
|
|
93
|
-
<SliderSelector
|
|
94
|
-
|
|
95
|
-
|
|
119
|
+
<v-card min-width="400" class="pa-4">
|
|
120
|
+
<SliderSelector
|
|
121
|
+
v-model:value="scanState.Display.Brightness"
|
|
122
|
+
label="Adjust Brightness"
|
|
123
|
+
/>
|
|
124
|
+
<SliderSelector
|
|
125
|
+
v-model:value="scanState.Display.Contrast"
|
|
126
|
+
label="Adjust Contrast"
|
|
127
|
+
/>
|
|
128
|
+
<SliderSelector
|
|
129
|
+
v-model:value="scanState.Display.Opacity"
|
|
130
|
+
label="Adjust Opacity"
|
|
131
|
+
/>
|
|
96
132
|
<v-divider class="my-4" />
|
|
97
133
|
<SliderSelector
|
|
98
134
|
v-model:value="scanState.InteractionSettings.PanSensivitity"
|
|
@@ -113,7 +149,9 @@
|
|
|
113
149
|
label="Rotate Sensitivity"
|
|
114
150
|
/>
|
|
115
151
|
<SliderSelector
|
|
116
|
-
v-model:value="
|
|
152
|
+
v-model:value="
|
|
153
|
+
scanState.InteractionSettings.CameraRotateSensitivity
|
|
154
|
+
"
|
|
117
155
|
:min="0"
|
|
118
156
|
:max="100"
|
|
119
157
|
label="Camera Rotate Sensitivity"
|
|
@@ -122,7 +160,9 @@
|
|
|
122
160
|
</v-menu>
|
|
123
161
|
|
|
124
162
|
<v-spacer />
|
|
125
|
-
<div class="font-weight-bold">
|
|
163
|
+
<div class="font-weight-bold">
|
|
164
|
+
<span v-if="isDemo">[DEMO] </span>Not for Diagnostic Use
|
|
165
|
+
</div>
|
|
126
166
|
<v-spacer />
|
|
127
167
|
<v-btn
|
|
128
168
|
class="ma-1 mr-0 pa-1"
|
|
@@ -140,7 +180,9 @@
|
|
|
140
180
|
@click="layouts('lo_03')"
|
|
141
181
|
><v-icon style="rotate: -90deg">view_comfy</v-icon></v-btn
|
|
142
182
|
>
|
|
143
|
-
<v-btn class="" variant="flat" color="red" @click="alterValue(false)"
|
|
183
|
+
<v-btn class="" variant="flat" color="red" @click="alterValue(false)"
|
|
184
|
+
>Close Viewer</v-btn
|
|
185
|
+
>
|
|
144
186
|
</v-toolbar>
|
|
145
187
|
<v-navigation-drawer
|
|
146
188
|
v-model="drawer"
|
|
@@ -154,7 +196,11 @@
|
|
|
154
196
|
width="300"
|
|
155
197
|
>
|
|
156
198
|
<template v-slot:prepend>
|
|
157
|
-
<div
|
|
199
|
+
<div
|
|
200
|
+
class="d-flex align-center pb-1"
|
|
201
|
+
:class="drawerCollapsed ? 'py-2' : 'pa-2'"
|
|
202
|
+
@click="snap"
|
|
203
|
+
>
|
|
158
204
|
<img
|
|
159
205
|
v-if="!drawerCollapsed"
|
|
160
206
|
src="../../assets/images/dark/3dicom-logo.svg"
|
|
@@ -197,14 +243,24 @@
|
|
|
197
243
|
<div
|
|
198
244
|
:class="[drawerCollapsed && 'mx-auto']"
|
|
199
245
|
class="mx-2"
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
246
|
+
:style="
|
|
247
|
+
drawerCollapsed &&
|
|
248
|
+
'margin-left: 10px !important; margin-right: 10px !important;'
|
|
249
|
+
"
|
|
250
|
+
>
|
|
251
|
+
<v-icon
|
|
252
|
+
:large="drawerCollapsed"
|
|
253
|
+
:size="drawerCollapsed ? 32 : 24"
|
|
254
|
+
:color="item.color"
|
|
255
|
+
>
|
|
256
|
+
{{ item.icon || "radio_button_checked" }}
|
|
204
257
|
</v-icon>
|
|
205
258
|
</div>
|
|
206
259
|
</template>
|
|
207
|
-
<v-list-item-title
|
|
260
|
+
<v-list-item-title
|
|
261
|
+
v-if="!drawerCollapsed"
|
|
262
|
+
class="text-white font-weight-medium ml-3"
|
|
263
|
+
>
|
|
208
264
|
{{ item.text }}
|
|
209
265
|
</v-list-item-title>
|
|
210
266
|
</v-list-item>
|
|
@@ -225,9 +281,16 @@
|
|
|
225
281
|
drawerCollapsed = false;
|
|
226
282
|
"
|
|
227
283
|
>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
284
|
+
<v-icon
|
|
285
|
+
size="36"
|
|
286
|
+
color="white"
|
|
287
|
+
style="
|
|
288
|
+
margin-left: 8px !important;
|
|
289
|
+
margin-right: 10px !important;
|
|
290
|
+
"
|
|
291
|
+
>
|
|
292
|
+
{{ item.icon || "radio_button_checked" }}
|
|
293
|
+
</v-icon>
|
|
231
294
|
</v-list-item>
|
|
232
295
|
</template>
|
|
233
296
|
{{ item.tooltip }}
|
|
@@ -239,24 +302,35 @@
|
|
|
239
302
|
style="max-height: 95vh"
|
|
240
303
|
theme="dark"
|
|
241
304
|
accordion
|
|
242
|
-
class="mt-1
|
|
305
|
+
class="mt-1 transparent pr-0 mr-0"
|
|
243
306
|
>
|
|
244
307
|
<v-expansion-panel class="transparent px-0">
|
|
245
|
-
<
|
|
246
|
-
|
|
308
|
+
<v-expansion-panel-title class="font-weight-bold transparent">
|
|
309
|
+
<span
|
|
310
|
+
><v-icon small>{{ miniMenu[0].icon }}</v-icon
|
|
311
|
+
> {{ miniMenu[0].text }}</span
|
|
312
|
+
>
|
|
313
|
+
<v-spacer />
|
|
314
|
+
</v-expansion-panel-title>
|
|
315
|
+
<v-expansion-panel-text class="px-0">
|
|
247
316
|
<DoubleSliderSelector
|
|
248
317
|
v-model:value="windowSlider"
|
|
249
318
|
label="Skin to Bone"
|
|
250
319
|
:min="huMinMax.min"
|
|
251
320
|
:max="huMinMax.max"
|
|
252
321
|
/>
|
|
253
|
-
<DoubleSliderSelector
|
|
322
|
+
<DoubleSliderSelector
|
|
323
|
+
v-model:value="thresholdSlider"
|
|
324
|
+
label="Fine Adjustment"
|
|
325
|
+
v-bind="huMinMax"
|
|
326
|
+
/>
|
|
254
327
|
<v-card-actions class="py-3">
|
|
255
328
|
<v-select
|
|
256
329
|
:value="getCurrentGreyscalePreset()"
|
|
257
330
|
:items="initialScanState.GreyscalePresets"
|
|
258
331
|
label="Greyscale Preset"
|
|
259
332
|
item-text="Name"
|
|
333
|
+
theme="light"
|
|
260
334
|
density="compact"
|
|
261
335
|
variant="outlined"
|
|
262
336
|
persistent-placeholder
|
|
@@ -266,7 +340,7 @@
|
|
|
266
340
|
closeOnContentClick: true,
|
|
267
341
|
}"
|
|
268
342
|
placeholder="Select a Density Preset"
|
|
269
|
-
@change="setPreset(
|
|
343
|
+
@change="setPreset(PresetsActions.pr01, $event)"
|
|
270
344
|
>
|
|
271
345
|
<template #item="{ props, item }">
|
|
272
346
|
<v-list-item
|
|
@@ -274,22 +348,27 @@
|
|
|
274
348
|
ripple
|
|
275
349
|
:title="item.raw.Name"
|
|
276
350
|
lines="three"
|
|
277
|
-
|
|
278
351
|
@mousedown.prevent
|
|
279
|
-
@click="setPreset(
|
|
352
|
+
@click="setPreset(PresetsActions.pr01, item.raw)"
|
|
280
353
|
>
|
|
281
354
|
<template v-slot:prepend>
|
|
282
|
-
<v-icon
|
|
355
|
+
<v-icon
|
|
356
|
+
:icon="getIconForPreset(item.raw.Name)"
|
|
357
|
+
></v-icon>
|
|
283
358
|
</template>
|
|
284
359
|
<template v-slot:subtitle>
|
|
285
|
-
Skin Density:
|
|
360
|
+
Skin Density:
|
|
361
|
+
<span class="text-mono">{{ item.raw.Lower }}</span>
|
|
286
362
|
<v-spacer />
|
|
287
|
-
Bone Density:
|
|
363
|
+
Bone Density:
|
|
364
|
+
<span class="text-mono">{{ item.raw.Upper }}</span>
|
|
288
365
|
</template>
|
|
289
366
|
</v-list-item>
|
|
290
367
|
</template>
|
|
291
368
|
<template v-slot:selection="{ item }">
|
|
292
|
-
<span v-if="item.raw === undefined || !item.raw.Name"
|
|
369
|
+
<span v-if="item.raw === undefined || !item.raw.Name"
|
|
370
|
+
>None</span
|
|
371
|
+
>
|
|
293
372
|
<span v-else>{{ item.raw.Name }}</span>
|
|
294
373
|
</template>
|
|
295
374
|
</v-select>
|
|
@@ -308,12 +387,11 @@
|
|
|
308
387
|
}"
|
|
309
388
|
placeholder="Select a Colour Preset"
|
|
310
389
|
return-object
|
|
311
|
-
@update:modelValue="setPreset(
|
|
390
|
+
@update:modelValue="setPreset(PresetsActions.pr02, $event)"
|
|
312
391
|
></v-select>
|
|
313
392
|
</v-card-actions>
|
|
314
393
|
</v-expansion-panel-text>
|
|
315
394
|
</v-expansion-panel>
|
|
316
|
-
|
|
317
395
|
</v-expansion-panels>
|
|
318
396
|
</v-navigation-drawer>
|
|
319
397
|
|
|
@@ -333,15 +411,21 @@
|
|
|
333
411
|
:style="drawerCollapsed ? 'left: 68px' : 'left: 300px'"
|
|
334
412
|
@click="drawerCollapsed = !drawerCollapsed"
|
|
335
413
|
>
|
|
336
|
-
<v-icon>{{
|
|
414
|
+
<v-icon>{{
|
|
415
|
+
drawerCollapsed ? "chevron_right" : "chevron_left"
|
|
416
|
+
}}</v-icon>
|
|
337
417
|
</v-btn>
|
|
338
418
|
|
|
339
|
-
<div
|
|
419
|
+
<div
|
|
420
|
+
class="position-relative pa-0"
|
|
421
|
+
:style="drawerCollapsed ? 'margin-left: 68px' : 'margin-left: 300px'"
|
|
422
|
+
>
|
|
340
423
|
<WebGL3DR
|
|
341
424
|
v-show="instanceLoaded && !scanLoading"
|
|
342
425
|
:class="!(instanceLoaded && !scanLoading) && 'no-pointer-events'"
|
|
343
426
|
v-if="value"
|
|
344
427
|
ref="web_gl"
|
|
428
|
+
id="webgl-container"
|
|
345
429
|
@on_payload="handleOnPayload"
|
|
346
430
|
@instance_loaded="load"
|
|
347
431
|
@hover="hoverOverCanvas"
|
|
@@ -352,140 +436,195 @@
|
|
|
352
436
|
:key="layout.Anchor"
|
|
353
437
|
:style="{
|
|
354
438
|
...generateDivStyleForLayout(layout),
|
|
355
|
-
cursor:
|
|
439
|
+
cursor:
|
|
440
|
+
getCurrentActiveView(layout) === ScanView.Volume
|
|
441
|
+
? 'grab !important'
|
|
442
|
+
: 'default',
|
|
356
443
|
}"
|
|
444
|
+
:data-box-internal="layout.DefaultView"
|
|
357
445
|
>
|
|
358
446
|
<v-hover>
|
|
359
447
|
<template v-slot:default="{ isHovering, props }">
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
448
|
+
<div style="width: 100%; height: 100%" v-bind="props">
|
|
449
|
+
<div class="buttons-in-view" v-show="isHovering">
|
|
450
|
+
<div v-if="scanState.Layout.PositionData.length !== 1">
|
|
451
|
+
<v-btn
|
|
452
|
+
color="transparent"
|
|
453
|
+
@click="fullscreenLayout(layout.DefaultView)"
|
|
454
|
+
:icon="true"
|
|
455
|
+
>
|
|
456
|
+
<v-icon color="white">fullscreen</v-icon>
|
|
457
|
+
</v-btn>
|
|
458
|
+
<v-tooltip
|
|
459
|
+
target="cursor"
|
|
460
|
+
location="top"
|
|
461
|
+
activator="parent"
|
|
462
|
+
>
|
|
463
|
+
Make
|
|
464
|
+
{{ getViewName(getCurrentActiveView(layout)) }}
|
|
465
|
+
fullscreen
|
|
466
|
+
</v-tooltip>
|
|
467
|
+
</div>
|
|
468
|
+
<div v-if="scanState.Layout.PositionData.length === 1">
|
|
469
|
+
<v-btn
|
|
470
|
+
color="transparent"
|
|
471
|
+
@click="layouts(previousLayout)"
|
|
472
|
+
:icon="true"
|
|
473
|
+
>
|
|
474
|
+
<v-icon color="white">fullscreen_exit</v-icon>
|
|
475
|
+
</v-btn>
|
|
476
|
+
<v-tooltip
|
|
477
|
+
target="cursor"
|
|
478
|
+
location="top"
|
|
479
|
+
activator="parent"
|
|
480
|
+
>
|
|
481
|
+
Exit Fullscreen View
|
|
482
|
+
</v-tooltip>
|
|
483
|
+
</div>
|
|
484
|
+
<div
|
|
485
|
+
v-if="getCurrentActiveView(layout) === ScanView.Volume"
|
|
368
486
|
>
|
|
369
|
-
<v-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
487
|
+
<v-btn
|
|
488
|
+
color="transparent"
|
|
489
|
+
:icon="true"
|
|
490
|
+
@click="
|
|
491
|
+
viewSelection('vs_05');
|
|
492
|
+
viewSelection('vs_06');
|
|
493
|
+
"
|
|
494
|
+
><v-icon color="white">home</v-icon></v-btn
|
|
495
|
+
>
|
|
496
|
+
<v-tooltip
|
|
497
|
+
target="cursor"
|
|
498
|
+
location="top"
|
|
499
|
+
activator="parent"
|
|
500
|
+
>
|
|
501
|
+
Reset volume to default view
|
|
502
|
+
</v-tooltip>
|
|
503
|
+
</div>
|
|
504
|
+
<div
|
|
505
|
+
v-if="getCurrentActiveView(layout) === ScanView.Volume"
|
|
381
506
|
>
|
|
382
|
-
<v-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
507
|
+
<v-menu
|
|
508
|
+
:close-on-content-click="false"
|
|
509
|
+
:close-on-click="true"
|
|
510
|
+
>
|
|
511
|
+
<template v-slot:activator="{ props }">
|
|
512
|
+
<div v-bind="{ ...props }">
|
|
513
|
+
<v-btn color="transparent" :icon="true">
|
|
514
|
+
<v-icon color="white">cut</v-icon>
|
|
515
|
+
</v-btn>
|
|
516
|
+
<v-tooltip
|
|
517
|
+
target="cursor"
|
|
518
|
+
location="top"
|
|
519
|
+
activator="parent"
|
|
520
|
+
>
|
|
521
|
+
Slice the 3D Volume
|
|
522
|
+
</v-tooltip>
|
|
523
|
+
</div>
|
|
524
|
+
</template>
|
|
525
|
+
<v-card min-width="400" class="pb-2">
|
|
526
|
+
<v-card-title>Slice into the 3D Volume</v-card-title>
|
|
527
|
+
<DoubleSliderSelector
|
|
528
|
+
v-model="tSlider"
|
|
529
|
+
label="Transverse"
|
|
530
|
+
v-bind="tMinMax"
|
|
531
|
+
/>
|
|
532
|
+
<DoubleSliderSelector
|
|
533
|
+
v-model="sSlider"
|
|
534
|
+
label="Sagittal"
|
|
535
|
+
v-bind="sMinMax"
|
|
536
|
+
/>
|
|
537
|
+
<DoubleSliderSelector
|
|
538
|
+
v-model="cSlider"
|
|
539
|
+
label="Coronal"
|
|
540
|
+
v-bind="cMinMax"
|
|
541
|
+
/>
|
|
542
|
+
</v-card>
|
|
543
|
+
</v-menu>
|
|
544
|
+
</div>
|
|
545
|
+
<div
|
|
546
|
+
v-if="getCurrentActiveView(layout) !== ScanView.Volume"
|
|
397
547
|
>
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
548
|
+
<v-menu
|
|
549
|
+
:close-on-content-click="false"
|
|
550
|
+
:close-on-click="true"
|
|
551
|
+
offset-overflow
|
|
552
|
+
top
|
|
553
|
+
>
|
|
554
|
+
<template v-slot:activator="{ props }">
|
|
555
|
+
<v-tooltip top>
|
|
556
|
+
<template #activator="{ props: ttprops }">
|
|
557
|
+
<v-btn
|
|
558
|
+
v-bind="{ ...props, ...ttprops }"
|
|
559
|
+
icon
|
|
560
|
+
class="icon transparent"
|
|
561
|
+
>
|
|
562
|
+
<v-icon color="white">360</v-icon>
|
|
563
|
+
</v-btn>
|
|
564
|
+
</template>
|
|
565
|
+
Rotate
|
|
566
|
+
{{ getViewName(getCurrentActiveView(layout)) }} by
|
|
567
|
+
an angle
|
|
415
568
|
</v-tooltip>
|
|
416
|
-
</
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
569
|
+
</template>
|
|
570
|
+
<v-card min-width="200" width="200" class="pb-2">
|
|
571
|
+
<v-card-subtitle
|
|
572
|
+
>Rotate
|
|
573
|
+
{{ getViewName(getCurrentActiveView(layout)) }} by
|
|
574
|
+
an angle</v-card-subtitle
|
|
575
|
+
>
|
|
576
|
+
<v-card-text class="py-0">
|
|
577
|
+
<v-text-field
|
|
578
|
+
hide-details
|
|
579
|
+
outlined
|
|
580
|
+
v-model="rotationDeg"
|
|
581
|
+
type="number"
|
|
582
|
+
suffix="deg"
|
|
583
|
+
></v-text-field>
|
|
584
|
+
</v-card-text>
|
|
585
|
+
<v-card-actions>
|
|
586
|
+
<v-spacer />
|
|
431
587
|
<v-btn
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
588
|
+
color="primary"
|
|
589
|
+
@click="
|
|
590
|
+
rotateByDeg(
|
|
591
|
+
getCurrentActiveView(layout),
|
|
592
|
+
rotationDeg
|
|
593
|
+
)
|
|
594
|
+
"
|
|
595
|
+
>Rotate</v-btn
|
|
435
596
|
>
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
>
|
|
460
|
-
</v-card-actions>
|
|
461
|
-
</v-card>
|
|
462
|
-
</v-menu>
|
|
597
|
+
</v-card-actions>
|
|
598
|
+
</v-card>
|
|
599
|
+
</v-menu>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
<div class="slider-in-view" v-if="isHovering">
|
|
603
|
+
<VerticalSliderSelector
|
|
604
|
+
v-if="
|
|
605
|
+
getCurrentActiveView(layout) === ScanView.Transverse
|
|
606
|
+
"
|
|
607
|
+
v-model:value="scanState.Orientations.Transverse.Slice"
|
|
608
|
+
v-bind="tMinMax"
|
|
609
|
+
/>
|
|
610
|
+
<VerticalSliderSelector
|
|
611
|
+
v-if="getCurrentActiveView(layout) === ScanView.Coronal"
|
|
612
|
+
v-model:value="scanState.Orientations.Coronal.Slice"
|
|
613
|
+
v-bind="cMinMax"
|
|
614
|
+
/>
|
|
615
|
+
<VerticalSliderSelector
|
|
616
|
+
v-if="getCurrentActiveView(layout) === ScanView.Sagittal"
|
|
617
|
+
v-model:value="scanState.Orientations.Sagittal.Slice"
|
|
618
|
+
v-bind="sMinMax"
|
|
619
|
+
/>
|
|
463
620
|
</div>
|
|
464
|
-
</div>
|
|
465
|
-
<div class="slider-in-view" v-if="isHovering">
|
|
466
|
-
<VerticalSliderSelector
|
|
467
|
-
v-if="getCurrentActiveView(layout) === ScanView.Transverse"
|
|
468
|
-
v-model:value="scanState.Orientations.Transverse.Slice"
|
|
469
|
-
v-bind="tMinMax"
|
|
470
|
-
/>
|
|
471
|
-
<VerticalSliderSelector
|
|
472
|
-
v-if="getCurrentActiveView(layout) === ScanView.Coronal"
|
|
473
|
-
v-model:value="scanState.Orientations.Coronal.Slice"
|
|
474
|
-
v-bind="cMinMax"
|
|
475
|
-
/>
|
|
476
|
-
<VerticalSliderSelector
|
|
477
|
-
v-if="getCurrentActiveView(layout) === ScanView.Sagittal"
|
|
478
|
-
v-model:value="scanState.Orientations.Sagittal.Slice"
|
|
479
|
-
v-bind="sMinMax"
|
|
480
|
-
/>
|
|
481
|
-
</div>
|
|
482
621
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
622
|
+
<div class="top-lhc" v-if="isHovering">
|
|
623
|
+
<div class="white--text">
|
|
624
|
+
{{ getViewName(getCurrentActiveView(layout)) }}
|
|
625
|
+
</div>
|
|
486
626
|
</div>
|
|
487
627
|
</div>
|
|
488
|
-
</div>
|
|
489
628
|
</template>
|
|
490
629
|
</v-hover>
|
|
491
630
|
</div>
|
|
@@ -493,10 +632,16 @@
|
|
|
493
632
|
</div>
|
|
494
633
|
|
|
495
634
|
<LoadingSpinner v-if="!instanceLoaded" />
|
|
496
|
-
<LoadingSpinner v-if="scanLoading" text="Rendering your scan in
|
|
635
|
+
<LoadingSpinner v-if="scanLoading" text="Rendering your scan in 3D" />
|
|
497
636
|
<v-textarea
|
|
498
637
|
v-if="stateOverlay"
|
|
499
|
-
style="
|
|
638
|
+
style="
|
|
639
|
+
position: absolute;
|
|
640
|
+
top: 0px;
|
|
641
|
+
right: -0px;
|
|
642
|
+
width: 240px;
|
|
643
|
+
z-index: 10000;
|
|
644
|
+
"
|
|
500
645
|
class="text--white"
|
|
501
646
|
color="white"
|
|
502
647
|
dark
|
|
@@ -508,66 +653,115 @@
|
|
|
508
653
|
</v-card>
|
|
509
654
|
</v-dialog>
|
|
510
655
|
</template>
|
|
511
|
-
|
|
656
|
+
<!-- /* c8 ignore stop */ -->
|
|
657
|
+
<script setup lang="ts">
|
|
658
|
+
import LoadingSpinner from "@/components/loading/LoadingSpinner.vue";
|
|
659
|
+
import WebGL3DR from "@/components/WebGL3DR.vue";
|
|
660
|
+
import DoubleSliderSelector from "@/components/sliders/DoubleSliderSelector.vue";
|
|
661
|
+
import SliderSelector from "@/components/selectors/ValueSelector.vue";
|
|
662
|
+
import VerticalSliderSelector from "@/components/sliders/VerticalSliderSelector.vue";
|
|
512
663
|
|
|
513
|
-
import
|
|
514
|
-
import LoadingSpinner from '@/components/loading/LoadingSpinner.vue';
|
|
515
|
-
import WebGL3DR from '@/components/WebGL3DR.vue';
|
|
516
|
-
import DoubleSliderSelector from '@/components/sliders/DoubleSliderSelector.vue';
|
|
517
|
-
import SliderSelector from '@/components/sliders/SliderSelector.vue';
|
|
518
|
-
import VerticalSliderSelector from '@/components/sliders/VerticalSliderSelector.vue';
|
|
664
|
+
import { generateDivStyleForLayout } from "@/helpers/layoutOverlayStyle";
|
|
519
665
|
|
|
520
|
-
import { generateDivStyleForLayout } from '@/helpers/layoutOverlayStyle';
|
|
521
666
|
import {
|
|
522
|
-
|
|
523
|
-
|
|
667
|
+
inflateInitialScanState,
|
|
668
|
+
inflateScanState,
|
|
669
|
+
} from "@/helpers/modelHelper";
|
|
670
|
+
import {
|
|
671
|
+
SlidersActions,
|
|
672
|
+
PresetsActions,
|
|
524
673
|
ScanMovementActions,
|
|
525
674
|
ScanOrientationActions,
|
|
526
675
|
FileManagementActions,
|
|
527
676
|
FrontEndInterfaces,
|
|
528
|
-
} from '@/helpers/models';
|
|
529
|
-
import {
|
|
530
|
-
inflateInitialScanState,
|
|
531
|
-
inflateScanState,
|
|
532
|
-
} from '../../helpers/modelHelper';
|
|
533
|
-
import {
|
|
534
677
|
AnchorPoint,
|
|
535
678
|
ColourPresetData,
|
|
536
679
|
CurrentScanState,
|
|
537
680
|
InitialScanState,
|
|
538
681
|
PositionData,
|
|
539
682
|
ScanView,
|
|
540
|
-
|
|
683
|
+
InteractivityActions,
|
|
684
|
+
NotificationsActions,
|
|
685
|
+
NotificationPayload,
|
|
686
|
+
} from "@3cr/types-ts";
|
|
541
687
|
|
|
542
|
-
import { toNumber } from
|
|
543
|
-
import {computed, ref, unref, watch, defineEmits, nextTick} from "vue";
|
|
544
|
-
import {
|
|
688
|
+
import { toNumber } from "@/helpers/utils";
|
|
689
|
+
import { computed, ref, unref, watch, defineEmits, nextTick } from "vue";
|
|
690
|
+
import {
|
|
691
|
+
defaultOptions,
|
|
692
|
+
LoadViewerOptions,
|
|
693
|
+
LoadViewerPayload,
|
|
694
|
+
} from "../../../index";
|
|
545
695
|
|
|
546
696
|
const emit = defineEmits<{
|
|
547
697
|
instanceLoaded: [void];
|
|
698
|
+
snap: [void];
|
|
548
699
|
}>();
|
|
549
700
|
|
|
550
|
-
defineExpose({
|
|
551
|
-
alterValue,
|
|
552
|
-
load
|
|
553
|
-
});
|
|
554
|
-
|
|
555
701
|
export interface Props {
|
|
556
|
-
payload
|
|
702
|
+
payload?: LoadViewerPayload;
|
|
703
|
+
options?: LoadViewerOptions;
|
|
557
704
|
}
|
|
558
|
-
const componentKey = ref(0);
|
|
559
705
|
|
|
560
706
|
const props = withDefaults(defineProps<Props>(), {
|
|
561
707
|
payload: () => ({
|
|
562
|
-
Url:"https://webgl-3dr.singular.health/test_scans/8bdddee1-e581-485d-827d-6aa12eef2fc8/Head+Axial+Axial.3vxl",
|
|
563
|
-
DecryptionKey:{
|
|
564
|
-
Iv:"x856FgjpYDsRhIa3BFj5cg==",
|
|
565
|
-
Key:"OWjSMiL/ewUV1V6fGybhKcTyiysTPsIMp2DjdVoOUGI="
|
|
566
|
-
}
|
|
567
|
-
})
|
|
708
|
+
Url: "https://webgl-3dr.singular.health/test_scans/8bdddee1-e581-485d-827d-6aa12eef2fc8/Head+Axial+Axial.3vxl",
|
|
709
|
+
DecryptionKey: {
|
|
710
|
+
Iv: "x856FgjpYDsRhIa3BFj5cg==",
|
|
711
|
+
Key: "OWjSMiL/ewUV1V6fGybhKcTyiysTPsIMp2DjdVoOUGI=",
|
|
712
|
+
},
|
|
713
|
+
}),
|
|
714
|
+
options: () => defaultOptions,
|
|
568
715
|
});
|
|
716
|
+
const isDemo = ref<boolean>(false);
|
|
717
|
+
let m_demo = ref<boolean>(false);
|
|
718
|
+
|
|
719
|
+
const demoOptions: LoadViewerOptions = {
|
|
720
|
+
OnClosePopup: () => Promise.resolve(),
|
|
721
|
+
OnExitViewer: () => {
|
|
722
|
+
m_demo.value = true;
|
|
723
|
+
},
|
|
724
|
+
OnLoadNewDicomSeries: () => {
|
|
725
|
+
m_demo.value = true;
|
|
726
|
+
},
|
|
727
|
+
OnDownloadDicomSeries: () => {
|
|
728
|
+
m_demo.value = true;
|
|
729
|
+
},
|
|
730
|
+
OnLoadSavedSession: () => {
|
|
731
|
+
m_demo.value = true;
|
|
732
|
+
},
|
|
733
|
+
OnSaveSession: () => {
|
|
734
|
+
m_demo.value = true;
|
|
735
|
+
},
|
|
736
|
+
OnSendTo3rdParty: () => {
|
|
737
|
+
m_demo.value = true;
|
|
738
|
+
},
|
|
739
|
+
OnShareToMobile: () => {
|
|
740
|
+
m_demo.value = true;
|
|
741
|
+
},
|
|
742
|
+
OnShare: () => {
|
|
743
|
+
m_demo.value = true;
|
|
744
|
+
},
|
|
745
|
+
OnScreenshot: () => {
|
|
746
|
+
m_demo.value = true;
|
|
747
|
+
},
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
function executeOption(key: keyof LoadViewerOptions) {
|
|
751
|
+
if (unref(isDemo)) {
|
|
752
|
+
const functionToExecute = demoOptions[key];
|
|
753
|
+
if (functionToExecute !== undefined) {
|
|
754
|
+
functionToExecute();
|
|
755
|
+
}
|
|
756
|
+
} else {
|
|
757
|
+
const functionToExecute = unref(props.options)[key];
|
|
758
|
+
if (functionToExecute !== undefined) {
|
|
759
|
+
functionToExecute();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
569
763
|
|
|
570
|
-
const emptyPayload = { Version:
|
|
764
|
+
const emptyPayload = { Version: "1.1.0" };
|
|
571
765
|
|
|
572
766
|
const value = ref<boolean>(false);
|
|
573
767
|
const drawer = ref<boolean>(true);
|
|
@@ -578,222 +772,295 @@ const scanState = ref<CurrentScanState>(inflateScanState());
|
|
|
578
772
|
const initialScanState = ref<InitialScanState>(inflateInitialScanState());
|
|
579
773
|
const currentColourPreset = ref<ColourPresetData | undefined>(undefined);
|
|
580
774
|
const openPanels = ref<number>(0);
|
|
581
|
-
const previousLayout = ref<string>(
|
|
775
|
+
const previousLayout = ref<string>("lo_02");
|
|
582
776
|
const footerItems = ref([
|
|
583
777
|
{
|
|
584
|
-
text:
|
|
585
|
-
icon:
|
|
586
|
-
color:
|
|
778
|
+
text: "Reset Scan",
|
|
779
|
+
icon: "refresh",
|
|
780
|
+
color: "red",
|
|
587
781
|
click: async () => {
|
|
588
|
-
console.log(
|
|
589
|
-
await viewSelection(
|
|
590
|
-
await viewSelection(
|
|
782
|
+
console.log("Reset Scan");
|
|
783
|
+
await viewSelection("vs_05");
|
|
784
|
+
await viewSelection("vs_06");
|
|
591
785
|
},
|
|
592
786
|
},
|
|
593
787
|
{
|
|
594
|
-
text:
|
|
595
|
-
icon:
|
|
596
|
-
color:
|
|
597
|
-
click: () =>
|
|
788
|
+
text: "Send to 3rd Party",
|
|
789
|
+
icon: "send",
|
|
790
|
+
color: "blue",
|
|
791
|
+
click: async () => executeOption("OnSendTo3rdParty"),
|
|
598
792
|
},
|
|
599
793
|
{
|
|
600
|
-
text:
|
|
601
|
-
icon:
|
|
602
|
-
color:
|
|
603
|
-
click: () =>
|
|
794
|
+
text: "Share to Mobile / VR",
|
|
795
|
+
icon: "share",
|
|
796
|
+
color: "yellow",
|
|
797
|
+
click: async () => executeOption("OnShareToMobile"),
|
|
604
798
|
},
|
|
605
799
|
{
|
|
606
|
-
text:
|
|
607
|
-
icon:
|
|
608
|
-
color:
|
|
609
|
-
click: () =>
|
|
610
|
-
snap();
|
|
611
|
-
},
|
|
800
|
+
text: "Screenshot View",
|
|
801
|
+
icon: "screenshot_region",
|
|
802
|
+
color: "green",
|
|
803
|
+
click: async () => executeOption("OnScreenshot"),
|
|
612
804
|
},
|
|
613
805
|
]);
|
|
614
806
|
|
|
615
807
|
const miniMenu = ref([
|
|
616
808
|
{
|
|
617
|
-
icon:
|
|
618
|
-
text:
|
|
809
|
+
icon: "display_settings",
|
|
810
|
+
text: "Tissue Density",
|
|
619
811
|
tooltip:
|
|
620
|
-
|
|
812
|
+
"Tissue Density - Change the view of density within the scan, allowing you to see through a certain density of particles",
|
|
621
813
|
},
|
|
622
814
|
// { icon: 'display_settings', text: 'Display', tooltip: 'Display - Alter the view of the current scan' },
|
|
623
|
-
])
|
|
815
|
+
]);
|
|
624
816
|
|
|
625
817
|
const huMinMax = ref({
|
|
626
818
|
min: -999999,
|
|
627
819
|
max: 999999,
|
|
628
|
-
})
|
|
820
|
+
});
|
|
629
821
|
|
|
630
822
|
const tMinMax = ref({
|
|
631
823
|
min: 0,
|
|
632
824
|
max: 999999,
|
|
633
|
-
})
|
|
825
|
+
});
|
|
634
826
|
const sMinMax = ref({
|
|
635
827
|
min: 0,
|
|
636
828
|
max: 999999,
|
|
637
|
-
})
|
|
829
|
+
});
|
|
638
830
|
const cMinMax = ref({
|
|
639
831
|
min: 0,
|
|
640
832
|
max: 999999,
|
|
641
|
-
})
|
|
642
|
-
const rotationDeg = ref<number>(0)
|
|
643
|
-
const scanStateIncoming = ref<string>(
|
|
644
|
-
const transactionStarted = ref<boolean>(false)
|
|
645
|
-
const stateOverlay = ref<boolean>(false)
|
|
646
|
-
const m_closeDialog = ref<boolean>(false)
|
|
647
|
-
|
|
648
|
-
watch(currentColourPreset, (val) => {console.log(val)})
|
|
833
|
+
});
|
|
834
|
+
const rotationDeg = ref<number>(0);
|
|
835
|
+
const scanStateIncoming = ref<string>("");
|
|
836
|
+
const transactionStarted = ref<boolean>(false);
|
|
837
|
+
const stateOverlay = ref<boolean>(false);
|
|
838
|
+
const m_closeDialog = ref<boolean>(false);
|
|
839
|
+
|
|
649
840
|
const windowSlider = computed({
|
|
650
841
|
get() {
|
|
651
|
-
return [
|
|
842
|
+
return [
|
|
843
|
+
unref(scanState).Display.WindowLower,
|
|
844
|
+
unref(scanState).Display.WindowUpper,
|
|
845
|
+
];
|
|
652
846
|
},
|
|
653
847
|
set(value: Array<number>) {
|
|
654
848
|
scanState.value.Display.WindowLower = value[0];
|
|
655
849
|
scanState.value.Display.WindowUpper = value[1];
|
|
656
|
-
}
|
|
657
|
-
})
|
|
850
|
+
},
|
|
851
|
+
});
|
|
658
852
|
const thresholdSlider = computed({
|
|
659
853
|
get() {
|
|
660
|
-
return [
|
|
854
|
+
return [
|
|
855
|
+
Math.trunc(unref(scanState).Display.ThresholdLower),
|
|
856
|
+
Math.trunc(unref(scanState).Display.ThresholdUpper),
|
|
857
|
+
];
|
|
661
858
|
},
|
|
662
859
|
set(value: Array<number>) {
|
|
663
860
|
scanState.value.Display.ThresholdLower = value[0];
|
|
664
861
|
scanState.value.Display.ThresholdUpper = value[1];
|
|
665
|
-
}
|
|
666
|
-
})
|
|
862
|
+
},
|
|
863
|
+
});
|
|
667
864
|
const tSlider = computed({
|
|
668
865
|
get() {
|
|
669
|
-
return [
|
|
866
|
+
return [
|
|
867
|
+
Math.trunc(unref(scanState).Slice.TransverseLower),
|
|
868
|
+
Math.trunc(unref(scanState).Slice.TransverseUpper),
|
|
869
|
+
];
|
|
670
870
|
},
|
|
671
871
|
set(value: Array<number>) {
|
|
672
872
|
scanState.value.Slice.TransverseLower = value[0];
|
|
673
873
|
scanState.value.Slice.TransverseLower = value[1];
|
|
674
|
-
}
|
|
675
|
-
})
|
|
874
|
+
},
|
|
875
|
+
});
|
|
676
876
|
const sSlider = computed({
|
|
677
877
|
get() {
|
|
678
|
-
return [
|
|
878
|
+
return [
|
|
879
|
+
Math.trunc(unref(scanState).Slice.SagittalLower),
|
|
880
|
+
Math.trunc(unref(scanState).Slice.SagittalUpper),
|
|
881
|
+
];
|
|
679
882
|
},
|
|
680
883
|
set(value: Array<number>) {
|
|
681
884
|
scanState.value.Slice.SagittalLower = value[0];
|
|
682
885
|
scanState.value.Slice.SagittalUpper = value[1];
|
|
683
|
-
}
|
|
684
|
-
})
|
|
886
|
+
},
|
|
887
|
+
});
|
|
685
888
|
|
|
686
889
|
const cSlider = computed({
|
|
687
890
|
get() {
|
|
688
|
-
return [
|
|
891
|
+
return [
|
|
892
|
+
Math.trunc(unref(scanState).Slice.CoronalLower),
|
|
893
|
+
Math.trunc(unref(scanState).Slice.CoronalUpper),
|
|
894
|
+
];
|
|
689
895
|
},
|
|
690
896
|
set(value: Array<number>) {
|
|
691
897
|
scanState.value.Slice.CoronalLower = value[0];
|
|
692
898
|
scanState.value.Slice.CoronalUpper = value[1];
|
|
693
|
-
}
|
|
694
|
-
})
|
|
899
|
+
},
|
|
900
|
+
});
|
|
695
901
|
const web_gl = ref<typeof WebGL3DR | null>(null);
|
|
696
902
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
903
|
+
watch(
|
|
904
|
+
() => scanState.value.Display.Brightness,
|
|
905
|
+
async (value: number) => {
|
|
906
|
+
await sliderHandler(SlidersActions.sl01, value);
|
|
907
|
+
}
|
|
908
|
+
);
|
|
909
|
+
watch(
|
|
910
|
+
() => scanState.value.Display.Contrast,
|
|
911
|
+
async (value: number) => {
|
|
912
|
+
await sliderHandler(SlidersActions.sl02, value);
|
|
913
|
+
}
|
|
914
|
+
);
|
|
915
|
+
watch(
|
|
916
|
+
() => scanState.value.Display.Opacity,
|
|
917
|
+
async (value: number) => {
|
|
918
|
+
await sliderHandler(SlidersActions.sl03, value);
|
|
919
|
+
}
|
|
920
|
+
);
|
|
921
|
+
watch(
|
|
922
|
+
() => scanState.value.Display.WindowLower,
|
|
923
|
+
async (value: number) => {
|
|
924
|
+
await sliderHandler(SlidersActions.sl04, value);
|
|
925
|
+
}
|
|
926
|
+
);
|
|
927
|
+
watch(
|
|
928
|
+
() => scanState.value.Display.WindowUpper,
|
|
929
|
+
async (value: number) => {
|
|
930
|
+
await sliderHandler(SlidersActions.sl05, value);
|
|
931
|
+
}
|
|
932
|
+
);
|
|
933
|
+
watch(
|
|
934
|
+
() => scanState.value.Display.ThresholdLower,
|
|
935
|
+
async (value: number) => {
|
|
936
|
+
await sliderHandler(SlidersActions.sl06, value);
|
|
937
|
+
}
|
|
938
|
+
);
|
|
939
|
+
watch(
|
|
940
|
+
() => scanState.value.Display.ThresholdUpper,
|
|
941
|
+
async (value: number) => {
|
|
942
|
+
await sliderHandler(SlidersActions.sl07, value);
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
watch(
|
|
946
|
+
() => scanState.value.Slice.TransverseLower,
|
|
947
|
+
async (value: number) => {
|
|
948
|
+
await sliderHandler(SlidersActions.sl08, value);
|
|
949
|
+
}
|
|
950
|
+
);
|
|
951
|
+
watch(
|
|
952
|
+
() => scanState.value.Orientations.Transverse.Slice,
|
|
953
|
+
async (value: number) => {
|
|
954
|
+
await sliderHandler(SlidersActions.sl09, value);
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
watch(
|
|
958
|
+
() => scanState.value.Slice.TransverseUpper,
|
|
959
|
+
async (value: number) => {
|
|
960
|
+
await sliderHandler(SlidersActions.sl10, value);
|
|
961
|
+
}
|
|
962
|
+
);
|
|
963
|
+
watch(
|
|
964
|
+
() => scanState.value.Slice.SagittalLower,
|
|
965
|
+
async (value: number) => {
|
|
966
|
+
await sliderHandler(SlidersActions.sl11, value);
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
watch(
|
|
970
|
+
() => scanState.value.Orientations.Sagittal.Slice,
|
|
971
|
+
async (value: number) => {
|
|
972
|
+
await sliderHandler(SlidersActions.sl12, value);
|
|
973
|
+
}
|
|
974
|
+
);
|
|
975
|
+
watch(
|
|
976
|
+
() => scanState.value.Slice.SagittalUpper,
|
|
977
|
+
async (value: number) => {
|
|
978
|
+
await sliderHandler(SlidersActions.sl13, value);
|
|
979
|
+
}
|
|
980
|
+
);
|
|
981
|
+
watch(
|
|
982
|
+
() => scanState.value.Slice.CoronalLower,
|
|
983
|
+
async (value: number) => {
|
|
984
|
+
await sliderHandler(SlidersActions.sl14, value);
|
|
985
|
+
}
|
|
986
|
+
);
|
|
987
|
+
watch(
|
|
988
|
+
() => scanState.value.Orientations.Coronal.Slice,
|
|
989
|
+
async (value: number) => {
|
|
990
|
+
await sliderHandler(SlidersActions.sl15, value);
|
|
991
|
+
}
|
|
992
|
+
);
|
|
993
|
+
watch(
|
|
994
|
+
() => scanState.value.Slice.CoronalUpper,
|
|
995
|
+
async (value: number) => {
|
|
996
|
+
await sliderHandler(SlidersActions.sl16, value);
|
|
997
|
+
}
|
|
998
|
+
);
|
|
999
|
+
watch(
|
|
1000
|
+
() => scanState.value.InteractionSettings.PanSensivitity,
|
|
1001
|
+
async (value: number) => {
|
|
1002
|
+
await scanMovementHandler(ScanMovementActions.sm05, value);
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
1005
|
+
watch(
|
|
1006
|
+
() => scanState.value.InteractionSettings.ZoomSensitivity,
|
|
1007
|
+
async (value: number) => {
|
|
1008
|
+
await scanMovementHandler(ScanMovementActions.sm08, value);
|
|
1009
|
+
}
|
|
1010
|
+
);
|
|
1011
|
+
watch(
|
|
1012
|
+
() => scanState.value.InteractionSettings.RotateSensitivity,
|
|
1013
|
+
async (value: number) => {
|
|
1014
|
+
await scanMovementHandler(ScanMovementActions.sm10, value);
|
|
1015
|
+
}
|
|
1016
|
+
);
|
|
1017
|
+
watch(
|
|
1018
|
+
() => scanState.value.InteractionSettings.CameraRotateSensitivity,
|
|
1019
|
+
async (value: number) => {
|
|
1020
|
+
await scanMovementHandler(ScanMovementActions.sm12, value);
|
|
1021
|
+
}
|
|
1022
|
+
);
|
|
761
1023
|
|
|
762
1024
|
function getIconForPreset(presetName: string): string | undefined {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
return undefined
|
|
1025
|
+
if (presetName === "Bone") return "fa:fas fa-bone";
|
|
1026
|
+
if (presetName === "Brain") return "fa:fas fa-brain";
|
|
1027
|
+
if (presetName === "Liver") return "custom:liver_icon";
|
|
1028
|
+
if (presetName === "Lungs") return "fa:fas fa-lungs";
|
|
1029
|
+
if (presetName === "Muscle") return "custom:muscle_icon";
|
|
1030
|
+
if (presetName === "Temporal Bones") return "custom:temporal_bones_icon";
|
|
1031
|
+
if (presetName === "Soft Tissue") return "custom:torso_icon";
|
|
1032
|
+
if (presetName === "Skin") return "custom:skin_icon";
|
|
1033
|
+
return undefined;
|
|
772
1034
|
}
|
|
773
1035
|
async function rotateByDeg(view: ScanView, deg: number) {
|
|
774
|
-
await (
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1036
|
+
await sendPayload(
|
|
1037
|
+
FrontEndInterfaces.scan_orientation,
|
|
1038
|
+
ScanOrientationActions.so01,
|
|
1039
|
+
{
|
|
1040
|
+
Version: "0.0.1",
|
|
1041
|
+
View: view,
|
|
1042
|
+
Angle: deg,
|
|
1043
|
+
}
|
|
1044
|
+
);
|
|
779
1045
|
}
|
|
780
1046
|
function getCurrentActiveView(position: PositionData): ScanView {
|
|
781
|
-
return unref(scanState).Layout.PositionData.length !== 1
|
|
1047
|
+
return unref(scanState).Layout.PositionData.length !== 1
|
|
1048
|
+
? position.DefaultView
|
|
1049
|
+
: unref(scanState).CurrentView;
|
|
782
1050
|
}
|
|
783
1051
|
function getViewName(index: number) {
|
|
784
1052
|
return Object.values(ScanView)
|
|
785
|
-
.filter((value) => typeof value ===
|
|
1053
|
+
.filter((value) => typeof value === "string")
|
|
786
1054
|
.map((x) => {
|
|
787
|
-
if (x ===
|
|
1055
|
+
if (x === "Volume") return "3D Volume";
|
|
788
1056
|
return x;
|
|
789
1057
|
})[index];
|
|
790
1058
|
}
|
|
791
1059
|
async function fullscreenLayout(view: ScanView) {
|
|
792
|
-
await layouts(
|
|
1060
|
+
await layouts("lo_01");
|
|
793
1061
|
await viewSelection(`vs_0${view + 1}`);
|
|
794
1062
|
}
|
|
795
|
-
|
|
796
|
-
async function scanMovementHandler(action: string, value: number) {
|
|
1063
|
+
async function scanMovementHandler(action: string, value: number) {
|
|
797
1064
|
if (unref(transactionStarted)) return;
|
|
798
1065
|
await scanMovement(action, value);
|
|
799
1066
|
}
|
|
@@ -805,55 +1072,77 @@ async function sliderHandler(action: string, value: number) {
|
|
|
805
1072
|
function closeModal() {
|
|
806
1073
|
m_closeDialog.value = false;
|
|
807
1074
|
value.value = false;
|
|
1075
|
+
executeOption("OnExitViewer");
|
|
808
1076
|
}
|
|
809
1077
|
function alterValue(val: boolean) {
|
|
810
1078
|
if (!val) {
|
|
811
1079
|
m_closeDialog.value = true;
|
|
812
|
-
return
|
|
1080
|
+
return;
|
|
1081
|
+
} else {
|
|
1082
|
+
isDemo.value =
|
|
1083
|
+
props.payload.Url ===
|
|
1084
|
+
"https://webgl-3dr.singular.health/test_scans/01440d4e-8b04-4b90-bb2c-698535ce16d6/CHEST.3vxl";
|
|
813
1085
|
}
|
|
814
1086
|
|
|
815
1087
|
value.value = val;
|
|
816
1088
|
}
|
|
817
|
-
async function sendPayload(
|
|
1089
|
+
async function sendPayload(
|
|
1090
|
+
interfaceType: string,
|
|
1091
|
+
actionType: string,
|
|
1092
|
+
message: any
|
|
1093
|
+
) {
|
|
818
1094
|
await unref(web_gl)?.sendPayload(
|
|
819
1095
|
JSON.stringify({
|
|
820
|
-
Version:
|
|
1096
|
+
Version: "0.0.1",
|
|
821
1097
|
Interface: interfaceType,
|
|
822
1098
|
Action: actionType,
|
|
823
1099
|
Message: JSON.stringify(message),
|
|
824
|
-
})
|
|
1100
|
+
})
|
|
825
1101
|
);
|
|
826
1102
|
}
|
|
827
1103
|
async function load() {
|
|
828
1104
|
instanceLoaded.value = true;
|
|
829
1105
|
scanLoading.value = true;
|
|
830
|
-
await sendPayload(
|
|
1106
|
+
await sendPayload("file_management", "fm_01", props.payload);
|
|
831
1107
|
}
|
|
832
1108
|
async function viewSelection(action: string) {
|
|
833
|
-
await sendPayload(FrontEndInterfaces.view_selection, action, emptyPayload)
|
|
1109
|
+
await sendPayload(FrontEndInterfaces.view_selection, action, emptyPayload);
|
|
834
1110
|
}
|
|
835
1111
|
async function layouts(action: string) {
|
|
836
|
-
if (action !==
|
|
837
|
-
await sendPayload(FrontEndInterfaces.layout, action, emptyPayload)
|
|
1112
|
+
if (action !== "lo_01") previousLayout.value = action;
|
|
1113
|
+
await sendPayload(FrontEndInterfaces.layout, action, emptyPayload);
|
|
838
1114
|
}
|
|
839
1115
|
async function snap() {
|
|
840
|
-
|
|
1116
|
+
emit("snap");
|
|
841
1117
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1118
|
+
|
|
1119
|
+
async function setPreset(action: PresetsActions, preset: any) {
|
|
1120
|
+
await sendPayload("presets", action, preset);
|
|
1121
|
+
if (action === PresetsActions.pr02) {
|
|
845
1122
|
currentColourPreset.value = preset;
|
|
846
1123
|
}
|
|
847
1124
|
}
|
|
848
1125
|
async function slider(action: string, value: number) {
|
|
849
|
-
await sendPayload(
|
|
1126
|
+
await sendPayload("sliders", action, {
|
|
1127
|
+
Version: "0.0.1",
|
|
1128
|
+
Value: toNumber(value),
|
|
1129
|
+
});
|
|
850
1130
|
}
|
|
851
1131
|
async function scanMovement(action: string, value: number) {
|
|
852
|
-
await sendPayload(
|
|
1132
|
+
await sendPayload(FrontEndInterfaces.scan_movement, action, {
|
|
1133
|
+
Version: "0.0.1",
|
|
1134
|
+
Value: toNumber(value),
|
|
1135
|
+
});
|
|
853
1136
|
}
|
|
854
1137
|
async function hoverOverCanvas(isHovering: boolean) {
|
|
855
|
-
await sendPayload(
|
|
856
|
-
|
|
1138
|
+
await sendPayload("interactivity", "in_01", {
|
|
1139
|
+
Version: "0.0.1",
|
|
1140
|
+
Value: isHovering,
|
|
1141
|
+
});
|
|
1142
|
+
await sendPayload("interactivity", "in_02", {
|
|
1143
|
+
Version: "0.0.1",
|
|
1144
|
+
Value: isHovering,
|
|
1145
|
+
});
|
|
857
1146
|
}
|
|
858
1147
|
async function i_scanState(_: string, message: string) {
|
|
859
1148
|
transactionStarted.value = true;
|
|
@@ -885,32 +1174,61 @@ async function i_fileManagement(action: string, message: string) {
|
|
|
885
1174
|
drawerCollapsed.value = false;
|
|
886
1175
|
await hoverOverCanvas(false);
|
|
887
1176
|
}
|
|
1177
|
+
|
|
1178
|
+
import { useNotification } from "@kyvg/vue3-notification";
|
|
1179
|
+
|
|
1180
|
+
const { notify } = useNotification();
|
|
1181
|
+
|
|
888
1182
|
async function i_notifications(action: string, message: string) {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1183
|
+
const notification = JSON.parse(message) as NotificationPayload;
|
|
1184
|
+
|
|
1185
|
+
switch (notification.Action) {
|
|
1186
|
+
case InteractivityActions.in01:
|
|
1187
|
+
case InteractivityActions.in02:
|
|
1188
|
+
case InteractivityActions.in03:
|
|
1189
|
+
case InteractivityActions.in04:
|
|
1190
|
+
return;
|
|
1191
|
+
default:
|
|
1192
|
+
}
|
|
1193
|
+
if (notification.Action.startsWith("sl")) return;
|
|
1194
|
+
|
|
1195
|
+
let type = "success";
|
|
1196
|
+
switch (action) {
|
|
1197
|
+
// Muting no01
|
|
1198
|
+
case NotificationsActions.no01:
|
|
1199
|
+
type = "success";
|
|
1200
|
+
return;
|
|
1201
|
+
|
|
1202
|
+
case NotificationsActions.no02:
|
|
1203
|
+
type = "warn";
|
|
1204
|
+
break;
|
|
1205
|
+
|
|
1206
|
+
case NotificationsActions.no03:
|
|
1207
|
+
type = "error";
|
|
1208
|
+
break;
|
|
1209
|
+
|
|
1210
|
+
// Muting no04
|
|
1211
|
+
case NotificationsActions.no04:
|
|
1212
|
+
type = "info";
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
notify({
|
|
1217
|
+
title: notification.Code,
|
|
1218
|
+
text: notification.Action,
|
|
1219
|
+
type,
|
|
1220
|
+
});
|
|
904
1221
|
}
|
|
905
1222
|
const isLayout2x2 = computed(() => {
|
|
906
1223
|
return (
|
|
907
1224
|
unref(scanState).Layout.PositionData.length > 1 &&
|
|
908
1225
|
unref(scanState).Layout.PositionData[0].Anchor === AnchorPoint.TOP_LEFT &&
|
|
909
1226
|
unref(scanState).Layout.PositionData[1].Anchor === AnchorPoint.TOP_RIGHT &&
|
|
910
|
-
unref(scanState).Layout.PositionData[2].Anchor ===
|
|
1227
|
+
unref(scanState).Layout.PositionData[2].Anchor ===
|
|
1228
|
+
AnchorPoint.BOTTOM_LEFT &&
|
|
911
1229
|
unref(scanState).Layout.PositionData[3].Anchor === AnchorPoint.BOTTOM_RIGHT
|
|
912
|
-
)
|
|
913
|
-
})
|
|
1230
|
+
);
|
|
1231
|
+
});
|
|
914
1232
|
const isLayout1x3 = computed(() => {
|
|
915
1233
|
return (
|
|
916
1234
|
unref(scanState).Layout.PositionData.length > 1 &&
|
|
@@ -918,19 +1236,20 @@ const isLayout1x3 = computed(() => {
|
|
|
918
1236
|
unref(scanState).Layout.PositionData[1].Anchor === AnchorPoint.TOP_RIGHT &&
|
|
919
1237
|
unref(scanState).Layout.PositionData[2].Anchor === AnchorPoint.RIGHT &&
|
|
920
1238
|
unref(scanState).Layout.PositionData[3].Anchor === AnchorPoint.BOTTOM_RIGHT
|
|
921
|
-
)
|
|
922
|
-
})
|
|
923
|
-
|
|
1239
|
+
);
|
|
1240
|
+
});
|
|
924
1241
|
|
|
925
1242
|
function getCurrentGreyscalePreset() {
|
|
926
1243
|
for (const preset of unref(initialScanState).GreyscalePresets) {
|
|
927
1244
|
if (
|
|
928
1245
|
(unref(scanState).Display.WindowLower === preset.Lower ||
|
|
929
|
-
(preset.Lower
|
|
930
|
-
unref(scanState).Display.WindowLower ===
|
|
1246
|
+
(preset.Lower < unref(initialScanState).HuLower &&
|
|
1247
|
+
unref(scanState).Display.WindowLower ===
|
|
1248
|
+
unref(initialScanState).HuLower)) &&
|
|
931
1249
|
(unref(scanState).Display.WindowUpper === preset.Upper ||
|
|
932
1250
|
(preset.Upper > unref(initialScanState).HuUpper &&
|
|
933
|
-
unref(scanState).Display.WindowUpper ===
|
|
1251
|
+
unref(scanState).Display.WindowUpper ===
|
|
1252
|
+
unref(initialScanState).HuUpper))
|
|
934
1253
|
) {
|
|
935
1254
|
return preset.Name;
|
|
936
1255
|
}
|
|
@@ -941,18 +1260,52 @@ function setScanState(message: string) {
|
|
|
941
1260
|
scanState.value = JSON.parse(message) as CurrentScanState;
|
|
942
1261
|
}
|
|
943
1262
|
|
|
944
|
-
function handleOnPayload(
|
|
945
|
-
|
|
946
|
-
|
|
1263
|
+
function handleOnPayload(
|
|
1264
|
+
interfaceSet: string | FrontEndInterfaces,
|
|
1265
|
+
actionSet: string,
|
|
1266
|
+
message: string
|
|
1267
|
+
) {
|
|
1268
|
+
if (interfaceSet === FrontEndInterfaces.scan_state) {
|
|
1269
|
+
i_scanState(actionSet, message);
|
|
947
1270
|
}
|
|
948
1271
|
if (interfaceSet === FrontEndInterfaces.file_management) {
|
|
949
|
-
i_fileManagement(actionSet, message)
|
|
1272
|
+
i_fileManagement(actionSet, message);
|
|
950
1273
|
}
|
|
951
|
-
if (interfaceSet ===
|
|
952
|
-
i_notifications(actionSet, message)
|
|
1274
|
+
if (interfaceSet === FrontEndInterfaces.notifications) {
|
|
1275
|
+
i_notifications(actionSet, message);
|
|
953
1276
|
}
|
|
954
1277
|
}
|
|
955
1278
|
|
|
1279
|
+
defineExpose({
|
|
1280
|
+
alterValue,
|
|
1281
|
+
load,
|
|
1282
|
+
handleOnPayload,
|
|
1283
|
+
setScanState,
|
|
1284
|
+
sendPayload,
|
|
1285
|
+
getIconForPreset,
|
|
1286
|
+
cSlider,
|
|
1287
|
+
sSlider,
|
|
1288
|
+
tSlider,
|
|
1289
|
+
thresholdSlider,
|
|
1290
|
+
windowSlider,
|
|
1291
|
+
isLayout2x2,
|
|
1292
|
+
isLayout1x3,
|
|
1293
|
+
m_closeDialog,
|
|
1294
|
+
getCurrentGreyscalePreset,
|
|
1295
|
+
closeModal,
|
|
1296
|
+
snap,
|
|
1297
|
+
scanState,
|
|
1298
|
+
initialScanState,
|
|
1299
|
+
footerItems,
|
|
1300
|
+
rotateByDeg,
|
|
1301
|
+
getCurrentActiveView,
|
|
1302
|
+
getViewName,
|
|
1303
|
+
fullscreenLayout,
|
|
1304
|
+
layouts,
|
|
1305
|
+
setPreset,
|
|
1306
|
+
value,
|
|
1307
|
+
transactionStarted,
|
|
1308
|
+
});
|
|
956
1309
|
</script>
|
|
957
1310
|
<style>
|
|
958
1311
|
.v-dialog:not(.v-dialog--fullscreen) {
|