From 3e795991d05a132af314da85a965e37d32e8f843 Mon Sep 17 00:00:00 2001 From: cclevenger Date: Fri, 3 May 2024 18:49:30 -0400 Subject: [PATCH 1/8] Fix ANNOTATION_REMOVED event listener on removing ALL annotations. --- ...rameOfReferenceSpecificAnnotationManager.ts | 12 +++++++++++- .../annotation/annotationState.ts | 18 +----------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts index ff68c3f301..86d4aeb429 100644 --- a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +++ b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts @@ -10,12 +10,14 @@ import { AnnotationGroupSelector, IAnnotationManager } from '../../types'; import { Enums, + triggerEvent, eventTarget, getEnabledElement, Types, utilities, } from '@cornerstonejs/core'; +import { Events as csToolEvents } from '../../enums'; import { checkAndDefineIsLockedProperty } from './annotationLocking'; import { checkAndDefineIsVisibleProperty } from './annotationVisibility'; @@ -257,6 +259,12 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { (annotation) => annotation.annotationUID === annotationUID ); + // Trigger annotation removed event. + triggerEvent(eventTarget, csToolEvents.ANNOTATION_REMOVED, { + annotation: toolAnnotations[index], + annotationManagerUID: this.uid, + }); + if (index !== -1) { toolAnnotations.splice(index, 1); @@ -402,7 +410,9 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { * Removes all annotations in the annotation state. */ removeAllAnnotations = (): void => { - this.annotations = {}; + for (const annotation of this.getAllAnnotations()) { + this.removeAnnotation(annotation.annotationUID); + } }; } diff --git a/packages/tools/src/stateManagement/annotation/annotationState.ts b/packages/tools/src/stateManagement/annotation/annotationState.ts index fe683d630a..bf5fb54125 100644 --- a/packages/tools/src/stateManagement/annotation/annotationState.ts +++ b/packages/tools/src/stateManagement/annotation/annotationState.ts @@ -1,12 +1,6 @@ -import { - triggerEvent, - eventTarget, - utilities as csUtils, -} from '@cornerstonejs/core'; -import { Events } from '../../enums'; +import { utilities as csUtils } from '@cornerstonejs/core'; import { defaultFrameOfReferenceSpecificAnnotationManager } from './FrameOfReferenceSpecificAnnotationManager'; import { Annotations, Annotation } from '../../types/AnnotationTypes'; -import { AnnotationRemovedEventDetail } from '../../types/EventTypes'; import { AnnotationGroupSelector } from '../../types'; import { triggerAnnotationAddedForElement, @@ -223,16 +217,6 @@ function removeAnnotation(annotationUID: string): void { ); manager.removeAnnotation(annotationUID); - - // trigger annotation removed - const eventType = Events.ANNOTATION_REMOVED; - - const eventDetail: AnnotationRemovedEventDetail = { - annotation, - annotationManagerUID: manager.uid, - }; - - triggerEvent(eventTarget, eventType, eventDetail); } /** From 58a0845f3fde1b51c0d5d11c0d4df77ab0be3218 Mon Sep 17 00:00:00 2001 From: cclevenger Date: Fri, 3 May 2024 19:36:51 -0400 Subject: [PATCH 2/8] I think the tests expect the annotation to be removed BEFORE the event fires --- ...ameOfReferenceSpecificAnnotationManager.ts | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts index 86d4aeb429..fcab3f1090 100644 --- a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +++ b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts @@ -248,6 +248,7 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { */ removeAnnotation = (annotationUID: string): void => { const { annotations } = this; + let annotationToRemove = null; for (const groupKey in annotations) { const groupAnnotations = annotations[groupKey]; @@ -259,11 +260,7 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { (annotation) => annotation.annotationUID === annotationUID ); - // Trigger annotation removed event. - triggerEvent(eventTarget, csToolEvents.ANNOTATION_REMOVED, { - annotation: toolAnnotations[index], - annotationManagerUID: this.uid, - }); + annotationToRemove = toolAnnotations[index]; if (index !== -1) { toolAnnotations.splice(index, 1); @@ -278,6 +275,13 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { delete annotations[groupKey]; } } + + if (annotationToRemove !== null) { + triggerEvent(eventTarget, csToolEvents.ANNOTATION_REMOVED, { + annotation: annotationToRemove, + annotationManagerUID: this.uid, + }); + } }; /** @@ -289,12 +293,24 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { */ removeAnnotations = (groupKey: string, toolName?: string): void => { const annotations = this.annotations; - if (annotations[groupKey]) { - if (toolName) { - delete annotations[groupKey][toolName]; - } else { - delete annotations[groupKey]; + if (!annotations[groupKey]) { + return; + } + + if (toolName) { + const annotationsForTool = annotations[groupKey][toolName]; + for (const annotation of annotationsForTool) { + this.removeAnnotation(annotation.annotationUID); } + delete annotations[groupKey][toolName]; + } else { + for (const toolName in annotations[groupKey]) { + const annotationsForTool = annotations[groupKey][toolName]; + for (const annotation of annotationsForTool) { + this.removeAnnotation(annotation.annotationUID); + } + } + delete annotations[groupKey]; } }; @@ -413,6 +429,8 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { for (const annotation of this.getAllAnnotations()) { this.removeAnnotation(annotation.annotationUID); } + + this.annotations = {}; }; } From c0d35cfe1e168389710e9c33f3b9a76b8b4599b3 Mon Sep 17 00:00:00 2001 From: cclevenger Date: Fri, 3 May 2024 19:47:34 -0400 Subject: [PATCH 3/8] This should work if the removeAnnotation code is correct. --- .../annotation/FrameOfReferenceSpecificAnnotationManager.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts index fcab3f1090..2fe586234e 100644 --- a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +++ b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts @@ -302,7 +302,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { for (const annotation of annotationsForTool) { this.removeAnnotation(annotation.annotationUID); } - delete annotations[groupKey][toolName]; } else { for (const toolName in annotations[groupKey]) { const annotationsForTool = annotations[groupKey][toolName]; @@ -310,7 +309,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { this.removeAnnotation(annotation.annotationUID); } } - delete annotations[groupKey]; } }; @@ -429,8 +427,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { for (const annotation of this.getAllAnnotations()) { this.removeAnnotation(annotation.annotationUID); } - - this.annotations = {}; }; } From cd1433e1c7335c36808c4e54f14c4a8330637ae2 Mon Sep 17 00:00:00 2001 From: cclevenger Date: Fri, 3 May 2024 20:01:34 -0400 Subject: [PATCH 4/8] retrigger checks From 9272f6cbdcd857b20a702e2d194bd930d1583d8c Mon Sep 17 00:00:00 2001 From: cclevenger Date: Sat, 18 May 2024 10:35:19 -0400 Subject: [PATCH 5/8] Move events into annotationState --- common/reviews/api/tools.api.md | 8 +++-- ...ameOfReferenceSpecificAnnotationManager.ts | 33 ++++++++++--------- .../annotation/annotationState.ts | 32 +++++++++++++++++- .../annotation/helpers/state.ts | 13 ++++++++ 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index e7ddb1e866..a22b14a0f4 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -2424,11 +2424,11 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { // (undocumented) _imageVolumeModifiedHandler: (evt: Types_2.EventTypes.ImageVolumeModifiedEvent) => void; // (undocumented) - removeAllAnnotations: () => void; + removeAllAnnotations: () => Annotations; // (undocumented) removeAnnotation: (annotationUID: string) => void; // (undocumented) - removeAnnotations: (groupKey: string, toolName?: string) => void; + removeAnnotations: (groupKey: string, toolName?: string) => Annotations; // (undocumented) restoreAnnotations: (state: AnnotationState | GroupSpecificAnnotations | Annotations, groupKey?: string, toolName?: string) => void; // (undocumented) @@ -4519,6 +4519,9 @@ function removeAllAnnotations(): void; // @public (undocumented) function removeAnnotation(annotationUID: string): void; +// @public (undocumented) +function removeAnnotations(groupKey: string, toolName?: string): void; + // @public (undocumented) function removeColorLUT(colorLUTIndex: number): void; @@ -5237,6 +5240,7 @@ declare namespace state_2 { addAnnotation, getAnnotation, removeAnnotation, + removeAnnotations, removeAllAnnotations, setAnnotationManager, getAnnotationManager, diff --git a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts index 2fe586234e..18dba76a23 100644 --- a/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +++ b/packages/tools/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts @@ -10,14 +10,12 @@ import { AnnotationGroupSelector, IAnnotationManager } from '../../types'; import { Enums, - triggerEvent, eventTarget, getEnabledElement, Types, utilities, } from '@cornerstonejs/core'; -import { Events as csToolEvents } from '../../enums'; import { checkAndDefineIsLockedProperty } from './annotationLocking'; import { checkAndDefineIsVisibleProperty } from './annotationVisibility'; @@ -248,7 +246,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { */ removeAnnotation = (annotationUID: string): void => { const { annotations } = this; - let annotationToRemove = null; for (const groupKey in annotations) { const groupAnnotations = annotations[groupKey]; @@ -260,8 +257,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { (annotation) => annotation.annotationUID === annotationUID ); - annotationToRemove = toolAnnotations[index]; - if (index !== -1) { toolAnnotations.splice(index, 1); @@ -275,13 +270,6 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { delete annotations[groupKey]; } } - - if (annotationToRemove !== null) { - triggerEvent(eventTarget, csToolEvents.ANNOTATION_REMOVED, { - annotation: annotationToRemove, - annotationManagerUID: this.uid, - }); - } }; /** @@ -290,26 +278,34 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { * * @param groupKey - The group key to remove annotations for (in default manager it is FrameOfReferenceUID). * @param toolName - Optional. The name of the tool to remove annotations for. + * + * @returns The removed annotations */ - removeAnnotations = (groupKey: string, toolName?: string): void => { + removeAnnotations = (groupKey: string, toolName?: string): Annotations => { const annotations = this.annotations; + const removedAnnotations = []; + if (!annotations[groupKey]) { - return; + return removedAnnotations; } if (toolName) { const annotationsForTool = annotations[groupKey][toolName]; for (const annotation of annotationsForTool) { this.removeAnnotation(annotation.annotationUID); + removedAnnotations.push(annotation); } } else { for (const toolName in annotations[groupKey]) { const annotationsForTool = annotations[groupKey][toolName]; for (const annotation of annotationsForTool) { this.removeAnnotation(annotation.annotationUID); + removedAnnotations.push(annotation); } } } + + return removedAnnotations; }; /** @@ -422,11 +418,18 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager { /** * Removes all annotations in the annotation state. + * + * @returns The removed annotations */ - removeAllAnnotations = (): void => { + removeAllAnnotations = (): Annotations => { + const removedAnnotations = []; + for (const annotation of this.getAllAnnotations()) { this.removeAnnotation(annotation.annotationUID); + removedAnnotations.push(annotation); } + + return removedAnnotations; }; } diff --git a/packages/tools/src/stateManagement/annotation/annotationState.ts b/packages/tools/src/stateManagement/annotation/annotationState.ts index bf5fb54125..6e93ed62b1 100644 --- a/packages/tools/src/stateManagement/annotation/annotationState.ts +++ b/packages/tools/src/stateManagement/annotation/annotationState.ts @@ -2,9 +2,11 @@ import { utilities as csUtils } from '@cornerstonejs/core'; import { defaultFrameOfReferenceSpecificAnnotationManager } from './FrameOfReferenceSpecificAnnotationManager'; import { Annotations, Annotation } from '../../types/AnnotationTypes'; import { AnnotationGroupSelector } from '../../types'; + import { triggerAnnotationAddedForElement, triggerAnnotationAddedForFOR, + triggerAnnotationRemoved, } from './helpers/state'; // our default annotation manager @@ -217,6 +219,8 @@ function removeAnnotation(annotationUID: string): void { ); manager.removeAnnotation(annotationUID); + + triggerAnnotationRemoved({ annotation, annotationManagerUID: manager.uid }); } /** @@ -235,7 +239,32 @@ function getAnnotation(annotationUID: string): Annotation { */ function removeAllAnnotations(): void { const manager = getAnnotationManager(); - manager.removeAllAnnotations(); + const removedAnnotations = manager.removeAllAnnotations(); + + for (const annotation of removedAnnotations) { + triggerAnnotationRemoved({ + annotation, + annotationManagerUID: manager.uid, + }); + } +} + +/** + * Removes all annotations associated with the specified group (FrameOfReferenceUID) and tool, or + * all annotations for the group (FrameOfReferenceUID) if the tool name is not provided. + * @param groupKey - The group key to remove annotations for (in default manager it is FrameOfReferenceUID). + * @param toolName - Optional. The name of the tool to remove annotations for. + */ +function removeAnnotations(groupKey: string, toolName?: string): void { + const manager = getAnnotationManager(); + const removedAnnotations = manager.removeAnnotations(groupKey, toolName); + + for (const annotation of removedAnnotations) { + triggerAnnotationRemoved({ + annotation, + annotationManagerUID: manager.uid, + }); + } } /** @@ -265,6 +294,7 @@ export { addAnnotation, getAnnotation, removeAnnotation, + removeAnnotations, removeAllAnnotations, // annotation manager setAnnotationManager, diff --git a/packages/tools/src/stateManagement/annotation/helpers/state.ts b/packages/tools/src/stateManagement/annotation/helpers/state.ts index 80ce1c6c95..be6edfe1f2 100644 --- a/packages/tools/src/stateManagement/annotation/helpers/state.ts +++ b/packages/tools/src/stateManagement/annotation/helpers/state.ts @@ -12,6 +12,7 @@ import { AnnotationModifiedEventDetail, AnnotationCompletedEventDetail, ContourAnnotationCompletedEventDetail, + AnnotationRemovedEventDetail, } from '../../../types/EventTypes'; /** @@ -81,6 +82,17 @@ function triggerAnnotationAddedForFOR(annotation: Annotation) { }); } +/** + * Triggers an annotation removed event. + * @param eventDetail - Event detail + */ +function triggerAnnotationRemoved( + eventDetail: AnnotationRemovedEventDetail +): void { + const eventType = Events.ANNOTATION_REMOVED; + triggerEvent(eventTarget, eventType, eventDetail); +} + /** * Triggers an annotation modified event. */ @@ -143,6 +155,7 @@ function _triggerAnnotationCompleted( export { triggerAnnotationAddedForElement, triggerAnnotationAddedForFOR, + triggerAnnotationRemoved, triggerAnnotationModified, triggerAnnotationCompleted, triggerContourAnnotationCompleted, From a739305aee4428aa010142266de6d836de215562 Mon Sep 17 00:00:00 2001 From: cclevenger Date: Thu, 30 May 2024 19:26:19 -0400 Subject: [PATCH 6/8] Make annotationState function more in-line with other functions --- common/reviews/api/tools.api.md | 2 +- .../src/stateManagement/annotation/annotationState.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index a22b14a0f4..a1b2918c17 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -4520,7 +4520,7 @@ function removeAllAnnotations(): void; function removeAnnotation(annotationUID: string): void; // @public (undocumented) -function removeAnnotations(groupKey: string, toolName?: string): void; +function removeAnnotations(annotationGroupSelector: AnnotationGroupSelector, toolName?: string): void; // @public (undocumented) function removeColorLUT(colorLUTIndex: number): void; diff --git a/packages/tools/src/stateManagement/annotation/annotationState.ts b/packages/tools/src/stateManagement/annotation/annotationState.ts index 6e93ed62b1..fdd349a29b 100644 --- a/packages/tools/src/stateManagement/annotation/annotationState.ts +++ b/packages/tools/src/stateManagement/annotation/annotationState.ts @@ -252,11 +252,15 @@ function removeAllAnnotations(): void { /** * Removes all annotations associated with the specified group (FrameOfReferenceUID) and tool, or * all annotations for the group (FrameOfReferenceUID) if the tool name is not provided. - * @param groupKey - The group key to remove annotations for (in default manager it is FrameOfReferenceUID). + * @param annotationGroupSelector - The group (FrameOfReferenceUID) to remove annotations for. * @param toolName - Optional. The name of the tool to remove annotations for. */ -function removeAnnotations(groupKey: string, toolName?: string): void { +function removeAnnotations( + annotationGroupSelector: AnnotationGroupSelector, + toolName?: string +): void { const manager = getAnnotationManager(); + const groupKey = manager.getGroupKey(annotationGroupSelector); const removedAnnotations = manager.removeAnnotations(groupKey, toolName); for (const annotation of removedAnnotations) { From 021c84bb0e6711505e08bd31329d55af6fdbb7e9 Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 5 Jun 2024 13:33:08 -0400 Subject: [PATCH 7/8] make api consistent --- .../tools/src/stateManagement/annotation/annotationState.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/tools/src/stateManagement/annotation/annotationState.ts b/packages/tools/src/stateManagement/annotation/annotationState.ts index fdd349a29b..4f35378f56 100644 --- a/packages/tools/src/stateManagement/annotation/annotationState.ts +++ b/packages/tools/src/stateManagement/annotation/annotationState.ts @@ -252,12 +252,12 @@ function removeAllAnnotations(): void { /** * Removes all annotations associated with the specified group (FrameOfReferenceUID) and tool, or * all annotations for the group (FrameOfReferenceUID) if the tool name is not provided. - * @param annotationGroupSelector - The group (FrameOfReferenceUID) to remove annotations for. * @param toolName - Optional. The name of the tool to remove annotations for. + * @param annotationGroupSelector - The group (FrameOfReferenceUID) to remove annotations for. */ function removeAnnotations( - annotationGroupSelector: AnnotationGroupSelector, - toolName?: string + toolName: string, + annotationGroupSelector: AnnotationGroupSelector ): void { const manager = getAnnotationManager(); const groupKey = manager.getGroupKey(annotationGroupSelector); From 773543afc1485e73a38b7493633ce57fcf6d1d0e Mon Sep 17 00:00:00 2001 From: Alireza Date: Wed, 5 Jun 2024 13:51:03 -0400 Subject: [PATCH 8/8] api --- common/reviews/api/tools.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/reviews/api/tools.api.md b/common/reviews/api/tools.api.md index 9cb8b22d1e..45cee4295f 100644 --- a/common/reviews/api/tools.api.md +++ b/common/reviews/api/tools.api.md @@ -4566,7 +4566,7 @@ function removeAllAnnotations(): void; function removeAnnotation(annotationUID: string): void; // @public (undocumented) -function removeAnnotations(annotationGroupSelector: AnnotationGroupSelector, toolName?: string): void; +function removeAnnotations(toolName: string, annotationGroupSelector: AnnotationGroupSelector): void; // @public (undocumented) function removeColorLUT(colorLUTIndex: number): void;