Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(events): ANNOTATION_REMOVED event listener on removing ALL annotations. #1236

Merged
merged 9 commits into from
Jun 5, 2024
8 changes: 6 additions & 2 deletions common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2463,11 +2463,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)
Expand Down Expand Up @@ -4565,6 +4565,9 @@ function removeAllAnnotations(): void;
// @public (undocumented)
function removeAnnotation(annotationUID: string): void;

// @public (undocumented)
function removeAnnotations(toolName: string, annotationGroupSelector: AnnotationGroupSelector): void;

// @public (undocumented)
function removeColorLUT(colorLUTIndex: number): void;

Expand Down Expand Up @@ -5283,6 +5286,7 @@ declare namespace state_2 {
addAnnotation,
getAnnotation,
removeAnnotation,
removeAnnotations,
removeAllAnnotations,
setAnnotationManager,
getAnnotationManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,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;
if (annotations[groupKey]) {
if (toolName) {
delete annotations[groupKey][toolName];
} else {
delete annotations[groupKey];
const removedAnnotations = [];

if (!annotations[groupKey]) {
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;
};

/**
Expand Down Expand Up @@ -407,9 +425,18 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager {

/**
* Removes all annotations in the annotation state.
*
* @returns The removed annotations
*/
removeAllAnnotations = (): void => {
this.annotations = {};
removeAllAnnotations = (): Annotations => {
const removedAnnotations = [];

for (const annotation of this.getAllAnnotations()) {
this.removeAnnotation(annotation.annotationUID);
removedAnnotations.push(annotation);
}

return removedAnnotations;
};
}

Expand Down
52 changes: 35 additions & 17 deletions packages/tools/src/stateManagement/annotation/annotationState.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
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,
triggerAnnotationAddedForFOR,
triggerAnnotationRemoved,
} from './helpers/state';

// our default annotation manager
Expand Down Expand Up @@ -224,15 +220,7 @@ function removeAnnotation(annotationUID: string): void {

manager.removeAnnotation(annotationUID);

// trigger annotation removed
const eventType = Events.ANNOTATION_REMOVED;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think make a copy here


const eventDetail: AnnotationRemovedEventDetail = {
annotation,
annotationManagerUID: manager.uid,
};

triggerEvent(eventTarget, eventType, eventDetail);
triggerAnnotationRemoved({ annotation, annotationManagerUID: manager.uid });
}

/**
Expand All @@ -251,7 +239,36 @@ 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 toolName - Optional. The name of the tool to remove annotations for.
* @param annotationGroupSelector - The group (FrameOfReferenceUID) to remove annotations for.
*/
function removeAnnotations(
toolName: string,
annotationGroupSelector: AnnotationGroupSelector
): void {
const manager = getAnnotationManager();
const groupKey = manager.getGroupKey(annotationGroupSelector);
const removedAnnotations = manager.removeAnnotations(groupKey, toolName);

for (const annotation of removedAnnotations) {
triggerAnnotationRemoved({
annotation,
annotationManagerUID: manager.uid,
});
}
}

/**
Expand Down Expand Up @@ -281,6 +298,7 @@ export {
addAnnotation,
getAnnotation,
removeAnnotation,
removeAnnotations,
removeAllAnnotations,
// annotation manager
setAnnotationManager,
Expand Down
13 changes: 13 additions & 0 deletions packages/tools/src/stateManagement/annotation/helpers/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
AnnotationModifiedEventDetail,
AnnotationCompletedEventDetail,
ContourAnnotationCompletedEventDetail,
AnnotationRemovedEventDetail,
} from '../../../types/EventTypes';

/**
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -143,6 +155,7 @@ function _triggerAnnotationCompleted(
export {
triggerAnnotationAddedForElement,
triggerAnnotationAddedForFOR,
triggerAnnotationRemoved,
triggerAnnotationModified,
triggerAnnotationCompleted,
triggerContourAnnotationCompleted,
Expand Down