From 4eeb94d3ba72856166f263cf08fc977f4f3ca953 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 18:50:15 +0300 Subject: [PATCH 01/10] Validation for frame input value --- .../top-bar/player-navigation.tsx | 37 ++++++++++++------- .../annotation-page/top-bar/top-bar.tsx | 8 +--- .../annotation-page/top-bar/top-bar.tsx | 2 +- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 397bf8d6..93d25911 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -2,18 +2,13 @@ // // SPDX-License-Identifier: MIT -import React from 'react'; +import React, { useState } from 'react'; -import { - Row, - Col, - Icon, - Slider, - Tooltip, - InputNumber, -} from 'antd'; - -import { SliderValue } from 'antd/lib/slider'; +import { Row, Col } from 'antd/lib/grid'; +import Icon from 'antd/lib/icon'; +import Slider, { SliderValue } from 'antd/lib/slider'; +import Tooltip from 'antd/lib/tooltip'; +import InputNumber from 'antd/lib/input-number'; import Text from 'antd/lib/typography/Text'; interface Props { @@ -37,6 +32,8 @@ function PlayerNavigation(props: Props): JSX.Element { onURLIconClick, } = props; + const [frameInputValue, setFrameInputValue] = useState(frameNumber); + return ( <> @@ -68,9 +65,23 @@ function PlayerNavigation(props: Props): JSX.Element { { + setFrameInputValue( + Math.max( + Math.min( + Number(value), stopFrame, + ), startFrame, + ), + ); + }} + onBlur={() => { + onInputChange(frameInputValue); + }} + onPressEnter={() => { + onInputChange(frameInputValue); + }} ref={inputFrameRef} /> diff --git a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx index 370702fe..5942fbae 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx @@ -4,12 +4,8 @@ import React from 'react'; -import { - Row, - Col, - InputNumber, -} from 'antd'; - +import { Row, Col } from 'antd/lib/grid'; +import InputNumber from 'antd/lib/input-number'; import { SliderValue } from 'antd/lib/slider'; import { Workspace } from 'reducers/interfaces'; 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 48695dbe..ebde5bd3 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 @@ -10,7 +10,7 @@ import { withRouter } from 'react-router'; import { RouteComponentProps } from 'react-router-dom'; import { GlobalHotKeys, KeyMap } from 'react-hotkeys'; -import { InputNumber } from 'antd'; +import InputNumber from 'antd/lib/input-number'; import { SliderValue } from 'antd/lib/slider'; import { From e55deb7142ab019b87ab4c9fbb0a48df579ba179 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 19:01:02 +0300 Subject: [PATCH 02/10] Fixed UI fail when write characters in auto save interval input --- .../top-bar/player-navigation.tsx | 16 +++---- .../settings-page/workspace-settings.tsx | 42 ++++++++++++------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 93d25911..666b504f 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -68,13 +68,15 @@ function PlayerNavigation(props: Props): JSX.Element { value={frameInputValue} // https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput onChange={(value: number | undefined) => { - setFrameInputValue( - Math.max( - Math.min( - Number(value), stopFrame, - ), startFrame, - ), - ); + if (typeof (value) === 'number') { + setFrameInputValue( + Math.max( + Math.min( + Number(value), stopFrame, + ), startFrame, + ), + ); + } }} onBlur={() => { onInputChange(frameInputValue); diff --git a/cvat-ui/src/components/settings-page/workspace-settings.tsx b/cvat-ui/src/components/settings-page/workspace-settings.tsx index a7a5fd2c..e287bb75 100644 --- a/cvat-ui/src/components/settings-page/workspace-settings.tsx +++ b/cvat-ui/src/components/settings-page/workspace-settings.tsx @@ -4,15 +4,10 @@ import React from 'react'; -import { - Row, - Col, - Checkbox, - InputNumber, -} from 'antd'; - +import { Row, Col } from 'antd/lib/grid'; +import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; +import InputNumber from 'antd/lib/input-number'; import Text from 'antd/lib/typography/Text'; -import { CheckboxChangeEvent } from 'antd/lib/checkbox'; interface Props { autoSave: boolean; @@ -37,6 +32,11 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { onSwitchShowingInterpolatedTracks, } = props; + const minAutoSaveInterval = 5; + const maxAutoSaveInterval = 60; + const minAAMMargin = 0; + const maxAAMMargin = 1000; + return (
@@ -56,13 +56,19 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { Auto save every { - if (value) { - onChangeAutoSaveInterval(value * 60 * 1000); + if (typeof (value) === 'number') { + onChangeAutoSaveInterval( + Math.max( + Math.min( + Number(value), maxAutoSaveInterval, + ), minAutoSaveInterval, + ) * 60 * 1000, + ); } }} /> @@ -89,12 +95,18 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { Attribute annotation mode (AAM) zoom margin { if (typeof (value) === 'number') { - onChangeAAMZoomMargin(value); + onChangeAAMZoomMargin( + Math.max( + Math.min( + Number(value), maxAAMMargin, + ), minAAMMargin, + ), + ); } }} /> From b12ae3471b6898a4a0c28949c836b1916440e5d4 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 19:13:58 +0300 Subject: [PATCH 03/10] Fixed input numbers in player settings --- .../top-bar/player-navigation.tsx | 10 ++-- .../settings-page/player-settings.tsx | 51 +++++++++---------- .../settings-page/workspace-settings.tsx | 18 +++---- cvat-ui/src/utils/math.ts | 4 ++ 4 files changed, 37 insertions(+), 46 deletions(-) create mode 100644 cvat-ui/src/utils/math.ts diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 666b504f..11a59dee 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -11,6 +11,8 @@ import Tooltip from 'antd/lib/tooltip'; import InputNumber from 'antd/lib/input-number'; import Text from 'antd/lib/typography/Text'; +import { clamp } from 'utils/math'; + interface Props { startFrame: number; stopFrame: number; @@ -69,13 +71,7 @@ function PlayerNavigation(props: Props): JSX.Element { // https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput onChange={(value: number | undefined) => { if (typeof (value) === 'number') { - setFrameInputValue( - Math.max( - Math.min( - Number(value), stopFrame, - ), startFrame, - ), - ); + setFrameInputValue(clamp(value, stopFrame, startFrame)); } }} onBlur={() => { diff --git a/cvat-ui/src/components/settings-page/player-settings.tsx b/cvat-ui/src/components/settings-page/player-settings.tsx index 73f2a00a..84717863 100644 --- a/cvat-ui/src/components/settings-page/player-settings.tsx +++ b/cvat-ui/src/components/settings-page/player-settings.tsx @@ -4,28 +4,17 @@ import React from 'react'; -import { - Row, - Col, - Checkbox, - Slider, - Select, - InputNumber, - Icon, -} from 'antd'; - +import { Row, Col } from 'antd/lib/grid'; +import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; +import Slider from 'antd/lib/slider'; +import Select from 'antd/lib/select'; +import InputNumber from 'antd/lib/input-number'; +import Icon from 'antd/lib/icon'; import Text from 'antd/lib/typography/Text'; -import { CheckboxChangeEvent } from 'antd/lib/checkbox'; - -import { - BackJumpIcon, - ForwardJumpIcon, -} from 'icons'; -import { - FrameSpeed, - GridColor, -} from 'reducers/interfaces'; +import { clamp } from 'utils/math'; +import { BackJumpIcon, ForwardJumpIcon } from 'icons'; +import { FrameSpeed, GridColor } from 'reducers/interfaces'; interface Props { frameStep: number; @@ -78,18 +67,24 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { onChangeSaturationLevel, } = props; + const minFrameStep = 2; + const maxFrameStep = 1000; + const minGridSize = 5; + const maxGridSize = 1000; + + return (
Player step { - if (value) { - onChangeFrameStep(value); + if (typeof (value) === 'number') { + onChangeFrameStep(clamp(value, minFrameStep, maxFrameStep)); } }} /> @@ -138,14 +133,14 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { Grid size { - if (value) { - onChangeGridSize(value); + if (typeof (value) === 'number') { + onChangeGridSize(clamp(value, minGridSize, maxGridSize)); } }} /> diff --git a/cvat-ui/src/components/settings-page/workspace-settings.tsx b/cvat-ui/src/components/settings-page/workspace-settings.tsx index e287bb75..23770178 100644 --- a/cvat-ui/src/components/settings-page/workspace-settings.tsx +++ b/cvat-ui/src/components/settings-page/workspace-settings.tsx @@ -9,6 +9,8 @@ import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import InputNumber from 'antd/lib/input-number'; import Text from 'antd/lib/typography/Text'; +import { clamp } from 'utils/math'; + interface Props { autoSave: boolean; autoSaveInterval: number; @@ -63,10 +65,10 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { onChange={(value: number | undefined): void => { if (typeof (value) === 'number') { onChangeAutoSaveInterval( - Math.max( - Math.min( - Number(value), maxAutoSaveInterval, - ), minAutoSaveInterval, + clamp( + value, + minAutoSaveInterval, + maxAutoSaveInterval, ) * 60 * 1000, ); } @@ -100,13 +102,7 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { value={aamZoomMargin} onChange={(value: number | undefined): void => { if (typeof (value) === 'number') { - onChangeAAMZoomMargin( - Math.max( - Math.min( - Number(value), maxAAMMargin, - ), minAAMMargin, - ), - ); + onChangeAAMZoomMargin(clamp(value, minAAMMargin, maxAAMMargin)); } }} /> diff --git a/cvat-ui/src/utils/math.ts b/cvat-ui/src/utils/math.ts new file mode 100644 index 00000000..960bd4d1 --- /dev/null +++ b/cvat-ui/src/utils/math.ts @@ -0,0 +1,4 @@ +/* eslint-disable-next-line import/prefer-default-export */ +export function clamp(value: number, min: number, max: number): number { + return Math.max(Math.min(value, max), min); +} From d789087dd36bdf8ee9c71342a38e950128ae8716 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 19:46:44 +0300 Subject: [PATCH 04/10] Fixed ui failing in propagate confirmation --- .../standard-workspace/propagate-confirm.tsx | 41 +++++++++++++++---- .../top-bar/player-navigation.tsx | 7 +++- .../settings-page/player-settings.tsx | 11 +++-- .../settings-page/workspace-settings.tsx | 10 +++-- .../standard-workspace/propagate-confirm.tsx | 18 ++++---- 5 files changed, 63 insertions(+), 24 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx index f47d5b12..9f68bb64 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx @@ -4,17 +4,17 @@ import React from 'react'; -import { - Modal, - InputNumber, -} from 'antd'; - +import Modal from 'antd/lib/modal'; +import InputNumber from 'antd/lib/input-number'; import Text from 'antd/lib/typography/Text'; +import { clamp } from 'utils/math'; interface Props { visible: boolean; propagateFrames: number; propagateUpToFrame: number; + stopFrame: number; + frameNumber: number; propagateObject(): void; cancel(): void; changePropagateFrames(value: number | undefined): void; @@ -26,12 +26,16 @@ export default function PropagateConfirmComponent(props: Props): JSX.Element { visible, propagateFrames, propagateUpToFrame, + stopFrame, + frameNumber, propagateObject, changePropagateFrames, changeUpToFrame, cancel, } = props; + const minPropagateFrames = 1; + return (
Do you want to make a copy of the object on - + { + if (typeof (value) === 'number') { + changePropagateFrames(Math.floor( + clamp(value, minPropagateFrames, Number.MAX_SAFE_INTEGER), + )); + } + }} + /> { propagateFrames > 1 ? frames : frame } up to the - + { + if (typeof (value) === 'number') { + changeUpToFrame(Math.floor( + clamp(value, frameNumber + 1, stopFrame), + )); + } + }} + /> frame
diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 11a59dee..d3a727ee 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -35,6 +35,9 @@ function PlayerNavigation(props: Props): JSX.Element { } = props; const [frameInputValue, setFrameInputValue] = useState(frameNumber); + if (frameNumber !== frameInputValue) { + setFrameInputValue(frameNumber); + } return ( <> @@ -71,7 +74,9 @@ function PlayerNavigation(props: Props): JSX.Element { // https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput onChange={(value: number | undefined) => { if (typeof (value) === 'number') { - setFrameInputValue(clamp(value, stopFrame, startFrame)); + setFrameInputValue(Math.floor( + clamp(value, stopFrame, startFrame), + )); } }} onBlur={() => { diff --git a/cvat-ui/src/components/settings-page/player-settings.tsx b/cvat-ui/src/components/settings-page/player-settings.tsx index 84717863..779a03b0 100644 --- a/cvat-ui/src/components/settings-page/player-settings.tsx +++ b/cvat-ui/src/components/settings-page/player-settings.tsx @@ -84,7 +84,11 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { value={frameStep} onChange={(value: number | undefined): void => { if (typeof (value) === 'number') { - onChangeFrameStep(clamp(value, minFrameStep, maxFrameStep)); + onChangeFrameStep( + Math.floor( + clamp(value, minFrameStep, maxFrameStep), + ), + ); } }} /> @@ -135,12 +139,13 @@ export default function PlayerSettingsComponent(props: Props): JSX.Element { { if (typeof (value) === 'number') { - onChangeGridSize(clamp(value, minGridSize, maxGridSize)); + onChangeGridSize(Math.floor( + clamp(value, minGridSize, maxGridSize), + )); } }} /> diff --git a/cvat-ui/src/components/settings-page/workspace-settings.tsx b/cvat-ui/src/components/settings-page/workspace-settings.tsx index 23770178..52ba4a50 100644 --- a/cvat-ui/src/components/settings-page/workspace-settings.tsx +++ b/cvat-ui/src/components/settings-page/workspace-settings.tsx @@ -64,13 +64,13 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { value={Math.round(autoSaveInterval / (60 * 1000))} onChange={(value: number | undefined): void => { if (typeof (value) === 'number') { - onChangeAutoSaveInterval( + onChangeAutoSaveInterval(Math.floor( clamp( value, minAutoSaveInterval, maxAutoSaveInterval, - ) * 60 * 1000, - ); + ), + ) * 60 * 1000); } }} /> @@ -102,7 +102,9 @@ export default function WorkspaceSettingsComponent(props: Props): JSX.Element { value={aamZoomMargin} onChange={(value: number | undefined): void => { if (typeof (value) === 'number') { - onChangeAAMZoomMargin(clamp(value, minAAMMargin, maxAAMMargin)); + onChangeAAMZoomMargin(Math.floor( + clamp(value, minAAMMargin, maxAAMMargin), + )); } }} /> diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx index e7c4d706..e795cd56 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx @@ -13,6 +13,7 @@ import { import { CombinedState } from 'reducers/interfaces'; import PropagateConfirmComponent from 'components/annotation-page/standard-workspace/propagate-confirm'; +import { clamp } from 'utils/math'; interface StateToProps { objectState: any | null; @@ -88,23 +89,20 @@ class PropagateConfirmContainer extends React.PureComponent { propagateObject(jobInstance, objectState, frameNumber + 1, propagateUpToFrame); }; - private changePropagateFrames = (value: number | undefined): void => { + private changePropagateFrames = (value: number): void => { const { changePropagateFrames } = this.props; - if (typeof (value) !== 'undefined') { - changePropagateFrames(value); - } + changePropagateFrames(value); }; - private changeUpToFrame = (value: number | undefined): void => { + private changeUpToFrame = (value: number): void => { const { stopFrame, frameNumber, changePropagateFrames, } = this.props; - if (typeof (value) !== 'undefined') { - const propagateFrames = Math.max(0, Math.min(stopFrame, value)) - frameNumber; - changePropagateFrames(propagateFrames); - } + + const propagateFrames = Math.max(0, Math.min(stopFrame, value)) - frameNumber; + changePropagateFrames(propagateFrames); }; public render(): JSX.Element { @@ -122,6 +120,8 @@ class PropagateConfirmContainer extends React.PureComponent { Date: Tue, 24 Mar 2020 20:12:22 +0300 Subject: [PATCH 05/10] Fixed latest input numbers, removed extra code, fixed typings --- .../attribute-editor.tsx | 7 --- .../controls-side-bar/draw-shape-popover.tsx | 26 ++++++---- .../objects-side-bar/object-item.tsx | 52 +++++++++---------- .../standard-workspace/propagate-confirm.tsx | 4 +- .../top-bar/player-navigation.tsx | 4 +- .../annotation-page/top-bar/top-bar.tsx | 2 +- .../controls-side-bar/draw-shape-popover.tsx | 12 ++--- .../standard-workspace/propagate-confirm.tsx | 1 - .../annotation-page/top-bar/top-bar.tsx | 2 +- 9 files changed, 48 insertions(+), 62 deletions(-) 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 5b9150a2..de8a6222 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 @@ -9,7 +9,6 @@ import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Select, { SelectValue } from 'antd/lib/select'; import Radio, { RadioChangeEvent } from 'antd/lib/radio'; import Input from 'antd/lib/input'; -import InputNumber from 'antd/lib/input-number'; interface InputElementParameters { attrID: number; @@ -17,7 +16,6 @@ interface InputElementParameters { values: string[]; currentValue: string; onChange(value: string): void; - ref: React.RefObject; } function renderInputElement(parameters: InputElementParameters): JSX.Element { @@ -27,7 +25,6 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element { values, currentValue, onChange, - ref, } = parameters; const renderCheckbox = (): JSX.Element => ( @@ -114,7 +111,6 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element { } }} onKeyDown={handleKeydown} - ref={ref as React.RefObject} />
@@ -259,8 +255,6 @@ interface Props { function AttributeEditor(props: Props): JSX.Element { const { attribute, currentValue, onChange } = props; const { inputType, values, id: attrID } = attribute; - const ref = inputType === 'number' ? React.createRef() - : React.createRef(); return (
@@ -268,7 +262,6 @@ function AttributeEditor(props: Props): JSX.Element {
{renderInputElement({ attrID, - ref, inputType, currentValue, values, diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx index 9ee0f8a9..73786bc3 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx @@ -4,20 +4,16 @@ import React from 'react'; -import { - Row, - Col, - Select, - Button, - InputNumber, - Radio, -} from 'antd'; - -import { RadioChangeEvent } from 'antd/lib/radio'; +import { Row, Col } from 'antd/lib/grid'; +import Select from 'antd/lib/select'; +import Button from 'antd/lib/button'; +import InputNumber from 'antd/lib/input-number'; +import Radio, { RadioChangeEvent } from 'antd/lib/radio'; import Text from 'antd/lib/typography/Text'; import { RectDrawingMethod } from 'cvat-canvas'; import { ShapeType } from 'reducers/interfaces'; +import { clamp } from 'utils/math'; interface Props { shapeType: ShapeType; @@ -117,7 +113,15 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { { + if (typeof (value) === 'number') { + onChangePoints(Math.floor( + clamp(value, minimumPoints, Number.MAX_SAFE_INTEGER), + )); + } else if (!value) { + onChangePoints(undefined); + } + }} className='cvat-draw-shape-popover-points-selector' min={minimumPoints} value={numberOfPoints} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx index dc7952cf..12ccd044 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx @@ -4,26 +4,21 @@ import React from 'react'; -import { - Row, - Col, - Icon, - Select, - Radio, - Input, - Collapse, - Checkbox, - InputNumber, - Dropdown, - Menu, - Button, - Modal, - Popover, -} from 'antd'; - +import { Row, Col } from 'antd/lib/grid'; +import Icon from 'antd/lib/icon'; +import Select from 'antd/lib/select'; +import Radio, { RadioChangeEvent } from 'antd/lib/radio'; +import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; +import Input from 'antd/lib/input'; +import InputNumber from 'antd/lib/input-number'; +import Collapse from 'antd/lib/collapse'; +import Dropdown from 'antd/lib/dropdown'; +import Menu from 'antd/lib/menu'; +import Button from 'antd/lib/button'; +import Modal from 'antd/lib/modal'; +import Popover from 'antd/lib/popover'; import Text from 'antd/lib/typography/Text'; -import { RadioChangeEvent } from 'antd/lib/radio'; -import { CheckboxChangeEvent } from 'antd/lib/checkbox'; + import ColorChanger from 'components/annotation-page/standard-workspace/objects-side-bar/color-changer'; import { @@ -36,9 +31,8 @@ import { ForegroundIcon, } from 'icons'; -import { - ObjectType, ShapeType, -} from 'reducers/interfaces'; +import { ObjectType, ShapeType } from 'reducers/interfaces'; +import { clamp } from 'utils/math'; function ItemMenu( serverID: number | undefined, @@ -463,7 +457,7 @@ function ItemAttributeComponent(props: ItemAttributeComponentProps): JSX.Element } if (attrInputType === 'number') { - const [min, max, step] = attrValues; + const [min, max, step] = attrValues.map((value: string): number => +value); return ( <> @@ -476,15 +470,17 @@ function ItemAttributeComponent(props: ItemAttributeComponentProps): JSX.Element { - if (typeof (value) !== 'undefined') { - changeAttribute(attrID, `${value}`); + if (typeof (value) === 'number') { + changeAttribute( + attrID, `${clamp(value, min, max)}`, + ); } }} value={+attrValue} className='cvat-object-item-number-attribute' - min={+min} - max={+max} - step={+step} + min={min} + max={max} + step={step} /> diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx index 9f68bb64..66bebffa 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/propagate-confirm.tsx @@ -17,8 +17,8 @@ interface Props { frameNumber: number; propagateObject(): void; cancel(): void; - changePropagateFrames(value: number | undefined): void; - changeUpToFrame(value: number | undefined): void; + changePropagateFrames(value: number): void; + changeUpToFrame(value: number): void; } export default function PropagateConfirmComponent(props: Props): JSX.Element { diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index d3a727ee..794fb755 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -19,7 +19,7 @@ interface Props { frameNumber: number; inputFrameRef: React.RefObject; onSliderChange(value: SliderValue): void; - onInputChange(value: number | undefined): void; + onInputChange(value: number): void; onURLIconClick(): void; } @@ -34,7 +34,7 @@ function PlayerNavigation(props: Props): JSX.Element { onURLIconClick, } = props; - const [frameInputValue, setFrameInputValue] = useState(frameNumber); + const [frameInputValue, setFrameInputValue] = useState(frameNumber); if (frameNumber !== frameInputValue) { setFrameInputValue(frameNumber); } diff --git a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx index 5942fbae..53648454 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx @@ -36,7 +36,7 @@ interface Props { onFirstFrame(): void; onLastFrame(): void; onSliderChange(value: SliderValue): void; - onInputChange(value: number | undefined): void; + onInputChange(value: number): void; onURLIconClick(): void; onUndoClick(): void; onRedoClick(): void; diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx index 868b1ddb..e92c0f26 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx @@ -145,15 +145,9 @@ class DrawShapePopoverContainer extends React.PureComponent { }; private onChangePoints = (value: number | undefined): void => { - if (typeof (value) === 'undefined') { - this.setState({ - numberOfPoints: value, - }); - } else if (typeof (value) === 'number') { - this.setState({ - numberOfPoints: Math.max(value, this.minimumPoints), - }); - } + this.setState({ + numberOfPoints: value, + }); }; private onChangeLabel = (value: string): void => { diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx index e795cd56..f0de8809 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/propagate-confirm.tsx @@ -13,7 +13,6 @@ import { import { CombinedState } from 'reducers/interfaces'; import PropagateConfirmComponent from 'components/annotation-page/standard-workspace/propagate-confirm'; -import { clamp } from 'utils/math'; interface StateToProps { objectState: any | null; 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 ebde5bd3..150fb9e6 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 @@ -403,7 +403,7 @@ class AnnotationTopBarContainer extends React.PureComponent { onChangeFrame(value as number); }; - private onChangePlayerInputValue = (value: number | undefined): void => { + private onChangePlayerInputValue = (value: number): void => { const { onSwitchPlay, onChangeFrame, From ef11ca4fc6696c9a7fbcf489695def8831c5e625 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 20:24:29 +0300 Subject: [PATCH 06/10] Fix navigation --- .../annotation-page/top-bar/player-navigation.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 794fb755..b5c846d0 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Row, Col } from 'antd/lib/grid'; import Icon from 'antd/lib/icon'; @@ -35,9 +35,12 @@ function PlayerNavigation(props: Props): JSX.Element { } = props; const [frameInputValue, setFrameInputValue] = useState(frameNumber); - if (frameNumber !== frameInputValue) { - setFrameInputValue(frameNumber); - } + + useEffect(() => { + if (frameNumber !== frameInputValue) { + setFrameInputValue(frameNumber); + } + }, [frameNumber]); return ( <> @@ -75,7 +78,7 @@ function PlayerNavigation(props: Props): JSX.Element { onChange={(value: number | undefined) => { if (typeof (value) === 'number') { setFrameInputValue(Math.floor( - clamp(value, stopFrame, startFrame), + clamp(value, startFrame, stopFrame), )); } }} From 472d3174b6854ca0e084e41cf8b0921292cc0c9b Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 20:34:25 +0300 Subject: [PATCH 07/10] Added undopoint in editing --- cvat-canvas/src/typescript/editHandler.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cvat-canvas/src/typescript/editHandler.ts b/cvat-canvas/src/typescript/editHandler.ts index defdb69e..07f366d6 100644 --- a/cvat-canvas/src/typescript/editHandler.ts +++ b/cvat-canvas/src/typescript/editHandler.ts @@ -99,6 +99,12 @@ export class EditHandlerImpl implements EditHandler { if (e.which === 1) { mouseX = e.clientX; mouseY = e.clientY; + } else if (e.which === 3 && this.editLine) { + if (this.editData.state.shapeType === 'points' + || this.editLine.attr('points').split(' ').length > 2 + ) { + (this.editLine as any).draw('undo'); + } } }); From b700719bd5474401554c373667578ee3872e8f21 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 20:40:03 +0300 Subject: [PATCH 08/10] Fixed: Could not receive frame (after merge on the latest frame) --- cvat-core/src/annotations-collection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js index 309d387d..2135780c 100644 --- a/cvat-core/src/annotations-collection.js +++ b/cvat-core/src/annotations-collection.js @@ -317,7 +317,7 @@ // Push outside shape after each annotation shape // Any not outside shape rewrites it - if (!((object.frame + 1) in keyframes)) { + if (!((object.frame + 1) in keyframes) && object.frame + 1 <= this.stopFrame) { keyframes[object.frame + 1] = JSON .parse(JSON.stringify(keyframes[object.frame])); keyframes[object.frame + 1].outside = true; From 71d0bb51241bdebaf5eb74f0bf44aabb473f2aa9 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Tue, 24 Mar 2020 20:49:06 +0300 Subject: [PATCH 09/10] Removed extra action dispatching --- cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 150fb9e6..2c8020c3 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 @@ -408,9 +408,10 @@ class AnnotationTopBarContainer extends React.PureComponent { onSwitchPlay, onChangeFrame, playing, + frameNumber, } = this.props; - if (typeof (value) !== 'undefined') { + if (value !== frameNumber) { if (playing) { onSwitchPlay(false); } From 1806c9977b9e810f8a277f1bbdd127c1edef2335 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Wed, 25 Mar 2020 15:17:29 +0300 Subject: [PATCH 10/10] Which -> button property --- cvat-canvas/src/typescript/editHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cvat-canvas/src/typescript/editHandler.ts b/cvat-canvas/src/typescript/editHandler.ts index 07f366d6..ba0ed7f6 100644 --- a/cvat-canvas/src/typescript/editHandler.ts +++ b/cvat-canvas/src/typescript/editHandler.ts @@ -96,10 +96,10 @@ export class EditHandlerImpl implements EditHandler { let mouseY: number | null = null; this.canvas.on('mousedown.edit', (e: MouseEvent): void => { - if (e.which === 1) { + if (e.button === 0) { mouseX = e.clientX; mouseY = e.clientY; - } else if (e.which === 3 && this.editLine) { + } else if (e.button === 2 && this.editLine) { if (this.editData.state.shapeType === 'points' || this.editLine.attr('points').split(' ').length > 2 ) { @@ -110,7 +110,7 @@ export class EditHandlerImpl implements EditHandler { this.canvas.on('mouseup.edit', (e: MouseEvent): void => { const threshold = 10; // px - if (e.which === 1) { + if (e.button === 0) { if (Math.sqrt( // l2 distance < threshold ((mouseX - e.clientX) ** 2) + ((mouseY - e.clientY) ** 2),