feat(ui-next): Adds toggle state for ToolButton and Crosshair example (#5914)
Co-authored-by: sedghi <ar.sedghi@gmail.com>
This commit is contained in:
parent
e6816f6de4
commit
691e26731f
@ -145,7 +145,21 @@ function commandsModule({
|
||||
|
||||
function _getActiveViewportToolGroupId() {
|
||||
const viewport = _getActiveViewportEnabledElement();
|
||||
return toolGroupService.getToolGroupForViewport(viewport.id);
|
||||
const toolGroup = viewport && toolGroupService.getToolGroupForViewport(viewport.id);
|
||||
return toolGroup?.id;
|
||||
}
|
||||
|
||||
function _usesPrimaryActivation(bindings) {
|
||||
if (!bindings?.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return bindings.some(
|
||||
binding =>
|
||||
binding.mouseButton === Enums.MouseBindings.Primary &&
|
||||
binding.modifierKey == null &&
|
||||
binding.numTouchPoints == null
|
||||
);
|
||||
}
|
||||
|
||||
function _getActiveSegmentationInfo() {
|
||||
@ -1017,9 +1031,13 @@ function commandsModule({
|
||||
|
||||
toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName);
|
||||
},
|
||||
toggleActiveDisabledToolbar({ value, itemId, toolGroupId }) {
|
||||
toggleActiveDisabledToolbar({ value, itemId, toolGroupId, toolGroupIds }) {
|
||||
const toolName = itemId || value;
|
||||
toolGroupId = toolGroupId ?? _getActiveViewportToolGroupId();
|
||||
const resolvedToolGroupIds = toolGroupIds?.length
|
||||
? toolGroupIds
|
||||
: [toolGroupId ?? _getActiveViewportToolGroupId()];
|
||||
|
||||
resolvedToolGroupIds.forEach(toolGroupId => {
|
||||
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
|
||||
if (!toolGroup || !toolGroup.hasTool(toolName)) {
|
||||
return;
|
||||
@ -1031,18 +1049,30 @@ function commandsModule({
|
||||
Enums.ToolModes.Passive,
|
||||
].includes(toolGroup.getToolOptions(toolName).mode);
|
||||
|
||||
toolIsActive
|
||||
? toolGroup.setToolDisabled(toolName)
|
||||
: actions.setToolActive({ toolName, toolGroupId });
|
||||
if (toolIsActive) {
|
||||
toolGroup.setToolDisabled(toolName);
|
||||
|
||||
const bindings = toolGroupService.getToolBindings(toolGroupId, toolName);
|
||||
|
||||
if (_usesPrimaryActivation(bindings)) {
|
||||
// we should set the previously active tool to active after we set the
|
||||
// current tool disabled
|
||||
if (toolIsActive) {
|
||||
const prevToolName = toolGroup.getPrevActivePrimaryToolName();
|
||||
if (prevToolName !== toolName) {
|
||||
actions.setToolActive({ toolName: prevToolName, toolGroupId });
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const bindings = toolGroupService.getToolBindings(toolGroupId, toolName);
|
||||
if (_usesPrimaryActivation(bindings)) {
|
||||
actions.setToolActive({ toolName, toolGroupId, bindings });
|
||||
} else {
|
||||
toolGroup.setToolActive(toolName, { bindings });
|
||||
}
|
||||
});
|
||||
},
|
||||
setToolActiveToolbar: ({ value, itemId, toolName, toolGroupIds = [], bindings }) => {
|
||||
// Sometimes it is passed as value (tools with options), sometimes as itemId (toolbar buttons)
|
||||
|
||||
@ -429,6 +429,40 @@ export default function getToolbarModule({ servicesManager, extensionManager }:
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'evaluate.cornerstoneTool.toggleWithModifier',
|
||||
evaluate: ({ viewportId, button, disabledText, toggledOnIcon, defaultIcon }) => {
|
||||
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
||||
if (!toolGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toolName = toolbarService.getToolNameForButton(button);
|
||||
if (!toolGroup.hasTool(toolName)) {
|
||||
return getDisabledState(disabledText);
|
||||
}
|
||||
|
||||
const { mode } = toolGroup.getToolOptions(toolName) ?? {};
|
||||
const isToggled =
|
||||
mode === Enums.ToolModes.Passive ||
|
||||
mode === Enums.ToolModes.Active ||
|
||||
mode === Enums.ToolModes.Enabled;
|
||||
|
||||
const toolBindings = toolGroupService.getToolBindings(toolGroup.id, toolName);
|
||||
const hasModifierKey =
|
||||
toolBindings?.some(binding => binding.modifierKey != null) ?? false;
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
isActive: false,
|
||||
isToggled,
|
||||
icon:
|
||||
isToggled && hasModifierKey && toggledOnIcon
|
||||
? toggledOnIcon
|
||||
: defaultIcon ?? button.props.icon,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'evaluate.action',
|
||||
evaluate: () => {
|
||||
|
||||
@ -36,7 +36,9 @@ export default class ToolGroupService {
|
||||
cornerstoneViewportService: any;
|
||||
viewportGridService: any;
|
||||
uiNotificationService: any;
|
||||
customizationService: any;
|
||||
private toolGroupIds: Set<string> = new Set();
|
||||
private toolBindingsMap: Map<string, Map<string, Array<Record<string, unknown>>>> = new Map();
|
||||
/**
|
||||
* Service-specific
|
||||
*/
|
||||
@ -44,11 +46,17 @@ export default class ToolGroupService {
|
||||
EVENTS: { [key: string]: string };
|
||||
|
||||
constructor(servicesManager: AppTypes.ServicesManager) {
|
||||
const { cornerstoneViewportService, viewportGridService, uiNotificationService } =
|
||||
const {
|
||||
cornerstoneViewportService,
|
||||
viewportGridService,
|
||||
uiNotificationService,
|
||||
customizationService,
|
||||
} =
|
||||
servicesManager.services;
|
||||
this.cornerstoneViewportService = cornerstoneViewportService;
|
||||
this.viewportGridService = viewportGridService;
|
||||
this.uiNotificationService = uiNotificationService;
|
||||
this.customizationService = customizationService;
|
||||
this.listeners = {};
|
||||
this.EVENTS = EVENTS;
|
||||
Object.assign(this, pubSubServiceInterface);
|
||||
@ -122,6 +130,7 @@ export default class ToolGroupService {
|
||||
public destroy(): void {
|
||||
ToolGroupManager.destroy();
|
||||
this.toolGroupIds = new Set();
|
||||
this.toolBindingsMap.clear();
|
||||
|
||||
eventTarget.removeEventListener(Enums.Events.TOOL_ACTIVATED, this._onToolActivated);
|
||||
}
|
||||
@ -198,6 +207,7 @@ export default class ToolGroupService {
|
||||
// this.changeConfigurationIfNecessary(toolGroup, volumeId);
|
||||
this._addTools(toolGroup, tools, configs);
|
||||
this._setToolsMode(toolGroup, tools);
|
||||
this._loadPersistedBindings(toolGroupId);
|
||||
}
|
||||
|
||||
public createToolGroupAndAddTools(toolGroupId: string, tools: Array<Tool>): Types.IToolGroup {
|
||||
@ -242,29 +252,92 @@ export default class ToolGroupService {
|
||||
return this.getToolGroup(toolGroupId)?.getActivePrimaryMouseButtonTool();
|
||||
}
|
||||
|
||||
public getToolBindings(
|
||||
toolGroupId: string,
|
||||
toolName: string
|
||||
): Array<Record<string, unknown>> | undefined {
|
||||
return this.toolBindingsMap.get(toolGroupId)?.get(toolName);
|
||||
}
|
||||
|
||||
public setToolBindings(
|
||||
toolGroupId: string,
|
||||
toolName: string,
|
||||
bindings: Array<Record<string, unknown>>
|
||||
): void {
|
||||
if (!this.toolBindingsMap.has(toolGroupId)) {
|
||||
this.toolBindingsMap.set(toolGroupId, new Map());
|
||||
}
|
||||
this.toolBindingsMap.get(toolGroupId).set(toolName, bindings);
|
||||
}
|
||||
|
||||
public applyToolBindings(toolGroupId: string, toolName: string): void {
|
||||
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);
|
||||
if (!toolGroup || !toolGroup.hasTool(toolName)) {
|
||||
return;
|
||||
}
|
||||
const bindings = this.getToolBindings(toolGroupId, toolName);
|
||||
if (!bindings) {
|
||||
return;
|
||||
}
|
||||
const { mode } = toolGroup.getToolOptions(toolName);
|
||||
if (
|
||||
mode === Enums.ToolModes.Active ||
|
||||
mode === Enums.ToolModes.Passive ||
|
||||
mode === Enums.ToolModes.Enabled
|
||||
) {
|
||||
toolGroup.setToolActive(toolName, { bindings });
|
||||
}
|
||||
}
|
||||
|
||||
public getAllToolBindings(): Array<{
|
||||
toolGroupId: string;
|
||||
toolName: string;
|
||||
bindings: Array<Record<string, unknown>>;
|
||||
}> {
|
||||
const result = [];
|
||||
for (const [toolGroupId, toolMap] of this.toolBindingsMap) {
|
||||
for (const [toolName, bindings] of toolMap) {
|
||||
result.push({ toolGroupId, toolName, bindings });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private _setToolsMode(toolGroup, tools) {
|
||||
const { active, passive, enabled, disabled } = tools;
|
||||
|
||||
if (active) {
|
||||
active.forEach(({ toolName, bindings }) => {
|
||||
if (bindings) {
|
||||
this.setToolBindings(toolGroup.id, toolName, bindings);
|
||||
}
|
||||
toolGroup.setToolActive(toolName, { bindings });
|
||||
});
|
||||
}
|
||||
|
||||
if (passive) {
|
||||
passive.forEach(({ toolName }) => {
|
||||
passive.forEach(({ toolName, bindings }) => {
|
||||
if (bindings) {
|
||||
this.setToolBindings(toolGroup.id, toolName, bindings);
|
||||
}
|
||||
toolGroup.setToolPassive(toolName);
|
||||
});
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
enabled.forEach(({ toolName }) => {
|
||||
enabled.forEach(({ toolName, bindings }) => {
|
||||
if (bindings) {
|
||||
this.setToolBindings(toolGroup.id, toolName, bindings);
|
||||
}
|
||||
toolGroup.setToolEnabled(toolName);
|
||||
});
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
disabled.forEach(({ toolName }) => {
|
||||
disabled.forEach(({ toolName, bindings }) => {
|
||||
if (bindings) {
|
||||
this.setToolBindings(toolGroup.id, toolName, bindings);
|
||||
}
|
||||
toolGroup.setToolDisabled(toolName);
|
||||
});
|
||||
}
|
||||
@ -300,6 +373,35 @@ export default class ToolGroupService {
|
||||
}
|
||||
}
|
||||
|
||||
private _loadPersistedBindings(toolGroupId: string): void {
|
||||
try {
|
||||
const stored = localStorage.getItem(this._getToolBindingsStorageKey());
|
||||
if (!stored) {
|
||||
return;
|
||||
}
|
||||
const parsed = JSON.parse(stored);
|
||||
const toolGroupBindings = parsed[toolGroupId];
|
||||
if (!toolGroupBindings) {
|
||||
return;
|
||||
}
|
||||
for (const [toolName, bindings] of Object.entries(toolGroupBindings)) {
|
||||
this.setToolBindings(toolGroupId, toolName, bindings as Array<Record<string, unknown>>);
|
||||
}
|
||||
} catch {
|
||||
// ignore corrupt localStorage
|
||||
}
|
||||
}
|
||||
|
||||
private _getToolBindingsStorageKey(): string {
|
||||
const customizationValue = this.customizationService?.getCustomization(
|
||||
'ohif.userPreferences.toolBindingsStorageKey'
|
||||
);
|
||||
|
||||
return typeof customizationValue === 'string' && customizationValue.length > 0
|
||||
? customizationValue
|
||||
: 'user-preferred-tool-bindings';
|
||||
}
|
||||
|
||||
private _onToolActivated = (evt: Types.EventTypes.ToolActivatedEventType) => {
|
||||
const { toolGroupId, toolName, toolBindingsOptions } = evt.detail;
|
||||
const isPrimaryTool = toolBindingsOptions.bindings?.some(
|
||||
|
||||
@ -17,9 +17,46 @@ interface HotkeyDefinitions {
|
||||
[key: string]: HotkeyDefinition;
|
||||
}
|
||||
|
||||
const MODIFIER_OPTIONS = [
|
||||
{ value: '16', label: 'Shift' },
|
||||
{ value: '17', label: 'Ctrl' },
|
||||
{ value: '18', label: 'Alt' },
|
||||
{ value: '91', label: 'Meta' },
|
||||
];
|
||||
|
||||
const DEFAULT_TOOL_BINDINGS_STORAGE_KEY = 'user-preferred-tool-bindings';
|
||||
|
||||
function getToolBindingsStorageKey(customizationService: any): string {
|
||||
const customizationValue = customizationService?.getCustomization(
|
||||
'ohif.userPreferences.toolBindingsStorageKey'
|
||||
);
|
||||
|
||||
return typeof customizationValue === 'string' && customizationValue.length > 0
|
||||
? customizationValue
|
||||
: DEFAULT_TOOL_BINDINGS_STORAGE_KEY;
|
||||
}
|
||||
|
||||
function getToolModifier(toolGroupService: any, toolGroupId: string, toolName: string): string | null {
|
||||
if (!toolGroupService) {
|
||||
return null;
|
||||
}
|
||||
const bindings = toolGroupService.getToolBindings(toolGroupId, toolName);
|
||||
if (!bindings?.length) {
|
||||
return null;
|
||||
}
|
||||
const modifierBinding = bindings.find(
|
||||
binding => binding.modifierKey != null && binding.numTouchPoints == null
|
||||
);
|
||||
|
||||
return modifierBinding?.modifierKey != null ? String(modifierBinding.modifierKey) : null;
|
||||
}
|
||||
|
||||
function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
const { hotkeysManager } = useSystem();
|
||||
const { hotkeysManager, servicesManager } = useSystem();
|
||||
const { t, i18n: i18nextInstance } = useTranslation('UserPreferencesModal');
|
||||
const toolGroupService = (servicesManager as any)?.services?.toolGroupService;
|
||||
const customizationService = (servicesManager as any)?.services?.customizationService;
|
||||
const toolBindingsStorageKey = getToolBindingsStorageKey(customizationService);
|
||||
|
||||
const { hotkeyDefinitions = {}, hotkeyDefaults = {} } = hotkeysManager;
|
||||
|
||||
@ -51,9 +88,15 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
|
||||
const currentLanguage = currentLanguageFn();
|
||||
|
||||
const initialCrosshairModifier = useMemo(
|
||||
() => getToolModifier(toolGroupService, 'mpr', 'Crosshairs'),
|
||||
[toolGroupService]
|
||||
);
|
||||
|
||||
const [state, setState] = useState({
|
||||
hotkeyDefinitions: initialHotkeyDefinitions,
|
||||
languageValue: currentLanguage.value,
|
||||
crosshairModifier: initialCrosshairModifier,
|
||||
});
|
||||
|
||||
const onLanguageChangeHandler = (value: string) => {
|
||||
@ -78,9 +121,11 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
...state,
|
||||
languageValue: defaultLanguage.value,
|
||||
hotkeyDefinitions: resolvedHotkeyDefaults,
|
||||
crosshairModifier: initialCrosshairModifier,
|
||||
}));
|
||||
|
||||
hotkeysManager.restoreDefaultBindings();
|
||||
localStorage.removeItem(toolBindingsStorageKey);
|
||||
};
|
||||
|
||||
const displayNames = React.useMemo(() => {
|
||||
@ -165,6 +210,44 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
/>
|
||||
))}
|
||||
</UserPreferencesModal.HotkeysGrid>
|
||||
|
||||
{state.crosshairModifier != null && (
|
||||
<>
|
||||
<UserPreferencesModal.SubHeading>
|
||||
{t('ModifierKeys', { defaultValue: 'Modifier Keys' })}
|
||||
</UserPreferencesModal.SubHeading>
|
||||
<UserPreferencesModal.HotkeysGrid>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-foreground text-base">
|
||||
{t('CrosshairsModifier', { defaultValue: 'Crosshairs' })}
|
||||
</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-muted-foreground text-sm">
|
||||
{t('PlusLeftClick', { defaultValue: 'Left Click +' })}
|
||||
</span>
|
||||
<Select
|
||||
value={state.crosshairModifier}
|
||||
onValueChange={val => setState(s => ({ ...s, crosshairModifier: val }))}
|
||||
>
|
||||
<SelectTrigger className="w-16">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{MODIFIER_OPTIONS.map(opt => (
|
||||
<SelectItem
|
||||
key={opt.value}
|
||||
value={opt.value}
|
||||
>
|
||||
{opt.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</UserPreferencesModal.HotkeysGrid>
|
||||
</>
|
||||
)}
|
||||
</UserPreferencesModal.Body>
|
||||
<FooterAction>
|
||||
<FooterAction.Left>
|
||||
@ -191,6 +274,19 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
return; // Exit early since we're reloading
|
||||
}
|
||||
hotkeysManager.setHotkeys(state.hotkeyDefinitions);
|
||||
|
||||
if (toolGroupService && state.crosshairModifier != null) {
|
||||
const bindings = [
|
||||
{ mouseButton: 1, modifierKey: Number(state.crosshairModifier) },
|
||||
];
|
||||
toolGroupService.setToolBindings('mpr', 'Crosshairs', bindings);
|
||||
toolGroupService.applyToolBindings('mpr', 'Crosshairs');
|
||||
localStorage.setItem(
|
||||
toolBindingsStorageKey,
|
||||
JSON.stringify({ mpr: { Crosshairs: bindings } })
|
||||
);
|
||||
}
|
||||
|
||||
hotkeysModule.stopRecord();
|
||||
hotkeysModule.unpause();
|
||||
hide();
|
||||
@ -206,4 +302,5 @@ function UserPreferencesModalDefault({ hide }: { hide: () => void }) {
|
||||
|
||||
export default {
|
||||
'ohif.userPreferencesModal': UserPreferencesModalDefault,
|
||||
'ohif.userPreferences.toolBindingsStorageKey': DEFAULT_TOOL_BINDINGS_STORAGE_KEY,
|
||||
};
|
||||
|
||||
@ -239,6 +239,9 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
||||
disabled: [
|
||||
{
|
||||
toolName: toolNames.Crosshairs,
|
||||
bindings: [
|
||||
{ mouseButton: Enums.MouseBindings.Primary, modifierKey: Enums.KeyboardBindings.Shift },
|
||||
],
|
||||
configuration: {
|
||||
viewportIndicators: true,
|
||||
viewportIndicatorsConfig: {
|
||||
@ -246,7 +249,6 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
||||
xOffset: 0.95,
|
||||
yOffset: 0.05,
|
||||
},
|
||||
disableOnPassive: true,
|
||||
autoPan: {
|
||||
enabled: false,
|
||||
panSize: 10,
|
||||
|
||||
@ -647,15 +647,18 @@ const toolbarButtons: Button[] = [
|
||||
type: 'tool',
|
||||
icon: 'tool-crosshair',
|
||||
label: i18n.t('Buttons:Crosshairs'),
|
||||
tooltip: i18n.t('Buttons:Click to toggle on or off'),
|
||||
commands: {
|
||||
commandName: 'setToolActiveToolbar',
|
||||
commandName: 'toggleActiveDisabledToolbar',
|
||||
commandOptions: {
|
||||
toolGroupIds: ['mpr'],
|
||||
},
|
||||
},
|
||||
evaluate: {
|
||||
name: 'evaluate.cornerstoneTool',
|
||||
name: 'evaluate.cornerstoneTool.toggleWithModifier',
|
||||
disabledText: i18n.t('Buttons:Select an MPR viewport to enable this tool'),
|
||||
toggledOnIcon: 'tool-crosshair-checked',
|
||||
defaultIcon: 'tool-crosshair',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -133,6 +133,9 @@ function _initToolGroups(toolNames, Enums, toolGroupService, commandsManager) {
|
||||
disabled: [
|
||||
{
|
||||
toolName: toolNames.Crosshairs,
|
||||
bindings: [
|
||||
{ mouseButton: Enums.MouseBindings.Primary, modifierKey: Enums.KeyboardBindings.Shift },
|
||||
],
|
||||
configuration: {
|
||||
disableOnPassive: true,
|
||||
autoPan: {
|
||||
|
||||
@ -99,6 +99,7 @@ import {
|
||||
ToolCobbAngle,
|
||||
ToolCreateThreshold,
|
||||
ToolCrosshair,
|
||||
ToolCrosshairChecked,
|
||||
ToolDicomTagBrowser,
|
||||
ToolFlipHorizontal,
|
||||
ToolFreehandPolygon,
|
||||
@ -436,6 +437,7 @@ export const Icons = {
|
||||
ToolCobbAngle,
|
||||
ToolCreateThreshold,
|
||||
ToolCrosshair,
|
||||
ToolCrosshairChecked,
|
||||
ToolDicomTagBrowser,
|
||||
ToolFlipHorizontal,
|
||||
ToolFreehandPolygon,
|
||||
@ -703,6 +705,7 @@ export const Icons = {
|
||||
'tool-cobb-angle': (props: IconProps) => ToolCobbAngle(props),
|
||||
'tool-create-threshold': (props: IconProps) => ToolCreateThreshold(props),
|
||||
'tool-crosshair': (props: IconProps) => ToolCrosshair(props),
|
||||
'tool-crosshair-checked': (props: IconProps) => ToolCrosshairChecked(props),
|
||||
'dicom-tag-browser': (props: IconProps) => ToolDicomTagBrowser(props),
|
||||
'tool-flip-horizontal': (props: IconProps) => ToolFlipHorizontal(props),
|
||||
'tool-freehand-polygon': (props: IconProps) => ToolFreehandPolygon(props),
|
||||
|
||||
@ -930,6 +930,68 @@ export const ToolCrosshair = (props: IconProps) => (
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ToolCrosshairChecked = (props: IconProps) => (
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
viewBox="0 0 28 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<g clipPath="url(#clip0_tool_crosshair_checked)">
|
||||
<path
|
||||
d="M14 3V9"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M3 14H9"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M14 25V19"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M25 14H19"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M14.001 16.001C15.1056 16.001 16.001 15.1056 16.001 14.001C16.001 12.8964 15.1056 12.001 14.001 12.001C12.8964 12.001 12.001 12.8964 12.001 14.001C12.001 15.1056 12.8964 16.001 14.001 16.001Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M22 17C24.7614 17 27 19.2386 27 22C27 24.7614 24.7614 27 22 27C19.2386 27 17 24.7614 17 22C17 19.2386 19.2386 17 22 17ZM24.7998 19.7998C24.5789 19.6344 24.2652 19.6796 24.0996 19.9004L21.4453 23.4385L19.8535 21.8467C19.6583 21.6514 19.3417 21.6514 19.1465 21.8467C18.9513 22.0419 18.9513 22.3585 19.1465 22.5537L21.1465 24.5537C21.2489 24.6561 21.3907 24.7094 21.5352 24.6992C21.6797 24.6889 21.8134 24.6159 21.9004 24.5L24.9004 20.5C25.0658 20.2791 25.0205 19.9654 24.7998 19.7998Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_tool_crosshair_checked">
|
||||
<rect
|
||||
width="28"
|
||||
height="28"
|
||||
fill="white"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ToolDicomTagBrowser = (props: IconProps) => (
|
||||
<svg
|
||||
width="28px"
|
||||
|
||||
@ -8,6 +8,7 @@ import { useIconPresentation } from '../../contextProviders/IconPresentationProv
|
||||
const baseClasses = '!rounded-lg inline-flex items-center justify-center';
|
||||
const defaultClasses = 'bg-transparent text-foreground/80 hover:bg-background hover:text-highlight';
|
||||
const activeClasses = 'bg-highlight text-background hover:!bg-highlight/80';
|
||||
const toggledClasses = 'bg-transparent text-highlight hover:bg-muted';
|
||||
const disabledClasses =
|
||||
'text-foreground hover:bg-muted hover:text-highlight opacity-40 cursor-not-allowed';
|
||||
|
||||
@ -33,6 +34,7 @@ interface ToolButtonProps {
|
||||
tooltip?: string;
|
||||
size?: 'default' | 'small';
|
||||
isActive?: boolean;
|
||||
isToggled?: boolean;
|
||||
disabled?: boolean;
|
||||
disabledText?: string;
|
||||
commands?: Record<string, unknown>;
|
||||
@ -50,6 +52,7 @@ function ToolButton(props: ToolButtonProps) {
|
||||
size = 'default',
|
||||
disabled = false,
|
||||
isActive = false,
|
||||
isToggled = false,
|
||||
disabledText,
|
||||
commands,
|
||||
onInteraction,
|
||||
@ -63,7 +66,7 @@ function ToolButton(props: ToolButtonProps) {
|
||||
const buttonClasses = cn(
|
||||
baseClasses,
|
||||
buttonSizeClass,
|
||||
disabled ? disabledClasses : isActive ? activeClasses : defaultClasses,
|
||||
disabled ? disabledClasses : isActive ? activeClasses : isToggled ? toggledClasses : defaultClasses,
|
||||
className
|
||||
);
|
||||
|
||||
@ -85,6 +88,7 @@ function ToolButton(props: ToolButtonProps) {
|
||||
data-cy={id}
|
||||
data-tool={id}
|
||||
data-active={isActive}
|
||||
data-toggled={isToggled}
|
||||
>
|
||||
<Button
|
||||
className={buttonClasses}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user