diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx index f7a84eecc64e..8114c3b73ded 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx @@ -89,6 +89,30 @@ const componentShortcuts = { sequences: ['shift+n'], scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, }, + SWITCH_GROUP_MODE_STANDARD_CONTROLS: { + name: 'Group mode', + description: 'Activate or deactivate mode to grouping shapes', + sequences: ['g'], + scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, + }, + RESET_GROUP_STANDARD_CONTROLS: { + name: 'Reset group', + description: 'Reset group for selected shapes (in group mode)', + sequences: ['shift+g'], + scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, + }, + SWITCH_MERGE_MODE_STANDARD_CONTROLS: { + name: 'Merge mode', + description: 'Activate or deactivate mode to merging shapes', + sequences: ['m'], + scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, + }, + SWITCH_SPLIT_MODE_STANDARD_CONTROLS: { + name: 'Split mode', + description: 'Activate or deactivate mode to splitting shapes', + sequences: ['alt+m'], + scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, + }, }; registerComponentShortcuts(componentShortcuts); @@ -161,6 +185,58 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { } }; + const dynamicMergeIconProps = + activeControl === ActiveControl.MERGE ? + { + className: 'cvat-merge-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.merge({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + } : + { + className: 'cvat-merge-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.merge({ enabled: true }); + updateActiveControl(ActiveControl.MERGE); + }, + }; + + const dynamicGroupIconProps = + activeControl === ActiveControl.GROUP ? + { + className: 'cvat-group-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.group({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + } : + { + className: 'cvat-group-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.group({ enabled: true }); + updateActiveControl(ActiveControl.GROUP); + }, + }; + + const dynamicTrackIconProps = activeControl === ActiveControl.SPLIT ? + { + className: 'cvat-split-track-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.split({ enabled: false }); + }, + } : + { + className: 'cvat-split-track-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.split({ enabled: true }); + updateActiveControl(ActiveControl.SPLIT); + }, + }; + let handlers: Partial void>> = { CLOCKWISE_ROTATION_STANDARD_CONTROLS: (event: KeyboardEvent | undefined) => { preventDefault(event); @@ -170,6 +246,28 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { preventDefault(event); rotateFrame(Rotation.ANTICLOCKWISE90); }, + SWITCH_GROUP_MODE_STANDARD_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + dynamicGroupIconProps.onClick(); + }, + RESET_GROUP_STANDARD_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + const grouping = activeControl === ActiveControl.GROUP; + if (!grouping) { + return; + } + resetGroup(); + canvasInstance.group({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + SWITCH_MERGE_MODE_STANDARD_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + dynamicMergeIconProps.onClick(); + }, + SWITCH_SPLIT_MODE_STANDARD_CONTROLS: (event: KeyboardEvent | undefined) => { + if (event) event.preventDefault(); + dynamicTrackIconProps.onClick(); + }, }; const handleDrawMode = (event: KeyboardEvent | undefined, action: 'draw' | 'redraw'): void => { @@ -339,22 +437,18 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {
; + canvasInstance: Canvas | Canvas3d; } -const componentShortcuts = { - SWITCH_GROUP_MODE_STANDARD_CONTROLS: { - name: 'Group mode', - description: 'Activate or deactivate mode to grouping shapes', - sequences: ['g'], - scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, - }, - RESET_GROUP_STANDARD_CONTROLS: { - name: 'Reset group', - description: 'Reset group for selected shapes (in group mode)', - sequences: ['shift+g'], - scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, - }, - SWITCH_GROUP_MODE_STANDARD_3D_CONTROLS: { - name: 'Group mode', - description: 'Activate or deactivate mode to grouping shapes', - sequences: ['g'], - scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], - }, - RESET_GROUP_STANDARD_3D_CONTROLS: { - name: 'Reset group', - description: 'Reset group for selected shapes (in group mode)', - sequences: ['shift+g'], - scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], - }, -}; - -registerComponentShortcuts(componentShortcuts); - function GroupControl(props: Props): JSX.Element { const { - updateActiveControl, - resetGroup, - activeControl, - canvasInstance, disabled, + dynamicIconProps, + canvasInstance, } = props; - const { keyMap, normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); - - const dynamicIconProps = - activeControl === ActiveControl.GROUP ? - { - className: 'cvat-group-control cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.group({ enabled: false }); - updateActiveControl(ActiveControl.CURSOR); - }, - } : - { - className: 'cvat-group-control', - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.group({ enabled: true }); - updateActiveControl(ActiveControl.GROUP); - }, - }; - - const handleSwitchGroupMode = (event: KeyboardEvent | undefined): void => { - if (event) event.preventDefault(); - dynamicIconProps.onClick(); - }; - - const handleResetGroup = (event: KeyboardEvent | undefined): void => { - if (event) event.preventDefault(); - const grouping = activeControl === ActiveControl.GROUP; - if (!grouping) { - return; - } - resetGroup(); - canvasInstance.group({ enabled: false }); - updateActiveControl(ActiveControl.CURSOR); - }; - - const handlers: Partial void>> = { - SWITCH_GROUP_MODE_STANDARD_CONTROLS: handleSwitchGroupMode, - RESET_GROUP_STANDARD_CONTROLS: handleResetGroup, - SWITCH_GROUP_MODE_STANDARD_3D_CONTROLS: handleSwitchGroupMode, - RESET_GROUP_STANDARD_3D_CONTROLS: handleResetGroup, - }; + const { normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); - const title = [ - `Group shapes/tracks ${normalizedKeyMap.SWITCH_GROUP_MODE_STANDARD_CONTROLS}`, - `Select and press ${normalizedKeyMap.RESET_GROUP_STANDARD_CONTROLS} to reset a group.`, - ].join(' '); + const title = []; + if (canvasInstance instanceof Canvas) { + title.push(`Group shapes ${normalizedKeyMap.SWITCH_GROUP_MODE_STANDARD_CONTROLS}`); + title.push(`Select and press ${normalizedKeyMap.RESET_GROUP_STANDARD_CONTROLS} to reset a group.`); + } else if (canvasInstance instanceof Canvas3d) { + title.push(`Group shapes/tracks ${normalizedKeyMap.SWITCH_GROUP_MODE_STANDARD_3D_CONTROLS}`); + title.push(`Select and press ${normalizedKeyMap.RESET_GROUP_STANDARD_3D_CONTROLS} to reset a group.`); + } return disabled ? ( ) : ( - <> - - - - - + + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx index e1ea80e3a882..3252d12954a1 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx @@ -7,87 +7,39 @@ import React from 'react'; import Icon from '@ant-design/icons'; import { MergeIcon } from 'icons'; -import { Canvas } from 'cvat-canvas-wrapper'; -import { Canvas3d } from 'cvat-canvas3d-wrapper'; -import { ActiveControl, CombinedState } from 'reducers'; +import { CombinedState } from 'reducers'; import CVATTooltip from 'components/common/cvat-tooltip'; -import GlobalHotKeys from 'utils/mousetrap-react'; -import { registerComponentShortcuts } from 'actions/shortcuts-actions'; -import { ShortcutScope } from 'utils/enums'; import { useSelector } from 'react-redux'; -import { subKeyMap } from 'utils/component-subkeymap'; +import { Canvas3d } from 'cvat-canvas3d-wrapper'; +import { Canvas } from 'cvat-canvas-wrapper'; export interface Props { - updateActiveControl(activeControl: ActiveControl): void; - canvasInstance: Canvas | Canvas3d; - activeControl: ActiveControl; disabled?: boolean; + dynamicIconProps: Record; + canvasInstance: Canvas | Canvas3d; } -const componentShortcuts = { - SWITCH_MERGE_MODE_STANDARD_CONTROLS: { - name: 'Merge mode', - description: 'Activate or deactivate mode to merging shapes', - sequences: ['m'], - scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, - }, - SWITCH_MERGE_MODE_STANDARD_3D_CONTROLS: { - name: 'Merge mode', - description: 'Activate or deactivate mode to merging shapes', - sequences: ['m'], - scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], - }, -}; - -registerComponentShortcuts(componentShortcuts); - function MergeControl(props: Props): JSX.Element { const { - activeControl, canvasInstance, updateActiveControl, disabled, + disabled, + dynamicIconProps, + canvasInstance, } = props; - const { keyMap, normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); - - const dynamicIconProps = - activeControl === ActiveControl.MERGE ? - { - className: 'cvat-merge-control cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.merge({ enabled: false }); - updateActiveControl(ActiveControl.CURSOR); - }, - } : - { - className: 'cvat-merge-control', - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.merge({ enabled: true }); - updateActiveControl(ActiveControl.MERGE); - }, - }; - - const handleMergeMode = (event: KeyboardEvent | undefined): void => { - if (event) event.preventDefault(); - dynamicIconProps.onClick(); - }; - - const handlers: Partial void>> = { - SWITCH_MERGE_MODE_STANDARD_CONTROLS: handleMergeMode, - SWITCH_MERGE_MODE_STANDARD_3D_CONTROLS: handleMergeMode, - }; + const { normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); return disabled ? ( ) : ( - <> - - - - - + + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx index e01eca5c0da8..11b68adbf979 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx @@ -9,74 +9,38 @@ import Icon from '@ant-design/icons'; import { SplitIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { Canvas3d } from 'cvat-canvas3d-wrapper'; -import { ActiveControl, CombinedState } from 'reducers'; +import { CombinedState } from 'reducers'; import CVATTooltip from 'components/common/cvat-tooltip'; -import GlobalHotKeys from 'utils/mousetrap-react'; -import { registerComponentShortcuts } from 'actions/shortcuts-actions'; -import { ShortcutScope } from 'utils/enums'; import { useSelector } from 'react-redux'; -import { subKeyMap } from 'utils/component-subkeymap'; export interface Props { - updateActiveControl(activeControl: ActiveControl): void; canvasInstance: Canvas | Canvas3d; - activeControl: ActiveControl; + dynamicIconProps: Record; disabled?: boolean; } -const componentShortcuts = { - SWITCH_SPLIT_MODE_STANDARD_CONTROLS: { - name: 'Split mode', - description: 'Activate or deactivate mode to splitting shapes', - sequences: ['alt+m'], - scope: ShortcutScope.STANDARD_WORKSPACE_CONTROLS, - }, -}; - -registerComponentShortcuts(componentShortcuts); - function SplitControl(props: Props): JSX.Element { const { - activeControl, canvasInstance, updateActiveControl, disabled, + dynamicIconProps, + canvasInstance, + disabled, } = props; - const { keyMap, normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); - - const dynamicIconProps = activeControl === ActiveControl.SPLIT ? - { - className: 'cvat-split-track-control cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.split({ enabled: false }); - }, - } : - { - className: 'cvat-split-track-control', - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.split({ enabled: true }); - updateActiveControl(ActiveControl.SPLIT); - }, - }; - - const handlers: Record void> = { - SWITCH_SPLIT_MODE_STANDARD_CONTROLS: (event: KeyboardEvent | undefined) => { - if (event) event.preventDefault(); - dynamicIconProps.onClick(); - }, - }; + const { normalizedKeyMap } = useSelector((state: CombinedState) => state.shortcuts); return disabled ? ( ) : ( - <> - - - - - + + + ); } diff --git a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/controls-side-bar.tsx index 4f883df658a5..640017fd30f4 100644 --- a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/controls-side-bar.tsx @@ -67,6 +67,30 @@ const componentShortcuts: Record = { sequences: ['shift+n'], scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], }, + SWITCH_GROUP_MODE_STANDARD_3D_CONTROLS: { + name: 'Group mode', + description: 'Activate or deactivate mode to grouping shapes', + sequences: ['g'], + scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], + }, + RESET_GROUP_STANDARD_3D_CONTROLS: { + name: 'Reset group', + description: 'Reset group for selected shapes (in group mode)', + sequences: ['shift+g'], + scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], + }, + SWITCH_MERGE_MODE_STANDARD_3D_CONTROLS: { + name: 'Merge mode', + description: 'Activate or deactivate mode to merging shapes', + sequences: ['m'], + scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], + }, + SWITCH_SPLIT_MODE_STANDARD_3D_CONTROLS: { + name: 'Split mode', + description: 'Activate or deactivate mode to splitting shapes', + sequences: ['alt+m'], + scope: ShortcutScope['3D_ANNOTATION_WORKSPACE_CONTROLS'], + }, }; registerComponentShortcuts(componentShortcuts); @@ -114,7 +138,85 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { } }; - const handlers: any = applicableLabels.length ? { + const dynamicMergeIconProps = + activeControl === ActiveControl.MERGE ? + { + className: 'cvat-merge-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.merge({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + } : + { + className: 'cvat-merge-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.merge({ enabled: true }); + updateActiveControl(ActiveControl.MERGE); + }, + }; + + const dynamicGroupIconProps = + activeControl === ActiveControl.GROUP ? + { + className: 'cvat-group-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.group({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + } : + { + className: 'cvat-group-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.group({ enabled: true }); + updateActiveControl(ActiveControl.GROUP); + }, + }; + + const dynamicTrackIconProps = activeControl === ActiveControl.SPLIT ? + { + className: 'cvat-split-track-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.split({ enabled: false }); + }, + } : + { + className: 'cvat-split-track-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.split({ enabled: true }); + updateActiveControl(ActiveControl.SPLIT); + }, + }; + + let handlers: any = { + SWITCH_GROUP_MODE_STANDARD_3D_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + dynamicGroupIconProps.onClick(); + }, + RESET_GROUP_STANDARD_3D_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + const grouping = activeControl === ActiveControl.GROUP; + if (!grouping) { + return; + } + resetGroup(); + canvasInstance.group({ enabled: false }); + updateActiveControl(ActiveControl.CURSOR); + }, + SWITCH_MERGE_MODE_STANDARD_3D_CONTROLS: (event: KeyboardEvent | undefined): void => { + if (event) event.preventDefault(); + dynamicMergeIconProps.onClick(); + }, + SWITCH_SPLIT_MODE_STANDARD_3D_CONTROLS: (event: KeyboardEvent | undefined) => { + if (event) event.preventDefault(); + dynamicTrackIconProps.onClick(); + }, + }; + + handlers = applicableLabels.length ? { + ...handlers, PASTE_SHAPE: (event: KeyboardEvent | undefined) => { preventDefault(event); canvasInstance.cancel(); @@ -126,7 +228,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { SWITCH_REDRAW_MODE_STANDARD_3D_CONTROLS: (event: KeyboardEvent | undefined) => { handleDrawMode(event, 'redraw'); }, - } : {}; + } : { ...handlers }; const controlsDisabled = !applicableLabels.length; return ( @@ -150,22 +252,18 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {