From 83e191b8507bc5990addb231fb4327d0bfe26b76 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Sun, 14 Jun 2020 21:20:32 -0400 Subject: [PATCH] Update toolbar service to use button types, update longitudinal flow to use new service api --- modes/longitudinal/src/index.js | 65 ++------ modes/longitudinal/src/toolbarButtons.js | 115 +++++++++++++ .../services/ToolBarService/ToolBarService.js | 154 +++++++++++++----- 3 files changed, 247 insertions(+), 87 deletions(-) create mode 100644 modes/longitudinal/src/toolbarButtons.js diff --git a/modes/longitudinal/src/index.js b/modes/longitudinal/src/index.js index 68754c8bc..82ad973e5 100644 --- a/modes/longitudinal/src/index.js +++ b/modes/longitudinal/src/index.js @@ -1,3 +1,5 @@ +import toolbarButtons from './toolbarButtons.js'; + const ohif = { layout: 'org.ohif.default.layoutTemplateModule.viewerLayout', sopClassHandler: 'org.ohif.default.sopClassHandlerModule.stack', @@ -27,57 +29,24 @@ export default function mode({ modeConfiguration }) { init: ({ servicesManager, extensionManager }) => { const { ToolBarService } = servicesManager.services; ToolBarService.init(extensionManager); - ToolBarService.addButtons([ - { - id: 'Zoom', - namespace: 'org.ohif.cornerstone.toolbarModule.Zoom', - }, - { - id: 'Levels', - namespace: 'org.ohif.cornerstone.toolbarModule.Wwwc', - }, - { - id: 'Pan', - namespace: 'org.ohif.cornerstone.toolbarModule.Pan', - }, - { - id: 'Capture', - namespace: 'org.ohif.cornerstone.toolbarModule.Capture', - }, - { - id: 'Layout', - namespace: 'org.ohif.default.toolbarModule.Layout', - }, - { - id: 'Annotate', - namespace: 'org.ohif.cornerstone.toolbarModule.Annotate', - }, - { - id: 'Bidirectional', - namespace: 'org.ohif.cornerstone.toolbarModule.Bidirectional', - }, - { - id: 'Ellipse', - namespace: 'org.ohif.cornerstone.toolbarModule.Ellipse', - }, - { - id: 'Length', - namespace: 'org.ohif.cornerstone.toolbarModule.Length', - }, + ToolBarService.addButtons(toolbarButtons); + ToolBarService.createButtonSection('primary', [ + 'Zoom', + 'Wwwc', + 'Pan', + 'Capture', // toggle --> command to open capture modal? needs to know when it should be off? (promise?) + 'Layout', // toggle --> command to open layout dialog? needs to know when it should be off? (promise?) + 'Divider', + 'Zoom', // ? array of arrays? + ]); + ToolBarService.createButtonSection('secondary', [ + 'Annotate', + 'Bidirectional', + 'Ellipse', + 'Length', ]); // Could import layout selector here from org.ohif.default (when it exists!) - ToolBarService.setToolBarLayout([ - // Primary - { - tools: ['Zoom', 'Levels', 'Pan', 'Capture', 'Layout'], - moreTools: ['Zoom'], - }, - // Secondary - { - tools: ['Annotate', 'Bidirectional', 'Ellipse', 'Length'], - }, - ]); }, layoutTemplate: ({ routeProps }) => { return { diff --git a/modes/longitudinal/src/toolbarButtons.js b/modes/longitudinal/src/toolbarButtons.js new file mode 100644 index 000000000..04cbb481f --- /dev/null +++ b/modes/longitudinal/src/toolbarButtons.js @@ -0,0 +1,115 @@ +export default [ + // Divider + { + id: 'Divider', + type: 'ohif.divider', + }, + // Primary + { + id: 'Zoom', + type: 'ohif.radioGroup', + config: { + groupName: 'primaryTool', + }, + props: { + isActive: false, + icon: 'tool-zoom', + label: 'Zoom', + commandName: 'setToolActive', + commandOptions: { toolName: 'Zoom' }, + type: 'primary', + }, + }, + { + id: 'Wwwc', + type: 'ohif.radioGroup', + config: { + groupName: 'primaryTool', + }, + props: { + isActive: true, + icon: 'tool-window-level', + label: 'Levels', + commandName: 'setToolActive', + commandOptions: { toolName: 'Wwwc' }, + type: 'primary', + }, + }, + { + id: 'Pan', + type: 'ohif.radioGroup', + config: { + groupName: 'primaryTool', + }, + props: { + isActive: false, + icon: 'tool-move', + label: 'Pan', + commandName: 'setToolActive', + commandOptions: { toolName: 'Pan' }, + 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', // Purely for background color/hover styles :| + // Layout Template can set this? + }, + }, + { + 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', + }, + }, +]; diff --git a/platform/core/src/services/ToolBarService/ToolBarService.js b/platform/core/src/services/ToolBarService/ToolBarService.js index 1c3757c9e..1522fbca7 100644 --- a/platform/core/src/services/ToolBarService/ToolBarService.js +++ b/platform/core/src/services/ToolBarService/ToolBarService.js @@ -6,32 +6,138 @@ const EVENTS = { export default class ToolBarService { constructor() { - this.displaySets = {}; this.EVENTS = EVENTS; this.listeners = {}; + this.buttons = {}; + this.buttonSections = { + /** + * primary: ['Zoom', 'Wwwc'], + * secondary: ['Length', 'RectangleRoi'] + */ + }; Object.assign(this, pubSubServiceInterface); } init(extensionManager) { - this.buttons = {}; this.extensionManager = extensionManager; } - addButtons(buttons) { - buttons.forEach(button => { - const buttonDefinition = this.extensionManager.getModuleEntry( - button.namespace + getButtons() { + return this.buttons; + } + + setButtons(buttons) { + this.buttons = buttons; + this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {}); + } + + _buttonTypes() { + console.log(this.extensionManager.modules); + const buttonTypes = {}; + const registeredToolbarModules = this.extensionManager.modules[ + 'toolbarModule' + ]; + + if ( + Array.isArray(registeredToolbarModules) && + registeredToolbarModules.length + ) { + registeredToolbarModules.forEach(toolbarModule => + toolbarModule.module.forEach(def => { + buttonTypes[def.name] = def; + }) ); + } - const id = button.id || buttonDefinition.id; + return buttonTypes; + } - this.buttons[id] = buttonDefinition; + + createButtonSection(key, buttons) { + // Maybe do this mapping at time of return, instead of time of create + // Props check important for validation here... + + this.buttonSections[key] = buttons; + this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {}); + } + + getButtonSection(key) { + const buttonSection = this.buttonSections[key]; + const buttonsInSection = []; + + if (!buttonSection) { + return buttonsInSection; + } + + buttonSection.forEach(btnId => { + const button = this.buttons[btnId]; + if (button) { + buttonsInSection.push(button); + } else { + console.warn(`${btnId} is not a registered button.`); + } }); + + const mappedButtonSection = buttonsInSection.map(bt => { + const { id, type, component, props } = bt; + const buttonType = this._buttonTypes()[type]; + + // Filter out & warn + if (!buttonType) { + return; + } + + const onClick = evt => { + console.warn( + `Handling click for: BTN::${id}`, + evt, + bt, + buttonType, + btnSection + ); + const btnSection = key; + if (buttonType.clickHandler) { + buttonType.clickHandler(evt, bt, btnSection); + } + if (bt.props.onClick) { + bt.onClick(evt, bt, btnSection); + } + if (bt.props.clickHandler) { + bt.clickHandler(evt, bt, btnSection); + } + + this._trySetButtonActive(id); + }; + + return { + id, + Component: component || buttonType.defaultComponent, + componentProps: Object.assign({}, props, { onClick }), // + }; + }); + + return mappedButtonSection; } /** - * Broadcasts displaySetService changes. + * + * @param {object[]} buttons + * @param {string} buttons[].id + */ + addButtons(buttons) { + buttons.forEach(button => { + if (!this.buttons[button.id]) { + this.buttons[button.id] = button; + } + }); + + this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, {}); + } + } + + /** + * Broadcasts toolbarService changes. * * @param {string} eventName The event name * @return void @@ -46,34 +152,4 @@ export default class ToolBarService { }); } }; - - setToolBarLayout(layouts) { - const toolBarLayout = []; - - layouts.forEach(layout => { - const toolBarDefinitions = { tools: [], moreTools: [] }; - - const { tools, moreTools } = layout; - - tools && - tools.forEach(element => { - const button = this.buttons[element]; - - toolBarDefinitions.tools.push(button); - }); - - moreTools && - moreTools.forEach(element => { - const button = this.buttons[element]; - - toolBarDefinitions.moreTools.push(button); - }); - - toolBarLayout.push(toolBarDefinitions); - }); - - this.toolBarLayout = toolBarLayout; - - this._broadcastChange(this.EVENTS.TOOL_BAR_MODIFIED, toolBarLayout); - } }