feat(layout): new layout selector with 3D volume rendering (#3923)
@ -180,7 +180,8 @@ function getUpdatedViewportsForSegmentation({
|
||||
});
|
||||
}
|
||||
});
|
||||
return updatedViewports;
|
||||
|
||||
return updatedViewports.filter(v => v.viewportOptions?.viewportType !== 'volume3d');
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
@ -311,6 +311,10 @@ function commandsModule({
|
||||
return;
|
||||
}
|
||||
|
||||
if (!toolGroup.hasTool(toolName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeToolName = toolGroup.getActivePrimaryMouseButtonTool();
|
||||
|
||||
if (activeToolName) {
|
||||
|
||||
@ -166,6 +166,19 @@ export default function getToolbarModule({ commandsManager, servicesManager }) {
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'evaluate.not3D',
|
||||
evaluate: ({ viewportId, button }) => {
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
|
||||
if (viewport?.type === 'volume3d') {
|
||||
return {
|
||||
disabled: true,
|
||||
className: '!text-common-bright ohif-disabled',
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'evaluate.viewportProperties.toggle',
|
||||
evaluate: ({ viewportId, button }) => {
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const fourUp = {
|
||||
id: 'fourUp',
|
||||
locked: true,
|
||||
name: 'fourUp',
|
||||
name: '3D four up',
|
||||
icon: 'layout-advanced-3d-four-up',
|
||||
isPreset: true,
|
||||
createdDate: '2023-03-15T10:29:44.894Z',
|
||||
modifiedDate: '2023-03-15T10:29:44.894Z',
|
||||
availableTo: {},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const main3D = {
|
||||
id: 'main3D',
|
||||
locked: true,
|
||||
name: 'main3D',
|
||||
name: '3D main',
|
||||
icon: 'layout-advanced-3d-main',
|
||||
isPreset: true,
|
||||
createdDate: '2023-03-15T10:29:44.894Z',
|
||||
modifiedDate: '2023-03-15T10:29:44.894Z',
|
||||
availableTo: {},
|
||||
|
||||
@ -2,8 +2,10 @@ import { Types } from '@ohif/core';
|
||||
|
||||
export const mpr: Types.HangingProtocol.Protocol = {
|
||||
id: 'mpr',
|
||||
name: 'Multi-Planar Reconstruction',
|
||||
name: 'MPR',
|
||||
locked: true,
|
||||
icon: 'layout-advanced-mpr',
|
||||
isPreset: true,
|
||||
createdDate: '2021-02-23',
|
||||
modifiedDate: '2023-08-15',
|
||||
availableTo: {},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const only3D = {
|
||||
id: 'only3D',
|
||||
locked: true,
|
||||
name: 'only3D',
|
||||
name: '3D only',
|
||||
icon: 'layout-advanced-3d-only',
|
||||
isPreset: true,
|
||||
createdDate: '2023-03-15T10:29:44.894Z',
|
||||
modifiedDate: '2023-03-15T10:29:44.894Z',
|
||||
availableTo: {},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const primary3D = {
|
||||
id: 'primary3D',
|
||||
locked: true,
|
||||
name: 'primary3D',
|
||||
name: '3D primary',
|
||||
icon: 'layout-advanced-3d-primary',
|
||||
isPreset: true,
|
||||
createdDate: '2023-03-15T10:29:44.894Z',
|
||||
modifiedDate: '2023-03-15T10:29:44.894Z',
|
||||
availableTo: {},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
export const primaryAxial = {
|
||||
id: 'primaryAxial',
|
||||
locked: true,
|
||||
name: 'primaryAxial',
|
||||
name: 'Axial Primary',
|
||||
icon: 'layout-advanced-axial-primary',
|
||||
isPreset: true,
|
||||
createdDate: '2023-03-15T10:29:44.894Z',
|
||||
modifiedDate: '2023-03-15T10:29:44.894Z',
|
||||
availableTo: {},
|
||||
|
||||
88
extensions/default/src/Toolbar/LegacyLayoutSelector.tsx
Normal file
@ -0,0 +1,88 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
|
||||
import { ServicesManager } from '@ohif/core';
|
||||
|
||||
function LegacyLayoutSelectorWithServices({ servicesManager, ...props }) {
|
||||
const { toolbarService } = servicesManager.services;
|
||||
|
||||
const onSelection = useCallback(
|
||||
props => {
|
||||
toolbarService.recordInteraction({
|
||||
interactionType: 'action',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setViewportGridLayout',
|
||||
commandOptions: { ...props },
|
||||
context: 'DEFAULT',
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
[toolbarService]
|
||||
);
|
||||
|
||||
return (
|
||||
<LayoutSelector
|
||||
{...props}
|
||||
onSelection={onSelection}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function LayoutSelector({ rows, columns, className, onSelection, ...rest }) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const closeOnOutsideClick = () => {
|
||||
if (isOpen) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('click', closeOnOutsideClick);
|
||||
return () => {
|
||||
window.removeEventListener('click', closeOnOutsideClick);
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
const onInteractionHandler = () => setIsOpen(!isOpen);
|
||||
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
|
||||
|
||||
return (
|
||||
<ToolbarButton
|
||||
id="Layout"
|
||||
label="Grid Layout"
|
||||
icon="tool-layout"
|
||||
onInteraction={onInteractionHandler}
|
||||
className={className}
|
||||
rounded={rest.rounded}
|
||||
dropdownContent={
|
||||
DropdownContent !== null && (
|
||||
<DropdownContent
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
onSelection={onSelection}
|
||||
/>
|
||||
)
|
||||
}
|
||||
isActive={isOpen}
|
||||
type="toggle"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
LayoutSelector.propTypes = {
|
||||
rows: PropTypes.number,
|
||||
columns: PropTypes.number,
|
||||
onLayoutChange: PropTypes.func,
|
||||
servicesManager: PropTypes.instanceOf(ServicesManager),
|
||||
};
|
||||
|
||||
LayoutSelector.defaultProps = {
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
onLayoutChange: () => {},
|
||||
};
|
||||
|
||||
export default LegacyLayoutSelectorWithServices;
|
||||
@ -1,37 +1,127 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
|
||||
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton, LayoutPreset } from '@ohif/ui';
|
||||
import { ServicesManager } from '@ohif/core';
|
||||
|
||||
function ToolbarLayoutSelectorWithServices({ servicesManager, commands, ...props }) {
|
||||
const { toolbarService, viewportGridService } = servicesManager.services;
|
||||
const defaultCommonPresets = [
|
||||
{
|
||||
icon: 'layout-common-1x1',
|
||||
commandOptions: {
|
||||
numRows: 1,
|
||||
numCols: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'layout-common-1x2',
|
||||
commandOptions: {
|
||||
numRows: 1,
|
||||
numCols: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'layout-common-2x2',
|
||||
commandOptions: {
|
||||
numRows: 2,
|
||||
numCols: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: 'layout-common-2x3',
|
||||
commandOptions: {
|
||||
numRows: 2,
|
||||
numCols: 3,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const onInteraction = useCallback(
|
||||
args => {
|
||||
const viewportId = viewportGridService.getActiveViewportId();
|
||||
const refreshProps = {
|
||||
viewportId,
|
||||
};
|
||||
|
||||
if (props.onLayoutChange) {
|
||||
props.onLayoutChange(args);
|
||||
const generateAdvancedPresets = hangingProtocolService => {
|
||||
const hangingProtocols = Array.from(hangingProtocolService.protocols.values());
|
||||
return hangingProtocols
|
||||
.map(hp => {
|
||||
if (!hp.isPreset) {
|
||||
return null;
|
||||
}
|
||||
toolbarService.recordInteraction({ commands }, { ...args, refreshProps });
|
||||
return {
|
||||
icon: hp.icon,
|
||||
title: hp.name,
|
||||
commandOptions: {
|
||||
protocolId: hp.id,
|
||||
},
|
||||
};
|
||||
})
|
||||
.filter(preset => preset !== null);
|
||||
};
|
||||
|
||||
function ToolbarLayoutSelectorWithServices({ servicesManager, ...props }) {
|
||||
const { toolbarService } = servicesManager.services;
|
||||
|
||||
const [isDisabled, setIsDisabled] = useState(false);
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
setIsDisabled(false);
|
||||
};
|
||||
|
||||
const onSelection = useCallback(
|
||||
props => {
|
||||
toolbarService.recordInteraction({
|
||||
interactionType: 'action',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setViewportGridLayout',
|
||||
commandOptions: { ...props },
|
||||
},
|
||||
],
|
||||
});
|
||||
setIsDisabled(true);
|
||||
},
|
||||
[toolbarService]
|
||||
);
|
||||
const onSelectionPreset = useCallback(
|
||||
props => {
|
||||
toolbarService.recordInteraction({
|
||||
interactionType: 'action',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setHangingProtocol',
|
||||
commandOptions: { ...props },
|
||||
},
|
||||
],
|
||||
});
|
||||
setIsDisabled(true);
|
||||
},
|
||||
[toolbarService]
|
||||
);
|
||||
|
||||
return (
|
||||
<LayoutSelector
|
||||
{...props}
|
||||
onInteraction={onInteraction}
|
||||
/>
|
||||
<div onMouseEnter={handleMouseEnter}>
|
||||
<LayoutSelector
|
||||
{...props}
|
||||
onSelection={onSelection}
|
||||
onSelectionPreset={onSelectionPreset}
|
||||
servicesManager={servicesManager}
|
||||
tooltipDisabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LayoutSelector({ rows, columns, className, onInteraction, ...rest }) {
|
||||
function LayoutSelector({
|
||||
rows,
|
||||
columns,
|
||||
className,
|
||||
onSelection,
|
||||
onSelectionPreset,
|
||||
servicesManager,
|
||||
tooltipDisabled,
|
||||
...rest
|
||||
}) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const { customizationService, hangingProtocolService } = servicesManager.services;
|
||||
const commonPresets = customizationService.get('commonPresets') || defaultCommonPresets;
|
||||
const advancedPresets =
|
||||
customizationService.get('advancedPresets') || generateAdvancedPresets(hangingProtocolService);
|
||||
|
||||
const closeOnOutsideClick = () => {
|
||||
if (isOpen) {
|
||||
setIsOpen(false);
|
||||
@ -45,24 +135,68 @@ function LayoutSelector({ rows, columns, className, onInteraction, ...rest }) {
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
const onInteractionHandler = () => setIsOpen(!isOpen);
|
||||
const onInteractionHandler = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
|
||||
|
||||
return (
|
||||
<ToolbarButton
|
||||
id="Layout"
|
||||
label="Grid Layout"
|
||||
label="Layout"
|
||||
icon="tool-layout"
|
||||
onInteraction={onInteractionHandler}
|
||||
className={className}
|
||||
rounded={rest.rounded}
|
||||
disableToolTip={tooltipDisabled}
|
||||
dropdownContent={
|
||||
DropdownContent !== null && (
|
||||
<DropdownContent
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
onSelection={onInteraction}
|
||||
/>
|
||||
<div className="flex">
|
||||
<div className="bg-secondary-dark flex flex-col gap-2.5 p-2">
|
||||
<div className="text-aqua-pale text-xs">Common</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
{commonPresets.map((preset, index) => (
|
||||
<LayoutPreset
|
||||
key={index}
|
||||
classNames="hover:bg-primary-dark group p-1"
|
||||
icon={preset.icon}
|
||||
commandOptions={preset.commandOptions}
|
||||
onSelection={onSelection}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="h-[2px] bg-black"></div>
|
||||
|
||||
<div className="text-aqua-pale text-xs">Advanced</div>
|
||||
|
||||
<div className="flex flex-col gap-2.5">
|
||||
{advancedPresets.map((preset, index) => (
|
||||
<LayoutPreset
|
||||
key={index + commonPresets.length}
|
||||
classNames="hover:bg-primary-dark group flex gap-2 p-1"
|
||||
icon={preset.icon}
|
||||
title={preset.title}
|
||||
commandOptions={preset.commandOptions}
|
||||
onSelection={onSelectionPreset}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-primary-dark flex flex-col gap-2.5 border-l-2 border-solid border-black p-2">
|
||||
<div className="text-aqua-pale text-xs">Custom</div>
|
||||
<DropdownContent
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
onSelection={onSelection}
|
||||
/>
|
||||
<p className="text-aqua-pale text-xs leading-tight">
|
||||
Hover to select <br></br>rows and columns <br></br> Click to apply
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
isActive={isOpen}
|
||||
@ -79,8 +213,8 @@ LayoutSelector.propTypes = {
|
||||
};
|
||||
|
||||
LayoutSelector.defaultProps = {
|
||||
columns: 4,
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
onLayoutChange: () => {},
|
||||
};
|
||||
|
||||
|
||||
@ -148,7 +148,7 @@ const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.layoutSelector',
|
||||
props: {
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
columns: 4,
|
||||
evaluate: 'evaluate.action',
|
||||
commands: [
|
||||
{
|
||||
|
||||
@ -193,10 +193,38 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
||||
toolGroupService.createToolGroupAndAddTools('mpr', tools);
|
||||
}
|
||||
|
||||
function initVolume3DToolGroup(extensionManager, toolGroupService) {
|
||||
const utilityModule = extensionManager.getModuleEntry(
|
||||
'@ohif/extension-cornerstone.utilityModule.tools'
|
||||
);
|
||||
|
||||
const { toolNames, Enums } = utilityModule.exports;
|
||||
|
||||
const tools = {
|
||||
active: [
|
||||
{
|
||||
toolName: toolNames.TrackballRotateTool,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
|
||||
},
|
||||
{
|
||||
toolName: toolNames.Zoom,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
|
||||
},
|
||||
{
|
||||
toolName: toolNames.Pan,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
toolGroupService.createToolGroupAndAddTools('volume3d', tools);
|
||||
}
|
||||
|
||||
function initToolGroups(extensionManager, toolGroupService, commandsManager) {
|
||||
initDefaultToolGroup(extensionManager, toolGroupService, commandsManager, 'default');
|
||||
initSRToolGroup(extensionManager, toolGroupService, commandsManager);
|
||||
initMPRToolGroup(extensionManager, toolGroupService, commandsManager);
|
||||
initVolume3DToolGroup(extensionManager, toolGroupService);
|
||||
}
|
||||
|
||||
export default initToolGroups;
|
||||
|
||||
@ -155,6 +155,41 @@ const toolbarButtons: Button[] = [
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'MPR',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
icon: 'icon-mpr',
|
||||
label: 'MPR',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleHangingProtocol',
|
||||
commandOptions: {
|
||||
protocolId: 'mpr',
|
||||
},
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.mpr',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'TrackBallRotate',
|
||||
type: 'ohif.radioGroup',
|
||||
props: {
|
||||
type: 'tool',
|
||||
icon: 'tool-3d-rotate',
|
||||
label: '3D Rotate',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setToolActive',
|
||||
commandOptions: {
|
||||
toolName: 'TrackBallRotate',
|
||||
},
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'Capture',
|
||||
uiType: 'ohif.radioGroup',
|
||||
@ -174,30 +209,9 @@ const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.layoutSelector',
|
||||
props: {
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
columns: 4,
|
||||
evaluate: 'evaluate.action',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setViewportGridLayout',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'MPR',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
icon: 'icon-mpr',
|
||||
label: 'MPR',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleHangingProtocol',
|
||||
commandOptions: {
|
||||
protocolId: 'mpr',
|
||||
},
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.mpr',
|
||||
commands: 'setViewportGridLayout',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -83,11 +83,11 @@ function modeFactory({ modeConfiguration }) {
|
||||
toolbarService.createButtonSection('primary', [
|
||||
'MeasurementTools',
|
||||
'Zoom',
|
||||
'WindowLevel',
|
||||
'Pan',
|
||||
'TrackballRotate',
|
||||
'WindowLevel',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
|
||||
@ -54,7 +54,7 @@ const moreTools = [
|
||||
label: 'Flip Horizontal',
|
||||
tooltip: 'Flip Horizontally',
|
||||
commands: 'flipViewportHorizontal',
|
||||
evaluate: 'evaluate.viewportProperties.toggle',
|
||||
evaluate: ['evaluate.viewportProperties.toggle', 'evaluate.not3D'],
|
||||
}),
|
||||
createButton({
|
||||
id: 'ImageSliceSync',
|
||||
@ -73,7 +73,7 @@ const moreTools = [
|
||||
commandOptions: { toggledState: true },
|
||||
},
|
||||
},
|
||||
evaluate: 'evaluate.cornerstone.synchronizer',
|
||||
evaluate: ['evaluate.cornerstone.synchronizer', 'evaluate.not3D'],
|
||||
}),
|
||||
createButton({
|
||||
id: 'ReferenceLines',
|
||||
@ -137,7 +137,7 @@ const moreTools = [
|
||||
label: 'Cine',
|
||||
tooltip: 'Cine',
|
||||
commands: 'toggleCine',
|
||||
evaluate: 'evaluate.cine',
|
||||
evaluate: ['evaluate.cine', 'evaluate.not3D'],
|
||||
}),
|
||||
createButton({
|
||||
id: 'Angle',
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
// 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 {
|
||||
// ListMenu,
|
||||
WindowLevelMenuItem,
|
||||
} from '@ohif/ui';
|
||||
import { WindowLevelMenuItem } from '@ohif/ui';
|
||||
import { defaults, ToolbarService } from '@ohif/core';
|
||||
import type { Button } from '@ohif/core/types';
|
||||
|
||||
@ -36,7 +33,7 @@ function _createWwwcPreset(preset, title, subtitle) {
|
||||
export const setToolActiveToolbar = {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandOptions: {
|
||||
toolGroupIds: ['default', 'mpr', 'SRToolGroup'],
|
||||
toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d'],
|
||||
},
|
||||
};
|
||||
|
||||
@ -155,6 +152,17 @@ const toolbarButtons: Button[] = [
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'TrackballRotate',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
type: 'tool',
|
||||
icon: 'tool-3d-rotate',
|
||||
label: '3D Rotate',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'Capture',
|
||||
uiType: 'ohif.radioGroup',
|
||||
@ -174,7 +182,7 @@ const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.layoutSelector',
|
||||
props: {
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
columns: 4,
|
||||
evaluate: 'evaluate.action',
|
||||
commands: [
|
||||
{
|
||||
@ -183,23 +191,6 @@ const toolbarButtons: Button[] = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'MPR',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
icon: 'icon-mpr',
|
||||
label: 'MPR',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleHangingProtocol',
|
||||
commandOptions: {
|
||||
protocolId: 'mpr',
|
||||
},
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.mpr',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'Crosshairs',
|
||||
uiType: 'ohif.radioGroup',
|
||||
|
||||
@ -35,7 +35,14 @@
|
||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ohif/core": "3.8.0-beta.64"
|
||||
"@ohif/core": "3.8.0-beta.64",
|
||||
"@ohif/extension-cornerstone": "3.8.0-beta.64",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "3.8.0-beta.64",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "3.8.0-beta.64",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "3.8.0-beta.64",
|
||||
"@ohif/extension-default": "3.8.0-beta.64",
|
||||
"@ohif/extension-dicom-pdf": "3.8.0-beta.64",
|
||||
"@ohif/extension-dicom-video": "3.8.0-beta.64"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
|
||||
@ -4,6 +4,9 @@ import toolbarButtons from './toolbarButtons';
|
||||
import segmentationButtons from './segmentationButtons';
|
||||
import initToolGroups from './initToolGroups';
|
||||
|
||||
const DEFAULT_TOOL_GROUP_ID = 'default';
|
||||
const VOLUME3D_TOOL_GROUP_ID = 'volume3d';
|
||||
|
||||
const ohif = {
|
||||
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
||||
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
|
||||
@ -62,12 +65,13 @@ function modeFactory({ modeConfiguration }) {
|
||||
toolbarService.addButtons(segmentationButtons);
|
||||
|
||||
toolbarService.createButtonSection('primary', [
|
||||
'WindowLevel',
|
||||
'Pan',
|
||||
'Zoom',
|
||||
'TrackballRotate',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'Zoom',
|
||||
'MoreTools',
|
||||
]);
|
||||
toolbarService.createButtonSection('segmentationToolbox', ['BrushTools', 'Shapes']);
|
||||
@ -105,9 +109,13 @@ function modeFactory({ modeConfiguration }) {
|
||||
// that is not supported by the mode
|
||||
const modalitiesArray = modalities.split('\\');
|
||||
return {
|
||||
valid: modalitiesArray.length === 1 ? !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0]) : true,
|
||||
description: 'The mode does not support studies that ONLY include the following modalities: SM, US, MG, OT, DOC, CR',
|
||||
}
|
||||
valid:
|
||||
modalitiesArray.length === 1
|
||||
? !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0])
|
||||
: true,
|
||||
description:
|
||||
'The mode does not support studies that ONLY include the following modalities: SM, US, MG, OT, DOC, CR',
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Mode Routes are used to define the mode's behavior. A list of Mode Route
|
||||
|
||||
@ -81,6 +81,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
||||
toolName: utilityModule.exports.toolNames.Crosshairs,
|
||||
configuration: {
|
||||
viewportIndicators: false,
|
||||
disableOnPassive: true,
|
||||
autoPan: {
|
||||
enabled: false,
|
||||
panSize: 10,
|
||||
@ -92,9 +93,37 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
||||
toolGroupService.createToolGroupAndAddTools('mpr', tools);
|
||||
}
|
||||
|
||||
function initVolume3DToolGroup(extensionManager, toolGroupService) {
|
||||
const utilityModule = extensionManager.getModuleEntry(
|
||||
'@ohif/extension-cornerstone.utilityModule.tools'
|
||||
);
|
||||
|
||||
const { toolNames, Enums } = utilityModule.exports;
|
||||
|
||||
const tools = {
|
||||
active: [
|
||||
{
|
||||
toolName: toolNames.TrackballRotateTool,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
|
||||
},
|
||||
{
|
||||
toolName: toolNames.Zoom,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
|
||||
},
|
||||
{
|
||||
toolName: toolNames.Pan,
|
||||
bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
toolGroupService.createToolGroupAndAddTools('volume3d', tools);
|
||||
}
|
||||
|
||||
function initToolGroups(extensionManager, toolGroupService, commandsManager) {
|
||||
initDefaultToolGroup(extensionManager, toolGroupService, commandsManager, 'default');
|
||||
initMPRToolGroup(extensionManager, toolGroupService, commandsManager);
|
||||
initVolume3DToolGroup(extensionManager, toolGroupService);
|
||||
}
|
||||
|
||||
export default initToolGroups;
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
import { defaults, ToolbarService } from '@ohif/core';
|
||||
import type { Button } from '@ohif/core/types';
|
||||
import { defaults, ToolbarService, ViewportGridService } from '@ohif/core';
|
||||
import { WindowLevelMenuItem } from '@ohif/ui';
|
||||
|
||||
const { windowLevelPresets } = defaults;
|
||||
const { createButton } = ToolbarService;
|
||||
|
||||
const ReferenceLinesListeners: RunCommand = [
|
||||
{
|
||||
commandName: 'setSourceViewportForReferenceLinesTool',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
];
|
||||
|
||||
function _createWwwcPreset(preset, title, subtitle) {
|
||||
return {
|
||||
@ -21,16 +29,12 @@ function _createWwwcPreset(preset, title, subtitle) {
|
||||
};
|
||||
}
|
||||
|
||||
function _createSetToolActiveCommands(toolName, toolGroupIds = ['default', 'mpr', 'SRToolGroup']) {
|
||||
return toolGroupIds.map(toolGroupId => ({
|
||||
commandName: 'setToolActive',
|
||||
commandOptions: {
|
||||
toolGroupId,
|
||||
toolName,
|
||||
},
|
||||
context: 'CORNERSTONE',
|
||||
}));
|
||||
}
|
||||
export const setToolActiveToolbar = {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandOptions: {
|
||||
toolGroupIds: ['default', 'mpr', 'SRToolGroup'],
|
||||
},
|
||||
};
|
||||
|
||||
const toolbarButtons: Button[] = [
|
||||
{
|
||||
@ -39,7 +43,7 @@ const toolbarButtons: Button[] = [
|
||||
props: {
|
||||
icon: 'tool-zoom',
|
||||
label: 'Zoom',
|
||||
commands: _createSetToolActiveCommands('Zoom'),
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
@ -48,12 +52,12 @@ const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.splitButton',
|
||||
props: {
|
||||
groupId: 'WindowLevel',
|
||||
primary: ToolbarService.createButton({
|
||||
primary: createButton({
|
||||
id: 'WindowLevel',
|
||||
icon: 'tool-window-level',
|
||||
label: 'Window Level',
|
||||
tooltip: 'Window Level',
|
||||
commands: _createSetToolActiveCommands('WindowLevel'),
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
secondary: {
|
||||
@ -76,7 +80,18 @@ const toolbarButtons: Button[] = [
|
||||
props: {
|
||||
icon: 'tool-move',
|
||||
label: 'Pan',
|
||||
commands: _createSetToolActiveCommands('Pan'),
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'TrackballRotate',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
type: 'tool',
|
||||
icon: 'tool-3d-rotate',
|
||||
label: '3D Rotate',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
@ -86,12 +101,7 @@ const toolbarButtons: Button[] = [
|
||||
props: {
|
||||
icon: 'tool-capture',
|
||||
label: 'Capture',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'showDownloadViewportModal',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
commands: 'showDownloadViewportModal',
|
||||
evaluate: 'evaluate.action',
|
||||
},
|
||||
},
|
||||
@ -100,31 +110,9 @@ const toolbarButtons: Button[] = [
|
||||
uiType: 'ohif.layoutSelector',
|
||||
props: {
|
||||
rows: 3,
|
||||
columns: 3,
|
||||
columns: 4,
|
||||
evaluate: 'evaluate.action',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'setViewportGridLayout',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'MPR',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
icon: 'icon-mpr',
|
||||
label: 'MPR',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleHangingProtocol',
|
||||
commandOptions: {
|
||||
protocolId: 'mpr',
|
||||
},
|
||||
context: 'DEFAULT',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.mpr',
|
||||
commands: 'setViewportGridLayout',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -133,7 +121,12 @@ const toolbarButtons: Button[] = [
|
||||
props: {
|
||||
icon: 'tool-crosshair',
|
||||
label: 'Crosshairs',
|
||||
commands: _createSetToolActiveCommands('Crosshairs', ['mpr']),
|
||||
commands: {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandOptions: {
|
||||
toolGroupIds: ['mpr'],
|
||||
},
|
||||
},
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
@ -143,104 +136,146 @@ const toolbarButtons: Button[] = [
|
||||
props: {
|
||||
groupId: 'MoreTools',
|
||||
evaluate: 'evaluate.group.promoteToPrimaryIfCornerstoneToolNotActiveInTheList',
|
||||
primary: ToolbarService.createButton({
|
||||
primary: createButton({
|
||||
id: 'Reset',
|
||||
icon: 'tool-reset',
|
||||
label: 'Reset View',
|
||||
tooltip: 'Reset',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'resetViewport',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
tooltip: 'Reset View',
|
||||
label: 'Reset',
|
||||
commands: 'resetViewport',
|
||||
evaluate: 'evaluate.action',
|
||||
}),
|
||||
secondary: {
|
||||
icon: 'chevron-down',
|
||||
label: '',
|
||||
tooltip: 'More Tools',
|
||||
},
|
||||
items: [
|
||||
ToolbarService.createButton({
|
||||
id: 'RotateRight',
|
||||
createButton({
|
||||
id: 'Reset',
|
||||
icon: 'tool-reset',
|
||||
label: 'Reset View',
|
||||
tooltip: 'Reset View',
|
||||
commands: 'resetViewport',
|
||||
evaluate: 'evaluate.action',
|
||||
}),
|
||||
createButton({
|
||||
id: 'rotate-right',
|
||||
icon: 'tool-rotate-right',
|
||||
label: 'Rotate Right',
|
||||
tooltip: 'Rotate +90',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'rotateViewportCW',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
commands: 'rotateViewportCW',
|
||||
evaluate: 'evaluate.action',
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
id: 'FlipHorizontal',
|
||||
createButton({
|
||||
id: 'flipHorizontal',
|
||||
icon: 'tool-flip-horizontal',
|
||||
label: 'Flip Horizontally',
|
||||
tooltip: 'Flip Horizontal',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'flipViewportHorizontal',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.action',
|
||||
label: 'Flip Horizontal',
|
||||
tooltip: 'Flip Horizontally',
|
||||
commands: 'flipViewportHorizontal',
|
||||
evaluate: ['evaluate.viewportProperties.toggle', 'evaluate.not3D'],
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
createButton({
|
||||
id: 'ReferenceLines',
|
||||
icon: 'tool-referenceLines',
|
||||
label: 'Reference Lines',
|
||||
tooltip: 'Show Reference Lines',
|
||||
commands: {
|
||||
commandName: 'setToolEnabled',
|
||||
commandOptions: {
|
||||
toolName: 'ReferenceLines',
|
||||
toggle: true, // Toggle the tool on/off upon click
|
||||
},
|
||||
},
|
||||
listeners: {
|
||||
[ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners,
|
||||
[ViewportGridService.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners,
|
||||
},
|
||||
evaluate: 'evaluate.cornerstoneTool.toggle',
|
||||
}),
|
||||
createButton({
|
||||
id: 'ImageOverlay',
|
||||
icon: 'toggle-dicom-overlay',
|
||||
label: 'Image Overlay',
|
||||
tooltip: 'Toggle Image Overlay',
|
||||
commands: {
|
||||
commandName: 'setToolEnabled',
|
||||
commandOptions: {
|
||||
toolName: 'ImageOverlayViewer',
|
||||
toggle: true, // Toggle the tool on/off upon click
|
||||
},
|
||||
},
|
||||
evaluate: 'evaluate.cornerstoneTool.toggle',
|
||||
}),
|
||||
createButton({
|
||||
id: 'StackScroll',
|
||||
icon: 'tool-stack-scroll',
|
||||
label: 'Stack Scroll',
|
||||
tooltip: 'Stack Scroll',
|
||||
commands: _createSetToolActiveCommands('StackScroll'),
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
id: 'Magnify',
|
||||
icon: 'tool-magnify',
|
||||
label: 'Magnify',
|
||||
tooltip: 'Magnify',
|
||||
commands: _createSetToolActiveCommands('Magnify'),
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
id: 'Invert',
|
||||
createButton({
|
||||
id: 'invert',
|
||||
icon: 'tool-invert',
|
||||
label: 'Invert',
|
||||
tooltip: 'Invert Colors',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'invertViewport',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.action',
|
||||
commands: 'invertViewport',
|
||||
evaluate: 'evaluate.viewportProperties.toggle',
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
createButton({
|
||||
id: 'Probe',
|
||||
icon: 'tool-probe',
|
||||
label: 'Probe',
|
||||
tooltip: 'Probe',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
createButton({
|
||||
id: 'Cine',
|
||||
icon: 'tool-cine',
|
||||
label: 'Cine',
|
||||
tooltip: 'Cine',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleCine',
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.action',
|
||||
commands: 'toggleCine',
|
||||
evaluate: ['evaluate.cine', 'evaluate.not3D'],
|
||||
}),
|
||||
ToolbarService.createButton({
|
||||
id: 'DicomTagBrowser',
|
||||
createButton({
|
||||
id: 'Angle',
|
||||
icon: 'tool-angle',
|
||||
label: 'Angle',
|
||||
tooltip: 'Angle',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
createButton({
|
||||
id: 'Magnify',
|
||||
icon: 'tool-magnify',
|
||||
label: 'Magnify',
|
||||
tooltip: 'Magnify',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
createButton({
|
||||
id: 'RectangleROI',
|
||||
icon: 'tool-rectangle',
|
||||
label: 'Rectangle',
|
||||
tooltip: 'Rectangle',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
createButton({
|
||||
id: 'CalibrationLine',
|
||||
icon: 'tool-calibration',
|
||||
label: 'Calibration',
|
||||
tooltip: 'Calibration Line',
|
||||
commands: setToolActiveToolbar,
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
}),
|
||||
createButton({
|
||||
id: 'TagBrowser',
|
||||
icon: 'list-bullets',
|
||||
label: 'Dicom Tag Browser',
|
||||
tooltip: 'Dicom Tag Browser',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'openDICOMTagViewer',
|
||||
context: 'DEFAULT',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.action',
|
||||
commands: 'openDICOMTagViewer',
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
@ -100,22 +100,6 @@ const toolbarButtons = [
|
||||
evaluate: 'evaluate.cornerstoneTool',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'MPR',
|
||||
uiType: 'ohif.radioGroup',
|
||||
props: {
|
||||
icon: 'icon-mpr',
|
||||
label: 'MPR',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleHangingProtocol',
|
||||
commandOptions: { protocolId: 'mpr' },
|
||||
context: 'DEFAULT',
|
||||
},
|
||||
],
|
||||
evaluate: 'evaluate.mpr',
|
||||
},
|
||||
},
|
||||
// Window Level + Presets
|
||||
{
|
||||
id: 'WindowLevel',
|
||||
|
||||
@ -12,7 +12,6 @@ export function initCornerstoneToolsAliases() {
|
||||
cy.get('[data-cy="MoreTools-split-button-secondary"]').as('moreBtnSecondary');
|
||||
cy.get('[data-cy="Layout"]').as('layoutBtn');
|
||||
cy.get('.cornerstone-viewport-element').as('viewport');
|
||||
cy.get('[data-cy="MPR"]').as('mprBtn');
|
||||
}
|
||||
|
||||
//Creating aliases for Common page elements
|
||||
|
||||
@ -56,7 +56,6 @@ function modeFactory({ modeConfiguration }) {
|
||||
'Pan',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
|
||||
@ -420,6 +420,34 @@ export default class ToolbarService extends PubSubService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(evaluate)) {
|
||||
const evaluators = evaluate.map(evaluatorName => {
|
||||
const evaluateFunction = this._evaluateFunction[evaluatorName];
|
||||
|
||||
if (!evaluateFunction) {
|
||||
throw new Error(
|
||||
`Evaluate function not found for name: ${evaluatorName}, you can register an evaluate function with the getToolbarModule in your extensions`
|
||||
);
|
||||
}
|
||||
|
||||
return evaluateFunction;
|
||||
});
|
||||
|
||||
props.evaluate = args => {
|
||||
const results = evaluators.map(evaluator => evaluator(args));
|
||||
const mergedResult = results.reduce((acc, result) => {
|
||||
return {
|
||||
...acc,
|
||||
...result,
|
||||
};
|
||||
}, {});
|
||||
|
||||
return mergedResult;
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof evaluate === 'string') {
|
||||
const evaluateFunction = this._evaluateFunction[evaluate];
|
||||
|
||||
@ -429,7 +457,7 @@ export default class ToolbarService extends PubSubService {
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Evaluate function not found for name: ${evaluate}, you can register an evaluate function with the getToolbarModule in your extensions`
|
||||
`Evaluate function not found for name: ${evaluate}, you can register an evaluate function with the getToolbarModule in your extensions`
|
||||
);
|
||||
}
|
||||
|
||||
@ -443,7 +471,7 @@ export default class ToolbarService extends PubSubService {
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Evaluate function not found for name: ${name}, you can register an evaluate function with the getToolbarModule in your extensions`
|
||||
`Evaluate function not found for name: ${name}, you can register an evaluate function with the getToolbarModule in your extensions`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { RunCommand } from '../../types/Command';
|
||||
|
||||
export type EvaluatePublic = string | EvaluateFunction;
|
||||
export type EvaluatePublic = string | EvaluateFunction | string[];
|
||||
|
||||
export type EvaluateFunction = (props: Record<string, unknown>) => {
|
||||
disabled: boolean;
|
||||
|
||||
@ -304,6 +304,16 @@ export type Protocol = {
|
||||
*/
|
||||
minSeriesLoaded: number;
|
||||
};
|
||||
|
||||
/*
|
||||
* The icon to use for this protocol. This is used to display the protocol
|
||||
* in the advanced layout selector.
|
||||
*/
|
||||
|
||||
icon?: string;
|
||||
|
||||
/** Indicates if the protocol is a preset or not. Useful for setting presets for the layout selector */
|
||||
isPreset?: true;
|
||||
};
|
||||
|
||||
/** Used to dynamically generate protocols.
|
||||
|
||||
@ -657,7 +657,6 @@ onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
|
||||
'Pan',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
|
||||
@ -184,7 +184,6 @@ function modeFactory({ modeConfiguration }) {
|
||||
'Pan',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
|
||||
@ -243,7 +243,6 @@ toolbarService.createButtonSection('primary', [
|
||||
'Pan',
|
||||
'Capture',
|
||||
'Layout',
|
||||
'MPR',
|
||||
'Crosshairs',
|
||||
'MoreTools',
|
||||
]);
|
||||
|
||||
13
platform/ui/src/assets/icons/layout-advanced-3d-four-up.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-3d-four-up</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-3d-four-up" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="27" height="16.2" rx="2"></rect>
|
||||
<path d="M0,0 L11.8857143,-2.22044605e-16 C12.9902838,5.56104062e-16 13.8857143,0.8954305 13.8857143,2 L13.8857143,14.2 C13.8857143,15.3045695 12.9902838,16.2 11.8857143,16.2 L0,16.2 L0,16.2 L0,0 Z" id="Rectangle" transform="translate(6.9429, 8.1) scale(-1, 1) translate(-6.9429, -8.1)"></path>
|
||||
<path d="M13.8857143,0 L25,0 C26.1045695,-1.18396092e-15 27,0.8954305 27,2 L27,8.5 L27,8.5 L13.8857143,8.5 L13.8857143,0 Z" id="Rectangle" fill="#263A71"></path>
|
||||
<path d="M0,8.48571429 L13.8857143,8.48571429 L13.8857143,14.2 C13.8857143,15.3045695 12.9902838,16.2 11.8857143,16.2 L0,16.2 L0,16.2 L0,8.48571429 Z" id="Rectangle" transform="translate(6.9429, 12.3429) scale(-1, 1) translate(-6.9429, -12.3429)"></path>
|
||||
<path d="M13.8857143,8.48571429 L27,8.48571429 L27,14.2 C27,15.3045695 26.1045695,16.2 25,16.2 L13.8857143,16.2 L13.8857143,16.2 L13.8857143,8.48571429 Z" id="Rectangle"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
12
platform/ui/src/assets/icons/layout-advanced-3d-main.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-3d-main</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-3d-main" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="27" height="16.2" rx="2"></rect>
|
||||
<path d="M18,7.71428571 L27,7.71428571 L27,14.2 C27,15.3045695 26.1045695,16.2 25,16.2 L18,16.2 L18,16.2 L18,7.71428571 Z" id="Rectangle"></path>
|
||||
<path d="M0,7.71428571 L9.25714286,7.71428571 L9.25714286,16.2 L2,16.2 C0.8954305,16.2 9.55813795e-16,15.3045695 8.8817842e-16,14.2 L0,7.71428571 L0,7.71428571 Z" id="Rectangle"></path>
|
||||
<path d="M2,0 L25,0 C26.1045695,-2.02906125e-16 27,0.8954305 27,2 L27,8.48571429 L27,8.48571429 L0,8.48571429 L0,2 C-1.3527075e-16,0.8954305 0.8954305,1.3527075e-16 2,0 Z" id="Rectangle" fill="#263A71" transform="translate(13.5, 4.2429) scale(-1, 1) translate(-13.5, -4.2429)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
9
platform/ui/src/assets/icons/layout-advanced-3d-only.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-3d-only</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-3d-only" transform="translate(1, 1)" fill="#263A71" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="27" height="16.2" rx="2"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 545 B |
12
platform/ui/src/assets/icons/layout-advanced-3d-primary.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-3d-primary</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-3d-primary" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="27" height="16.2" rx="2"></rect>
|
||||
<path d="M15.4285714,10.5 L27,10.5 L27,14 C27,15.1045695 26.1045695,16 25,16 L15.4285714,16 L15.4285714,16 L15.4285714,10.5 Z" id="Rectangle"></path>
|
||||
<path d="M15.4285714,0 L25,0 C26.1045695,-2.02906125e-16 27,0.8954305 27,2 L27,5.4 L27,5.4 L15.4285714,5.4 L15.4285714,0 Z" id="Rectangle"></path>
|
||||
<path d="M0,0 L14.2,0 C15.3045695,-2.02906125e-16 16.2,0.8954305 16.2,2 L16.2,14.2 C16.2,15.3045695 15.3045695,16.2 14.2,16.2 L0,16.2 L0,16.2 L0,0 Z" id="Rectangle" fill="#263A71" transform="translate(8.1, 8.1) scale(-1, 1) translate(-8.1, -8.1)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-axial-primary</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-axial-primary" transform="translate(1, 1)" stroke="currentColor">
|
||||
<path d="M15.4285714,0 L25,0 C26.1045695,-2.02906125e-16 27,0.8954305 27,2 L27,14.2 C27,15.3045695 26.1045695,16.2 25,16.2 L15.4285714,16.2 L15.4285714,16.2 L15.4285714,0 Z" id="Rectangle"></path>
|
||||
<path d="M15.4285714,0 L25,0 C26.1045695,-2.02906125e-16 27,0.8954305 27,2 L27,8.48571429 L27,8.48571429 L15.4285714,8.48571429 L15.4285714,0 Z" id="Rectangle"></path>
|
||||
<path d="M4.54747351e-13,0 L13.7,0 C14.8045695,-2.02906125e-16 15.7,0.8954305 15.7,2 L15.7,14.2 C15.7,15.3045695 14.8045695,16.2 13.7,16.2 L4.54747351e-13,16.2 L4.54747351e-13,16.2 L4.54747351e-13,0 Z" id="Rectangle" transform="translate(7.85, 8.1) scale(-1, 1) translate(-7.85, -8.1)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
11
platform/ui/src/assets/icons/layout-advanced-mpr.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="29px" height="18px" viewBox="0 0 29 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-advanced-mpr</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-advanced-mpr" transform="translate(1, 1)" stroke="currentColor">
|
||||
<path d="M17.7428571,0 L25,0 C26.1045695,-2.02906125e-16 27,0.8954305 27,2 L27,14.2 C27,15.3045695 26.1045695,16.2 25,16.2 L17.7428571,16.2 L17.7428571,16.2 L17.7428571,0 Z" id="Rectangle"></path>
|
||||
<rect id="Rectangle" x="9" y="0" width="9" height="16.2"></rect>
|
||||
<path d="M0,0 L7.25714286,0 C8.36171236,-1.18396092e-15 9.25714286,0.8954305 9.25714286,2 L9.25714286,14.2 C9.25714286,15.3045695 8.36171236,16.2 7.25714286,16.2 L0,16.2 L0,16.2 L0,0 Z" id="Rectangle" transform="translate(4.6286, 8.1) scale(-1, 1) translate(-4.6286, -8.1)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1017 B |
9
platform/ui/src/assets/icons/layout-common-1x1.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="18px" viewBox="0 0 28 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-common-1x1</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-common-1x1" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="26" height="15.6" rx="2"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 518 B |
10
platform/ui/src/assets/icons/layout-common-1x2.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="18px" viewBox="0 0 28 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-common-1x2</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-common-1x2" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="26" height="15.6" rx="2"></rect>
|
||||
<path d="M0,0 L11,-4.4408921e-16 C12.1045695,-6.46995335e-16 13,0.8954305 13,2 L13,13.6 C13,14.7045695 12.1045695,15.6 11,15.6 L0,15.6 L0,15.6 L0,0 Z" id="Rectangle" transform="translate(6.5, 7.8) scale(-1, 1) translate(-6.5, -7.8)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 771 B |
11
platform/ui/src/assets/icons/layout-common-2x2.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="18px" viewBox="0 0 28 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-common-2x2</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-common-2x2" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="26" height="15.6" rx="2"></rect>
|
||||
<path d="M0,0 L11,-4.4408921e-16 C12.1045695,-6.46995335e-16 13,0.8954305 13,2 L13,13.6 C13,14.7045695 12.1045695,15.6 11,15.6 L0,15.6 L0,15.6 L0,0 Z" id="Rectangle" transform="translate(6.5, 7.8) scale(-1, 1) translate(-6.5, -7.8)"></path>
|
||||
<path d="M2,0 L24,0 C25.1045695,-2.02906125e-16 26,0.8954305 26,2 L26,8 L26,8 L0,8 L0,2 C-1.3527075e-16,0.8954305 0.8954305,1.3527075e-16 2,0 Z" id="Rectangle" transform="translate(13, 4) scale(-1, 1) translate(-13, -4)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1012 B |
12
platform/ui/src/assets/icons/layout-common-2x3.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="18px" viewBox="0 0 28 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>layout-common-2x3</title>
|
||||
<g id="Layout-select----FINAL" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="layout-common-2x3" transform="translate(1, 1)" stroke="currentColor">
|
||||
<rect id="Rectangle" x="0" y="0" width="26" height="15.6" rx="2"></rect>
|
||||
<path d="M0,0 L7,0 C8.1045695,-2.02906125e-16 9,0.8954305 9,2 L9,13.6 C9,14.7045695 8.1045695,15.6 7,15.6 L0,15.6 L0,15.6 L0,0 Z" id="Rectangle" transform="translate(4.5, 7.8) scale(-1, 1) translate(-4.5, -7.8)"></path>
|
||||
<path d="M0,0 L15,-4.4408921e-16 C16.1045695,-6.46995335e-16 17,0.8954305 17,2 L17,13.6 C17,14.7045695 16.1045695,15.6 15,15.6 L0,15.6 L0,15.6 L0,0 Z" id="Rectangle" transform="translate(8.5, 7.8) scale(-1, 1) translate(-8.5, -7.8)"></path>
|
||||
<path d="M2,0 L24,0 C25.1045695,-2.02906125e-16 26,0.8954305 26,2 L26,8 L26,8 L0,8 L0,2 C-1.3527075e-16,0.8954305 0.8954305,1.3527075e-16 2,0 Z" id="Rectangle" transform="translate(13, 4) scale(-1, 1) translate(-13, -4)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
20
platform/ui/src/assets/icons/tool-3d-rotate.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>tool-3d-rotate</title>
|
||||
<g id="tool-3d-rotate" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle" x="0" y="0" width="28" height="28"></rect>
|
||||
<g id="Group" transform="translate(4, 3)" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
||||
<g id="group">
|
||||
<polyline id="Path" points="6 21.996 8.5 19.998 6 17.996"></polyline>
|
||||
<path d="M8.5,19.998 C5.038,20.652 1,18.498 0,14.998" id="Path"></path>
|
||||
<polyline id="Path" points="14 0 11.5 1.998 14 4"></polyline>
|
||||
<path d="M11.5,1.998 C14.962,1.344 19,3.498 20,6.998" id="Path"></path>
|
||||
</g>
|
||||
<g id="3d" transform="translate(5, 5.75)">
|
||||
<polygon id="Path" points="5 0 0 2.1875 5 4.375 10 2.1875"></polygon>
|
||||
<polyline id="Path" points="0 2.1875 0 8.125 5 10.3125 10 8.125 10 2.1875"></polyline>
|
||||
<line x1="5" y1="4.375" x2="5" y2="10.3125" id="Path"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,6 +1,21 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21">
|
||||
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
||||
<path fill="currentColor" d="M8.313 7.52c0 .438-.355.793-.792.793H1.188c-.438 0-.792-.355-.792-.792V1.188c0-.438.354-.792.791-.792h6.334c.437 0 .792.354.792.791v6.334z" transform="translate(1 1)"/>
|
||||
<path d="M18.604 7.52c0 .438-.354.793-.791.793h-6.334c-.437 0-.791-.355-.791-.792V1.188c0-.438.354-.792.791-.792h6.334c.437 0 .791.354.791.791v6.334zM8.313 17.813c0 .437-.355.791-.792.791H1.188c-.438 0-.792-.354-.792-.791v-6.334c0-.437.354-.791.791-.791h6.334c.437 0 .792.354.792.791v6.334zM18.604 17.813c0 .437-.354.791-.791.791h-6.334c-.437 0-.791-.354-.791-.791v-6.334c0-.437.354-.791.791-.791h6.334c.437 0 .791.354.791.791v6.334z" transform="translate(1 1)"/>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>tool-layout</title>
|
||||
<g id="tool-layout" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle" x="0" y="0" width="28" height="28"></rect>
|
||||
<g id="Group" transform="translate(0.5, 0.5)" stroke="currentColor">
|
||||
<path d="M5.45696821e-12,9.49450549 L5.45696821e-12,17.3947362 C5.45710348e-12,18.4993057 0.8954305,19.3947362 2,19.3947362 L10.861569,19.3947362 L10.861569,19.3947362" id="Path-3" stroke-width="1.25" stroke-linecap="round"></path>
|
||||
<path d="M9.49450549,0 L9.49450549,3.85708618 C9.49450549,4.96165568 10.389936,5.85708618 11.4945055,5.85708618 L19.195248,5.85708618 L19.195248,5.85708618" id="Path-3" stroke-width="1.25" stroke-linecap="round" transform="translate(14.3449, 2.9285) rotate(180) translate(-14.3449, -2.9285)"></path>
|
||||
<path d="M0.0997440877,-0.0997440877 L0.0997440877,7.80048659 C0.0997440877,8.90505609 0.995174588,9.80048659 2.09974409,9.80048659 L9.80048659,9.80048659 L9.80048659,9.80048659" id="Path-3" stroke-width="1.25" stroke-linecap="round" transform="translate(4.9501, 4.8504) rotate(90) translate(-4.9501, -4.8504)"></path>
|
||||
<g id="Group-10" opacity="0.550000012" transform="translate(2, 2)" stroke-linecap="round" stroke-width="1.5">
|
||||
<line x1="7.5" y1="14.5" x2="7.5" y2="0.5" id="Line-2"></line>
|
||||
<line x1="7" y1="14" x2="7" y2="1" id="Line-2" transform="translate(7, 7.5) rotate(90) translate(-7, -7.5)"></line>
|
||||
</g>
|
||||
<g id="gear" transform="translate(20.6492, 15.8718) rotate(-20) translate(-20.6492, -15.8718)translate(15.525, 10.1048)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.25">
|
||||
<circle id="Oval" cx="5.12378058" cy="5.76719178" r="1.28158482"></circle>
|
||||
<path d="M6.21361819,0.80762797 L6.59086967,2.04907966 C6.72061095,2.47639719 7.15892721,2.73042581 7.59419808,2.63056421 L8.85259487,2.33893009 C9.34216301,2.22858155 9.84650092,2.45011894 10.0964357,2.88530436 C10.3463705,3.32048979 10.2835655,3.86774756 9.94154064,4.23499782 L9.06128718,5.18481538 C8.75980718,5.51248709 8.75980718,6.0165454 9.06128718,6.3442171 L9.94154064,7.29403466 C10.2835655,7.66128493 10.3463705,8.2085427 10.0964357,8.64372812 C9.84650092,9.07891354 9.34216301,9.30045094 8.85259487,9.1901024 L7.59419808,8.89846827 C7.15663131,8.79632613 6.71524652,9.05279063 6.58730228,9.48352022 L6.2100508,10.7249719 C6.0649735,11.2053044 5.62242271,11.5339347 5.12065911,11.5339347 C4.61889551,11.5339347 4.17634472,11.2053044 4.03126742,10.7249719 L3.65669148,9.48352022 C3.52807698,9.05567912 3.08963152,8.80095947 2.65425492,8.90114382 L1.39585813,9.19277794 C0.90628999,9.30312648 0.401952083,9.08158909 0.152017275,8.64640366 C-0.0979175321,8.21121824 -0.035112502,7.66396047 0.306912358,7.29671021 L1.18716582,6.34689264 C1.48864582,6.01922094 1.48864582,5.51516263 1.18716582,5.18749093 L0.306912358,4.23767336 C-0.035112502,3.8704231 -0.0979175321,3.32316533 0.152017275,2.88797991 C0.401952083,2.45279448 0.90628999,2.23125709 1.39585813,2.34160563 L2.65425492,2.63323975 C3.08937078,2.73350334 3.52770594,2.47923776 3.65669148,2.0517552 L4.03483481,0.810303513 C4.17932126,0.32979188 4.62146882,0.000617032116 5.12323309,0 C5.62499736,-0.000615299293 6.06795204,0.327472644 6.21361819,0.80762797 Z" id="Path"></path>
|
||||
</g>
|
||||
<polygon id="w/l-chevron" stroke-linejoin="round" transform="translate(20.5, 25.25) rotate(-360) translate(-20.5, -25.25)" points="20.5 26.75 18 24.1184211 18.35 23.75 20.5 26.0131579 22.65 23.75 23 24.1184211"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 3.7 KiB |
@ -145,6 +145,20 @@ import oldTrash from './../../assets/icons/old-trash.svg';
|
||||
import oldPlay from './../../assets/icons/old-play.svg';
|
||||
import oldStop from './../../assets/icons/old-stop.svg';
|
||||
|
||||
/** LAYOUT */
|
||||
|
||||
import layoutAdvanced3DFourUp from './../../assets/icons/layout-advanced-3d-four-up.svg';
|
||||
import layoutAdvanced3DMain from './../../assets/icons/layout-advanced-3d-main.svg';
|
||||
import layoutAdvanced3DOnly from './../../assets/icons/layout-advanced-3d-only.svg';
|
||||
import layoutAdvanced3DPrimary from './../../assets/icons/layout-advanced-3d-primary.svg';
|
||||
import layoutAdvancedAxialPrimary from './../../assets/icons/layout-advanced-axial-primary.svg';
|
||||
import layoutAdvancedMPR from './../../assets/icons/layout-advanced-mpr.svg';
|
||||
import layoutCommon1x1 from './../../assets/icons/layout-common-1x1.svg';
|
||||
import layoutCommon1x2 from './../../assets/icons/layout-common-1x2.svg';
|
||||
import layoutCommon2x2 from './../../assets/icons/layout-common-2x2.svg';
|
||||
import layoutCommon2x3 from './../../assets/icons/layout-common-2x3.svg';
|
||||
import iconToolRotate from './../../assets/icons/tool-3d-rotate.svg';
|
||||
|
||||
/** New investigational use */
|
||||
|
||||
import investigationalUse from './../../assets/icons/illustration-investigational-use.svg';
|
||||
@ -256,6 +270,7 @@ const ICONS = {
|
||||
'tool-freehand-line': toolFreehand,
|
||||
'tool-freehand-polygon': toolFreehandPolygon,
|
||||
'tool-polygon': toolPolygon,
|
||||
'tool-3d-rotate': iconToolRotate,
|
||||
'edit-patient': editPatient,
|
||||
'icon-mpr': iconMPR,
|
||||
'icon-next-inactive': iconNextInactive,
|
||||
@ -295,6 +310,18 @@ const ICONS = {
|
||||
'old-play': oldPlay,
|
||||
'old-stop': oldStop,
|
||||
|
||||
/** LAYOUT */
|
||||
'layout-advanced-3d-four-up': layoutAdvanced3DFourUp,
|
||||
'layout-advanced-3d-main': layoutAdvanced3DMain,
|
||||
'layout-advanced-3d-only': layoutAdvanced3DOnly,
|
||||
'layout-advanced-3d-primary': layoutAdvanced3DPrimary,
|
||||
'layout-advanced-axial-primary': layoutAdvancedAxialPrimary,
|
||||
'layout-advanced-mpr': layoutAdvancedMPR,
|
||||
'layout-common-1x1': layoutCommon1x1,
|
||||
'layout-common-1x2': layoutCommon1x2,
|
||||
'layout-common-2x2': layoutCommon2x2,
|
||||
'layout-common-2x3': layoutCommon2x3,
|
||||
|
||||
/** New investigational use */
|
||||
'illustration-investigational-use': investigationalUse,
|
||||
};
|
||||
|
||||
34
platform/ui/src/components/LayoutPreset/LayoutPreset.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon from '../Icon/Icon';
|
||||
|
||||
function LayoutPreset({ onSelection, title, icon, commandOptions, classNames }) {
|
||||
return (
|
||||
<div
|
||||
className={classNames}
|
||||
onClick={() => {
|
||||
onSelection(commandOptions);
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name={icon}
|
||||
className="group-hover:text-primary-light"
|
||||
/>
|
||||
{title && <div className="font-inter text-sm text-white">{title}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
LayoutPreset.defaultProps = {
|
||||
onSelection: () => {},
|
||||
};
|
||||
|
||||
LayoutPreset.propTypes = {
|
||||
onSelection: PropTypes.func.isRequired,
|
||||
title: PropTypes.string,
|
||||
icon: PropTypes.string.isRequired,
|
||||
commandOptions: PropTypes.object.isRequired,
|
||||
classNames: PropTypes.string,
|
||||
};
|
||||
|
||||
export default LayoutPreset;
|
||||
2
platform/ui/src/components/LayoutPreset/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
import LayoutPreset from './LayoutPreset';
|
||||
export default LayoutPreset;
|
||||
@ -21,7 +21,6 @@ function LayoutSelector({ onSelection, rows, columns }) {
|
||||
gridTemplateRows: gridSize.repeat(rows),
|
||||
backgroundColor: '#090c29', // primary-dark
|
||||
}}
|
||||
className="p-2"
|
||||
>
|
||||
{Array.apply(null, Array(rows * columns))
|
||||
.map(function (_, i) {
|
||||
@ -30,12 +29,8 @@ function LayoutSelector({ onSelection, rows, columns }) {
|
||||
.map(index => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
border: '1px solid white',
|
||||
backgroundColor: isHovered(index) ? '#5acce6' : '#0b1a42',
|
||||
}}
|
||||
className={`border-primary-dark border ${isHovered(index) ? 'bg-primary-active' : 'bg-[#04225b]'} cursor-pointer`}
|
||||
data-cy={`Layout-${index % columns}-${Math.floor(index / columns)}`}
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
const x = index % columns;
|
||||
const y = Math.floor(index / columns);
|
||||
@ -55,7 +50,7 @@ function LayoutSelector({ onSelection, rows, columns }) {
|
||||
|
||||
LayoutSelector.defaultProps = {
|
||||
onSelection: () => {},
|
||||
columns: 3,
|
||||
columns: 4,
|
||||
rows: 3,
|
||||
};
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ const ToolbarButton = ({
|
||||
className,
|
||||
size,
|
||||
toolTipClassName,
|
||||
disableToolTip = false,
|
||||
...rest
|
||||
//
|
||||
}) => {
|
||||
@ -37,6 +38,7 @@ const ToolbarButton = ({
|
||||
content={shouldShowDropdown ? dropdownContent : label}
|
||||
tight={shouldShowDropdown}
|
||||
className={toolTipClassNameToUse}
|
||||
isDisabled={disableToolTip}
|
||||
>
|
||||
<IconButton
|
||||
size={sizeToUse}
|
||||
@ -75,6 +77,7 @@ ToolbarButton.propTypes = {
|
||||
dropdownContent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
||||
size: PropTypes.string,
|
||||
toolTipClassName: PropTypes.string,
|
||||
disableToolTip: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ToolbarButton;
|
||||
|
||||
@ -84,6 +84,7 @@ import { ToolSettings } from './AdvancedToolbox';
|
||||
import { Toolbox } from './Toolbox';
|
||||
import InvestigationalUseDialog from './InvestigationalUseDialog';
|
||||
import MeasurementItem from './MeasurementTable/MeasurementItem';
|
||||
import LayoutPreset from './LayoutPreset';
|
||||
|
||||
export {
|
||||
AboutModal,
|
||||
@ -168,6 +169,7 @@ export {
|
||||
ViewportPane,
|
||||
ViewportOverlay,
|
||||
WindowLevelMenuItem,
|
||||
LayoutPreset,
|
||||
LegacySplitButton,
|
||||
ToolSettings,
|
||||
Toolbox,
|
||||
|
||||
@ -118,6 +118,7 @@ export {
|
||||
Toolbox,
|
||||
InvestigationalUseDialog,
|
||||
MeasurementItem,
|
||||
LayoutPreset,
|
||||
} from './components';
|
||||
|
||||
export { useSessionStorage } from './hooks';
|
||||
|
||||
@ -30,5 +30,5 @@ body {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
user-select: none;
|
||||
opacity: 0.35;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
@ -2403,7 +2403,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
|
||||
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
|
||||
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.0.0", "@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
|
||||
integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
|
||||
|
||||