Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React UI: Batch of fixes #1314

Merged
merged 10 commits into from
Mar 25, 2020
10 changes: 8 additions & 2 deletions cvat-canvas/src/typescript/editHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,21 @@ 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.button === 2 && this.editLine) {
if (this.editData.state.shapeType === 'points'
|| this.editLine.attr('points').split(' ').length > 2
) {
(this.editLine as any).draw('undo');
}
}
});

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),
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/annotations-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ 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;
inputType: string;
values: string[];
currentValue: string;
onChange(value: string): void;
ref: React.RefObject<Input | InputNumber>;
}

function renderInputElement(parameters: InputElementParameters): JSX.Element {
Expand All @@ -27,7 +25,6 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element {
values,
currentValue,
onChange,
ref,
} = parameters;

const renderCheckbox = (): JSX.Element => (
Expand Down Expand Up @@ -114,7 +111,6 @@ function renderInputElement(parameters: InputElementParameters): JSX.Element {
}
}}
onKeyDown={handleKeydown}
ref={ref as React.RefObject<Input>}
/>
</div>
</>
Expand Down Expand Up @@ -259,16 +255,13 @@ 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<InputNumber>()
: React.createRef<Input>();

return (
<div>
{renderList({ values, inputType, onChange })}
<hr />
{renderInputElement({
attrID,
ref,
inputType,
currentValue,
values,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -117,7 +113,15 @@ function DrawShapePopoverComponent(props: Props): JSX.Element {
</Col>
<Col span={10}>
<InputNumber
onChange={onChangePoints}
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
onChangePoints(Math.floor(
clamp(value, minimumPoints, Number.MAX_SAFE_INTEGER),
bsekachev marked this conversation as resolved.
Show resolved Hide resolved
));
} else if (!value) {
onChangePoints(undefined);
}
}}
className='cvat-draw-shape-popover-points-selector'
min={minimumPoints}
value={numberOfPoints}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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 (
<>
Expand All @@ -476,15 +470,17 @@ function ItemAttributeComponent(props: ItemAttributeComponentProps): JSX.Element
<InputNumber
size='small'
onChange={(value: number | undefined): void => {
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}
/>
</Col>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,38 @@

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;
changeUpToFrame(value: number | undefined): void;
changePropagateFrames(value: number): void;
changeUpToFrame(value: number): void;
}

export default function PropagateConfirmComponent(props: Props): JSX.Element {
const {
visible,
propagateFrames,
propagateUpToFrame,
stopFrame,
frameNumber,
propagateObject,
changePropagateFrames,
changeUpToFrame,
cancel,
} = props;

const minPropagateFrames = 1;

return (
<Modal
okType='primary'
Expand All @@ -44,14 +48,37 @@ export default function PropagateConfirmComponent(props: Props): JSX.Element {
>
<div className='cvat-propagate-confirm'>
<Text>Do you want to make a copy of the object on</Text>
<InputNumber size='small' min={1} value={propagateFrames} onChange={changePropagateFrames} />
<InputNumber
size='small'
min={minPropagateFrames}
value={propagateFrames}
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
changePropagateFrames(Math.floor(
clamp(value, minPropagateFrames, Number.MAX_SAFE_INTEGER),
));
}
}}
/>
{
propagateFrames > 1
? <Text> frames </Text>
: <Text> frame </Text>
}
<Text>up to the </Text>
<InputNumber size='small' value={propagateUpToFrame} onChange={changeUpToFrame} />
<InputNumber
size='small'
value={propagateUpToFrame}
min={frameNumber + 1}
max={stopFrame}
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
changeUpToFrame(Math.floor(
clamp(value, frameNumber + 1, stopFrame),
));
}
}}
/>
<Text>frame</Text>
</div>
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@
//
// SPDX-License-Identifier: MIT

import React from 'react';
import React, { useState, useEffect } 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';

import { clamp } from 'utils/math';

interface Props {
startFrame: number;
stopFrame: number;
frameNumber: number;
inputFrameRef: React.RefObject<InputNumber>;
onSliderChange(value: SliderValue): void;
onInputChange(value: number | undefined): void;
onInputChange(value: number): void;
onURLIconClick(): void;
}

Expand All @@ -37,6 +34,14 @@ function PlayerNavigation(props: Props): JSX.Element {
onURLIconClick,
} = props;

const [frameInputValue, setFrameInputValue] = useState<number>(frameNumber);

useEffect(() => {
if (frameNumber !== frameInputValue) {
setFrameInputValue(frameNumber);
}
}, [frameNumber]);

return (
<>
<Col className='cvat-player-controls'>
Expand Down Expand Up @@ -68,9 +73,21 @@ function PlayerNavigation(props: Props): JSX.Element {
<InputNumber
className='cvat-player-frame-selector'
type='number'
value={frameNumber || 0}
value={frameInputValue}
// https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput
onChange={onInputChange}
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
setFrameInputValue(Math.floor(
clamp(value, startFrame, stopFrame),
));
}
}}
onBlur={() => {
onInputChange(frameInputValue);
}}
onPressEnter={() => {
onInputChange(frameInputValue);
}}
ref={inputFrameRef}
/>
</Col>
Expand Down
10 changes: 3 additions & 7 deletions cvat-ui/src/components/annotation-page/top-bar/top-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -40,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;
Expand Down
Loading