From fb17dca505a7eaa85f2f46285033bd0cd5ef5e30 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Sun, 28 Feb 2021 18:33:38 +0300 Subject: [PATCH] Migration to mousetrap, redesigned visualization settings (#2872) * Initial version of shortcut fixes using mousetrap * Redesigned visualization settings * Updated cypress tests * Minor fix in AAM * Aborted extra changes * 1.1.0 * Updated version & changelog * Aborted extra changes * Fixed headers * Using keycodes in cypress * Fixed a couple of commands --- CHANGELOG.md | 2 + cvat-ui/package-lock.json | 23 ++- cvat-ui/package.json | 7 +- .../attribute-annotation-sidebar.tsx | 8 +- .../attribute-editor.tsx | 12 +- .../annotation-page/canvas/canvas-wrapper.tsx | 108 +--------- .../canvas/canvas-wrapper3D.tsx | 3 - .../canvas/image-setups-content.tsx | 189 ++++++++++++++++++ .../controls-side-bar/controls-side-bar.tsx | 8 +- .../controls-side-bar/controls-side-bar.tsx | 8 +- .../controls-side-bar/controls-side-bar.tsx | 3 - .../components/annotation-page/styles.scss | 71 +++++++ .../shortcuts-select.tsx | 8 +- .../tag-annotation-sidebar.tsx | 8 +- cvat-ui/src/components/cvat-app.tsx | 10 +- .../header/settings-modal/player-settings.tsx | 170 +--------------- .../header/settings-modal/styles.scss | 34 ---- .../components/layout-grid/layout-grid.tsx | 20 +- .../shortcuts-dialog/shortcuts-dialog.tsx | 8 +- .../annotation-page/canvas/canvas-wrapper.tsx | 6 +- .../controls-side-bar/controls-side-bar.tsx | 6 +- .../controls-side-bar/controls-side-bar.tsx | 6 +- .../objects-side-bar/objects-list.tsx | 8 +- .../controls-side-bar/controls-side-bar.tsx | 4 +- .../annotation-page/top-bar/top-bar.tsx | 6 +- .../header/settings-modal/player-settings.tsx | 55 +---- cvat-ui/src/index.tsx | 6 +- cvat-ui/src/reducers/interfaces.ts | 8 +- cvat-ui/src/reducers/shortcuts-reducer.ts | 88 ++------ cvat-ui/src/utils/mousetrap-react.tsx | 57 ++++++ .../case_23_canvas_grid_feature.js | 14 +- ..._brightness_contrast_saturation_feature.js | 38 ++-- .../issue_1433_hide_functionality.js | 5 +- .../issue_1540_add_remove_tag.js | 5 +- .../issue_1882_polygon_interpolation.js | 7 +- tests/cypress/support/commands.js | 24 ++- 36 files changed, 498 insertions(+), 545 deletions(-) create mode 100644 cvat-ui/src/components/annotation-page/canvas/image-setups-content.tsx create mode 100644 cvat-ui/src/utils/mousetrap-react.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 272042f7..28020188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - All methods for interative segmentation accept negative points as well - Persistent queue added to logstash () - Improved maintanance of popups visibility () +- Image visualizations settings on canvas for faster access () ### Deprecated @@ -56,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Polygon editing using trailing point () - Updated the path to python for DL models inside automatic annotation documentation () - Fixed of receiving function variable () +- Shortcuts with CAPSLOCK enabled and with non-US languages activated () ### Security diff --git a/cvat-ui/package-lock.json b/cvat-ui/package-lock.json index 9371c38e..ce87ebab 100644 --- a/cvat-ui/package-lock.json +++ b/cvat-ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.14.3", + "version": "1.15.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1227,6 +1227,12 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/mousetrap": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.5.tgz", + "integrity": "sha512-OwVhKFim9Y/MprzCe4I6a59p31pMy8+LrtP6qS7J0kaOxYmW6VVJPBw5NYm+g7nSbgPUz22FvqU1F1hC5YGTfg==", + "dev": true + }, "@types/node": { "version": "14.14.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz", @@ -12873,7 +12879,7 @@ "cvat-canvas3d": { "version": "file:../cvat-canvas3d", "requires": { - "camera-controls": "1.25.3", + "camera-controls": "^1.25.3", "three": "^0.125.0" }, "dependencies": { @@ -25965,6 +25971,11 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, + "mousetrap": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz", + "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -28852,14 +28863,6 @@ "scheduler": "^0.19.1" } }, - "react-hotkeys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-hotkeys/-/react-hotkeys-2.0.0.tgz", - "integrity": "sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q==", - "requires": { - "prop-types": "^15.6.1" - } - }, "react-is": { "version": "16.11.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", diff --git a/cvat-ui/package.json b/cvat-ui/package.json index f81a7986..49d93b64 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.14.3", + "version": "1.15.0", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { @@ -20,6 +20,7 @@ "@babel/preset-env": "^7.6.0", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.6.0", + "@types/mousetrap": "^1.6.5", "@typescript-eslint/eslint-plugin": "^4.5.0", "@typescript-eslint/parser": "^4.5.0", "babel-loader": "^8.0.6", @@ -60,20 +61,20 @@ "@types/redux-logger": "^3.0.8", "antd": "^4.12.2", "copy-to-clipboard": "^3.3.1", - "cvat-canvas3d": "file:../cvat-canvas3d", "cvat-canvas": "file:../cvat-canvas", + "cvat-canvas3d": "file:../cvat-canvas3d", "cvat-core": "file:../cvat-core", "dotenv-webpack": "^1.8.0", "error-stack-parser": "^2.0.6", "lodash": "^4.17.21", "moment": "^2.29.1", + "mousetrap": "^1.6.5", "platform": "^1.3.6", "prop-types": "^15.7.2", "react": "^16.14.0", "react-color": "^2.19.3", "react-cookie": "^4.0.3", "react-dom": "^16.14.0", - "react-hotkeys": "^2.0.0", "react-redux": "^7.2.2", "react-router": "^5.1.0", "react-router-dom": "^5.1.0", diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx index 10f0b596..4aaa95ea 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-annotation-sidebar.tsx @@ -1,9 +1,9 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useState, useEffect } from 'react'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import { connect } from 'react-redux'; import Layout, { SiderProps } from 'antd/lib/layout'; import { SelectValue } from 'antd/lib/select'; @@ -35,7 +35,7 @@ interface StateToProps { states: any[]; labels: any[]; jobInstance: any; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; canvasInstance: Canvas; canvasIsReady: boolean; @@ -295,7 +295,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX. > {sidebarCollapsed ? : } - + diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx index 808cee83..8be1bfdd 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/attribute-editor.tsx @@ -1,9 +1,9 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; -import { GlobalHotKeys, KeyMap } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import Text from 'antd/lib/typography/Text'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Select, { SelectValue } from 'antd/lib/select'; @@ -150,7 +150,7 @@ function renderList(parameters: ListParameters): JSX.Element | null { keyMap[key] = { name: `Set value "${value}"`, description: `Change current value for the attribute to "${value}"`, - sequence: `${index}`, + sequences: [`${index}`], action: 'keydown', }; @@ -165,7 +165,7 @@ function renderList(parameters: ListParameters): JSX.Element | null { return (
- +
0: {` ${sortedValues[0]}`} @@ -190,7 +190,7 @@ function renderList(parameters: ListParameters): JSX.Element | null { keyMap[key] = { name: `Set value "${value}"`, description: `Change current value for the attribute to "${value}"`, - sequence: `${index}`, + sequences: [`${index}`], action: 'keydown', }; @@ -205,7 +205,7 @@ function renderList(parameters: ListParameters): JSX.Element | null { return (
- + {filteredValues.map( (value: string, index: number): JSX.Element => (
diff --git a/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx index 380e2ab3..fcae62d5 100644 --- a/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-wrapper.tsx @@ -3,10 +3,11 @@ // SPDX-License-Identifier: MIT import React from 'react'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import Layout from 'antd/lib/layout'; import Slider from 'antd/lib/slider'; -import { PlusCircleOutlined } from '@ant-design/icons'; +import Dropdown from 'antd/lib/dropdown'; +import { PlusCircleOutlined, UpOutlined } from '@ant-design/icons'; import { ColorBy, GridColor, ObjectType, ContextMenuType, Workspace, ShapeType, @@ -16,6 +17,7 @@ import { Canvas } from 'cvat-canvas-wrapper'; import getCore from 'cvat-core-wrapper'; import consts from 'consts'; import CVATTooltip from 'components/common/cvat-tooltip'; +import ImageSetupsContent from './image-setups-content'; const cvat = getCore(); @@ -59,7 +61,7 @@ interface Props { showAllInterpolationTracks: boolean; workspace: Workspace; automaticBordering: boolean; - keyMap: Record; + keyMap: KeyMap; canvasBackgroundColor: string; switchableAutomaticBordering: boolean; onSetupCanvas: () => void; @@ -762,21 +764,9 @@ export default class CanvasWrapperComponent extends React.PureComponent { minZLayer, onSwitchZLayer, onAddZLayer, - brightnessLevel, - contrastLevel, - saturationLevel, keyMap, - grid, - gridColor, - gridOpacity, switchableAutomaticBordering, automaticBordering, - onChangeBrightnessLevel, - onChangeSaturationLevel, - onChangeContrastLevel, - onChangeGridColor, - onChangeGridOpacity, - onSwitchGrid, onSwitchAutomaticBordering, } = this.props; @@ -787,91 +777,10 @@ export default class CanvasWrapperComponent extends React.PureComponent { }; const subKeyMap = { - INCREASE_BRIGHTNESS: keyMap.INCREASE_BRIGHTNESS, - DECREASE_BRIGHTNESS: keyMap.DECREASE_BRIGHTNESS, - INCREASE_CONTRAST: keyMap.INCREASE_CONTRAST, - DECREASE_CONTRAST: keyMap.DECREASE_CONTRAST, - INCREASE_SATURATION: keyMap.INCREASE_SATURATION, - DECREASE_SATURATION: keyMap.DECREASE_SATURATION, - INCREASE_GRID_OPACITY: keyMap.INCREASE_GRID_OPACITY, - DECREASE_GRID_OPACITY: keyMap.DECREASE_GRID_OPACITY, - CHANGE_GRID_COLOR: keyMap.CHANGE_GRID_COLOR, SWITCH_AUTOMATIC_BORDERING: keyMap.SWITCH_AUTOMATIC_BORDERING, }; - const step = 10; const handlers = { - INCREASE_BRIGHTNESS: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const maxLevel = 200; - if (brightnessLevel < maxLevel) { - onChangeBrightnessLevel(Math.min(brightnessLevel + step, maxLevel)); - } - }, - DECREASE_BRIGHTNESS: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const minLevel = 50; - if (brightnessLevel > minLevel) { - onChangeBrightnessLevel(Math.max(brightnessLevel - step, minLevel)); - } - }, - INCREASE_CONTRAST: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const maxLevel = 200; - if (contrastLevel < maxLevel) { - onChangeContrastLevel(Math.min(contrastLevel + step, maxLevel)); - } - }, - DECREASE_CONTRAST: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const minLevel = 50; - if (contrastLevel > minLevel) { - onChangeContrastLevel(Math.max(contrastLevel - step, minLevel)); - } - }, - INCREASE_SATURATION: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const maxLevel = 300; - if (saturationLevel < maxLevel) { - onChangeSaturationLevel(Math.min(saturationLevel + step, maxLevel)); - } - }, - DECREASE_SATURATION: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const minLevel = 0; - if (saturationLevel > minLevel) { - onChangeSaturationLevel(Math.max(saturationLevel - step, minLevel)); - } - }, - INCREASE_GRID_OPACITY: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const maxLevel = 100; - if (!grid) { - onSwitchGrid(true); - } - - if (gridOpacity < maxLevel) { - onChangeGridOpacity(Math.min(gridOpacity + step, maxLevel)); - } - }, - DECREASE_GRID_OPACITY: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const minLevel = 0; - if (gridOpacity - step <= minLevel) { - onSwitchGrid(false); - } - - if (gridOpacity > minLevel) { - onChangeGridOpacity(Math.max(gridOpacity - step, minLevel)); - } - }, - CHANGE_GRID_COLOR: (event: KeyboardEvent | undefined) => { - preventDefault(event); - const colors = [GridColor.Black, GridColor.Blue, GridColor.Green, GridColor.Red, GridColor.White]; - const indexOf = colors.indexOf(gridColor) + 1; - const color = colors[indexOf >= colors.length ? 0 : indexOf]; - onChangeGridColor(color); - }, SWITCH_AUTOMATIC_BORDERING: (event: KeyboardEvent | undefined) => { if (switchableAutomaticBordering) { preventDefault(event); @@ -882,7 +791,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { return ( - + {/* This element doesn't have any props So, React isn't going to rerender it @@ -896,6 +805,11 @@ export default class CanvasWrapperComponent extends React.PureComponent { height: '100%', }} /> + + }> + + +
{ return ( - - state.settings.player); + + return ( +
+ Image grid +
+ + + + Size + + + Color + + + Opacity + + + + + { + dispatch(switchGrid(event.target.checked)); + }} + /> + + + { + if (typeof value !== 'undefined' && value !== null) { + const converted = Math.floor(clamp(+value, minGridSize, maxGridSize)); + dispatch(changeGridSize(converted)); + } + }} + /> + + + + + + { + dispatch(changeGridOpacity(value as number)); + }} + /> + + + Color settings +
+ + + + + Brightness + + + { + dispatch(changeBrightnessLevel(value as number)); + }} + /> + + + + + Contrast + + + { + dispatch(changeContrastLevel(value as number)); + }} + /> + + + + + Saturation + + + { + dispatch(changeSaturationLevel(value as number)); + }} + /> + + + + + + + + + +
+ ); +} diff --git a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx index 9eb53fa2..56e25c6f 100644 --- a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx @@ -1,9 +1,9 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import Layout from 'antd/lib/layout'; import { ActiveControl, Rotation } from 'reducers/interfaces'; @@ -19,7 +19,7 @@ import IssueControl from './issue-control'; interface Props { canvasInstance: Canvas; activeControl: ActiveControl; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; rotateFrame(rotation: Rotation): void; @@ -64,7 +64,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { return ( - + ; + keyMap: KeyMap; normalizedKeyMap: Record; mergeObjects(enabled: boolean): void; @@ -169,7 +169,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { return ( - + - - div:first-child { + margin-bottom: 10px; + } +} + +.cvat-image-setups-grid-size, +.cvat-image-setups-grid-color, +.cvat-image-setups-opacity { + margin-bottom: 25px; +} + +.cvat-image-setups-grid-size, +.cvat-image-setups-grid-color, +.cvat-image-setups-grid-opacity { + display: flex; + justify-items: start; +} + +.cvat-image-setups-grid-size-input { + height: fit-content; +} + +.cvat-image-setups-grid-color { + > .ant-select { + width: 150px; + } +} + +.cvat-image-setups-grid-opacity { + > .ant-slider { + width: 150px; + } +} + +.cvat-image-setups-reset-color-settings, +.cvat-image-setups-brightness, +.cvat-image-setups-contrast, +.cvat-image-setups-saturation { + width: 100%; +} + .cvat-canvas-z-axis-wrapper { position: absolute; background: $background-color-2; diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx index 854f6f36..1ec42848 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/shortcuts-select.tsx @@ -1,10 +1,10 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; -import { GlobalHotKeys, KeyMap } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import { Row, Col } from 'antd/lib/grid'; import Text from 'antd/lib/typography/Text'; import Select from 'antd/lib/select'; @@ -60,7 +60,7 @@ const ShortcutsSelect = (props: Props): JSX.Element => { keyMap[key] = { name: `Setup ${label.name} tag`, description: `Setup tag with "${label.name}" label`, - sequence: `${id}`, + sequences: [`${id}`], action: 'keydown', }; @@ -81,7 +81,7 @@ const ShortcutsSelect = (props: Props): JSX.Element => { return (
- + Shortcuts for labels: diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx index b67b07c4..775d13c4 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/tag-annotation-sidebar/tag-annotation-sidebar.tsx @@ -1,10 +1,10 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import { Action } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { Row, Col } from 'antd/lib/grid'; @@ -35,7 +35,7 @@ interface StateToProps { jobInstance: any; canvasInstance: Canvas; frameNumber: number; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; } @@ -198,7 +198,7 @@ function TagAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.Elemen return ( <> - + {/* eslint-disable-next-line */} void; switchSettingsDialog: () => void; loadAuthActions: () => void; - keyMap: Record; + keyMap: KeyMap; userInitialized: boolean; userFetching: boolean; pluginsInitialized: boolean; @@ -71,7 +71,7 @@ class CVATApplication extends React.PureComponent void)[] = []; @@ -256,12 +256,12 @@ class CVATApplication extends React.PureComponent { + SWITCH_SHORTCUTS: (event: KeyboardEvent) => { if (event) event.preventDefault(); switchShortcutsDialog(); }, - SWITCH_SETTINGS: (event: KeyboardEvent | undefined) => { + SWITCH_SETTINGS: (event: KeyboardEvent) => { if (event) event.preventDefault(); switchSettingsDialog(); diff --git a/cvat-ui/src/components/header/settings-modal/player-settings.tsx b/cvat-ui/src/components/header/settings-modal/player-settings.tsx index 59523f2b..ddc203e1 100644 --- a/cvat-ui/src/components/header/settings-modal/player-settings.tsx +++ b/cvat-ui/src/components/header/settings-modal/player-settings.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Button from 'antd/lib/button'; -import Slider from 'antd/lib/slider'; import Select from 'antd/lib/select'; import Popover from 'antd/lib/popover'; import InputNumber from 'antd/lib/input-number'; @@ -17,7 +16,7 @@ import { CompactPicker } from 'react-color'; import { clamp } from 'utils/math'; import { BackJumpIcon, ForwardJumpIcon } from 'icons'; -import { FrameSpeed, GridColor } from 'reducers/interfaces'; +import { FrameSpeed } from 'reducers/interfaces'; import consts from 'consts'; interface Props { @@ -25,25 +24,11 @@ interface Props { frameSpeed: FrameSpeed; resetZoom: boolean; rotateAll: boolean; - grid: boolean; - gridSize: number; - gridColor: GridColor; - gridOpacity: number; - brightnessLevel: number; - contrastLevel: number; - saturationLevel: number; canvasBackgroundColor: string; onChangeFrameStep(step: number): void; onChangeFrameSpeed(speed: FrameSpeed): void; onSwitchResetZoom(enabled: boolean): void; onSwitchRotateAll(rotateAll: boolean): void; - onSwitchGrid(grid: boolean): void; - onChangeGridSize(gridSize: number): void; - onChangeGridColor(gridColor: GridColor): void; - onChangeGridOpacity(gridOpacity: number): void; - onChangeBrightnessLevel(level: number): void; - onChangeContrastLevel(level: number): void; - onChangeSaturationLevel(level: number): void; onChangeCanvasBackgroundColor(color: string): void; } @@ -53,32 +38,16 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { frameSpeed, resetZoom, rotateAll, - grid, - gridSize, - gridColor, - gridOpacity, - brightnessLevel, - contrastLevel, - saturationLevel, canvasBackgroundColor, onChangeFrameStep, onChangeFrameSpeed, onSwitchResetZoom, onSwitchRotateAll, - onSwitchGrid, - onChangeGridSize, - onChangeGridColor, - onChangeGridOpacity, - onChangeBrightnessLevel, - onChangeContrastLevel, - onChangeSaturationLevel, onChangeCanvasBackgroundColor, } = props; const minFrameStep = 2; const maxFrameStep = 1000; - const minGridSize = 5; - const maxGridSize = 1000; return (
@@ -89,8 +58,8 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { min={minFrameStep} max={maxFrameStep} value={frameStep} - onChange={(value: number | undefined | string): void => { - if (typeof value !== 'undefined') { + onChange={(value: number | undefined | string | null): void => { + if (typeof value !== 'undefined' && value !== null) { onChangeFrameStep(Math.floor(clamp(+value, minFrameStep, maxFrameStep))); } }} @@ -169,77 +138,6 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { - - - { - onSwitchGrid(event.target.checked); - }} - > - Show grid - - - - - - Grid size - { - if (typeof value !== 'undefined') { - onChangeGridSize(Math.floor(clamp(+value, minGridSize, maxGridSize))); - } - }} - /> - - - Grid color - - - - Grid opacity - { - onChangeGridOpacity(value as number); - }} - /> - {`${gridOpacity} %`} - - @@ -278,68 +176,6 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { - - - - - Brightness - - - { - onChangeBrightnessLevel(value as number); - }} - /> - - - - - Contrast - - - { - onChangeContrastLevel(value as number); - }} - /> - - - - - Saturation - - - { - onChangeSaturationLevel(value as number); - }} - /> - - - - - - - - -
); } diff --git a/cvat-ui/src/components/header/settings-modal/styles.scss b/cvat-ui/src/components/header/settings-modal/styles.scss index 070e38d5..f47a7d52 100644 --- a/cvat-ui/src/components/header/settings-modal/styles.scss +++ b/cvat-ui/src/components/header/settings-modal/styles.scss @@ -23,7 +23,6 @@ padding: 24px; } -.cvat-player-settings-grid, .cvat-workspace-settings-auto-save, .cvat-workspace-settings-autoborders, .cvat-workspace-settings-show-text-always, @@ -35,9 +34,6 @@ } } -.cvat-player-settings-grid-size, -.cvat-player-settings-grid-color, -.cvat-player-settings-grid-opacity, .cvat-player-settings-step, .cvat-player-settings-speed, .cvat-player-settings-reset-zoom, @@ -48,29 +44,6 @@ margin-bottom: 25px; } -.cvat-player-settings-grid-size, -.cvat-player-settings-grid-color, -.cvat-player-settings-grid-opacity { - display: grid; - justify-items: start; -} - -.cvat-player-settings-grid-size-input { - height: fit-content; -} - -.cvat-player-settings-grid-color { - > .ant-select { - width: 150px; - } -} - -.cvat-player-settings-grid-opacity { - > .ant-slider { - width: 150px; - } -} - .cvat-player-settings-step, .cvat-player-settings-speed { > div { @@ -88,13 +61,6 @@ width: 90px; } -.cvat-player-reset-color-settings, -.cvat-player-settings-brightness, -.cvat-player-settings-contrast, -.cvat-player-settings-saturation { - width: 40%; -} - .cvat-player-reset-color-settings { > .ant-col { text-align: center; diff --git a/cvat-ui/src/components/layout-grid/layout-grid.tsx b/cvat-ui/src/components/layout-grid/layout-grid.tsx index 9fa35326..f43c1119 100644 --- a/cvat-ui/src/components/layout-grid/layout-grid.tsx +++ b/cvat-ui/src/components/layout-grid/layout-grid.tsx @@ -1,17 +1,19 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useCallback, useState } from 'react'; import ReactDOM from 'react-dom'; -import { GlobalHotKeys } from 'react-hotkeys'; +import GlobalHotKeys from 'utils/mousetrap-react'; +import { useSelector } from 'react-redux'; +import { CombinedState } from 'reducers/interfaces'; import './styles.scss'; const LayoutGrid = (): React.ReactPortal => { const [showGrid, setShowGrid] = useState(false); - - const keyMap = { - TOGGLE_LAYOUT_GRID: 'ctrl+alt+enter', + const keyMap = useSelector((state: CombinedState) => state.shortcuts.keyMap); + const subKeyMap = { + TOGGLE_LAYOUT_GRID: keyMap.TOGGLE_LAYOUT_GRID, }; const toggleLayoutGrid = useCallback((): void => { @@ -23,9 +25,11 @@ const LayoutGrid = (): React.ReactPortal => { }; const portalContent: JSX.Element = ( - - {showGrid &&
} - {showGrid &&
} + + <> + {showGrid &&
} + {showGrid &&
} + ); diff --git a/cvat-ui/src/components/shortcuts-dialog/shortcuts-dialog.tsx b/cvat-ui/src/components/shortcuts-dialog/shortcuts-dialog.tsx index ca2a75b3..9bf13e16 100644 --- a/cvat-ui/src/components/shortcuts-dialog/shortcuts-dialog.tsx +++ b/cvat-ui/src/components/shortcuts-dialog/shortcuts-dialog.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -6,7 +6,7 @@ import { shortcutsActions } from 'actions/shortcuts-actions'; import Modal from 'antd/lib/modal'; import Table from 'antd/lib/table'; import React from 'react'; -import { getApplicationKeyMap } from 'react-hotkeys'; +import { getApplicationKeyMap } from 'utils/mousetrap-react'; import { connect } from 'react-redux'; import { CombinedState } from 'reducers/interfaces'; @@ -80,8 +80,8 @@ function ShorcutsDialog(props: StateToProps & DispatchToProps): JSX.Element | nu key: id, name: keyMap[key].name || key, description: keyMap[key].description || '', - shortcut: keyMap[key].sequences.map((value) => value.sequence), - action: keyMap[key].sequences.map((value) => value.action || 'keydown'), + shortcut: keyMap[key].sequences, + action: [keyMap[key].action], })); return ( diff --git a/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper.tsx b/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper.tsx index ef8b5dc3..359c0598 100644 --- a/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper.tsx +++ b/cvat-ui/src/containers/annotation-page/canvas/canvas-wrapper.tsx @@ -1,8 +1,8 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT -import { ExtendedKeyMapOptions } from 'react-hotkeys'; +import { KeyMap } from 'utils/mousetrap-react'; import { connect } from 'react-redux'; import CanvasWrapperComponent from 'components/annotation-page/canvas/canvas-wrapper'; @@ -90,7 +90,7 @@ interface StateToProps { curZLayer: number; automaticBordering: boolean; switchableAutomaticBordering: boolean; - keyMap: Record; + keyMap: KeyMap; canvasBackgroundColor: string; } diff --git a/cvat-ui/src/containers/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/containers/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx index 03dc9cb1..2125213a 100644 --- a/cvat-ui/src/containers/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/containers/annotation-page/review-workspace/controls-side-bar/controls-side-bar.tsx @@ -1,8 +1,8 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT -import { ExtendedKeyMapOptions } from 'react-hotkeys'; +import { KeyMap } from 'utils/mousetrap-react'; import { connect } from 'react-redux'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -24,7 +24,7 @@ interface StateToProps { canvasInstance: Canvas; rotateAll: boolean; activeControl: ActiveControl; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; } diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx index aad9b531..22a33f9d 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx @@ -1,8 +1,8 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT -import { ExtendedKeyMapOptions } from 'react-hotkeys'; +import { KeyMap } from 'utils/mousetrap-react'; import { connect } from 'react-redux'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -23,7 +23,7 @@ interface StateToProps { canvasInstance: Canvas; rotateAll: boolean; activeControl: ActiveControl; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; } diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx index 7614bab2..f8c14866 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx @@ -1,10 +1,10 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import { connect } from 'react-redux'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import ObjectsListComponent from 'components/annotation-page/standard-workspace/objects-side-bar/objects-list'; import { @@ -41,7 +41,7 @@ interface StateToProps { minZLayer: number; maxZLayer: number; annotationsFiltersHistory: string[]; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; canvasInstance: Canvas; } @@ -442,7 +442,7 @@ class ObjectsListContainer extends React.PureComponent { return ( <> - + ; + keyMap: KeyMap; normalizedKeyMap: Record; contextImageHide: boolean; loaded: boolean; diff --git a/cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx b/cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx index 5019b143..cb3024e0 100644 --- a/cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx +++ b/cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx @@ -7,7 +7,7 @@ import copy from 'copy-to-clipboard'; import { connect } from 'react-redux'; import { withRouter } from 'react-router'; import { RouteComponentProps } from 'react-router-dom'; -import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys'; +import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import Input from 'antd/lib/input'; import { @@ -45,7 +45,7 @@ interface StateToProps { autoSave: boolean; autoSaveInterval: number; workspace: Workspace; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; canvasInstance: Canvas; forceExit: boolean; @@ -584,7 +584,7 @@ class AnnotationTopBarContainer extends React.PureComponent { return ( <> - + ; -} - -export default connect(mapStateToProps, mapDispatchToProps)(PlayerSettingsContainer); +export default connect(mapStateToProps, mapDispatchToProps)(PlayerSettingsComponent); diff --git a/cvat-ui/src/index.tsx b/cvat-ui/src/index.tsx index 31188f77..35ca24dc 100644 --- a/cvat-ui/src/index.tsx +++ b/cvat-ui/src/index.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -16,7 +16,7 @@ import logger, { LogType } from 'cvat-logger'; import createCVATStore, { getCVATStore } from 'cvat-store'; import React from 'react'; import ReactDOM from 'react-dom'; -import { ExtendedKeyMapOptions } from 'react-hotkeys'; +import { KeyMap } from 'utils/mousetrap-react'; import { connect, Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; import createRootReducer from 'reducers/root-reducer'; @@ -45,7 +45,7 @@ interface StateToProps { allowResetPassword: boolean; notifications: NotificationsState; user: any; - keyMap: Record; + keyMap: KeyMap; isModelPluginActive: boolean; } diff --git a/cvat-ui/src/reducers/interfaces.ts b/cvat-ui/src/reducers/interfaces.ts index 2f09b198..fa20fe5c 100644 --- a/cvat-ui/src/reducers/interfaces.ts +++ b/cvat-ui/src/reducers/interfaces.ts @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: MIT -import { ExtendedKeyMapOptions } from 'react-hotkeys'; -import { Canvas, RectDrawingMethod } from 'cvat-canvas-wrapper'; -import { IntelligentScissors } from 'utils/opencv-wrapper/intelligent-scissors'; import { MutableRefObject } from 'react'; +import { Canvas, RectDrawingMethod } from 'cvat-canvas-wrapper'; import { Canvas3d } from 'cvat-canvas3d/src/typescript/canvas3d'; +import { IntelligentScissors } from 'utils/opencv-wrapper/intelligent-scissors'; +import { KeyMap } from 'utils/mousetrap-react'; export type StringObject = { [index: string]: string; @@ -539,7 +539,7 @@ export interface SettingsState { export interface ShortcutsState { visibleShortcutsHelp: boolean; - keyMap: Record; + keyMap: KeyMap; normalizedKeyMap: Record; } diff --git a/cvat-ui/src/reducers/shortcuts-reducer.ts b/cvat-ui/src/reducers/shortcuts-reducer.ts index 788c2831..98baa9aa 100644 --- a/cvat-ui/src/reducers/shortcuts-reducer.ts +++ b/cvat-ui/src/reducers/shortcuts-reducer.ts @@ -1,15 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT -import { ExtendedKeyMapOptions } from 'react-hotkeys'; - import { BoundariesActions, BoundariesActionTypes } from 'actions/boundaries-actions'; import { AuthActions, AuthActionTypes } from 'actions/auth-actions'; import { ShortcutsActions, ShortcutsActionsTypes } from 'actions/shortcuts-actions'; +import { KeyMap, KeyMapItem } from 'utils/mousetrap-react'; import { ShortcutsState } from './interfaces'; -function formatShortcuts(shortcuts: ExtendedKeyMapOptions): string { +function formatShortcuts(shortcuts: KeyMapItem): string { const list: string[] = shortcuts.sequences as string[]; return `[${list .map((shortcut: string): string => { @@ -39,7 +38,7 @@ const defaultKeyMap = ({ SWITCH_ALL_LOCK: { name: 'Lock/unlock all objects', description: 'Change locked state for all objects in the side bar', - sequences: ['t+l'], + sequences: ['t l'], action: 'keydown', }, SWITCH_LOCK: { @@ -51,7 +50,7 @@ const defaultKeyMap = ({ SWITCH_ALL_HIDDEN: { name: 'Hide/show all objects', description: 'Change hidden state for objects in the side bar', - sequences: ['t+h'], + sequences: ['t h'], action: 'keydown', }, SWITCH_HIDDEN: { @@ -124,80 +123,25 @@ const defaultKeyMap = ({ NEXT_ATTRIBUTE: { name: 'Next attribute', description: 'Go to the next attribute', - sequences: ['ArrowDown'], + sequences: ['down'], action: 'keydown', }, PREVIOUS_ATTRIBUTE: { name: 'Previous attribute', description: 'Go to the previous attribute', - sequences: ['ArrowUp'], + sequences: ['up'], action: 'keydown', }, NEXT_OBJECT: { name: 'Next object', description: 'Go to the next object', - sequences: ['Tab'], + sequences: ['tab'], action: 'keydown', }, PREVIOUS_OBJECT: { name: 'Previous object', description: 'Go to the previous object', - sequences: ['Shift+Tab'], - action: 'keydown', - }, - - INCREASE_BRIGHTNESS: { - name: 'Brightness+', - description: 'Increase brightness level for the image', - sequences: ['shift+b+='], - action: 'keypress', - }, - DECREASE_BRIGHTNESS: { - name: 'Brightness-', - description: 'Decrease brightness level for the image', - sequences: ['shift+b+-'], - action: 'keydown', - }, - INCREASE_CONTRAST: { - name: 'Contrast+', - description: 'Increase contrast level for the image', - sequences: ['shift+c+='], - action: 'keydown', - }, - DECREASE_CONTRAST: { - name: 'Contrast-', - description: 'Decrease contrast level for the image', - sequences: ['shift+c+-'], - action: 'keydown', - }, - INCREASE_SATURATION: { - name: 'Saturation+', - description: 'Increase saturation level for the image', - sequences: ['shift+s+='], - action: 'keydown', - }, - DECREASE_SATURATION: { - name: 'Saturation-', - description: 'Increase contrast level for the image', - sequences: ['shift+s+-'], - action: 'keydown', - }, - INCREASE_GRID_OPACITY: { - name: 'Grid opacity+', - description: 'Make the grid more visible', - sequences: ['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', - sequences: ['shift+g+enter'], + sequences: ['shift+tab'], action: 'keydown', }, @@ -326,22 +270,28 @@ const defaultKeyMap = ({ FOCUS_INPUT_FRAME: { name: 'Focus input frame', description: 'Focus on the element to change the current frame', - sequences: ['`', '~'], + sequences: ['~'], action: 'keydown', }, SWITCH_AUTOMATIC_BORDERING: { name: 'Switch automatic bordering', description: 'Switch automatic bordering for polygons and polylines during drawing/editing', - sequences: ['Control'], + sequences: ['ctrl'], action: 'keydown', }, CHANGE_OBJECT_COLOR: { name: 'Change color', description: 'Set the next color for an activated shape', - sequences: ['Enter'], + sequences: ['enter'], + action: 'keydown', + }, + TOGGLE_LAYOUT_GRID: { + name: 'Toggle layout grid', + description: 'Is used in development', + sequences: ['ctrl+alt+enter'], action: 'keydown', }, -} as any) as Record; +} as any) as KeyMap; const defaultState: ShortcutsState = { visibleShortcutsHelp: false, diff --git a/cvat-ui/src/utils/mousetrap-react.tsx b/cvat-ui/src/utils/mousetrap-react.tsx new file mode 100644 index 00000000..c51fe5fc --- /dev/null +++ b/cvat-ui/src/utils/mousetrap-react.tsx @@ -0,0 +1,57 @@ +// Copyright (C) 2021 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React, { useEffect } from 'react'; +import Mousetrap from 'mousetrap'; + +export interface KeyMapItem { + name: string; + description: string; + sequences: string[]; + action: 'keydown' | 'keyup' | 'keypress'; +} + +export interface KeyMap { + [index: string]: KeyMapItem; +} + +export interface Handlers { + [index: string]: (event: KeyboardEvent) => void; +} + +interface Props { + children?: JSX.Element; + keyMap: KeyMap; + handlers: Handlers; +} + +const applicationKeyMap: KeyMap = {}; + +export default function GlobalHotKeys(props: Props): JSX.Element { + const { children, keyMap, handlers } = props; + useEffect(() => { + for (const key of Object.keys(keyMap)) { + const { sequences, action } = keyMap[key]; + const handler = handlers[key]; + Mousetrap.bind(sequences, handler, action); + applicationKeyMap[key] = keyMap[key]; + } + + return () => { + for (const key of Object.keys(keyMap)) { + const { sequences, action } = keyMap[key]; + Mousetrap.unbind(sequences, action); + delete applicationKeyMap[key]; + } + }; + }); + + return children || <>; +} + +export function getApplicationKeyMap(): KeyMap { + return { + ...applicationKeyMap, + }; +} diff --git a/tests/cypress/integration/actions_tasks_objects/case_23_canvas_grid_feature.js b/tests/cypress/integration/actions_tasks_objects/case_23_canvas_grid_feature.js index 8c24dc46..81cd9cdc 100644 --- a/tests/cypress/integration/actions_tasks_objects/case_23_canvas_grid_feature.js +++ b/tests/cypress/integration/actions_tasks_objects/case_23_canvas_grid_feature.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -22,22 +22,20 @@ context('Canvas grid feature', () => { before(() => { cy.openTaskJob(taskName); + cy.get('.cvat-canvas-image-setups-trigger').click(); }); describe(`Testing case "${caseId}"`, () => { - it('Go to settings.', () => { - cy.openSettings(); - }); it('Set "Show grid" to true.', () => { - cy.get('.cvat-player-settings-grid').click(); + cy.get('.cvat-image-setups-grid').click(); }); it('Set "Grid size" to 50.', () => { - cy.get('.cvat-player-settings-grid-size-input').within(() => { + cy.get('.cvat-image-setups-grid-size-input').within(() => { cy.get('[role="spinbutton"]').clear().type(settingsGridSize); }); }); it('Set "Grid color" to black.', () => { - cy.get('.cvat-player-settings-grid-color-input').click(); + cy.get('.cvat-image-setups-grid-color-input').click(); cy.get('.ant-select-dropdown') .not('.ant-select-dropdown-hidden') .within(() => { @@ -45,7 +43,7 @@ context('Canvas grid feature', () => { }); }); it('Set "Grid opacity" to 80%.', () => { - cy.get('.cvat-player-settings-grid-opacity-input').within(() => { + cy.get('.cvat-image-setups-grid-opacity-input').within(() => { cy.get('[role="slider"]').type(generateString(20)); // Moving the slider to the left up to 80. cy.get('[role="slider"]').should('have.attr', 'aria-valuenow', gridOpacity); }); diff --git a/tests/cypress/integration/actions_tasks_objects/case_26_canvas_brightness_contrast_saturation_feature.js b/tests/cypress/integration/actions_tasks_objects/case_26_canvas_brightness_contrast_saturation_feature.js index c5f64156..ed343710 100644 --- a/tests/cypress/integration/actions_tasks_objects/case_26_canvas_brightness_contrast_saturation_feature.js +++ b/tests/cypress/integration/actions_tasks_objects/case_26_canvas_brightness_contrast_saturation_feature.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -12,41 +12,45 @@ context('Canvas brightness/contrast/saturation feature', () => { const defaultValueInSidebar = 100; const expectedResultInSetting = defaultValueInSidebar + countActionMoveSlider; const classNameSliders = [ - '.cvat-player-settings-brightness', - '.cvat-player-settings-contrast', - '.cvat-player-settings-saturation', + '.cvat-image-setups-brightness', + '.cvat-image-setups-contrast', + '.cvat-image-setups-saturation', ]; function generateStringCountAction(countAction) { let stringAction = ''; for (let i = 0; i < countAction; i++) { stringAction += '{rightarrow}'; - }; + } return stringAction; - }; + } function checkStateValuesInBackground(expectedValue) { cy.get('#cvat_canvas_background') .should('have.attr', 'style') - .and('contain', `filter: brightness(${expectedValue}) contrast(${expectedValue}) saturate(${expectedValue})`); - }; + .and( + 'contain', + `filter: brightness(${expectedValue}) contrast(${expectedValue}) saturate(${expectedValue})`, + ); + } before(() => { cy.openTaskJob(taskName); + cy.get('.cvat-canvas-image-setups-trigger').click(); }); describe(`Testing case "${caseId}"`, () => { it('Check apply of settings', () => { let stringAction = generateStringCountAction(countActionMoveSlider); - cy.openSettings(); - cy.get('.cvat-settings-modal').within(() => { - cy.contains('Player').click(); + cy.get('.cvat-canvas-image-setups-content').within(() => { cy.wrap(classNameSliders).each(($el) => { - cy.wrap($el).get($el).within(() => { - cy.get('[role=slider]') - .type(stringAction) - .should('have.attr', 'aria-valuenow', expectedResultInSetting); - }); + cy.wrap($el) + .get($el) + .within(() => { + cy.get('[role=slider]') + .type(stringAction) + .should('have.attr', 'aria-valuenow', expectedResultInSetting); + }); }); }); const expectedResultInBackground = (defaultValueInSidebar + countActionMoveSlider) / 100; @@ -54,7 +58,7 @@ context('Canvas brightness/contrast/saturation feature', () => { }); it('Check reset of settings', () => { - cy.get('.cvat-player-reset-color-settings').click(); + cy.get('.cvat-image-setups-reset-color-settings').find('button').click(); const expectedResultInBackground = defaultValueInSidebar / 100; checkStateValuesInBackground(expectedResultInBackground); }); diff --git a/tests/cypress/integration/actions_tasks_objects/issue_1433_hide_functionality.js b/tests/cypress/integration/actions_tasks_objects/issue_1433_hide_functionality.js index 6dc8f5ad..cc49d88e 100644 --- a/tests/cypress/integration/actions_tasks_objects/issue_1433_hide_functionality.js +++ b/tests/cypress/integration/actions_tasks_objects/issue_1433_hide_functionality.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -24,11 +24,12 @@ context('Check hide functionality (H)', () => { describe(`Testing issue "${issueId}"`, () => { it('Object is hidden', () => { + const keyCodeH = 72; cy.createRectangle(createRectangleShape2Points); cy.get('#cvat_canvas_shape_1') .trigger('mousemove') .trigger('mouseover') - .trigger('keydown', { key: 'h' }) + .trigger('keydown', { keyCode: keyCodeH }) .should('be.hidden'); }); }); diff --git a/tests/cypress/integration/actions_tasks_objects/issue_1540_add_remove_tag.js b/tests/cypress/integration/actions_tasks_objects/issue_1540_add_remove_tag.js index 273b6685..80ac02b2 100644 --- a/tests/cypress/integration/actions_tasks_objects/issue_1540_add_remove_tag.js +++ b/tests/cypress/integration/actions_tasks_objects/issue_1540_add_remove_tag.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -22,11 +22,12 @@ context('Check if the UI not to crash after remove a tag', () => { cy.changeWorkspace('Standard'); }); it('Remove the tag', () => { + const keyCodeDel = 46; cy.get('#cvat-objects-sidebar-state-item-1') .should('contain', '1') .and('contain', 'TAG') .trigger('mouseover') - .trigger('keydown', { key: 'Delete' }); + .trigger('keydown', { keyCode: keyCodeDel }); }); it('Page with the error is missing', () => { cy.contains('Oops, something went wrong').should('not.exist'); diff --git a/tests/cypress/integration/actions_tasks_objects/issue_1882_polygon_interpolation.js b/tests/cypress/integration/actions_tasks_objects/issue_1882_polygon_interpolation.js index 95092731..867395fe 100644 --- a/tests/cypress/integration/actions_tasks_objects/issue_1882_polygon_interpolation.js +++ b/tests/cypress/integration/actions_tasks_objects/issue_1882_polygon_interpolation.js @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -43,10 +43,11 @@ context("The points of the previous polygon mustn't appear while polygon's inter cy.get('#cvat-objects-sidebar-state-item-1').should('contain', '1').and('contain', 'POLYGON TRACK'); }); it('Redraw the polygon', () => { + const keyCodeN = 78; cy.get('#cvat_canvas_shape_1') .trigger('mousemove', { force: true }) - .trigger('keydown', { key: 'n', shiftKey: true }) - .trigger('keyup', { force: true }, { key: 'n', shiftKey: true }); + .trigger('keydown', { keyCode: keyCodeN, shiftKey: true }) + .trigger('keyup', { force: true }, { keyCode: keyCodeN, shiftKey: true }); cy.createPolygon(reDrawPolygonTrack); }); it('Activate auto bordering mode', () => { diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index 3ffab4f6..63ac25d9 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -216,7 +216,10 @@ Cypress.Commands.add('createPoint', (createPointParams) => { cy.get('.cvat-canvas-container').click(element.x, element.y); }); if (createPointParams.complete) { - cy.get('.cvat-canvas-container').trigger('keydown', { key: 'n' }).trigger('keyup', { key: 'n' }); + const keyCodeN = 78; + cy.get('.cvat-canvas-container') + .trigger('keydown', { keyCode: keyCodeN }) + .trigger('keyup', { keyCode: keyCodeN }); } cy.checkObjectParameters(createPointParams, 'POINTS'); }); @@ -228,14 +231,15 @@ Cypress.Commands.add('changeAppearance', (colorBy) => { }); Cypress.Commands.add('shapeGrouping', (firstX, firstY, lastX, lastY) => { + const keyCodeG = 71; cy.get('.cvat-canvas-container') - .trigger('keydown', { key: 'g' }) - .trigger('keyup', { key: 'g' }) + .trigger('keydown', { keyCode: keyCodeG }) + .trigger('keyup', { keyCode: keyCodeG }) .trigger('mousedown', firstX, firstY, { which: 1 }) .trigger('mousemove', lastX, lastY) .trigger('mouseup', lastX, lastY) - .trigger('keydown', { key: 'g' }) - .trigger('keyup', { key: 'g' }); + .trigger('keydown', { keyCode: keyCodeG }) + .trigger('keyup', { keyCode: keyCodeG }); }); Cypress.Commands.add('createPolygon', (createPolygonParams) => { @@ -257,7 +261,10 @@ Cypress.Commands.add('createPolygon', (createPolygonParams) => { cy.get('.cvat-canvas-container').click(element.x, element.y); }); if (createPolygonParams.complete) { - cy.get('.cvat-canvas-container').trigger('keydown', { key: 'n' }).trigger('keyup', { key: 'n' }); + const keyCodeN = 78; + cy.get('.cvat-canvas-container') + .trigger('keydown', { keyCode: keyCodeN }) + .trigger('keyup', { keyCode: keyCodeN }); } cy.checkObjectParameters(createPolygonParams, 'POLYGON'); }); @@ -383,7 +390,10 @@ Cypress.Commands.add('createPolyline', (createPolylineParams) => { cy.get('.cvat-canvas-container').click(element.x, element.y); }); if (createPolylineParams.complete) { - cy.get('.cvat-canvas-container').trigger('keydown', { key: 'n' }).trigger('keyup', { key: 'n' }); + const keyCodeN = 78; + cy.get('.cvat-canvas-container') + .trigger('keydown', { keyCode: keyCodeN }) + .trigger('keyup', { keyCode: keyCodeN }); } cy.checkObjectParameters(createPolylineParams, 'POLYLINE'); });