Shortcuts keymaps moved to state

main
Boris Sekachev 6 years ago
parent e7808cfb03
commit ece8a7e18b

@ -32,6 +32,7 @@ interface StateToProps {
states: any[]; states: any[];
labels: any[]; labels: any[];
jobInstance: any; jobInstance: any;
keyMap: KeyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -56,6 +57,9 @@ function mapStateToProps(state: CombinedState): StateToProps {
labels, labels,
}, },
}, },
shortcuts: {
keyMap,
},
} = state; } = state;
return { return {
@ -64,6 +68,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
activatedStateID, activatedStateID,
activatedAttributeID, activatedAttributeID,
states, states,
keyMap,
}; };
} }
@ -87,6 +92,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
jobInstance, jobInstance,
updateAnnotations, updateAnnotations,
activateObject, activateObject,
keyMap,
} = props; } = props;
const [labelAttrMap, setLabelAttrMap] = useState( const [labelAttrMap, setLabelAttrMap] = useState(
@ -167,31 +173,11 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
trigger: null, trigger: null,
}; };
const keyMap = { const subKeyMap = {
NEXT_ATTRIBUTE: { NEXT_ATTRIBUTE: keyMap.NEXT_ATTRIBUTE,
name: 'Next attribute', PREVIOUS_ATTRIBUTE: keyMap.PREVIOUS_ATTRIBUTE,
description: 'Go to the next attribute', NEXT_OBJECT: keyMap.NEXT_OBJECT,
sequence: 'ArrowDown', PREVIOUS_OBJECT: keyMap.PREVIOUS_OBJECT,
action: 'keydown',
},
PREVIOUS_ATTRIBUTE: {
name: 'Previous attribute',
description: 'Go to the previous attribute',
sequence: 'ArrowUp',
action: 'keydown',
},
NEXT_OBJECT: {
name: 'Next object',
description: 'Go to the next object',
sequence: 'Tab',
action: 'keydown',
},
PREVIOUS_OBJECT: {
name: 'Previous object',
description: 'Go to the previous object',
sequence: 'Shift+Tab',
action: 'keydown',
},
}; };
const handlers = { const handlers = {
@ -228,7 +214,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
if (activeObjectState) { if (activeObjectState) {
return ( return (
<Layout.Sider {...siderProps}> <Layout.Sider {...siderProps}>
<GlobalHotKeys keyMap={keyMap as any as KeyMap} handlers={handlers} allowChanges /> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
<Row> <Row>
<Col> <Col>
<AnnotationsFiltersInput /> <AnnotationsFiltersInput />

@ -59,6 +59,7 @@ interface Props {
contextType: ContextMenuType; contextType: ContextMenuType;
aamZoomMargin: number; aamZoomMargin: number;
workspace: Workspace; workspace: Workspace;
keyMap: KeyMap;
onSetupCanvas: () => void; onSetupCanvas: () => void;
onDragCanvas: (enabled: boolean) => void; onDragCanvas: (enabled: boolean) => void;
onZoomCanvas: (enabled: boolean) => void; onZoomCanvas: (enabled: boolean) => void;
@ -683,6 +684,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
onChangeGridColor, onChangeGridColor,
onChangeGridOpacity, onChangeGridOpacity,
onSwitchGrid, onSwitchGrid,
keyMap,
} = this.props; } = this.props;
const preventDefault = (event: KeyboardEvent | undefined): void => { const preventDefault = (event: KeyboardEvent | undefined): void => {
@ -691,61 +693,16 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
} }
}; };
const keyMap = { const subKeyMap = {
INCREASE_BRIGHTNESS: { INCREASE_BRIGHTNESS: keyMap.INCREASE_BRIGHTNESS,
name: 'Brightness+', DECREASE_BRIGHTNESS: keyMap.DECREASE_BRIGHTNESS,
description: 'Increase brightness level for the image', INCREASE_CONTRAST: keyMap.INCREASE_CONTRAST,
sequence: 'shift+b+=', DECREASE_CONTRAST: keyMap.DECREASE_CONTRAST,
action: 'keypress', INCREASE_SATURATION: keyMap.INCREASE_SATURATION,
}, DECREASE_SATURATION: keyMap.DECREASE_SATURATION,
DECREASE_BRIGHTNESS: { INCREASE_GRID_OPACITY: keyMap.INCREASE_GRID_OPACITY,
name: 'Brightness-', DECREASE_GRID_OPACITY: keyMap.DECREASE_GRID_OPACITY,
description: 'Decrease brightness level for the image', CHANGE_GRID_COLOR: keyMap.CHANGE_GRID_COLOR,
sequence: 'shift+b+-',
action: 'keydown',
},
INCREASE_CONTRAST: {
name: 'Contrast+',
description: 'Increase contrast level for the image',
sequence: 'shift+c+=',
action: 'keydown',
},
DECREASE_CONTRAST: {
name: 'Contrast-',
description: 'Decrease contrast level for the image',
sequence: 'shift+c+-',
action: 'keydown',
},
INCREASE_SATURATION: {
name: 'Saturation+',
description: 'Increase saturation level for the image',
sequence: 'shift+s+=',
action: 'keydown',
},
DECREASE_SATURATION: {
name: 'Saturation-',
description: 'Increase contrast level for the image',
sequence: 'shift+s+-',
action: 'keydown',
},
INCREASE_GRID_OPACITY: {
name: 'Grid opacity+',
description: 'Make the grid more visible',
sequence: 'shift+g+=',
action: 'keydown',
},
DECREASE_GRID_OPACITY: {
name: 'Grid opacity-',
description: 'Make the grid less visible',
sequences: 'shift+g+-',
action: 'keydown',
},
CHANGE_GRID_COLOR: {
name: 'Grid color',
description: 'Set another color for the image grid',
sequence: 'shift+g+enter',
action: 'keydown',
},
}; };
const step = 10; const step = 10;
@ -826,7 +783,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
return ( return (
<Layout.Content style={{ position: 'relative' }}> <Layout.Content style={{ position: 'relative' }}>
<GlobalHotKeys keyMap={keyMap as any as KeyMap} handlers={handlers} allowChanges /> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
{/* {/*
This element doesn't have any props This element doesn't have any props
So, React isn't going to rerender it So, React isn't going to rerender it

@ -35,6 +35,7 @@ import SplitControl from './split-control';
interface Props { interface Props {
canvasInstance: Canvas; canvasInstance: Canvas;
activeControl: ActiveControl; activeControl: ActiveControl;
keyMap: KeyMap;
mergeObjects(enabled: boolean): void; mergeObjects(enabled: boolean): void;
groupObjects(enabled: boolean): void; groupObjects(enabled: boolean): void;
@ -57,6 +58,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {
repeatDrawShape, repeatDrawShape,
pasteShape, pasteShape,
resetGroup, resetGroup,
keyMap,
} = props; } = props;
const preventDefault = (event: KeyboardEvent | undefined): void => { const preventDefault = (event: KeyboardEvent | undefined): void => {
@ -65,55 +67,15 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {
} }
}; };
const keyMap = { const subKeyMap = {
PASTE_SHAPE: { PASTE_SHAPE: keyMap.PASTE_SHAPE,
name: 'Paste shape', SWITCH_DRAW_MODE: keyMap.SWITCH_DRAW_MODE,
description: 'Paste a shape from internal CVAT clipboard', SWITCH_MERGE_MODE: keyMap.SWITCH_MERGE_MODE,
sequence: 'ctrl+v', SWITCH_GROUP_MODE: keyMap.SWITCH_GROUP_MODE,
action: 'keydown', RESET_GROUP: keyMap.RESET_GROUP,
}, CANCEL: keyMap.CANCEL,
SWITCH_DRAW_MODE: { CLOCKWISE_ROTATION: keyMap.CLOCKWISE_ROTATION,
name: 'Draw mode', ANTICLOCKWISE_ROTATION: keyMap.ANTICLOCKWISE_ROTATION,
description: 'Repeat the latest procedure of drawing with the same parameters',
sequence: 'n',
action: 'keydown',
},
SWITCH_MERGE_MODE: {
name: 'Merge mode',
description: 'Activate or deactivate mode to merging shapes',
sequence: 'm',
action: 'keydown',
},
SWITCH_GROUP_MODE: {
name: 'Group mode',
description: 'Activate or deactivate mode to grouping shapes',
sequence: 'g',
action: 'keydown',
},
RESET_GROUP: {
name: 'Reset group',
description: 'Reset group for selected shapes (in group mode)',
sequence: 'shift+g',
action: 'keyup',
},
CANCEL: {
name: 'Cancel',
description: 'Cancel any active canvas mode',
sequence: 'esc',
action: 'keydown',
},
CLOCKWISE_ROTATION: {
name: 'Rotate clockwise',
description: 'Change image angle (add 90 degrees)',
sequence: 'ctrl+r',
action: 'keydown',
},
ANTICLOCKWISE_ROTATION: {
name: 'Rotate anticlockwise',
description: 'Change image angle (substract 90 degrees)',
sequence: 'ctrl+shift+r',
action: 'keydown',
},
}; };
const handlers = { const handlers = {
@ -186,7 +148,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {
theme='light' theme='light'
width={44} width={44}
> >
<GlobalHotKeys keyMap={keyMap as any as KeyMap} handlers={handlers} allowChanges /> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
<CursorControl canvasInstance={canvasInstance} activeControl={activeControl} /> <CursorControl canvasInstance={canvasInstance} activeControl={activeControl} />
<MoveControl canvasInstance={canvasInstance} activeControl={activeControl} /> <MoveControl canvasInstance={canvasInstance} activeControl={activeControl} />

@ -37,6 +37,7 @@ interface CVATAppProps {
resetErrors: () => void; resetErrors: () => void;
resetMessages: () => void; resetMessages: () => void;
switchShortcutsDialog: () => void; switchShortcutsDialog: () => void;
keyMap: KeyMap;
userInitialized: boolean; userInitialized: boolean;
userFetching: boolean; userFetching: boolean;
pluginsInitialized: boolean; pluginsInitialized: boolean;
@ -209,6 +210,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
switchShortcutsDialog, switchShortcutsDialog,
user, user,
history, history,
keyMap,
} = this.props; } = this.props;
const readyForRender = (userInitialized && user == null) const readyForRender = (userInitialized && user == null)
@ -218,19 +220,9 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
const withModels = installedAutoAnnotation const withModels = installedAutoAnnotation
|| installedTFAnnotation || installedTFSegmentation; || installedTFAnnotation || installedTFSegmentation;
const keyMap = { const subKeyMap = {
SWITCH_SHORTCUTS: { SWITCH_SHORTCUTS: keyMap.SWITCH_SHORTCUTS,
name: 'Show shortcuts', OPEN_SETTINGS: keyMap.OPEN_SETTINGS,
description: 'Open/hide the list of available shortcuts',
sequence: 'f1',
action: 'keydown',
},
OPEN_SETTINGS: {
name: 'Open settings',
description: 'Go to the settings page or go back',
sequence: 'f2',
action: 'keydown',
},
}; };
const handlers = { const handlers = {
@ -262,7 +254,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
<HeaderContainer> </HeaderContainer> <HeaderContainer> </HeaderContainer>
<Layout.Content> <Layout.Content>
<ShorcutsDialog /> <ShorcutsDialog />
<GlobalHotKeys keyMap={keyMap as KeyMap} handlers={handlers}> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers}>
<Switch> <Switch>
<Route exact path='/settings' component={SettingsPageContainer} /> <Route exact path='/settings' component={SettingsPageContainer} />
<Route exact path='/tasks' component={TasksPageContainer} /> <Route exact path='/tasks' component={TasksPageContainer} />

@ -2,6 +2,7 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { KeyMap } from 'react-hotkeys';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import CanvasWrapperComponent from 'components/annotation-page/standard-workspace/canvas-wrapper'; import CanvasWrapperComponent from 'components/annotation-page/standard-workspace/canvas-wrapper';
@ -78,6 +79,7 @@ interface StateToProps {
curZLayer: number; curZLayer: number;
contextVisible: boolean; contextVisible: boolean;
contextType: ContextMenuType; contextType: ContextMenuType;
keyMap: KeyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -169,6 +171,9 @@ function mapStateToProps(state: CombinedState): StateToProps {
blackBorders, blackBorders,
}, },
}, },
shortcuts: {
keyMap,
},
} = state; } = state;
return { return {
@ -204,6 +209,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
contextVisible, contextVisible,
contextType, contextType,
workspace, workspace,
keyMap,
}; };
} }

@ -2,10 +2,10 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { KeyMap } from 'react-hotkeys';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Canvas } from 'cvat-canvas'; import { Canvas } from 'cvat-canvas';
import { import {
mergeObjects, mergeObjects,
groupObjects, groupObjects,
@ -16,16 +16,13 @@ import {
resetAnnotationsGroup, resetAnnotationsGroup,
} from 'actions/annotation-actions'; } from 'actions/annotation-actions';
import ControlsSideBarComponent from 'components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar'; import ControlsSideBarComponent from 'components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar';
import { import { ActiveControl, CombinedState, Rotation } from 'reducers/interfaces';
ActiveControl,
CombinedState,
Rotation,
} from 'reducers/interfaces';
interface StateToProps { interface StateToProps {
canvasInstance: Canvas; canvasInstance: Canvas;
rotateAll: boolean; rotateAll: boolean;
activeControl: ActiveControl; activeControl: ActiveControl;
keyMap: KeyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -51,12 +48,16 @@ function mapStateToProps(state: CombinedState): StateToProps {
rotateAll, rotateAll,
}, },
}, },
shortcuts: {
keyMap,
},
} = state; } = state;
return { return {
rotateAll, rotateAll,
canvasInstance, canvasInstance,
activeControl, activeControl,
keyMap,
}; };
} }

@ -7,11 +7,7 @@ import copy from 'copy-to-clipboard';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { LogType } from 'cvat-logger'; import { LogType } from 'cvat-logger';
import { import { ActiveControl, CombinedState, ColorBy } from 'reducers/interfaces';
ActiveControl,
CombinedState,
ColorBy,
} from 'reducers/interfaces';
import { import {
collapseObjectItems, collapseObjectItems,
changeLabelColorAsync, changeLabelColorAsync,

@ -16,11 +16,7 @@ import {
propagateObject as propagateObjectAction, propagateObject as propagateObjectAction,
} from 'actions/annotation-actions'; } from 'actions/annotation-actions';
import { import { CombinedState, StatesOrdering, ObjectType } from 'reducers/interfaces';
CombinedState,
StatesOrdering,
ObjectType,
} from 'reducers/interfaces';
interface StateToProps { interface StateToProps {
jobInstance: any; jobInstance: any;
@ -35,6 +31,7 @@ interface StateToProps {
minZLayer: number; minZLayer: number;
maxZLayer: number; maxZLayer: number;
annotationsFiltersHistory: string[]; annotationsFiltersHistory: string[];
keyMap: KeyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -70,6 +67,9 @@ function mapStateToProps(state: CombinedState): StateToProps {
}, },
tabContentHeight: listHeight, tabContentHeight: listHeight,
}, },
shortcuts: {
keyMap,
},
} = state; } = state;
let statesHidden = true; let statesHidden = true;
@ -101,6 +101,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
minZLayer, minZLayer,
maxZLayer, maxZLayer,
annotationsFiltersHistory, annotationsFiltersHistory,
keyMap,
}; };
} }
@ -249,97 +250,28 @@ class ObjectsListContainer extends React.PureComponent<Props, State> {
changeFrame, changeFrame,
maxZLayer, maxZLayer,
minZLayer, minZLayer,
keyMap,
} = this.props; } = this.props;
const { const {
sortedStatesID, sortedStatesID,
statesOrdering, statesOrdering,
} = this.state; } = this.state;
const keyMap = { const subKeyMap = {
SWITCH_ALL_LOCK: { SWITCH_ALL_LOCK: keyMap.SWITCH_ALL_LOCK,
name: 'Lock/unlock all objects', SWITCH_LOCK: keyMap.SWITCH_LOCK,
description: 'Change locked state for all objects in the side bar', SWITCH_ALL_HIDDEN: keyMap.SWITCH_ALL_HIDDEN,
sequence: 't+l', SWITCH_HIDDEN: keyMap.SWITCH_HIDDEN,
action: 'keydown', SWITCH_OCCLUDED: keyMap.SWITCH_OCCLUDED,
}, SWITCH_KEYFRAME: keyMap.SWITCH_KEYFRAME,
SWITCH_LOCK: { SWITCH_OUTSIDE: keyMap.SWITCH_OUTSIDE,
name: 'Lock/unlock an object', DELETE_OBJECT: keyMap.DELETE_OBJECT,
description: 'Change locked state for an active object', TO_BACKGROUND: keyMap.TO_BACKGROUND,
sequence: 'l', TO_FOREGROUND: keyMap.TO_FOREGROUND,
action: 'keydown', COPY_SHAPE: keyMap.COPY_SHAPE,
}, PROPAGATE_OBJECT: keyMap.PROPAGATE_OBJECT,
SWITCH_ALL_HIDDEN: { NEXT_KEY_FRAME: keyMap.NEXT_KEY_FRAME,
name: 'Hide/show all objects', PREV_KEY_FRAME: keyMap.PREV_KEY_FRAME,
description: 'Change hidden state for objects in the side bar',
sequence: 't+h',
action: 'keydown',
},
SWITCH_HIDDEN: {
name: 'Hide/show an object',
description: 'Change hidden state for an active object',
sequence: 'h',
action: 'keydown',
},
SWITCH_OCCLUDED: {
name: 'Switch occluded',
description: 'Change occluded property for an active object',
sequences: ['q', '/'],
action: 'keydown',
},
SWITCH_KEYFRAME: {
name: 'Switch keyframe',
description: 'Change keyframe property for an active track',
sequence: 'k',
action: 'keydown',
},
SWITCH_OUTSIDE: {
name: 'Switch outside',
description: 'Change outside property for an active track',
sequence: 'o',
action: 'keydown',
},
DELETE_OBJECT: {
name: 'Delete object',
description: 'Delete an active object. Use shift to force delete of locked objects',
sequences: ['del', 'shift+del'],
action: 'keydown',
},
TO_BACKGROUND: {
name: 'To background',
description: 'Put an active object "farther" from the user (decrease z axis value)',
sequences: ['-', '_'],
action: 'keydown',
},
TO_FOREGROUND: {
name: 'To foreground',
description: 'Put an active object "closer" to the user (increase z axis value)',
sequences: ['+', '='],
action: 'keydown',
},
COPY_SHAPE: {
name: 'Copy shape',
description: 'Copy shape to CVAT internal clipboard',
sequence: 'ctrl+c',
action: 'keydown',
},
PROPAGATE_OBJECT: {
name: 'Propagate object',
description: 'Make a copy of the object on the following frames',
sequence: 'ctrl+b',
action: 'keydown',
},
NEXT_KEY_FRAME: {
name: 'Next keyframe',
description: 'Go to the next keyframe of an active track',
sequence: 'r',
action: 'keydown',
},
PREV_KEY_FRAME: {
name: 'Previous keyframe',
description: 'Go to the previous keyframe of an active track',
sequence: 'e',
action: 'keydown',
},
}; };
const preventDefault = (event: KeyboardEvent | undefined): void => { const preventDefault = (event: KeyboardEvent | undefined): void => {
@ -473,7 +405,7 @@ class ObjectsListContainer extends React.PureComponent<Props, State> {
return ( return (
<> <>
<GlobalHotKeys keyMap={keyMap as any as KeyMap} handlers={handlers} allowChanges /> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
<ObjectsListComponent <ObjectsListComponent
{...this.props} {...this.props}
statesOrdering={statesOrdering} statesOrdering={statesOrdering}

@ -45,6 +45,7 @@ interface StateToProps {
autoSave: boolean; autoSave: boolean;
autoSaveInterval: number; autoSaveInterval: number;
workspace: Workspace; workspace: Workspace;
keyMap: KeyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -94,6 +95,9 @@ function mapStateToProps(state: CombinedState): StateToProps {
autoSaveInterval, autoSaveInterval,
}, },
}, },
shortcuts: {
keyMap,
},
} = state; } = state;
return { return {
@ -112,6 +116,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
autoSave, autoSave,
autoSaveInterval, autoSaveInterval,
workspace, workspace,
keyMap,
}; };
} }
@ -464,6 +469,7 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
canvasIsReady, canvasIsReady,
searchAnnotations, searchAnnotations,
changeWorkspace, changeWorkspace,
keyMap,
} = this.props; } = this.props;
const preventDefault = (event: KeyboardEvent | undefined): void => { const preventDefault = (event: KeyboardEvent | undefined): void => {
@ -472,73 +478,18 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
} }
}; };
const keyMap = { const subKeyMap = {
SAVE_JOB: { SAVE_JOB: keyMap.SAVE_JOB,
name: 'Save the job', UNDO: keyMap.UNDO,
description: 'Send all changes of annotations to the server', REDO: keyMap.REDO,
sequence: 'ctrl+s', NEXT_FRAME: keyMap.SAVE_JOB,
action: 'keydown', PREV_FRAME: keyMap.PREV_FRAME,
}, FORWARD_FRAME: keyMap.FORWARD_FRAME,
UNDO: { BACKWARD_FRAME: keyMap.BACKWARD_FRAME,
name: 'Undo action', SEARCH_FORWARD: keyMap.SEARCH_FORWARD,
description: 'Cancel the latest action related with objects', SEARCH_BACKWARD: keyMap.SEARCH_BACKWARD,
sequence: 'ctrl+z', PLAY_PAUSE: keyMap.PLAY_PAUSE,
action: 'keydown', FOCUS_INPUT_FRAME: keyMap.FOCUS_INPUT_FRAME,
},
REDO: {
name: 'Redo action',
description: 'Cancel undo action',
sequences: ['ctrl+shift+z', 'ctrl+y'],
action: 'keydown',
},
NEXT_FRAME: {
name: 'Next frame',
description: 'Go to the next frame',
sequence: 'f',
action: 'keydown',
},
PREV_FRAME: {
name: 'Previous frame',
description: 'Go to the previous frame',
sequence: 'd',
action: 'keydown',
},
FORWARD_FRAME: {
name: 'Forward frame',
description: 'Go forward with a step',
sequence: 'v',
action: 'keydown',
},
BACKWARD_FRAME: {
name: 'Backward frame',
description: 'Go backward with a step',
sequence: 'c',
action: 'keydown',
},
SEARCH_FORWARD: {
name: 'Search forward',
description: 'Search the next frame that satisfies to the filters',
sequence: 'right',
action: 'keydown',
},
SEARCH_BACKWARD: {
name: 'Search backward',
description: 'Search the previous frame that satisfies to the filters',
sequence: 'left',
action: 'keydown',
},
PLAY_PAUSE: {
name: 'Play/pause',
description: 'Start/stop automatic changing frames',
sequence: 'space',
action: 'keydown',
},
FOCUS_INPUT_FRAME: {
name: 'Focus input frame',
description: 'Focus on the element to change the current frame',
sequences: ['`', '~'],
action: 'keydown',
},
}; };
const handlers = { const handlers = {
@ -608,7 +559,7 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
return ( return (
<> <>
<GlobalHotKeys keyMap={keyMap as any as KeyMap} handlers={handlers} allowChanges /> <GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
<AnnotationTopBarComponent <AnnotationTopBarComponent
showStatistics={this.showStatistics} showStatistics={this.showStatistics}
onSwitchPlay={this.onSwitchPlay} onSwitchPlay={this.onSwitchPlay}

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { connect, Provider } from 'react-redux'; import { connect, Provider } from 'react-redux';
import { KeyMap } from 'react-hotkeys';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import CVATApplication from 'components/cvat-app'; import CVATApplication from 'components/cvat-app';
@ -48,6 +49,7 @@ interface StateToProps {
installedTFAnnotation: boolean; installedTFAnnotation: boolean;
notifications: NotificationsState; notifications: NotificationsState;
user: any; user: any;
keyMap: keyMap;
} }
interface DispatchToProps { interface DispatchToProps {
@ -67,6 +69,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
const { formats } = state; const { formats } = state;
const { users } = state; const { users } = state;
const { about } = state; const { about } = state;
const { shortcuts } = state;
return { return {
userInitialized: auth.initialized, userInitialized: auth.initialized,
@ -84,6 +87,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
installedTFAnnotation: plugins.list.TF_ANNOTATION, installedTFAnnotation: plugins.list.TF_ANNOTATION,
notifications: state.notifications, notifications: state.notifications,
user: auth.user, user: auth.user,
keyMap: shortcuts.keyMap,
}; };
} }

@ -2,6 +2,7 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { KeyMap } from 'react-hotkeys';
import { Canvas, RectDrawingMethod } from 'cvat-canvas'; import { Canvas, RectDrawingMethod } from 'cvat-canvas';
export type StringObject = { export type StringObject = {
@ -443,6 +444,7 @@ export interface SettingsState {
export interface ShortcutsState { export interface ShortcutsState {
visibleShortcutsHelp: boolean; visibleShortcutsHelp: boolean;
keyMap: KeyMap;
} }
export interface CombinedState { export interface CombinedState {

@ -1,10 +1,312 @@
// Copyright (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: MIT
import { KeyMap } from 'react-hotkeys';
import { boundariesActions, BoundariesActionTypes } from 'actions/boundaries-actions'; import { boundariesActions, BoundariesActionTypes } from 'actions/boundaries-actions';
import { AuthActions, AuthActionTypes } from 'actions/auth-actions'; import { AuthActions, AuthActionTypes } from 'actions/auth-actions';
import { ShortcutsActions, ShortcutsActionsTypes } from 'actions/shortcuts-actions'; import { ShortcutsActions, ShortcutsActionsTypes } from 'actions/shortcuts-actions';
import { ShortcutsState } from './interfaces'; import { ShortcutsState } from './interfaces';
const defaultState: ShortcutsState = { const defaultState: ShortcutsState = {
visibleShortcutsHelp: false, visibleShortcutsHelp: false,
keyMap: {
SWITCH_SHORTCUTS: {
name: 'Show shortcuts',
description: 'Open/hide the list of available shortcuts',
sequence: 'f1',
action: 'keydown',
},
OPEN_SETTINGS: {
name: 'Open settings',
description: 'Go to the settings page or go back',
sequence: 'f2',
action: 'keydown',
},
SWITCH_ALL_LOCK: {
name: 'Lock/unlock all objects',
description: 'Change locked state for all objects in the side bar',
sequence: 't+l',
action: 'keydown',
},
SWITCH_LOCK: {
name: 'Lock/unlock an object',
description: 'Change locked state for an active object',
sequence: 'l',
action: 'keydown',
},
SWITCH_ALL_HIDDEN: {
name: 'Hide/show all objects',
description: 'Change hidden state for objects in the side bar',
sequence: 't+h',
action: 'keydown',
},
SWITCH_HIDDEN: {
name: 'Hide/show an object',
description: 'Change hidden state for an active object',
sequence: 'h',
action: 'keydown',
},
SWITCH_OCCLUDED: {
name: 'Switch occluded',
description: 'Change occluded property for an active object',
sequences: ['q', '/'],
action: 'keydown',
},
SWITCH_KEYFRAME: {
name: 'Switch keyframe',
description: 'Change keyframe property for an active track',
sequence: 'k',
action: 'keydown',
},
SWITCH_OUTSIDE: {
name: 'Switch outside',
description: 'Change outside property for an active track',
sequence: 'o',
action: 'keydown',
},
DELETE_OBJECT: {
name: 'Delete object',
description: 'Delete an active object. Use shift to force delete of locked objects',
sequences: ['del', 'shift+del'],
action: 'keydown',
},
TO_BACKGROUND: {
name: 'To background',
description: 'Put an active object "farther" from the user (decrease z axis value)',
sequences: ['-', '_'],
action: 'keydown',
},
TO_FOREGROUND: {
name: 'To foreground',
description: 'Put an active object "closer" to the user (increase z axis value)',
sequences: ['+', '='],
action: 'keydown',
},
COPY_SHAPE: {
name: 'Copy shape',
description: 'Copy shape to CVAT internal clipboard',
sequence: 'ctrl+c',
action: 'keydown',
},
PROPAGATE_OBJECT: {
name: 'Propagate object',
description: 'Make a copy of the object on the following frames',
sequence: 'ctrl+b',
action: 'keydown',
},
NEXT_KEY_FRAME: {
name: 'Next keyframe',
description: 'Go to the next keyframe of an active track',
sequence: 'r',
action: 'keydown',
},
PREV_KEY_FRAME: {
name: 'Previous keyframe',
description: 'Go to the previous keyframe of an active track',
sequence: 'e',
action: 'keydown',
},
NEXT_ATTRIBUTE: {
name: 'Next attribute',
description: 'Go to the next attribute',
sequence: 'ArrowDown',
action: 'keydown',
},
PREVIOUS_ATTRIBUTE: {
name: 'Previous attribute',
description: 'Go to the previous attribute',
sequence: 'ArrowUp',
action: 'keydown',
},
NEXT_OBJECT: {
name: 'Next object',
description: 'Go to the next object',
sequence: 'Tab',
action: 'keydown',
},
PREVIOUS_OBJECT: {
name: 'Previous object',
description: 'Go to the previous object',
sequence: 'Shift+Tab',
action: 'keydown',
},
INCREASE_BRIGHTNESS: {
name: 'Brightness+',
description: 'Increase brightness level for the image',
sequence: 'shift+b+=',
action: 'keypress',
},
DECREASE_BRIGHTNESS: {
name: 'Brightness-',
description: 'Decrease brightness level for the image',
sequence: 'shift+b+-',
action: 'keydown',
},
INCREASE_CONTRAST: {
name: 'Contrast+',
description: 'Increase contrast level for the image',
sequence: 'shift+c+=',
action: 'keydown',
},
DECREASE_CONTRAST: {
name: 'Contrast-',
description: 'Decrease contrast level for the image',
sequence: 'shift+c+-',
action: 'keydown',
},
INCREASE_SATURATION: {
name: 'Saturation+',
description: 'Increase saturation level for the image',
sequence: 'shift+s+=',
action: 'keydown',
},
DECREASE_SATURATION: {
name: 'Saturation-',
description: 'Increase contrast level for the image',
sequence: 'shift+s+-',
action: 'keydown',
},
INCREASE_GRID_OPACITY: {
name: 'Grid opacity+',
description: 'Make the grid more visible',
sequence: 'shift+g+=',
action: 'keydown',
},
DECREASE_GRID_OPACITY: {
name: 'Grid opacity-',
description: 'Make the grid less visible',
sequences: 'shift+g+-',
action: 'keydown',
},
CHANGE_GRID_COLOR: {
name: 'Grid color',
description: 'Set another color for the image grid',
sequence: 'shift+g+enter',
action: 'keydown',
},
PASTE_SHAPE: {
name: 'Paste shape',
description: 'Paste a shape from internal CVAT clipboard',
sequence: 'ctrl+v',
action: 'keydown',
},
SWITCH_DRAW_MODE: {
name: 'Draw mode',
description: 'Repeat the latest procedure of drawing with the same parameters',
sequence: 'n',
action: 'keydown',
},
SWITCH_MERGE_MODE: {
name: 'Merge mode',
description: 'Activate or deactivate mode to merging shapes',
sequence: 'm',
action: 'keydown',
},
SWITCH_GROUP_MODE: {
name: 'Group mode',
description: 'Activate or deactivate mode to grouping shapes',
sequence: 'g',
action: 'keydown',
},
RESET_GROUP: {
name: 'Reset group',
description: 'Reset group for selected shapes (in group mode)',
sequence: 'shift+g',
action: 'keyup',
},
CANCEL: {
name: 'Cancel',
description: 'Cancel any active canvas mode',
sequence: 'esc',
action: 'keydown',
},
CLOCKWISE_ROTATION: {
name: 'Rotate clockwise',
description: 'Change image angle (add 90 degrees)',
sequence: 'ctrl+r',
action: 'keydown',
},
ANTICLOCKWISE_ROTATION: {
name: 'Rotate anticlockwise',
description: 'Change image angle (substract 90 degrees)',
sequence: 'ctrl+shift+r',
action: 'keydown',
},
SAVE_JOB: {
name: 'Save the job',
description: 'Send all changes of annotations to the server',
sequence: 'ctrl+s',
action: 'keydown',
},
UNDO: {
name: 'Undo action',
description: 'Cancel the latest action related with objects',
sequence: 'ctrl+z',
action: 'keydown',
},
REDO: {
name: 'Redo action',
description: 'Cancel undo action',
sequences: ['ctrl+shift+z', 'ctrl+y'],
action: 'keydown',
},
NEXT_FRAME: {
name: 'Next frame',
description: 'Go to the next frame',
sequence: 'f',
action: 'keydown',
},
PREV_FRAME: {
name: 'Previous frame',
description: 'Go to the previous frame',
sequence: 'd',
action: 'keydown',
},
FORWARD_FRAME: {
name: 'Forward frame',
description: 'Go forward with a step',
sequence: 'v',
action: 'keydown',
},
BACKWARD_FRAME: {
name: 'Backward frame',
description: 'Go backward with a step',
sequence: 'c',
action: 'keydown',
},
SEARCH_FORWARD: {
name: 'Search forward',
description: 'Search the next frame that satisfies to the filters',
sequence: 'right',
action: 'keydown',
},
SEARCH_BACKWARD: {
name: 'Search backward',
description: 'Search the previous frame that satisfies to the filters',
sequence: 'left',
action: 'keydown',
},
PLAY_PAUSE: {
name: 'Play/pause',
description: 'Start/stop automatic changing frames',
sequence: 'space',
action: 'keydown',
},
FOCUS_INPUT_FRAME: {
name: 'Focus input frame',
description: 'Focus on the element to change the current frame',
sequences: ['`', '~'],
action: 'keydown',
},
} as any as KeyMap,
}; };
export default ( export default (

Loading…
Cancel
Save