@cornerstonejs/tools 5.6.14 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/eventDispatchers/shared/getTouchCallbackWithMouseFallback.d.ts +1 -0
- package/dist/esm/eventDispatchers/shared/getTouchCallbackWithMouseFallback.js +24 -0
- package/dist/esm/eventDispatchers/shared/releaseToolForMultiTouchGesture.d.ts +2 -0
- package/dist/esm/eventDispatchers/shared/releaseToolForMultiTouchGesture.js +30 -0
- package/dist/esm/eventDispatchers/touchEventHandlers/touchDrag.js +7 -4
- package/dist/esm/eventDispatchers/touchEventHandlers/touchStart.js +7 -4
- package/dist/esm/eventDispatchers/touchEventHandlers/touchStartActivate.js +7 -2
- package/dist/esm/eventDispatchers/touchEventHandlers/touchTap.d.ts +2 -2
- package/dist/esm/eventDispatchers/touchEventHandlers/touchTap.js +29 -3
- package/dist/esm/eventDispatchers/touchToolEventDispatcher.js +1 -0
- package/dist/esm/eventListeners/touch/touchStartListener.js +7 -2
- package/dist/esm/store/ToolGroupManager/ToolGroup.js +1 -1
- package/dist/esm/store/filterMoveableAnnotationTools.js +2 -1
- package/dist/esm/store/filterToolsWithMoveableHandles.js +2 -1
- package/dist/esm/tools/AdvancedMagnifyTool.d.ts +11 -4
- package/dist/esm/tools/AdvancedMagnifyTool.js +141 -7
- package/dist/esm/tools/CrosshairsTool.d.ts +1 -1
- package/dist/esm/tools/CrosshairsTool.js +9 -8
- package/dist/esm/tools/MagnifyTool.d.ts +2 -0
- package/dist/esm/tools/MagnifyTool.js +19 -4
- package/dist/esm/tools/TrackballRotateTool.js +7 -0
- package/dist/esm/tools/VolumeCroppingTool.js +8 -0
- package/dist/esm/tools/VolumeRotateTool.d.ts +5 -1
- package/dist/esm/tools/VolumeRotateTool.js +24 -3
- package/dist/esm/tools/annotation/ArrowAnnotateTool.d.ts +1 -1
- package/dist/esm/tools/annotation/ArrowAnnotateTool.js +3 -3
- package/dist/esm/tools/annotation/ClickSegmentTool.d.ts +1 -0
- package/dist/esm/tools/annotation/ClickSegmentTool.js +14 -0
- package/dist/esm/tools/annotation/DragProbeTool.js +3 -1
- package/dist/esm/tools/annotation/LivewireContourTool.d.ts +3 -0
- package/dist/esm/tools/annotation/LivewireContourTool.js +36 -2
- package/dist/esm/tools/annotation/ProbeTool.d.ts +10 -2
- package/dist/esm/tools/annotation/ProbeTool.js +22 -3
- package/dist/esm/tools/annotation/RegionSegmentTool.js +6 -0
- package/dist/esm/tools/annotation/SplineROITool.d.ts +4 -0
- package/dist/esm/tools/annotation/SplineROITool.js +41 -3
- package/dist/esm/tools/annotation/WholeBodySegmentTool.js +7 -1
- package/dist/esm/tools/base/BaseTool.d.ts +7 -1
- package/dist/esm/tools/base/BaseTool.js +16 -0
- package/dist/esm/tools/base/ContourSegmentationBaseTool.d.ts +4 -0
- package/dist/esm/tools/base/ContourSegmentationBaseTool.js +23 -0
- package/dist/esm/tools/segmentation/BrushTool.d.ts +3 -0
- package/dist/esm/tools/segmentation/BrushTool.js +62 -4
- package/dist/esm/tools/segmentation/CircleScissorsTool.js +6 -1
- package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +5 -0
- package/dist/esm/tools/segmentation/LabelmapBaseTool.js +15 -0
- package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +1 -0
- package/dist/esm/tools/segmentation/RectangleScissorsTool.js +6 -1
- package/dist/esm/tools/segmentation/SegmentLabelTool.js +1 -1
- package/dist/esm/tools/segmentation/SegmentSelectTool.js +1 -1
- package/dist/esm/tools/segmentation/SphereScissorsTool.js +6 -1
- package/dist/esm/utilities/touch/constants.d.ts +4 -0
- package/dist/esm/utilities/touch/constants.js +4 -0
- package/dist/esm/utilities/touch/index.d.ts +3 -1
- package/dist/esm/utilities/touch/index.js +7 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function getTouchCallbackWithMouseFallback(tool: any, touchCallbackName: string, mouseCallbackName: string): ((evt: any) => unknown) | undefined;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MouseBindings } from '../../enums/index.js';
|
|
2
|
+
function augmentTouchDetailForMouseCallback(detail) {
|
|
3
|
+
detail.mouseButton ??= MouseBindings.Primary;
|
|
4
|
+
detail.startPoints ??= detail.currentPoints;
|
|
5
|
+
detail.lastPoints ??= detail.currentPoints;
|
|
6
|
+
detail.deltaPoints ??= {
|
|
7
|
+
page: [0, 0],
|
|
8
|
+
client: [0, 0],
|
|
9
|
+
canvas: [0, 0],
|
|
10
|
+
world: [0, 0, 0],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export default function getTouchCallbackWithMouseFallback(tool, touchCallbackName, mouseCallbackName) {
|
|
14
|
+
if (typeof tool?.[touchCallbackName] === 'function') {
|
|
15
|
+
return (evt) => tool[touchCallbackName](evt);
|
|
16
|
+
}
|
|
17
|
+
if (tool?.supportedInteractionTypes?.includes('Touch') &&
|
|
18
|
+
typeof tool[mouseCallbackName] === 'function') {
|
|
19
|
+
return (evt) => {
|
|
20
|
+
augmentTouchDetailForMouseCallback(evt.detail);
|
|
21
|
+
return tool[mouseCallbackName](evt);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { state } from '../../store/state.js';
|
|
2
|
+
import { getToolGroupForViewport } from '../../store/ToolGroupManager/index.js';
|
|
3
|
+
export default function releaseToolForMultiTouchGesture(evt) {
|
|
4
|
+
if (!state.isInteractingWithTool) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (!(evt.detail.currentPointsList?.length > 1)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const { renderingEngineId, viewportId, element } = evt.detail;
|
|
11
|
+
const toolGroup = getToolGroupForViewport(viewportId, renderingEngineId);
|
|
12
|
+
if (!toolGroup) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
let bypassInteractionGuard = false;
|
|
16
|
+
for (const toolName of Object.keys(toolGroup.toolOptions)) {
|
|
17
|
+
const tool = toolGroup.getToolInstance(toolName);
|
|
18
|
+
if (!tool) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (tool.handlesMultiTouchGestures) {
|
|
22
|
+
if (tool.isDrawing) {
|
|
23
|
+
bypassInteractionGuard = true;
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
tool.cancel?.(element);
|
|
28
|
+
}
|
|
29
|
+
return bypassInteractionGuard;
|
|
30
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import getActiveToolForTouchEvent from '../shared/getActiveToolForTouchEvent.js';
|
|
2
|
+
import getTouchCallbackWithMouseFallback from '../shared/getTouchCallbackWithMouseFallback.js';
|
|
3
|
+
import releaseToolForMultiTouchGesture from '../shared/releaseToolForMultiTouchGesture.js';
|
|
2
4
|
import { state } from '../../store/state.js';
|
|
3
5
|
export default function touchDrag(evt) {
|
|
4
|
-
|
|
6
|
+
const bypassInteractionGuard = releaseToolForMultiTouchGesture(evt);
|
|
7
|
+
if (state.isInteractingWithTool && !bypassInteractionGuard) {
|
|
5
8
|
return;
|
|
6
9
|
}
|
|
7
10
|
const activeTool = getActiveToolForTouchEvent(evt);
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
11
|
+
const dragCallback = getTouchCallbackWithMouseFallback(activeTool, 'touchDragCallback', 'mouseDragCallback');
|
|
12
|
+
if (!dragCallback) {
|
|
10
13
|
return;
|
|
11
14
|
}
|
|
12
|
-
|
|
15
|
+
dragCallback(evt);
|
|
13
16
|
}
|
|
@@ -7,6 +7,7 @@ import filterToolsWithMoveableHandles from '../../store/filterToolsWithMoveableH
|
|
|
7
7
|
import filterToolsWithAnnotationsForElement from '../../store/filterToolsWithAnnotationsForElement.js';
|
|
8
8
|
import filterMoveableAnnotationTools from '../../store/filterMoveableAnnotationTools.js';
|
|
9
9
|
import getActiveToolForTouchEvent from '../shared/getActiveToolForTouchEvent.js';
|
|
10
|
+
import getTouchCallbackWithMouseFallback from '../shared/getTouchCallbackWithMouseFallback.js';
|
|
10
11
|
import getToolsWithModesForTouchEvent from '../shared/getToolsWithModesForTouchEvent.js';
|
|
11
12
|
const { Active, Passive } = ToolModes;
|
|
12
13
|
export default function touchStart(evt) {
|
|
@@ -14,8 +15,9 @@ export default function touchStart(evt) {
|
|
|
14
15
|
return;
|
|
15
16
|
}
|
|
16
17
|
const activeTool = getActiveToolForTouchEvent(evt);
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const preCallback = getTouchCallbackWithMouseFallback(activeTool, 'preTouchStartCallback', 'preMouseDownCallback');
|
|
19
|
+
if (preCallback) {
|
|
20
|
+
const consumedEvent = preCallback(evt);
|
|
19
21
|
if (consumedEvent) {
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
@@ -45,8 +47,9 @@ export default function touchStart(evt) {
|
|
|
45
47
|
tool.toolSelectedCallback(evt, annotation, 'Touch', canvasCoords);
|
|
46
48
|
return;
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const postCallback = getTouchCallbackWithMouseFallback(activeTool, 'postTouchStartCallback', 'postMouseDownCallback');
|
|
51
|
+
if (postCallback) {
|
|
52
|
+
const consumedEvent = postCallback(evt);
|
|
50
53
|
if (consumedEvent) {
|
|
51
54
|
return;
|
|
52
55
|
}
|
|
@@ -13,7 +13,12 @@ export default function touchStartActivate(evt) {
|
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
if (activeTool.addNewAnnotation) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try {
|
|
17
|
+
const annotation = activeTool.addNewAnnotation(evt, 'touch');
|
|
18
|
+
setAnnotationSelected(annotation.annotationUID);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.warn('Error adding new annotation, viewport not ready:', error);
|
|
22
|
+
}
|
|
18
23
|
}
|
|
19
24
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export default touchTap;
|
|
1
|
+
import type { EventTypes } from '../../types/index.js';
|
|
2
|
+
export default function touchTap(evt: EventTypes.TouchTapEventType): void;
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { state } from '../../store/state.js';
|
|
2
|
+
import ToolModes from '../../enums/ToolModes.js';
|
|
3
|
+
import { getToolGroupForViewport } from '../../store/ToolGroupManager/index.js';
|
|
4
|
+
import getTouchCallbackWithMouseFallback from '../shared/getTouchCallbackWithMouseFallback.js';
|
|
5
|
+
const { Active } = ToolModes;
|
|
6
|
+
export default function touchTap(evt) {
|
|
7
|
+
if (state.isInteractingWithTool) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const { renderingEngineId, viewportId } = evt.detail;
|
|
11
|
+
const toolGroup = getToolGroupForViewport(viewportId, renderingEngineId);
|
|
12
|
+
if (!toolGroup) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const toolGroupToolNames = Object.keys(toolGroup.toolOptions);
|
|
16
|
+
for (let j = 0; j < toolGroupToolNames.length; j++) {
|
|
17
|
+
const toolName = toolGroupToolNames[j];
|
|
18
|
+
const toolOptions = toolGroup.toolOptions[toolName];
|
|
19
|
+
if (toolOptions.mode !== Active) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const toolInstance = toolGroup.getToolInstance(toolName);
|
|
23
|
+
const tapCallback = getTouchCallbackWithMouseFallback(toolInstance, 'touchTapCallback', 'mouseClickCallback');
|
|
24
|
+
if (tapCallback) {
|
|
25
|
+
tapCallback(evt);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -13,6 +13,7 @@ const disable = function (element) {
|
|
|
13
13
|
element.removeEventListener(Events.TOUCH_START_ACTIVATE, touchStartActivate);
|
|
14
14
|
element.removeEventListener(Events.TOUCH_DRAG, touchDrag);
|
|
15
15
|
element.removeEventListener(Events.TOUCH_END, touchEnd);
|
|
16
|
+
element.removeEventListener(Events.TOUCH_TAP, touchTap);
|
|
16
17
|
element.removeEventListener(Events.TOUCH_PRESS, touchPress);
|
|
17
18
|
};
|
|
18
19
|
const touchToolEventDispatcher = {
|
|
@@ -3,6 +3,7 @@ import Events from '../../enums/Events.js';
|
|
|
3
3
|
import { Swipe } from '../../enums/Touch.js';
|
|
4
4
|
import getTouchEventPoints from './getTouchEventPoints.js';
|
|
5
5
|
import { copyPoints, copyPointsList, getDeltaDistanceBetweenIPoints, getDeltaDistance, getDeltaPoints, getMeanTouchPoints, } from '../../utilities/touch/index.js';
|
|
6
|
+
import { TOUCH_TAP_MAX_CANVAS_DISTANCE, TOUCH_TAP_TOLERANCE_MS, } from '../../utilities/touch/constants.js';
|
|
6
7
|
import { Settings } from '@cornerstonejs/core';
|
|
7
8
|
const runtimeSettings = Settings.getRuntimeSettings();
|
|
8
9
|
const { TOUCH_START, TOUCH_START_ACTIVATE, TOUCH_PRESS, TOUCH_DRAG, TOUCH_END, TOUCH_TAP, TOUCH_SWIPE, } = Events;
|
|
@@ -56,8 +57,8 @@ const defaultTapState = {
|
|
|
56
57
|
],
|
|
57
58
|
taps: 0,
|
|
58
59
|
tapTimeout: null,
|
|
59
|
-
tapMaxDistance:
|
|
60
|
-
tapToleranceMs:
|
|
60
|
+
tapMaxDistance: TOUCH_TAP_MAX_CANVAS_DISTANCE,
|
|
61
|
+
tapToleranceMs: TOUCH_TAP_TOLERANCE_MS,
|
|
61
62
|
};
|
|
62
63
|
let state = utilities.deepClone(defaultState);
|
|
63
64
|
let tapState = utilities.deepClone(defaultTapState);
|
|
@@ -224,6 +225,10 @@ function _checkTouchTap(evt) {
|
|
|
224
225
|
clearTimeout(tapState.tapTimeout);
|
|
225
226
|
tapState.taps += 1;
|
|
226
227
|
tapState.tapTimeout = setTimeout(() => {
|
|
228
|
+
if (state.isTouchStart) {
|
|
229
|
+
tapState = utilities.deepClone(defaultTapState);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
227
232
|
const eventDetail = {
|
|
228
233
|
event: evt,
|
|
229
234
|
eventName: TOUCH_TAP,
|
|
@@ -407,7 +407,7 @@ export default class ToolGroup {
|
|
|
407
407
|
const sourceToolMode = sourceToolInstance.mode;
|
|
408
408
|
toolGroup.addTool(toolName);
|
|
409
409
|
toolGroup.setToolMode(toolName, sourceToolMode, {
|
|
410
|
-
bindings: sourceToolOptions
|
|
410
|
+
bindings: sourceToolOptions?.bindings ?? [],
|
|
411
411
|
});
|
|
412
412
|
});
|
|
413
413
|
return toolGroup;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { MOUSE_PROXIMITY, TOUCH_PROXIMITY } from '../utilities/touch/constants.js';
|
|
1
2
|
export default function filterMoveableAnnotationTools(element, ToolAndAnnotations, canvasCoords, interactionType = 'mouse') {
|
|
2
|
-
const proximity = interactionType === 'touch' ?
|
|
3
|
+
const proximity = interactionType === 'touch' ? TOUCH_PROXIMITY : MOUSE_PROXIMITY;
|
|
3
4
|
const moveableAnnotationTools = [];
|
|
4
5
|
ToolAndAnnotations.forEach(({ tool, annotations }) => {
|
|
5
6
|
for (const annotation of annotations) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { MOUSE_PROXIMITY, TOUCH_PROXIMITY } from '../utilities/touch/constants.js';
|
|
1
2
|
export default function filterToolsWithMoveableHandles(element, ToolAndAnnotations, canvasCoords, interactionType = 'mouse') {
|
|
2
|
-
const proximity = interactionType === 'touch' ?
|
|
3
|
+
const proximity = interactionType === 'touch' ? TOUCH_PROXIMITY : MOUSE_PROXIMITY;
|
|
3
4
|
const toolsWithMoveableHandles = [];
|
|
4
5
|
ToolAndAnnotations.forEach(({ tool, annotations }) => {
|
|
5
6
|
for (const annotation of annotations) {
|
|
@@ -55,18 +55,20 @@ declare class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
55
55
|
constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
|
|
56
56
|
addNewAnnotation: (evt: EventTypes.InteractionEventType) => AdvancedMagnifyAnnotation;
|
|
57
57
|
onSetToolDisabled: () => void;
|
|
58
|
-
isPointNearTool: (element: HTMLDivElement, annotation: AdvancedMagnifyAnnotation, canvasCoords: Types.Point2, proximity: number) => boolean;
|
|
58
|
+
isPointNearTool: (element: HTMLDivElement, annotation: AdvancedMagnifyAnnotation, canvasCoords: Types.Point2, proximity: number, interactionType?: string) => boolean;
|
|
59
59
|
toolSelectedCallback: (evt: EventTypes.InteractionEventType, annotation: AdvancedMagnifyAnnotation) => void;
|
|
60
60
|
handleSelectedCallback: (evt: EventTypes.InteractionEventType, annotation: AdvancedMagnifyAnnotation, handle: ToolHandle) => void;
|
|
61
|
-
_endCallback: (evt: EventTypes.InteractionEventType) => void;
|
|
61
|
+
_endCallback: (evt: EventTypes.InteractionEventType | EventTypes.TouchPressEventType) => void;
|
|
62
62
|
_dragDrawCallback: (evt: EventTypes.InteractionEventType) => void;
|
|
63
63
|
_dragModifyCallback: (evt: EventTypes.InteractionEventType) => void;
|
|
64
|
+
_pressModifyCallback: (evt: EventTypes.TouchPressEventType) => void;
|
|
64
65
|
_dragHandle: (evt: EventTypes.InteractionEventType) => void;
|
|
65
66
|
cancel: (element: HTMLDivElement) => string;
|
|
66
67
|
_activateModify: (element: any) => void;
|
|
67
68
|
_deactivateModify: (element: any) => void;
|
|
68
69
|
renderAnnotation: (enabledElement: Types.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean;
|
|
69
|
-
showZoomFactorsList(evt: EventTypes.InteractionEventType, annotation: AdvancedMagnifyAnnotation): void;
|
|
70
|
+
showZoomFactorsList(evt: EventTypes.InteractionEventType | EventTypes.TouchPressEventType, annotation: AdvancedMagnifyAnnotation): void;
|
|
71
|
+
touchPressCallback: (evt: EventTypes.TouchPressEventType) => void;
|
|
70
72
|
private _getZoomFactorsListDropdown;
|
|
71
73
|
private _getWorldHandlePoints;
|
|
72
74
|
private _getCanvasCircleData;
|
|
@@ -85,11 +87,12 @@ declare class AdvancedMagnifyViewport {
|
|
|
85
87
|
private _resized;
|
|
86
88
|
private _resizeViewportAsync;
|
|
87
89
|
private _canAutoPan;
|
|
90
|
+
private _annotation;
|
|
88
91
|
private _autoPan;
|
|
89
92
|
position: Types.Point2;
|
|
90
93
|
zoomFactor: number;
|
|
91
94
|
visible: boolean;
|
|
92
|
-
constructor({ magnifyViewportId, sourceEnabledElement, radius, position, zoomFactor, autoPan, }: {
|
|
95
|
+
constructor({ magnifyViewportId, sourceEnabledElement, radius, position, zoomFactor, autoPan, annotation, }: {
|
|
93
96
|
magnifyViewportId?: string;
|
|
94
97
|
sourceEnabledElement: Types.IEnabledElement;
|
|
95
98
|
radius?: number;
|
|
@@ -100,6 +103,7 @@ declare class AdvancedMagnifyViewport {
|
|
|
100
103
|
padding: number;
|
|
101
104
|
callback: AutoPanCallback;
|
|
102
105
|
};
|
|
106
|
+
annotation?: AdvancedMagnifyAnnotation;
|
|
103
107
|
});
|
|
104
108
|
get sourceEnabledElement(): Types.IEnabledElement;
|
|
105
109
|
get viewportId(): string;
|
|
@@ -120,7 +124,10 @@ declare class AdvancedMagnifyViewport {
|
|
|
120
124
|
private _cancelMouseEventCallback;
|
|
121
125
|
private _browserMouseUpCallback;
|
|
122
126
|
private _browserMouseDownCallback;
|
|
127
|
+
private _browserTouchEndCallback;
|
|
128
|
+
private _browserTouchStartCallback;
|
|
123
129
|
private _mouseDragCallback;
|
|
130
|
+
private _touchPressCallback;
|
|
124
131
|
private _addBrowserEventListeners;
|
|
125
132
|
private _removeBrowserEventListeners;
|
|
126
133
|
private _addEventListeners;
|
|
@@ -135,7 +135,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
};
|
|
138
|
-
this.isPointNearTool = (element, annotation, canvasCoords, proximity) => {
|
|
138
|
+
this.isPointNearTool = (element, annotation, canvasCoords, proximity, interactionType) => {
|
|
139
139
|
const { viewport } = getEnabledElement(element);
|
|
140
140
|
const { points } = annotation.data.handles;
|
|
141
141
|
const { radius, center } = this._getCanvasCircleData(viewport, points);
|
|
@@ -143,6 +143,9 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
143
143
|
if (Math.abs(radiusPoint - radius) < proximity * 2) {
|
|
144
144
|
return true;
|
|
145
145
|
}
|
|
146
|
+
if (interactionType === 'touch' && radiusPoint < radius) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
146
149
|
return false;
|
|
147
150
|
};
|
|
148
151
|
this.toolSelectedCallback = (evt, annotation) => {
|
|
@@ -227,6 +230,17 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
227
230
|
}
|
|
228
231
|
triggerAnnotationRenderForViewportIds(viewportIdsToRender);
|
|
229
232
|
};
|
|
233
|
+
this._pressModifyCallback = (evt) => {
|
|
234
|
+
const { element, startPoints } = evt.detail;
|
|
235
|
+
const annotation = this.editData.annotation;
|
|
236
|
+
const proximity = AdvancedMagnifyTool.TOUCH_PROXIMITY;
|
|
237
|
+
if (!this.isPointNearTool(element, annotation, startPoints.canvas, proximity)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
evt.stopImmediatePropagation();
|
|
241
|
+
this._endCallback(evt);
|
|
242
|
+
this.showZoomFactorsList(evt, annotation);
|
|
243
|
+
};
|
|
230
244
|
this._dragHandle = (evt) => {
|
|
231
245
|
const eventDetail = evt.detail;
|
|
232
246
|
const { element } = eventDetail;
|
|
@@ -274,6 +288,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
274
288
|
element.addEventListener(Events.TOUCH_END, this._endCallback);
|
|
275
289
|
element.addEventListener(Events.TOUCH_DRAG, this._dragModifyCallback);
|
|
276
290
|
element.addEventListener(Events.TOUCH_TAP, this._endCallback);
|
|
291
|
+
element.addEventListener(Events.TOUCH_PRESS, this._pressModifyCallback);
|
|
277
292
|
};
|
|
278
293
|
this._deactivateModify = (element) => {
|
|
279
294
|
state.isInteractingWithTool = false;
|
|
@@ -283,6 +298,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
283
298
|
element.removeEventListener(Events.TOUCH_END, this._endCallback);
|
|
284
299
|
element.removeEventListener(Events.TOUCH_DRAG, this._dragModifyCallback);
|
|
285
300
|
element.removeEventListener(Events.TOUCH_TAP, this._endCallback);
|
|
301
|
+
element.removeEventListener(Events.TOUCH_PRESS, this._pressModifyCallback);
|
|
286
302
|
};
|
|
287
303
|
this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
|
|
288
304
|
let renderStatus = false;
|
|
@@ -350,6 +366,27 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
350
366
|
}
|
|
351
367
|
return renderStatus;
|
|
352
368
|
};
|
|
369
|
+
this.touchPressCallback = (evt) => {
|
|
370
|
+
const { element, startPoints } = evt.detail;
|
|
371
|
+
const enabledElement = getEnabledElement(element);
|
|
372
|
+
if (!enabledElement) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const { viewport } = enabledElement;
|
|
376
|
+
const canvasPoint = startPoints.canvas;
|
|
377
|
+
const proximity = AdvancedMagnifyTool.TOUCH_PROXIMITY;
|
|
378
|
+
const annotations = (getAnnotations(this.getToolName(), element) ??
|
|
379
|
+
[]);
|
|
380
|
+
const annotation = annotations
|
|
381
|
+
.filter((a) => a.data.sourceViewportId === viewport.id)
|
|
382
|
+
.find((a) => isAnnotationVisible(a.annotationUID) &&
|
|
383
|
+
!isAnnotationLocked(a.annotationUID) &&
|
|
384
|
+
this.isPointNearTool(element, a, canvasPoint, proximity));
|
|
385
|
+
if (!annotation) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
this.showZoomFactorsList(evt, annotation);
|
|
389
|
+
};
|
|
353
390
|
this._getWorldHandlePoints = (viewport, canvasCenterPos, canvasRadius) => {
|
|
354
391
|
const canvasHandlePoints = this._getCanvasHandlePoints(canvasCenterPos, canvasRadius);
|
|
355
392
|
return canvasHandlePoints.map((handlePoint) => viewport.canvasToWorld(handlePoint));
|
|
@@ -377,13 +414,16 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
377
414
|
this.magnifyViewportManager = AdvancedMagnifyViewportManager.getInstance();
|
|
378
415
|
}
|
|
379
416
|
showZoomFactorsList(evt, annotation) {
|
|
380
|
-
const { element
|
|
417
|
+
const { element } = evt.detail;
|
|
418
|
+
const currentPoints = 'currentPoints' in evt.detail
|
|
419
|
+
? evt.detail.currentPoints
|
|
420
|
+
: evt.detail.startPoints;
|
|
381
421
|
const enabledElement = getEnabledElement(element);
|
|
382
422
|
const { viewport } = enabledElement;
|
|
383
423
|
const { canvas: canvasPoint } = currentPoints;
|
|
384
424
|
const viewportElement = element.querySelector(':scope .viewport-element');
|
|
385
425
|
const currentZoomFactor = annotation.data.zoomFactor;
|
|
386
|
-
const remove = () => dropdown.
|
|
426
|
+
const remove = () => dropdown.remove();
|
|
387
427
|
const dropdown = this._getZoomFactorsListDropdown(currentZoomFactor, (newZoomFactor) => {
|
|
388
428
|
if (newZoomFactor !== undefined) {
|
|
389
429
|
annotation.data.zoomFactor = Number.parseFloat(newZoomFactor);
|
|
@@ -407,19 +447,42 @@ class AdvancedMagnifyTool extends AnnotationTool {
|
|
|
407
447
|
width: '50px',
|
|
408
448
|
position: 'absolute',
|
|
409
449
|
});
|
|
410
|
-
[
|
|
450
|
+
[
|
|
451
|
+
'mousedown',
|
|
452
|
+
'mouseup',
|
|
453
|
+
'mousemove',
|
|
454
|
+
'click',
|
|
455
|
+
'touchstart',
|
|
456
|
+
'touchend',
|
|
457
|
+
'touchmove',
|
|
458
|
+
].forEach((eventName) => {
|
|
411
459
|
dropdown.addEventListener(eventName, (evt) => evt.stopPropagation());
|
|
412
460
|
});
|
|
461
|
+
let committed = false;
|
|
462
|
+
const commit = (value) => {
|
|
463
|
+
if (committed) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
committed = true;
|
|
467
|
+
onChangeCallback(value);
|
|
468
|
+
};
|
|
413
469
|
dropdown.addEventListener('change', (evt) => {
|
|
414
470
|
evt.stopPropagation();
|
|
415
|
-
|
|
471
|
+
commit(dropdown.value);
|
|
416
472
|
});
|
|
473
|
+
dropdown.addEventListener('click', (evt) => {
|
|
474
|
+
evt.stopPropagation();
|
|
475
|
+
if (evt.target?.tagName === 'OPTION') {
|
|
476
|
+
commit(dropdown.value);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
dropdown.addEventListener('blur', () => commit(dropdown.value));
|
|
417
480
|
dropdown.addEventListener('keydown', (evt) => {
|
|
418
481
|
const shouldCancel = (evt.keyCode ?? evt.which === 27) ||
|
|
419
482
|
evt.key?.toLowerCase() === 'escape';
|
|
420
483
|
if (shouldCancel) {
|
|
421
484
|
evt.stopPropagation();
|
|
422
|
-
|
|
485
|
+
commit();
|
|
423
486
|
}
|
|
424
487
|
});
|
|
425
488
|
zoomFactorList.forEach((zoomFactor) => {
|
|
@@ -474,6 +537,7 @@ class AdvancedMagnifyViewportManager {
|
|
|
474
537
|
position,
|
|
475
538
|
zoomFactor,
|
|
476
539
|
autoPan,
|
|
540
|
+
annotation,
|
|
477
541
|
});
|
|
478
542
|
this._addSourceElementEventListener(sourceElement);
|
|
479
543
|
this._magnifyViewportsMap.set(magnifyViewport.viewportId, {
|
|
@@ -617,7 +681,7 @@ class AdvancedMagnifyViewportManager {
|
|
|
617
681
|
}
|
|
618
682
|
}
|
|
619
683
|
class AdvancedMagnifyViewport {
|
|
620
|
-
constructor({ magnifyViewportId, sourceEnabledElement, radius = MAGNIFY_VIEWPORT_INITIAL_RADIUS, position = [0, 0], zoomFactor, autoPan, }) {
|
|
684
|
+
constructor({ magnifyViewportId, sourceEnabledElement, radius = MAGNIFY_VIEWPORT_INITIAL_RADIUS, position = [0, 0], zoomFactor, autoPan, annotation, }) {
|
|
621
685
|
this._enabledElement = null;
|
|
622
686
|
this._sourceToolGroup = null;
|
|
623
687
|
this._magnifyToolGroup = null;
|
|
@@ -628,12 +692,17 @@ class AdvancedMagnifyViewport {
|
|
|
628
692
|
this._viewportId = magnifyViewportId ?? csUtils.uuidv4();
|
|
629
693
|
this._sourceEnabledElement = sourceEnabledElement;
|
|
630
694
|
this._autoPan = autoPan;
|
|
695
|
+
this._annotation = annotation;
|
|
631
696
|
this.radius = radius;
|
|
632
697
|
this.position = position;
|
|
633
698
|
this.zoomFactor = zoomFactor;
|
|
634
699
|
this.visible = true;
|
|
635
700
|
this._browserMouseDownCallback = this._browserMouseDownCallback.bind(this);
|
|
636
701
|
this._browserMouseUpCallback = this._browserMouseUpCallback.bind(this);
|
|
702
|
+
this._browserTouchStartCallback =
|
|
703
|
+
this._browserTouchStartCallback.bind(this);
|
|
704
|
+
this._browserTouchEndCallback = this._browserTouchEndCallback.bind(this);
|
|
705
|
+
this._touchPressCallback = this._touchPressCallback.bind(this);
|
|
637
706
|
this._handleToolModeChanged = this._handleToolModeChanged.bind(this);
|
|
638
707
|
this._mouseDragCallback = this._mouseDragCallback.bind(this);
|
|
639
708
|
this._resizeViewportAsync = (debounce(this._resizeViewport.bind(this), 1));
|
|
@@ -837,6 +906,30 @@ class AdvancedMagnifyViewport {
|
|
|
837
906
|
element.removeEventListener('mouseup', this._cancelMouseEventCallback);
|
|
838
907
|
element.removeEventListener('mousemove', this._cancelMouseEventCallback);
|
|
839
908
|
}
|
|
909
|
+
_browserTouchEndCallback(evt) {
|
|
910
|
+
if (evt.touches?.length > 0) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
const { element } = this._enabledElement.viewport;
|
|
914
|
+
document.removeEventListener('touchend', this._browserTouchEndCallback);
|
|
915
|
+
document.removeEventListener('touchcancel', this._browserTouchEndCallback);
|
|
916
|
+
element.addEventListener('touchend', this._cancelMouseEventCallback, {
|
|
917
|
+
passive: false,
|
|
918
|
+
});
|
|
919
|
+
element.addEventListener('touchmove', this._cancelMouseEventCallback, {
|
|
920
|
+
passive: false,
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
_browserTouchStartCallback(evt) {
|
|
924
|
+
const { element } = this._enabledElement.viewport;
|
|
925
|
+
if (evt.touches?.length === 1) {
|
|
926
|
+
this._canAutoPan = !!evt.target?.closest('.advancedMagnifyTool');
|
|
927
|
+
}
|
|
928
|
+
document.addEventListener('touchend', this._browserTouchEndCallback);
|
|
929
|
+
document.addEventListener('touchcancel', this._browserTouchEndCallback);
|
|
930
|
+
element.removeEventListener('touchend', this._cancelMouseEventCallback);
|
|
931
|
+
element.removeEventListener('touchmove', this._cancelMouseEventCallback);
|
|
932
|
+
}
|
|
840
933
|
_mouseDragCallback(evt) {
|
|
841
934
|
if (!state.isInteractingWithTool) {
|
|
842
935
|
return;
|
|
@@ -882,12 +975,43 @@ class AdvancedMagnifyViewport {
|
|
|
882
975
|
};
|
|
883
976
|
autoPan.callback(autoPanCallbackData);
|
|
884
977
|
}
|
|
978
|
+
_touchPressCallback(evt) {
|
|
979
|
+
if (state.isInteractingWithTool) {
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
const toolInstance = this._sourceToolGroup?.getToolInstance(ADVANCED_MAGNIFY_TOOL_NAME);
|
|
983
|
+
if (!toolInstance || !this._annotation) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const { viewport: sourceViewport } = this._sourceEnabledElement;
|
|
987
|
+
const pressCanvas = evt.detail.startPoints.canvas;
|
|
988
|
+
const sourceCanvasPoint = [
|
|
989
|
+
pressCanvas[0] + this.position[0] - this.radius,
|
|
990
|
+
pressCanvas[1] + this.position[1] - this.radius,
|
|
991
|
+
];
|
|
992
|
+
toolInstance.showZoomFactorsList({
|
|
993
|
+
detail: {
|
|
994
|
+
element: sourceViewport.element,
|
|
995
|
+
startPoints: { canvas: sourceCanvasPoint },
|
|
996
|
+
},
|
|
997
|
+
}, this._annotation);
|
|
998
|
+
}
|
|
885
999
|
_addBrowserEventListeners(element) {
|
|
886
1000
|
document.addEventListener('mousedown', this._browserMouseDownCallback, true);
|
|
887
1001
|
element.addEventListener('mousedown', this._cancelMouseEventCallback);
|
|
888
1002
|
element.addEventListener('mouseup', this._cancelMouseEventCallback);
|
|
889
1003
|
element.addEventListener('mousemove', this._cancelMouseEventCallback);
|
|
890
1004
|
element.addEventListener('dblclick', this._cancelMouseEventCallback);
|
|
1005
|
+
document.addEventListener('touchstart', this._browserTouchStartCallback, true);
|
|
1006
|
+
element.addEventListener('touchstart', this._cancelMouseEventCallback, {
|
|
1007
|
+
passive: false,
|
|
1008
|
+
});
|
|
1009
|
+
element.addEventListener('touchend', this._cancelMouseEventCallback, {
|
|
1010
|
+
passive: false,
|
|
1011
|
+
});
|
|
1012
|
+
element.addEventListener('touchmove', this._cancelMouseEventCallback, {
|
|
1013
|
+
passive: false,
|
|
1014
|
+
});
|
|
891
1015
|
}
|
|
892
1016
|
_removeBrowserEventListeners(element) {
|
|
893
1017
|
document.removeEventListener('mousedown', this._browserMouseDownCallback, true);
|
|
@@ -896,17 +1020,27 @@ class AdvancedMagnifyViewport {
|
|
|
896
1020
|
element.removeEventListener('mouseup', this._cancelMouseEventCallback);
|
|
897
1021
|
element.removeEventListener('mousemove', this._cancelMouseEventCallback);
|
|
898
1022
|
element.removeEventListener('dblclick', this._cancelMouseEventCallback);
|
|
1023
|
+
document.removeEventListener('touchstart', this._browserTouchStartCallback, true);
|
|
1024
|
+
document.removeEventListener('touchend', this._browserTouchEndCallback);
|
|
1025
|
+
document.removeEventListener('touchcancel', this._browserTouchEndCallback);
|
|
1026
|
+
element.removeEventListener('touchstart', this._cancelMouseEventCallback);
|
|
1027
|
+
element.removeEventListener('touchend', this._cancelMouseEventCallback);
|
|
1028
|
+
element.removeEventListener('touchmove', this._cancelMouseEventCallback);
|
|
899
1029
|
}
|
|
900
1030
|
_addEventListeners(element) {
|
|
901
1031
|
eventTarget.addEventListener(cstEvents.TOOL_MODE_CHANGED, this._handleToolModeChanged);
|
|
902
1032
|
element.addEventListener(cstEvents.MOUSE_MOVE, this._mouseDragCallback);
|
|
903
1033
|
element.addEventListener(cstEvents.MOUSE_DRAG, this._mouseDragCallback);
|
|
1034
|
+
element.addEventListener(cstEvents.TOUCH_DRAG, this._mouseDragCallback);
|
|
1035
|
+
element.addEventListener(cstEvents.TOUCH_PRESS, this._touchPressCallback);
|
|
904
1036
|
this._addBrowserEventListeners(element);
|
|
905
1037
|
}
|
|
906
1038
|
_removeEventListeners(element) {
|
|
907
1039
|
eventTarget.removeEventListener(cstEvents.TOOL_MODE_CHANGED, this._handleToolModeChanged);
|
|
908
1040
|
element.addEventListener(cstEvents.MOUSE_MOVE, this._mouseDragCallback);
|
|
909
1041
|
element.addEventListener(cstEvents.MOUSE_DRAG, this._mouseDragCallback);
|
|
1042
|
+
element.removeEventListener(cstEvents.TOUCH_DRAG, this._mouseDragCallback);
|
|
1043
|
+
element.removeEventListener(cstEvents.TOUCH_PRESS, this._touchPressCallback);
|
|
910
1044
|
this._removeBrowserEventListeners(element);
|
|
911
1045
|
}
|
|
912
1046
|
_initialize() {
|
|
@@ -69,7 +69,7 @@ declare class CrosshairsTool extends AnnotationTool {
|
|
|
69
69
|
_filterAnnotationsByUniqueViewportOrientations: (enabledElement: any, annotations: any) => any[];
|
|
70
70
|
_checkIfViewportsRenderingSameScene: (viewport: any, otherViewport: any) => any;
|
|
71
71
|
_jump: (enabledElement: any, jumpWorld: any) => boolean;
|
|
72
|
-
_activateModify: (element: any) => void;
|
|
72
|
+
_activateModify: (element: any, evt?: EventTypes.InteractionEventType) => void;
|
|
73
73
|
_deactivateModify: (element: any) => void;
|
|
74
74
|
_endCallback: (evt: EventTypes.InteractionEventType) => void;
|
|
75
75
|
_dragCallback: (evt: EventTypes.InteractionEventType) => void;
|