OHIF-223: Add "Clear" all measurements to annotation toolbar (#1861)
* Add clear button * Use james event * Create new commands module to default
This commit is contained in:
parent
61fc093fc5
commit
11fbe4cf01
@ -121,6 +121,7 @@ const commandsModule = ({ servicesManager }) => {
|
||||
lesionNamingNumber,
|
||||
measurementNumber,
|
||||
} = measurementData;
|
||||
|
||||
if (!_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -271,6 +271,7 @@ const _connectToolsToMeasurementService = measurementService => {
|
||||
const csToolsVer4MeasurementSource = _initMeasurementService(
|
||||
measurementService
|
||||
);
|
||||
_connectMeasurementServiceToTools(measurementService, csToolsVer4MeasurementSource);
|
||||
const { addOrUpdate, remove } = csToolsVer4MeasurementSource;
|
||||
const elementEnabledEvt = cornerstone.EVENTS.ELEMENT_ENABLED;
|
||||
|
||||
@ -335,6 +336,30 @@ const _connectToolsToMeasurementService = measurementService => {
|
||||
});
|
||||
};
|
||||
|
||||
const _connectMeasurementServiceToTools = (measurementService, measurementSource) => {
|
||||
const { MEASUREMENTS_CLEARED, MEASUREMENT_REMOVED } = measurementService.EVENTS;
|
||||
const sourceId = measurementSource.id;
|
||||
|
||||
measurementService.subscribe(MEASUREMENTS_CLEARED, () => {
|
||||
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
||||
{}
|
||||
);
|
||||
cornerstone.getEnabledElements().forEach(enabledElement => {
|
||||
cornerstone.updateImage(enabledElement.element);
|
||||
});
|
||||
});
|
||||
|
||||
/* TODO: Remove per measurement
|
||||
measurementService.subscribe(MEASUREMENT_REMOVED,
|
||||
({ source, measurement }) => {
|
||||
if ([sourceId].includes(source.id)) {
|
||||
// const annotation = getAnnotation('Length', measurement.id);
|
||||
// iterate tool state
|
||||
}
|
||||
}
|
||||
); */
|
||||
};
|
||||
|
||||
// const {
|
||||
// MEASUREMENT_ADDED,
|
||||
// MEASUREMENT_UPDATED,
|
||||
|
||||
@ -23,9 +23,10 @@ export default function PanelMeasurementTable({
|
||||
const added = MeasurementService.EVENTS.MEASUREMENT_ADDED;
|
||||
const updated = MeasurementService.EVENTS.MEASUREMENT_UPDATED;
|
||||
const removed = MeasurementService.EVENTS.MEASUREMENT_REMOVED;
|
||||
const cleared = MeasurementService.EVENTS.MEASUREMENTS_CLEARED;
|
||||
const subscriptions = [];
|
||||
|
||||
[added, updated, removed].forEach(evt => {
|
||||
[added, updated, removed, cleared].forEach(evt => {
|
||||
subscriptions.push(
|
||||
MeasurementService.subscribe(evt, () => {
|
||||
debouncedSetDisplayMeasurements(
|
||||
|
||||
25
extensions/default/src/commandsModule.js
Normal file
25
extensions/default/src/commandsModule.js
Normal file
@ -0,0 +1,25 @@
|
||||
const commandsModule = ({ servicesManager }) => {
|
||||
const { MeasurementService } = servicesManager.services;
|
||||
|
||||
const actions = {
|
||||
clearMeasurements: () => {
|
||||
MeasurementService.clear();
|
||||
},
|
||||
};
|
||||
|
||||
const definitions = {
|
||||
clearMeasurements: {
|
||||
commandFn: actions.clearMeasurements,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
actions,
|
||||
definitions,
|
||||
defaultContext: 'DEFAULT',
|
||||
};
|
||||
};
|
||||
|
||||
export default commandsModule;
|
||||
@ -3,7 +3,7 @@ import { ViewModelContext } from '@ohif/core';
|
||||
|
||||
const HelloWorldContext = React.createContext({
|
||||
message: 'HelloWorldContextTesting',
|
||||
setMessage: () => {},
|
||||
setMessage: () => { },
|
||||
});
|
||||
|
||||
HelloWorldContext.displayName = 'HelloWorldContext';
|
||||
|
||||
@ -4,6 +4,7 @@ import getLayoutTemplateModule from './getLayoutTemplateModule.js';
|
||||
import getPanelModule from './getPanelModule.js';
|
||||
import getSopClassHandlerModule from './getSopClassHandlerModule.js';
|
||||
import getToolbarModule from './getToolbarModule.js';
|
||||
import commandsModule from './commandsModule';
|
||||
import id from './id';
|
||||
|
||||
export default {
|
||||
@ -17,4 +18,7 @@ export default {
|
||||
getPanelModule,
|
||||
getSopClassHandlerModule,
|
||||
getToolbarModule,
|
||||
getCommandsModule({ servicesManager }) {
|
||||
return commandsModule({ servicesManager });
|
||||
},
|
||||
};
|
||||
|
||||
@ -101,9 +101,10 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
||||
const added = MeasurementService.EVENTS.MEASUREMENT_ADDED;
|
||||
const updated = MeasurementService.EVENTS.MEASUREMENT_UPDATED;
|
||||
const removed = MeasurementService.EVENTS.MEASUREMENT_REMOVED;
|
||||
const cleared = MeasurementService.EVENTS.MEASUREMENTS_CLEARED;
|
||||
const subscriptions = [];
|
||||
|
||||
[added, updated, removed].forEach(evt => {
|
||||
[added, updated, removed, cleared].forEach(evt => {
|
||||
subscriptions.push(
|
||||
MeasurementService.subscribe(evt, () => {
|
||||
setMeasurementsUpdated(Date.now().toString());
|
||||
|
||||
@ -62,6 +62,7 @@ export default function mode({ modeConfiguration }) {
|
||||
'Bidirectional',
|
||||
'Ellipse',
|
||||
'Length',
|
||||
'Clear',
|
||||
]);
|
||||
|
||||
// Could import layout selector here from org.ohif.default (when it exists!)
|
||||
|
||||
@ -307,4 +307,19 @@ export default [
|
||||
type: 'secondary',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'Clear',
|
||||
type: 'ohif.action',
|
||||
config: {
|
||||
groupName: 'primaryTool',
|
||||
},
|
||||
props: {
|
||||
isActive: false,
|
||||
icon: 'old-trash',
|
||||
label: 'Clear',
|
||||
commandName: 'clearMeasurements',
|
||||
commandOptions: {},
|
||||
type: 'secondary',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@ -52,6 +52,7 @@ const EVENTS = {
|
||||
MEASUREMENT_UPDATED: 'event::measurement_updated',
|
||||
MEASUREMENT_ADDED: 'event::measurement_added',
|
||||
MEASUREMENT_REMOVED: 'event::measurement_removed',
|
||||
MEASUREMENTS_CLEARED: 'event::measurements_cleared',
|
||||
};
|
||||
|
||||
const VALUE_TYPES = {
|
||||
@ -500,6 +501,14 @@ class MeasurementService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all measurements and broadcasts cleared event.
|
||||
*/
|
||||
clear() {
|
||||
this.measurements = {};
|
||||
this._broadcastChange(this.EVENTS.MEASUREMENTS_CLEARED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get measurement mapping function if matching criteria.
|
||||
*
|
||||
@ -559,15 +568,27 @@ class MeasurementService {
|
||||
/**
|
||||
* Broadcasts measurement changes.
|
||||
*
|
||||
* @param {string} measurementId The measurement id
|
||||
* @param {MeasurementSource} source The measurement source
|
||||
* @param {string} eventName The event name
|
||||
* @param {MeasurementSource} source The measurement source
|
||||
* @param {string} measurement The measurement id
|
||||
* @return void
|
||||
*/
|
||||
_broadcastChange(eventName, source, measurement) {
|
||||
const hasListeners = Object.keys(this.listeners).length > 0;
|
||||
const hasCallbacks = Array.isArray(this.listeners[eventName]);
|
||||
|
||||
if (!source) {
|
||||
/* Broadcast to all sources */
|
||||
/* Object.keys(this.sources).forEach(source => {
|
||||
if (hasListeners && hasCallbacks) {
|
||||
this.listeners[eventName].forEach(listener => {
|
||||
listener.callback({ source, measurement });
|
||||
});
|
||||
}
|
||||
});
|
||||
return; */
|
||||
}
|
||||
|
||||
if (hasListeners && hasCallbacks) {
|
||||
this.listeners[eventName].forEach(listener => {
|
||||
listener.callback({ source, measurement });
|
||||
|
||||
9
platform/ui/src/assets/icons/old-trash.svg
Normal file
9
platform/ui/src/assets/icons/old-trash.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
aria-labelledby="title"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title id="title">Trash</title>
|
||||
<path d="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 532 B |
@ -57,6 +57,7 @@ import oldDotCircle from './../../assets/icons/old-dot-circle.svg';
|
||||
import oldAngleLeft from './../../assets/icons/old-angle-left.svg';
|
||||
import oldReset from './../../assets/icons/old-reset.svg';
|
||||
import oldCircleO from './../../assets/icons/old-circle-o.svg';
|
||||
import oldTrash from './../../assets/icons/old-trash.svg';
|
||||
|
||||
const ICONS = {
|
||||
'arrow-down': arrowDown,
|
||||
@ -114,7 +115,8 @@ const ICONS = {
|
||||
'old-dot-circle': oldDotCircle,
|
||||
'old-angle-left': oldAngleLeft,
|
||||
'old-reset': oldReset,
|
||||
'old-circle-o': oldCircleO
|
||||
'old-circle-o': oldCircleO,
|
||||
'old-trash': oldTrash
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -33,7 +33,7 @@ function appInit(appConfigOrFunc, defaultExtensions) {
|
||||
/** Used by commands to inject `viewports` from "redux" */
|
||||
getAppState: () => { },
|
||||
/** Used by commands to determine active context */
|
||||
getActiveContexts: () => ['VIEWER', 'ACTIVE_VIEWPORT::CORNERSTONE'],
|
||||
getActiveContexts: () => ['VIEWER', 'DEFAULT', 'ACTIVE_VIEWPORT::CORNERSTONE'],
|
||||
};
|
||||
|
||||
const servicesManager = new ServicesManager();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user