+
This is a destructive action.
Are you sure you want to continue?
@@ -444,7 +450,10 @@ function _mapDisplaySets(
switch (action.id) {
case 'save':
try {
- await dataSource.reject.series(ds.StudyInstanceUID, ds.SeriesInstanceUID);
+ await dataSource.reject.series(
+ ds.StudyInstanceUID,
+ ds.SeriesInstanceUID
+ );
DisplaySetService.deleteDisplaySet(displaySetInstanceUID);
UIDialogService.dismiss({ id: 'ds-reject-sr' });
UINotificationService.show({
@@ -525,9 +534,11 @@ function _createStudyBrowserTabs(
const displaySetsForStudy = displaySets.filter(
ds => ds.StudyInstanceUID === study.studyInstanceUid
);
-
- // Sort them
- const sortedDisplaySetsForStudy = utils.sortBySeriesDate(displaySetsForStudy);
+
+ // Sort them
+ const sortedDisplaySetsForStudy = utils.sortBySeriesDate(
+ displaySetsForStudy
+ );
/* Sort by series number, then by series date
displaySetsForStudy.sort((a, b) => {
@@ -541,7 +552,7 @@ function _createStudyBrowserTabs(
return seriesDateA - seriesDateB;
});
*/
-
+
// Map the study to it's tab/view representation
const tabStudy = Object.assign({}, study, {
displaySets: displaySetsForStudy,
diff --git a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js
index 72c03057e..9199a83fb 100644
--- a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js
+++ b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js
@@ -16,6 +16,8 @@ import { useTrackedMeasurements } from './../getContextModule';
import ViewportOverlay from './ViewportOverlay';
import ViewportLoadingIndicator from './ViewportLoadingIndicator';
import setCornerstoneMeasurementActive from '../_shared/setCornerstoneMeasurementActive';
+import setActiveAndPassiveToolsForElement from '../_shared/setActiveAndPassiveToolsForElement';
+import getTools from '../_shared/getTools';
const scrollToIndex = cornerstoneTools.importInternal('util/scrollToIndex');
const { formatDate } = utils;
@@ -44,7 +46,7 @@ function TrackedCornerstoneViewport({
displaySet,
viewportIndex,
servicesManager,
- commandsManager
+ commandsManager,
}) {
const {
ToolBarService,
@@ -52,7 +54,10 @@ function TrackedCornerstoneViewport({
MeasurementService,
} = servicesManager.services;
const [trackedMeasurements] = useTrackedMeasurements();
- const [{ activeViewportIndex, viewports }, viewportGridService] = useViewportGrid();
+ const [
+ { activeViewportIndex, viewports },
+ viewportGridService,
+ ] = useViewportGrid();
const [{ isCineEnabled, cines }, cineService] = useCine();
const [viewportDialogState, viewportDialogApi] = useViewportDialog();
const [viewportData, setViewportData] = useState(null);
@@ -126,9 +131,17 @@ function TrackedCornerstoneViewport({
const onElementEnabled = evt => {
const eventData = evt.detail;
const targetElement = eventData.element;
+ const tools = getTools();
+ const toolAlias = ToolBarService.state.primaryToolId;
+ // Activate appropriate tool bindings for element
+ setActiveAndPassiveToolsForElement(targetElement, tools);
+ cornerstoneTools.setToolActiveForElement(targetElement, toolAlias, {
+ mouseButtonMask: 1,
+ });
+
+ // Set dashed, based on tracking, for this viewport
const allTools = cornerstoneTools.store.state.tools;
-
const toolsForElement = allTools.filter(
tool => tool.element === targetElement
);
@@ -154,6 +167,7 @@ function TrackedCornerstoneViewport({
}
});
+ // Update image after setting tool config
const enabledElement = cornerstone.getEnabledElement(targetElement);
if (enabledElement.image) {
@@ -166,6 +180,7 @@ function TrackedCornerstoneViewport({
'ohif-cornerstone-enabled-element-event',
{
detail: {
+ context: 'ACTIVE_VIEWPORT::TRACKED',
enabledElement: targetElement,
viewportIndex,
},
@@ -256,7 +271,7 @@ function TrackedCornerstoneViewport({
PatientSex,
PatientAge,
SliceThickness,
- PixelSpacing,
+ SpacingBetweenSlices,
ManufacturerModelName,
} = displaySet.images[0];
@@ -300,8 +315,8 @@ function TrackedCornerstoneViewport({
}
const cine = cines[viewportIndex];
- const isPlaying = cine && cine.isPlaying || false;
- const frameRate = cine && cine.frameRate || 24;
+ const isPlaying = (cine && cine.isPlaying) || false;
+ const frameRate = (cine && cine.frameRate) || 24;
return (
<>
@@ -315,6 +330,7 @@ function TrackedCornerstoneViewport({
label,
isTracked,
isLocked: false,
+ isRehydratable: false,
studyDate: formatDate(SeriesDate), // TODO: This is series date. Is that ok?
currentSeries: SeriesNumber,
seriesDescription: SeriesDescription,
@@ -328,10 +344,8 @@ function TrackedCornerstoneViewport({
MRN: PatientID || '',
thickness: SliceThickness ? `${SliceThickness.toFixed(2)}mm` : '',
spacing:
- PixelSpacing && PixelSpacing.length
- ? `${PixelSpacing[0].toFixed(2)}mm x ${PixelSpacing[1].toFixed(
- 2
- )}mm`
+ SpacingBetweenSlices !== undefined
+ ? `${SpacingBetweenSlices.toFixed(2)}mm`
: '',
scanner: ManufacturerModelName || '',
},
@@ -341,8 +355,10 @@ function TrackedCornerstoneViewport({
cineProps={{
isPlaying,
onClose: () => commandsManager.runCommand('toggleCine'),
- onPlayPauseChange: isPlaying => cineService.setCine({ id: activeViewportIndex, isPlaying }),
- onFrameRateChange: frameRate => cineService.setCine({ id: activeViewportIndex, frameRate }),
+ onPlayPauseChange: isPlaying =>
+ cineService.setCine({ id: activeViewportIndex, isPlaying }),
+ onFrameRateChange: frameRate =>
+ cineService.setCine({ id: activeViewportIndex, frameRate }),
}}
/>
{/* TODO: Viewport interface to accept stack or layers of content like this? */}
diff --git a/modes/longitudinal/src/index.js b/modes/longitudinal/src/index.js
index 97648fd6b..531d303aa 100644
--- a/modes/longitudinal/src/index.js
+++ b/modes/longitudinal/src/index.js
@@ -39,34 +39,14 @@ export default function mode({ modeConfiguration }) {
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
+ 'MeasurementTools',
'Zoom',
- 'Wwwc',
+ 'WindowLevel',
'Pan',
'Capture',
'Layout',
- 'Divider',
- [
- 'ResetView',
- 'RotateClockwise',
- 'FlipHorizontally',
- 'StackScroll',
- 'Magnify',
- 'Invert',
- 'Cine',
- 'Angle',
- 'Probe',
- 'RectangleRoi',
- ],
+ 'MoreTools',
]);
- ToolBarService.createButtonSection('secondary', [
- 'Annotate',
- 'Bidirectional',
- 'Ellipse',
- 'Length',
- 'Clear',
- ]);
-
- // Could import layout selector here from org.ohif.default (when it exists!)
},
layoutTemplate: ({ routeProps }) => {
return {
diff --git a/modes/longitudinal/src/toolbarButtons.js b/modes/longitudinal/src/toolbarButtons.js
index b9673cb99..271961367 100644
--- a/modes/longitudinal/src/toolbarButtons.js
+++ b/modes/longitudinal/src/toolbarButtons.js
@@ -1,93 +1,149 @@
// TODO: torn, can either bake this here; or have to create a whole new button type
// Only ways that you can pass in a custom React component for render :l
-import { ExpandableToolbarButton, ListMenu, WindowLevelMenuItem } from '@ohif/ui';
+import {
+ // ExpandableToolbarButton,
+ // ListMenu,
+ WindowLevelMenuItem,
+} from '@ohif/ui';
import { defaults } from '@ohif/core';
const { windowLevelPresets } = defaults;
+/**
+ *
+ * @param {*} type - 'tool' | 'action' | 'toggle'
+ * @param {*} id
+ * @param {*} icon
+ * @param {*} label
+ */
+function _createButton(type, id, icon, label, commandName, commandOptions) {
+ return {
+ id,
+ icon,
+ label,
+ type,
+ commandName,
+ commandOptions,
+ };
+}
+
+const _createActionButton = _createButton.bind(null, 'action');
+const _createToggleButton = _createButton.bind(null, 'toggle');
+const _createToolButton = _createButton.bind(null, 'tool');
+
+/**
+ *
+ * @param {*} preset - preset number (from above import)
+ * @param {*} title
+ * @param {*} subtitle
+ */
+function _createWwwcPreset(preset, title, subtitle) {
+ return {
+ id: preset,
+ title,
+ subtitle,
+ type: 'action',
+ commandName: 'setWindowLevel',
+ commandOptions: windowLevelPresets[preset],
+ };
+}
export default [
- // Divider
+ // Measurement
{
- id: 'Divider',
- type: 'ohif.divider',
+ id: 'MeasurementTools',
+ type: 'ohif.splitButton',
+ props: {
+ groupId: 'MeasurementTools',
+ isRadio: true, // ?
+ // Switch?
+ primary: _createToolButton('Length', 'tool-length', 'Length', undefined, {
+ toolName: 'Length',
+ }),
+ secondary: {
+ icon: 'chevron-down',
+ label: '',
+ isActive: true,
+ tooltip: 'More Measure Tools',
+ },
+ items: [
+ _createToolButton('Length', 'tool-length', 'Length', undefined, {
+ toolName: 'Length',
+ }),
+ _createToolButton(
+ 'Bidirectional',
+ 'tool-bidirectional',
+ 'Bidirectional',
+ undefined,
+ { toolName: 'Bidirectional' }
+ ),
+ _createToolButton(
+ 'ArrowAnnotate',
+ 'tool-annotate',
+ 'Annotation',
+ undefined,
+ { toolName: 'ArrowAnnotate' }
+ ),
+ _createToolButton(
+ 'EllipticalRoi',
+ 'tool-elipse',
+ 'Ellipse',
+ undefined,
+ {
+ toolName: 'EllipticalRoi',
+ }
+ ),
+ ],
+ },
},
- // ~~ Primary
+ // Zoom..
{
id: 'Zoom',
type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
props: {
- isActive: false,
+ type: 'tool',
icon: 'tool-zoom',
label: 'Zoom',
- commandName: 'setToolActive',
commandOptions: { toolName: 'Zoom' },
- type: 'primary',
},
},
+ // Window Level + Presets...
{
- id: 'Wwwc',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- component: ExpandableToolbarButton,
+ id: 'WindowLevel',
+ type: 'ohif.splitButton',
props: {
- isActive: true,
- icon: 'tool-window-level',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'Wwwc' },
- commands: {
- 1: {
- commandName: 'setWindowLevel',
- commandOptions: windowLevelPresets[1],
- },
- 2: {
- commandName: 'setWindowLevel',
- commandOptions: windowLevelPresets[2],
- },
- 3: {
- commandName: 'setWindowLevel',
- commandOptions: windowLevelPresets[3],
- },
- 4: {
- commandName: 'setWindowLevel',
- commandOptions: windowLevelPresets[4],
- },
- 5: {
- commandName: 'setWindowLevel',
- commandOptions: windowLevelPresets[5],
- }
+ primary: _createToolButton(
+ 'Wwwc',
+ 'tool-window-level',
+ 'Window Level',
+ undefined,
+ { toolName: 'Wwwc' }
+ ),
+ secondary: {
+ icon: 'chevron-down',
+ label: '',
+ isActive: true,
+ tooltip: 'More Measure Tools',
},
- type: 'primary',
- content: ListMenu,
- contentProps: {
- items: [
- { value: 1, title: 'Soft tissue', subtitle: '400 / 40' },
- { value: 2, title: 'Lung', subtitle: '1500 / -600' },
- { value: 3, title: 'Liver', subtitle: '150 / 90' },
- { value: 4, title: 'Bone', subtitle: '80 / 40' },
- { value: 5, title: 'Brain', subtitle: '2500 / 480' },
- ],
- renderer: WindowLevelMenuItem
- }
+ isAction: true, // ?
+ renderer: WindowLevelMenuItem,
+ items: [
+ _createWwwcPreset(1, 'Soft tissue', '400 / 40'),
+ _createWwwcPreset(2, 'Lung', '1500 / -600'),
+ _createWwwcPreset(3, 'Liver', '150 / 90'),
+ _createWwwcPreset(4, 'Bone', '80 / 40'),
+ _createWwwcPreset(5, 'Brain', '2500 / 480'),
+ ],
},
},
+ // Pan...
{
id: 'Pan',
type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
props: {
- isActive: false,
+ type: 'tool',
icon: 'tool-move',
label: 'Pan',
- commandName: 'setToolActive',
commandOptions: { toolName: 'Pan' },
- type: 'primary',
},
},
{
@@ -96,219 +152,83 @@ export default [
props: {
icon: 'tool-capture',
label: 'Capture',
+ type: 'action',
commandName: 'showDownloadViewportModal',
- type: 'primary',
},
},
{
id: 'Layout',
type: 'ohif.layoutSelector',
},
- // ~~ Primary: NESTED
+ // More...
{
- id: 'ResetView',
- type: 'ohif.action',
+ id: 'MoreTools',
+ type: 'ohif.splitButton',
props: {
- icon: 'old-reset',
- label: 'Reset View',
- commandName: 'resetViewport',
- type: 'primary',
- },
- },
- {
- id: 'RotateClockwise',
- type: 'ohif.action',
- props: {
- icon: 'old-rotate-right',
- label: 'Rotate Right',
- commandName: 'rotateViewportCW',
- type: 'primary',
- },
- },
- {
- id: 'FlipHorizontally',
- type: 'ohif.action',
- props: {
- icon: 'old-ellipse-h',
- label: 'Flip Horizontally',
- commandName: 'flipViewportHorizontal',
- type: 'primary',
- },
- },
- {
- id: 'StackScroll',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-bars',
- label: 'Stack Scroll',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'StackScroll' },
- type: 'primary',
- },
- },
- {
- id: 'Magnify',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-circle',
- label: 'Magnify',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'Magnify' },
- type: 'primary',
- },
- },
- {
- id: 'Invert',
- type: 'ohif.action',
- props: {
- icon: 'old-invert',
- label: 'Invert',
- commandName: 'invertViewport',
- type: 'primary',
- },
- },
- {
- id: 'Cine',
- type: 'ohif.toggle',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-youtube',
- label: 'Cine',
- commandName: 'toggleCine',
- type: 'primary',
- },
- },
- // TODO: 2D MPR: We had said this was off the table?
- {
- id: 'Angle',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-angle-left',
- label: 'Angle',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'Angle' },
- type: 'primary',
- },
- },
- {
- id: 'Probe',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-dot-circle',
- label: 'Probe',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'DragProbe' },
- type: 'primary',
- },
- },
- {
- id: 'RectangleRoi',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-circle-o',
- label: 'Rectangle',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'RectangleRoi' },
- type: 'primary',
- },
- },
- // ~~ Secondary
- {
- id: 'Annotate',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'tool-annotate',
- label: 'Annotate',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'ArrowAnnotate' },
- type: 'secondary',
- },
- },
- {
- id: 'Bidirectional',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'tool-bidirectional',
- label: 'Bidirectional',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'Bidirectional' },
- type: 'secondary',
- },
- },
- {
- id: 'Ellipse',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'tool-elipse',
- label: 'Ellipse',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'EllipticalRoi' },
- type: 'secondary',
- },
- },
- {
- id: 'Length',
- type: 'ohif.radioGroup',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'tool-length',
- label: 'Length',
- commandName: 'setToolActive',
- commandOptions: { toolName: 'Length' },
- type: 'secondary',
- },
- },
- {
- id: 'Clear',
- type: 'ohif.action',
- config: {
- groupName: 'primaryTool',
- },
- props: {
- isActive: false,
- icon: 'old-trash',
- label: 'Clear',
- commandName: 'clearMeasurements',
- commandOptions: {},
- type: 'secondary',
+ isRadio: true, // ?
+ groupId: 'MoreTools',
+ primary: _createActionButton(
+ 'reset',
+ 'tool-reset',
+ 'Reset View',
+ 'resetViewport'
+ ),
+ secondary: {
+ icon: 'chevron-down',
+ label: '',
+ isActive: true,
+ tooltip: 'More Measure Tools',
+ },
+ items: [
+ _createActionButton(
+ 'reset',
+ 'tool-reset',
+ 'Reset View',
+ 'resetViewport'
+ ),
+ _createActionButton(
+ 'rotate-right',
+ 'tool-rotate-right',
+ 'Rotate Right',
+ 'rotateViewportCW'
+ ),
+ _createActionButton(
+ 'flip-horizontal',
+ 'tool-flip-horizontal',
+ 'Flip Horizontally',
+ 'flipViewportHorizontal'
+ ),
+ _createToolButton(
+ 'StackScroll',
+ 'tool-stack-scroll',
+ 'Stack Scroll',
+ undefined,
+ { toolName: 'StackScroll' }
+ ),
+ _createToolButton('Magnify', 'tool-magnify', 'Magnify', undefined, {
+ toolName: 'Magnify',
+ }),
+ _createActionButton(
+ 'invert',
+ 'tool-invert',
+ 'Invert',
+ 'invertViewport'
+ ),
+ _createToggleButton('cine', 'tool-cine', 'Cine', 'toggleCine'),
+ _createToolButton('Angle', 'tool-angle', 'Angle', undefined, {
+ toolName: 'Angle',
+ }),
+ _createToolButton('DragProbe', 'tool-probe', 'Probe', undefined, {
+ toolName: 'DragProbe',
+ }),
+ _createToolButton(
+ 'Rectangle',
+ 'tool-rectangle',
+ 'Rectangle',
+ undefined,
+ { toolName: 'RectangleRoi' }
+ ),
+ ],
},
},
];
diff --git a/modes/segmentation/src/toolbarButtons.js b/modes/segmentation/src/toolbarButtons.js
index d4a3a7a59..04b7c98c0 100644
--- a/modes/segmentation/src/toolbarButtons.js
+++ b/modes/segmentation/src/toolbarButtons.js
@@ -72,7 +72,7 @@ export default [
id: 'ResetView',
type: 'ohif.action',
props: {
- icon: 'old-reset',
+ icon: 'tool-reset',
label: 'Reset View',
commandName: 'resetViewport',
type: 'primary',
@@ -82,7 +82,7 @@ export default [
id: 'RotateClockwise',
type: 'ohif.action',
props: {
- icon: 'old-rotate-right',
+ icon: 'tool-rotate-right',
label: 'Rotate Right',
commandName: 'rotateViewportCW',
type: 'primary',
@@ -92,7 +92,7 @@ export default [
id: 'FlipHorizontally',
type: 'ohif.action',
props: {
- icon: 'old-ellipse-h',
+ icon: 'tool-flip-horizontal',
label: 'Flip Horizontally',
commandName: 'flipViewportHorizontal',
type: 'primary',
@@ -106,7 +106,7 @@ export default [
},
props: {
isActive: false,
- icon: 'old-bars',
+ icon: 'tool-stack-scroll',
label: 'Stack Scroll',
commandName: 'setToolActive',
commandOptions: { toolName: 'StackScroll' },
@@ -121,7 +121,7 @@ export default [
},
props: {
isActive: false,
- icon: 'old-circle',
+ icon: 'tool-magnify',
label: 'Magnify',
commandName: 'setToolActive',
commandOptions: { toolName: 'Magnify' },
@@ -132,7 +132,7 @@ export default [
id: 'Invert',
type: 'ohif.action',
props: {
- icon: 'old-invert',
+ icon: 'tool-invert',
label: 'Invert',
commandName: 'invertViewport',
type: 'primary',
@@ -143,7 +143,7 @@ export default [
id: 'Cine',
type: 'ohif.action',
props: {
- icon: 'old-youtube',
+ icon: 'tool-cine',
label: 'Cine',
commandName: '',
type: 'primary',
@@ -158,7 +158,7 @@ export default [
},
props: {
isActive: false,
- icon: 'old-angle-left',
+ icon: 'tool-angle',
label: 'Angle',
commandName: 'setToolActive',
commandOptions: { toolName: 'Angle' },
@@ -173,7 +173,7 @@ export default [
},
props: {
isActive: false,
- icon: 'old-dot-circle',
+ icon: 'tool-probe',
label: 'Probe',
commandName: 'setToolActive',
commandOptions: { toolName: 'Probe' },
@@ -188,7 +188,7 @@ export default [
},
props: {
isActive: false,
- icon: 'old-circle-o',
+ icon: 'tool-rectangle',
label: 'Rectangle',
commandName: 'setToolActive',
commandOptions: { toolName: 'RectangleRoi' },
diff --git a/platform/core/src/classes/CommandsManager.js b/platform/core/src/classes/CommandsManager.js
index 995bc0988..8e993c2cc 100644
--- a/platform/core/src/classes/CommandsManager.js
+++ b/platform/core/src/classes/CommandsManager.js
@@ -5,7 +5,6 @@ import log from '../log.js';
*
* @typedef {Object} CommandDefinition
* @property {Function} commandFn - Command to call
- * @property {Array} storeContexts - Array of string of modules required from store
* @property {Object} options - Object of params to pass action
*/
@@ -161,19 +160,10 @@ export class CommandsManager {
return;
}
- const { commandFn, storeContexts = [] } = definition;
- const definitionOptions = definition.options;
-
- let commandParams = {};
- const appState = this._getAppState();
- storeContexts.forEach(context => {
- commandParams[context] = appState[context];
- });
-
- commandParams = Object.assign(
+ const { commandFn } = definition;
+ const commandParams = Object.assign(
{},
- commandParams, // Required store contexts
- definitionOptions, // "Command configuration"
+ definition.options, // "Command configuration"
options // "Time of call" info
);
diff --git a/platform/core/src/services/ServicesManager.js b/platform/core/src/services/ServicesManager.js
index db5dec800..ad36592ef 100644
--- a/platform/core/src/services/ServicesManager.js
+++ b/platform/core/src/services/ServicesManager.js
@@ -1,7 +1,8 @@
import log from './../log.js';
export default class ServicesManager {
- constructor() {
+ constructor(commandsManager) {
+ this._commandsManager = commandsManager;
this.services = {};
this.registeredServiceNames = [];
}
@@ -35,6 +36,7 @@ export default class ServicesManager {
if (service.create) {
this.services[service.name] = service.create({
configuration,
+ commandsManager: this._commandsManager,
});
} else {
log.warn(`Service create factory function not defined. Exiting early.`);
diff --git a/platform/core/src/services/ToolBarService/ToolBarService.js b/platform/core/src/services/ToolBarService/ToolBarService.js
index daff7ebe4..025d9fb34 100644
--- a/platform/core/src/services/ToolBarService/ToolBarService.js
+++ b/platform/core/src/services/ToolBarService/ToolBarService.js
@@ -3,10 +3,13 @@ import pubSubServiceInterface from '../_shared/pubSubServiceInterface';
const EVENTS = {
TOOL_BAR_MODIFIED: 'event::toolBarService:toolBarModified',
+ TOOL_BAR_STATE_MODIFIED: 'event::toolBarService:toolBarStateModified',
};
export default class ToolBarService {
- constructor() {
+ constructor(commandsManager) {
+ this._commandsManager = commandsManager;
+ //
this.EVENTS = EVENTS;
this.listeners = {};
this.buttons = {};
@@ -17,6 +20,18 @@ export default class ToolBarService {
*/
};
+ // TODO: Do we need to track per context? Or do we allow for a mixed
+ // definition that adapts based on context?
+ this.state = {
+ primaryToolId: 'Wwwc',
+ toggles: {
+ /* id: true/false */
+ },
+ groups: {
+ /* track most recent click per group...? */
+ },
+ };
+
Object.assign(this, pubSubServiceInterface);
}
@@ -24,17 +39,59 @@ export default class ToolBarService {
this.extensionManager = extensionManager;
}
+ /**
+ *
+ * @param {*} interaction
+ */
+ recordInteraction(interaction) {
+ const commandsManager = this._commandsManager;
+ const { groupId, itemId, interactionType } = interaction;
+
+ switch (interactionType) {
+ case 'action': {
+ break;
+ }
+ case 'tool': {
+ this.state.primaryToolId = itemId;
+ // TODO: Force run this for all contexts? Even inactive?
+ // or... They'll just detect primaryToolId when they spin up and apply...
+ commandsManager.runCommand('setToolActive', interaction.commandOptions);
+ break;
+ }
+ case 'toggle': {
+ this.state.toggles[itemId] =
+ this.state.toggles[itemId] === undefined
+ ? true
+ : !this.state.toggles[itemId];
+ break;
+ }
+ }
+
+ // Run command if there's one associated
+ //
+ // NOTE: Should probably just do this for tools as well?
+ // But would be nice if we could enforce at least the command name?
+ if (interaction.commandName) {
+ commandsManager.runCommand(
+ interaction.commandName,
+ interaction.commandOptions
+ );
+ }
+
+ // Track last touched id for each group
+ if (groupId) {
+ this.state.groups[groupId] = itemId;
+ }
+
+ this._broadcastChange(this.EVENTS.TOOL_BAR_STATE_MODIFIED, {});
+ }
+
getButtons() {
return this.buttons;
}
getActiveTools() {
- return Object.keys(this.buttons).filter(key => {
- const button = this.buttons[key];
- if (button && button.props && button.props.isActive) {
- return button;
- }
- });
+ return [this.state.primaryToolId, ...Object.keys(this.state.toggles)];
}
setButton(id, button) {
@@ -43,7 +100,7 @@ export default class ToolBarService {
this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {
buttons: this.buttons,
button: this.buttons[id],
- buttonSections: this.buttonSections
+ buttonSections: this.buttonSections,
});
}
}
@@ -52,7 +109,7 @@ export default class ToolBarService {
this.buttons = buttons;
this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {
buttons: this.buttons,
- buttonSections: this.buttonSections
+ buttonSections: this.buttonSections,
});
}
@@ -84,41 +141,27 @@ export default class ToolBarService {
this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {});
}
+ /**
+ *
+ * Finds a button section by it's name, then maps the list of string name
+ * identifiers to schema/values that can be used to render the buttons.
+ *
+ * @param {string} key
+ * @param {*} props
+ */
getButtonSection(key, props) {
const buttonSectionIds = this.buttonSections[key];
const buttonsInSection = [];
- if (!buttonSectionIds) {
- return buttonsInSection;
- }
-
- buttonSectionIds.forEach(btnIdOrArray => {
- const isNested = Array.isArray(btnIdOrArray);
-
- if (isNested) {
- const btnIds = btnIdOrArray;
- const nestedButtons = [];
-
- btnIds.forEach(nestedBtnId => {
- const nestedBtn = this.buttons[nestedBtnId];
- const metadata = { isNested: true };
- const mappedNestedBtn = this._mapButtonToDisplay(nestedBtn, key, metadata, props);
-
- nestedButtons.push(mappedNestedBtn);
- });
-
- if (nestedButtons.length) {
- buttonsInSection.push(nestedButtons);
- }
- } else {
- const btnId = btnIdOrArray;
+ if (buttonSectionIds && buttonSectionIds.length !== 0) {
+ buttonSectionIds.forEach(btnId => {
const btn = this.buttons[btnId];
- const metadata = { isNested: false };
+ const metadata = {};
const mappedBtn = this._mapButtonToDisplay(btn, key, metadata, props);
buttonsInSection.push(mappedBtn);
- }
- });
+ });
+ }
return buttonsInSection;
}
@@ -159,6 +202,8 @@ export default class ToolBarService {
*
* @param {*} btn
* @param {*} btnSection
+ * @param {*} metadata
+ * @param {*} props - Props set by the Viewer layer
*/
_mapButtonToDisplay(btn, btnSection, metadata, props) {
const { id, type, component } = btn;
@@ -168,25 +213,10 @@ export default class ToolBarService {
return;
}
- const onClick = evt => {
- if (buttonType.clickHandler) {
- buttonType.clickHandler(evt, btn, btnSection, metadata, props);
- }
- if (btn.props.onClick) {
- btn.onClick(evt, btn, btnSection);
- }
- if (btn.props.clickHandler) {
- btn.clickHandler(evt, btn, btnSection);
- }
- if (props && props.onClick) {
- props.onClick(evt, btn, btnSection, props);
- }
- };
-
return {
id,
Component: component || buttonType.defaultComponent,
- componentProps: Object.assign({}, btn.props, { onClick }), //
+ componentProps: Object.assign({}, btn.props, props),
};
}
}
diff --git a/platform/core/src/services/ToolBarService/index.js b/platform/core/src/services/ToolBarService/index.js
index bbe3dd317..e283314d8 100644
--- a/platform/core/src/services/ToolBarService/index.js
+++ b/platform/core/src/services/ToolBarService/index.js
@@ -2,7 +2,7 @@ import ToolBarService from './ToolBarService';
export default {
name: 'ToolBarService',
- create: ({ configuration = {} }) => {
- return new ToolBarService();
+ create: ({ configuration = {}, commandsManager }) => {
+ return new ToolBarService(commandsManager);
},
};
diff --git a/platform/ui/src/assets/icons/arrow-left.svg b/platform/ui/src/assets/icons/arrow-left.svg
new file mode 100644
index 000000000..307f8ffdf
--- /dev/null
+++ b/platform/ui/src/assets/icons/arrow-left.svg
@@ -0,0 +1,6 @@
+
diff --git a/platform/ui/src/assets/icons/exclamation.svg b/platform/ui/src/assets/icons/exclamation.svg
new file mode 100644
index 000000000..5b6ae388b
--- /dev/null
+++ b/platform/ui/src/assets/icons/exclamation.svg
@@ -0,0 +1,9 @@
+
diff --git a/platform/ui/src/assets/icons/old-angle-left.svg b/platform/ui/src/assets/icons/old-angle-left.svg
deleted file mode 100644
index 5b87c1da3..000000000
--- a/platform/ui/src/assets/icons/old-angle-left.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-bars.svg b/platform/ui/src/assets/icons/old-bars.svg
deleted file mode 100644
index d7e430f0c..000000000
--- a/platform/ui/src/assets/icons/old-bars.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-circle-o.svg b/platform/ui/src/assets/icons/old-circle-o.svg
deleted file mode 100644
index 4242c992f..000000000
--- a/platform/ui/src/assets/icons/old-circle-o.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-circle.svg b/platform/ui/src/assets/icons/old-circle.svg
deleted file mode 100644
index 2cad5edcb..000000000
--- a/platform/ui/src/assets/icons/old-circle.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-dot-circle.svg b/platform/ui/src/assets/icons/old-dot-circle.svg
deleted file mode 100644
index 625f3b247..000000000
--- a/platform/ui/src/assets/icons/old-dot-circle.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-ellipse-h.svg b/platform/ui/src/assets/icons/old-ellipse-h.svg
deleted file mode 100644
index 1d95148f7..000000000
--- a/platform/ui/src/assets/icons/old-ellipse-h.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-invert.svg b/platform/ui/src/assets/icons/old-invert.svg
deleted file mode 100644
index f859c45bc..000000000
--- a/platform/ui/src/assets/icons/old-invert.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-reset.svg b/platform/ui/src/assets/icons/old-reset.svg
deleted file mode 100644
index 116676d9c..000000000
--- a/platform/ui/src/assets/icons/old-reset.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-rotate-right.svg b/platform/ui/src/assets/icons/old-rotate-right.svg
deleted file mode 100644
index 11646928f..000000000
--- a/platform/ui/src/assets/icons/old-rotate-right.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/old-youtube.svg b/platform/ui/src/assets/icons/old-youtube.svg
deleted file mode 100644
index 433789f12..000000000
--- a/platform/ui/src/assets/icons/old-youtube.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/platform/ui/src/assets/icons/tool-angle.svg b/platform/ui/src/assets/icons/tool-angle.svg
new file mode 100644
index 000000000..08d55baa8
--- /dev/null
+++ b/platform/ui/src/assets/icons/tool-angle.svg
@@ -0,0 +1,7 @@
+
diff --git a/platform/ui/src/assets/icons/tool-annotate.svg b/platform/ui/src/assets/icons/tool-annotate.svg
index 99fbfe3a3..34787d5d5 100644
--- a/platform/ui/src/assets/icons/tool-annotate.svg
+++ b/platform/ui/src/assets/icons/tool-annotate.svg
@@ -1,5 +1,5 @@
-