Added tag support in new UI (without canvas drawing)

main
Dmitry Kalinin 6 years ago
parent f468c4035f
commit 3199fbbdf9

@ -399,8 +399,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.svgTexts[state.clientID].remove();
}
this.svgShapes[state.clientID].off('click.canvas');
this.svgShapes[state.clientID].remove();
const shape = this.svgShapes[state.clientID];
if (shape) {
shape.off('click.canvas');
shape.remove();
}
delete this.drawnStates[state.clientID];
}
@ -847,7 +850,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
hidden: state.hidden,
lock: state.lock,
shapeType: state.shapeType,
points: [...state.points],
points: Array.isArray(state.points) ? [...state.points] : [],
attributes: { ...state.attributes },
zOrder: state.zOrder,
pinned: state.pinned,
@ -892,7 +895,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.activate(activeElement);
}
if (state.points
if (state.points && state.points
.some((p: number, id: number): boolean => p !== drawnState.points[id])
) {
const translatedPoints: number[] = translate(state.points);
@ -1021,22 +1024,24 @@ export class CanvasViewImpl implements CanvasView, Listener {
const drawnState = this.drawnStates[clientID];
const shape = this.svgShapes[clientID];
shape.removeClass('cvat_canvas_shape_activated');
if (shape) {
shape.removeClass('cvat_canvas_shape_activated');
if (!drawnState.pinned) {
(shape as any).off('dragstart');
(shape as any).off('dragend');
(shape as any).draggable(false);
}
if (!drawnState.pinned) {
(shape as any).off('dragstart');
(shape as any).off('dragend');
(shape as any).draggable(false);
}
if (drawnState.shapeType !== 'points') {
this.selectize(false, shape);
}
if (drawnState.shapeType !== 'points') {
this.selectize(false, shape);
}
(shape as any).off('resizestart');
(shape as any).off('resizing');
(shape as any).off('resizedone');
(shape as any).resize(false);
(shape as any).off('resizestart');
(shape as any).off('resizing');
(shape as any).off('resizedone');
(shape as any).resize(false);
}
// TODO: Hide text only if it is hidden by settings
const text = this.svgTexts[clientID];
@ -1085,6 +1090,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.activeElement = { ...activeElement };
const shape = this.svgShapes[clientID];
if (!shape) {
return;
}
let text = this.svgTexts[clientID];
if (!text) {
text = this.addText(state);

@ -810,11 +810,13 @@
'The object has not been saved yet. Call annotations.put([state]) before',
);
}
const distance = object.constructor.distance(state.points, x, y);
if (distance !== null && (minimumDistance === null || distance < minimumDistance)) {
minimumDistance = distance;
minimumState = state;
if (!(object instanceof Tag)) {
const distance = object.constructor.distance(state.points, x, y);
if (distance !== null && (minimumDistance === null
|| distance < minimumDistance)) {
minimumDistance = distance;
minimumState = state;
}
}
}

@ -85,7 +85,6 @@ export enum AnnotationActionTypes {
EDIT_SHAPE = 'EDIT_SHAPE',
DRAW_SHAPE = 'DRAW_SHAPE',
SHAPE_DRAWN = 'SHAPE_DRAWN',
SETUP_TAG = 'SETUP_TAG',
RESET_CANVAS = 'RESET_CANVAS',
UPDATE_ANNOTATIONS_SUCCESS = 'UPDATE_ANNOTATIONS_SUCCESS',
UPDATE_ANNOTATIONS_FAILED = 'UPDATE_ANNOTATIONS_FAILED',
@ -526,10 +525,31 @@ export function editShape(enabled: boolean): AnyAction {
}
export function copyShape(objectState: any): AnyAction {
const state = getStore().getState();
state.annotation.canvas.instance.cancel();
if (objectState.objectType !== ObjectType.TAG) {
state.annotation.canvas.instance.draw({
enabled: true,
initialState: objectState,
});
}
let activeControl = ActiveControl.CURSOR;
if (objectState.shapeType === ShapeType.RECTANGLE) {
activeControl = ActiveControl.DRAW_RECTANGLE;
} else if (objectState.shapeType === ShapeType.POINTS) {
activeControl = ActiveControl.DRAW_POINTS;
} else if (objectState.shapeType === ShapeType.POLYGON) {
activeControl = ActiveControl.DRAW_POLYGON;
} else if (objectState.shapeType === ShapeType.POLYLINE) {
activeControl = ActiveControl.DRAW_POLYLINE;
}
return {
type: AnnotationActionTypes.COPY_SHAPE,
payload: {
objectState,
activeControl,
},
};
}
@ -856,20 +876,6 @@ export function drawShape(
};
}
export function setupTag(
labelID: number,
objectType: ObjectType,
): AnyAction {
return {
type: AnnotationActionTypes.SETUP_TAG,
payload: {
labelID,
objectType,
activeControl: ActiveControl.SETUP_TAG,
},
};
}
export function shapeDrawn(): AnyAction {
return {
type: AnnotationActionTypes.SHAPE_DRAWN,

@ -43,6 +43,7 @@ import {
function ItemMenu(
serverID: number | undefined,
locked: boolean,
objectType: ObjectType,
copy: (() => void),
remove: (() => void),
propagate: (() => void),
@ -68,13 +69,13 @@ function ItemMenu(
</Button>
</Menu.Item>
<Menu.Item>
<Button type='link' onClick={toBackground}>
<Button disabled={objectType === ObjectType.TAG} type='link' onClick={toBackground}>
<Icon component={BackgroundIcon} />
To background
</Button>
</Menu.Item>
<Menu.Item>
<Button type='link' onClick={toForeground}>
<Button disabled={objectType === ObjectType.TAG} type='link' onClick={toForeground}>
<Icon component={ForegroundIcon} />
To foreground
</Button>
@ -109,6 +110,7 @@ interface ItemTopComponentProps {
serverID: number | undefined;
labelID: number;
labels: any[];
objectType: ObjectType;
type: string;
locked: boolean;
changeLabel(labelID: string): void;
@ -126,6 +128,7 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
serverID,
labelID,
labels,
objectType,
type,
locked,
changeLabel,
@ -159,6 +162,7 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
overlay={ItemMenu(
serverID,
locked,
objectType,
copy,
remove,
propagate,
@ -302,6 +306,22 @@ function ItemButtonsComponent(props: ItemButtonsComponentProps): JSX.Element {
);
}
if (objectType === ObjectType.TAG) {
return (
<Row type='flex' align='middle' justify='space-around'>
<Col span={20} style={{ textAlign: 'center' }}>
<Row type='flex' justify='space-around'>
<Col>
{ locked
? <Icon type='lock' onClick={unlock} />
: <Icon type='unlock' onClick={lock} />}
</Col>
</Row>
</Col>
</Row>
);
}
return (
<Row type='flex' align='middle' justify='space-around'>
<Col span={20} style={{ textAlign: 'center' }}>
@ -726,6 +746,7 @@ function ObjectItemComponent(props: Props): JSX.Element {
clientID={clientID}
labelID={labelID}
labels={labels}
objectType={objectType}
type={type}
locked={locked}
changeLabel={changeLabel}

@ -11,28 +11,28 @@ import {
} from 'reducers/interfaces';
import {
setupTag
createAnnotationsAsync,
} from 'actions/annotation-actions';
import { Canvas } from 'cvat-canvas';
import SetupTagPopoverComponent from 'components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover';
import getCore from 'cvat-core';
const cvat = getCore();
interface DispatchToProps {
onTagSetup(
labelID: number,
): void;
onCreateAnnotations(sessionInstance: any, frame: number, states: any[]): void;
}
interface StateToProps {
canvasInstance: Canvas;
jobInstance: any;
labels: any[];
frame: number;
}
function mapDispatchToProps(dispatch: any): DispatchToProps {
return {
onTagSetup(
labelID: number,
): void {
dispatch(setupTag(labelID, ObjectType.TAG));
onCreateAnnotations(sessionInstance: any, frame: number, states: any[]): void {
dispatch(createAnnotationsAsync(sessionInstance, frame, states));
},
};
}
@ -45,13 +45,21 @@ function mapStateToProps(state: CombinedState): StateToProps {
},
job: {
labels,
instance: jobInstance,
},
player: {
frame: {
number: frame,
},
},
},
} = state;
return {
canvasInstance,
jobInstance,
labels,
frame,
};
}
@ -77,11 +85,27 @@ class DrawShapePopoverContainer extends React.PureComponent<Props, State> {
});
};
private onSetup(labelID: number): void {
const { canvasInstance, onTagSetup } = this.props;
private onSetup(): void {
const {
canvasInstance,
onCreateAnnotations,
jobInstance,
frame,
} = this.props;
const { selectedLabelID } = this.state;
canvasInstance.cancel();
onTagSetup(labelID);
const state = {
objectType: ObjectType.TAG,
label: jobInstance.task.labels
.filter((label: any) => label.id === selectedLabelID)[0],
frame,
};
const objectState = new cvat.classes.ObjectState(state);
onCreateAnnotations(jobInstance, frame, [objectState]);
}
public render(): JSX.Element {

@ -9,10 +9,12 @@ import {
ActiveControl,
CombinedState,
ColorBy,
ObjectType,
} from 'reducers/interfaces';
import {
collapseObjectItems,
changeLabelColorAsync,
createAnnotationsAsync,
updateAnnotationsAsync,
changeFrameAsync,
removeObjectAsync,
@ -23,6 +25,9 @@ import {
} from 'actions/annotation-actions';
import ObjectStateItemComponent from 'components/annotation-page/standard-workspace/objects-side-bar/object-item';
import getCore from 'cvat-core';
const cvat = getCore();
interface OwnProps {
clientID: number;
@ -47,6 +52,7 @@ interface StateToProps {
interface DispatchToProps {
changeFrame(frame: number): void;
updateState(sessionInstance: any, frameNumber: number, objectState: any): void;
createAnnotations(sessionInstance: any, frameNumber: number, state: any): void
collapseOrExpand(objectStates: any[], collapsed: boolean): void;
activateObject: (activatedStateID: number | null) => void;
removeObject: (sessionInstance: any, objectState: any) => void;
@ -123,6 +129,9 @@ function mapDispatchToProps(dispatch: any): DispatchToProps {
updateState(sessionInstance: any, frameNumber: number, state: any): void {
dispatch(updateAnnotationsAsync(sessionInstance, frameNumber, [state]));
},
createAnnotations(sessionInstance: any, frameNumber: number, state: any): void {
dispatch(createAnnotationsAsync(sessionInstance, frameNumber, state));
},
collapseOrExpand(objectStates: any[], collapsed: boolean): void {
dispatch(collapseObjectItems(objectStates, collapsed));
},
@ -215,9 +224,21 @@ class ObjectItemContainer extends React.PureComponent<Props> {
const {
objectState,
copyShape,
jobInstance,
frameNumber,
createAnnotations,
} = this.props;
copyShape(objectState);
if (objectState.objectType === ObjectType.TAG) {
const state = new cvat.classes.ObjectState({
objectType: objectState.objectType,
label: objectState.label,
frame: frameNumber,
});
createAnnotations(jobInstance, frameNumber, [state]);
}
};
private propagate = (): void => {

@ -429,6 +429,7 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
...state,
annotations: {
...state.annotations,
activatedStateID: null,
},
canvas: {
...state.canvas,
@ -678,24 +679,9 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
}
case AnnotationActionTypes.COPY_SHAPE: {
const {
objectState,
activeControl,
} = action.payload;
state.canvas.instance.cancel();
state.canvas.instance.draw({
enabled: true,
initialState: objectState,
});
let activeControl = ActiveControl.DRAW_RECTANGLE;
if (objectState.shapeType === ShapeType.POINTS) {
activeControl = ActiveControl.DRAW_POINTS;
} else if (objectState.shapeType === ShapeType.POLYGON) {
activeControl = ActiveControl.DRAW_POLYGON;
} else if (objectState.shapeType === ShapeType.POLYLINE) {
activeControl = ActiveControl.DRAW_POLYLINE;
}
return {
...state,
canvas: {

@ -245,7 +245,6 @@ export enum ActiveControl {
DRAW_POLYGON = 'draw_polygon',
DRAW_POLYLINE = 'draw_polyline',
DRAW_POINTS = 'draw_points',
SETUP_TAG = 'setup_tag',
MERGE = 'merge',
GROUP = 'group',
SPLIT = 'split',

Loading…
Cancel
Save