From 25309732ddbd8d7eaf1192291d0c49c8fb1ea5d9 Mon Sep 17 00:00:00 2001 From: Kirill Lakhov Date: Tue, 10 Dec 2024 11:46:15 +0300 Subject: [PATCH 1/4] added finish draw on submit click + refactoring --- .../single-shape-sidebar.tsx | 7 +++++ .../annotation-page/top-bar/left-group.tsx | 9 ++---- .../annotation-page/top-bar/top-bar.tsx | 11 ++----- cvat-ui/src/utils/drawing.ts | 29 +++++++++++++++++++ 4 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 cvat-ui/src/utils/drawing.ts diff --git a/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx b/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx index fb2dae58e154..52e61eae2446 100644 --- a/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx @@ -37,6 +37,7 @@ import GlobalHotKeys from 'utils/mousetrap-react'; import { ShortcutScope } from 'utils/enums'; import { registerComponentShortcuts } from 'actions/shortcuts-actions'; import { subKeyMap } from 'utils/component-subkeymap'; +import { finishDraw, finishDrawAvailable } from 'utils/drawing'; enum ReducerActionType { SWITCH_AUTO_NEXT_FRAME = 'SWITCH_AUTO_NEXT_FRAME', @@ -295,6 +296,12 @@ function SingleShapeSidebar(): JSX.Element { if (typeof state.nextFrame === 'number') { appDispatch(changeFrameAsync(state.nextFrame)); } else if ((forceSave || state.saveOnFinish) && !savingRef.current) { + const finishDrawing = finishDrawAvailable(activeControl); + if (finishDrawing) { + const canvas = store.getState().annotation.canvas.instance as Canvas; + finishDraw(canvas, activeControl); + } + savingRef.current = true; appDispatch(finishCurrentJobAsync()).then(() => { diff --git a/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx b/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx index e59d7958528c..9ab9e088289b 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/left-group.tsx @@ -18,6 +18,7 @@ import CVATTooltip from 'components/common/cvat-tooltip'; import { ShortcutScope } from 'utils/enums'; import { subKeyMap } from 'utils/component-subkeymap'; import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; +import { finishDrawAvailable } from 'utils/drawing'; import SaveAnnotationsButton from './save-annotations-button'; interface Props { @@ -78,13 +79,7 @@ function LeftGroup(props: Props): JSX.Element { onSwitchToolsBlockerState, } = props; - const includesDoneButton = [ - ActiveControl.DRAW_POLYGON, - ActiveControl.DRAW_POLYLINE, - ActiveControl.DRAW_POINTS, - ActiveControl.AI_TOOLS, - ActiveControl.OPENCV_TOOLS, - ].includes(activeControl); + const includesDoneButton = finishDrawAvailable(activeControl); const includesToolsBlockerButton = [ActiveControl.OPENCV_TOOLS, ActiveControl.AI_TOOLS].includes(activeControl) && toolsBlockerState.buttonVisible; 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 7185106e05d8..b2966d679258 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 @@ -41,6 +41,7 @@ import isAbleToChangeFrame from 'utils/is-able-to-change-frame'; import { KeyMap } from 'utils/mousetrap-react'; import { switchToolsBlockerState } from 'actions/settings-actions'; import { writeLatestFrame } from 'utils/remember-latest-frame'; +import { finishDraw } from 'utils/drawing'; interface StateToProps { jobInstance: Job; @@ -546,15 +547,7 @@ class AnnotationTopBarContainer extends React.PureComponent { private onFinishDraw = (): void => { const { activeControl, canvasInstance } = this.props; - if ( - [ActiveControl.AI_TOOLS, ActiveControl.OPENCV_TOOLS].includes(activeControl) && - canvasInstance instanceof Canvas - ) { - canvasInstance.interact({ enabled: false }); - return; - } - - canvasInstance.draw({ enabled: false }); + finishDraw(canvasInstance, activeControl); }; private onSwitchToolsBlockerState = (): void => { diff --git a/cvat-ui/src/utils/drawing.ts b/cvat-ui/src/utils/drawing.ts new file mode 100644 index 000000000000..3cca125d855a --- /dev/null +++ b/cvat-ui/src/utils/drawing.ts @@ -0,0 +1,29 @@ +// Copyright (C) 2024 CVAT.ai Corporation +// +// SPDX-License-Identifier: MIT + +import { Canvas } from 'cvat-canvas-wrapper'; +import { Canvas3d } from 'cvat-canvas3d-wrapper'; +import { ActiveControl } from 'reducers'; + +export function finishDrawAvailable(activeControl: ActiveControl): boolean { + return [ + ActiveControl.DRAW_POLYGON, + ActiveControl.DRAW_POLYLINE, + ActiveControl.DRAW_POINTS, + ActiveControl.AI_TOOLS, + ActiveControl.OPENCV_TOOLS, + ].includes(activeControl); +} + +export function finishDraw(canvas: Canvas | Canvas3d, activeControl: ActiveControl): void { + if ( + [ActiveControl.AI_TOOLS, ActiveControl.OPENCV_TOOLS].includes(activeControl) && + canvas instanceof Canvas + ) { + canvas.interact({ enabled: false }); + return; + } + + canvas.draw({ enabled: false }); +} From 3f387030b6401e6dd58024aa5bec2a2bce9f49bf Mon Sep 17 00:00:00 2001 From: Kirill Lakhov Date: Tue, 10 Dec 2024 12:39:53 +0300 Subject: [PATCH 2/4] changelog & package --- .../20241210_120116_klakhov_improve_single_shape_save.md | 4 ++++ cvat-ui/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelog.d/20241210_120116_klakhov_improve_single_shape_save.md diff --git a/changelog.d/20241210_120116_klakhov_improve_single_shape_save.md b/changelog.d/20241210_120116_klakhov_improve_single_shape_save.md new file mode 100644 index 000000000000..7654a174b19f --- /dev/null +++ b/changelog.d/20241210_120116_klakhov_improve_single_shape_save.md @@ -0,0 +1,4 @@ +### Added + +- Saving drawn shape on submit in `single shape` mode + () diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 703718121cd1..8c5df6547df3 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.67.0", + "version": "1.67.1", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { From a881d9966109ee24961d2b187fad5d34952d6af9 Mon Sep 17 00:00:00 2001 From: Kirill Lakhov Date: Wed, 18 Dec 2024 10:43:19 +0300 Subject: [PATCH 3/4] added dependency, changed defining shape type from selected labelType --- .../single-shape-sidebar.tsx | 4 ++-- cvat-ui/src/reducers/annotation-reducer.ts | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx b/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx index 52e61eae2446..00521d87ef3b 100644 --- a/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx +++ b/cvat-ui/src/components/annotation-page/single-shape-workspace/single-shape-sidebar/single-shape-sidebar.tsx @@ -261,7 +261,7 @@ function SingleShapeSidebar(): JSX.Element { appDispatch(rememberObject({ activeObjectType: ObjectType.SHAPE, activeLabelID: state.label.id, - activeShapeType: labelShapeType(state.label), + activeShapeType: labelShapeType(state.labelType), })); canvas.draw({ @@ -317,7 +317,7 @@ function SingleShapeSidebar(): JSX.Element { savingRef.current = false; }); } - }, [state.saveOnFinish, state.nextFrame, jobInstance]); + }, [state.saveOnFinish, state.nextFrame, jobInstance, activeControl]); useEffect(() => { const defaultLabelInstance = defaultLabel ? state.labels diff --git a/cvat-ui/src/reducers/annotation-reducer.ts b/cvat-ui/src/reducers/annotation-reducer.ts index 311f54c0fe96..7a60ab2c3f7d 100644 --- a/cvat-ui/src/reducers/annotation-reducer.ts +++ b/cvat-ui/src/reducers/annotation-reducer.ts @@ -31,13 +31,18 @@ function updateActivatedStateID(newStates: any[], prevActivatedStateID: number | null; } -export function labelShapeType(label?: Label): ShapeType | null { - if (label && Object.values(ShapeType).includes(label.type as any)) { - return label.type as unknown as ShapeType; - } - if (label?.type === LabelType.TAG) { - return null; +export function labelShapeType(labelData?: Label | Partial): ShapeType | null { + const labelType = labelData instanceof Label ? labelData.type : labelData; + if (labelType) { + if (Object.values(ShapeType).includes(labelType as any)) { + return labelType as unknown as ShapeType; + } + + if (labelType === LabelType.TAG) { + return null; + } } + return ShapeType.RECTANGLE; } From 01e0313562fc6e591b52aea8dbcf62791a97d4c3 Mon Sep 17 00:00:00 2001 From: Kirill Lakhov Date: Thu, 23 Jan 2025 12:15:36 +0300 Subject: [PATCH 4/4] updated package json --- cvat-ui/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 2af09a07c7f3..cbc584303933 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.67.1", + "version": "2.25.1", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": {