Skip to content

Commit

Permalink
Improved interface of interactors on UI (#2054)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsekachev authored Aug 31, 2020
1 parent 174fe16 commit 908e056
Show file tree
Hide file tree
Showing 38 changed files with 1,223 additions and 516 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
-

### Changed
-
- UI models (like DEXTR) were redesigned to be more interactive (<https://github.com/opencv/cvat/pull/2054>)

### Deprecated
-
Expand Down
53 changes: 34 additions & 19 deletions cvat-canvas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Canvas itself handles:
IDLE = 'idle',
DRAG = 'drag',
RESIZE = 'resize',
INTERACT = 'interact',
DRAW = 'draw',
EDIT = 'edit',
MERGE = 'merge',
Expand All @@ -70,6 +71,11 @@ Canvas itself handles:
crosshair?: boolean;
}

interface InteractionData {
shapeType: string;
minVertices?: number;
}

interface GroupData {
enabled: boolean;
resetGroup?: boolean;
Expand All @@ -83,6 +89,12 @@ Canvas itself handles:
enabled: boolean;
}

interface InteractionResult {
points: number[];
shapeType: string;
button: number;
};

interface DrawnData {
shapeType: string;
points: number[];
Expand All @@ -104,6 +116,7 @@ Canvas itself handles:
grid(stepX: number, stepY: number): void;

draw(drawData: DrawData): void;
interact(interactionData: InteractionData): void;
group(groupData: GroupData): void;
split(splitData: SplitData): void;
merge(mergeData: MergeData): void;
Expand Down Expand Up @@ -146,6 +159,7 @@ Standard JS events are used.
- canvas.moved => {states: ObjectState[], x: number, y: number}
- canvas.find => {states: ObjectState[], x: number, y: number}
- canvas.drawn => {state: DrawnData}
- canvas.interacted => {shapes: InteractionResult[]}
- canvas.editstart
- canvas.edited => {state: ObjectState, points: number[]}
- canvas.splitted => {state: ObjectState}
Expand Down Expand Up @@ -187,25 +201,26 @@ Standard JS events are used.

## API Reaction

| | IDLE | GROUP | SPLIT | DRAW | MERGE | EDIT | DRAG | RESIZE | ZOOM_CANVAS | DRAG_CANVAS |
|--------------|------|-------|-------|------|-------|------|------|--------|-------------|-------------|
| setup() | + | + | + | +/- | + | +/- | +/- | +/- | + | + |
| activate() | + | - | - | - | - | - | - | - | - | - |
| rotate() | + | + | + | + | + | + | + | + | + | + |
| focus() | + | + | + | + | + | + | + | + | + | + |
| fit() | + | + | + | + | + | + | + | + | + | + |
| grid() | + | + | + | + | + | + | + | + | + | + |
| draw() | + | - | - | - | - | - | - | - | - | - |
| split() | + | - | + | - | - | - | - | - | - | - |
| group() | + | + | - | - | - | - | - | - | - | - |
| merge() | + | - | - | - | + | - | - | - | - | - |
| fitCanvas() | + | + | + | + | + | + | + | + | + | + |
| dragCanvas() | + | - | - | - | - | - | + | - | - | + |
| zoomCanvas() | + | - | - | - | - | - | - | + | + | - |
| cancel() | - | + | + | + | + | + | + | + | + | + |
| configure() | + | + | + | + | + | + | + | + | + | + |
| bitmap() | + | + | + | + | + | + | + | + | + | + |
| setZLayer() | + | + | + | + | + | + | + | + | + | + |
| | IDLE | GROUP | SPLIT | DRAW | MERGE | EDIT | DRAG | RESIZE | ZOOM_CANVAS | DRAG_CANVAS | INTERACT |
|--------------|------|-------|-------|------|-------|------|------|--------|-------------|-------------|----------|
| setup() | + | + | + | +/- | + | +/- | +/- | +/- | + | + | + |
| activate() | + | - | - | - | - | - | - | - | - | - | - |
| rotate() | + | + | + | + | + | + | + | + | + | + | + |
| focus() | + | + | + | + | + | + | + | + | + | + | + |
| fit() | + | + | + | + | + | + | + | + | + | + | + |
| grid() | + | + | + | + | + | + | + | + | + | + | + |
| draw() | + | - | - | + | - | - | - | - | - | - | - |
| interact() | + | - | - | - | - | - | - | - | - | - | + |
| split() | + | - | + | - | - | - | - | - | - | - | - |
| group() | + | + | - | - | - | - | - | - | - | - | - |
| merge() | + | - | - | - | + | - | - | - | - | - | - |
| fitCanvas() | + | + | + | + | + | + | + | + | + | + | + |
| dragCanvas() | + | - | - | - | - | - | + | - | - | + | - |
| zoomCanvas() | + | - | - | - | - | - | - | + | + | - | - |
| cancel() | - | + | + | + | + | + | + | + | + | + | + |
| configure() | + | + | + | + | + | + | + | + | + | + | + |
| bitmap() | + | + | + | + | + | + | + | + | + | + | + |
| setZLayer() | + | + | + | + | + | + | + | + | + | + | + |

You can call setup() during editing, dragging, and resizing only to update objects, not to change a frame.
You can change frame during draw only when you do not redraw an existing object
Expand Down
2 changes: 1 addition & 1 deletion cvat-canvas/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-canvas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-canvas",
"version": "2.0.2",
"version": "2.1.0",
"description": "Part of Computer Vision Annotation Tool which presents its canvas library",
"main": "src/canvas.ts",
"scripts": {
Expand Down
26 changes: 12 additions & 14 deletions cvat-canvas/src/typescript/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,17 @@ import {
MergeData,
SplitData,
GroupData,
InteractionData,
InteractionResult,
CanvasModel,
CanvasModelImpl,
RectDrawingMethod,
CuboidDrawingMethod,
Configuration,
} from './canvasModel';

import {
Master,
} from './master';

import {
CanvasController,
CanvasControllerImpl,
} from './canvasController';

import {
CanvasView,
CanvasViewImpl,
} from './canvasView';
import { Master } from './master';
import { CanvasController, CanvasControllerImpl } from './canvasController';
import { CanvasView, CanvasViewImpl } from './canvasView';

import '../scss/canvas.scss';
import pjson from '../../package.json';
Expand All @@ -43,6 +34,7 @@ interface Canvas {
fit(): void;
grid(stepX: number, stepY: number): void;

interact(interactionData: InteractionData): void;
draw(drawData: DrawData): void;
group(groupData: GroupData): void;
split(splitData: SplitData): void;
Expand Down Expand Up @@ -118,6 +110,10 @@ class CanvasImpl implements Canvas {
this.model.grid(stepX, stepY);
}

public interact(interactionData: InteractionData): void {
this.model.interact(interactionData);
}

public draw(drawData: DrawData): void {
this.model.draw(drawData);
}
Expand Down Expand Up @@ -162,4 +158,6 @@ export {
RectDrawingMethod,
CuboidDrawingMethod,
Mode as CanvasMode,
InteractionData,
InteractionResult,
};
11 changes: 11 additions & 0 deletions cvat-canvas/src/typescript/canvasController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SplitData,
GroupData,
Mode,
InteractionData,
} from './canvasModel';

export interface CanvasController {
Expand All @@ -21,6 +22,7 @@ export interface CanvasController {
readonly focusData: FocusData;
readonly activeElement: ActiveElement;
readonly drawData: DrawData;
readonly interactionData: InteractionData;
readonly mergeData: MergeData;
readonly splitData: SplitData;
readonly groupData: GroupData;
Expand All @@ -30,6 +32,7 @@ export interface CanvasController {

zoom(x: number, y: number, direction: number): void;
draw(drawData: DrawData): void;
interact(interactionData: InteractionData): void;
merge(mergeData: MergeData): void;
split(splitData: SplitData): void;
group(groupData: GroupData): void;
Expand Down Expand Up @@ -84,6 +87,10 @@ export class CanvasControllerImpl implements CanvasController {
this.model.draw(drawData);
}

public interact(interactionData: InteractionData): void {
this.model.interact(interactionData);
}

public merge(mergeData: MergeData): void {
this.model.merge(mergeData);
}
Expand Down Expand Up @@ -124,6 +131,10 @@ export class CanvasControllerImpl implements CanvasController {
return this.model.drawData;
}

public get interactionData(): InteractionData {
return this.model.interactionData;
}

public get mergeData(): MergeData {
return this.model.mergeData;
}
Expand Down
49 changes: 48 additions & 1 deletion cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ export interface DrawData {
redraw?: number;
}

export interface InteractionData {
enabled: boolean;
shapeType?: string;
crosshair?: boolean;
minPosVertices?: number;
minNegVertices?: number;
}

export interface InteractionResult {
points: number[];
shapeType: string;
button: number;
}

export interface EditData {
enabled: boolean;
state: any;
Expand Down Expand Up @@ -105,6 +119,7 @@ export enum UpdateReasons {

FITTED_CANVAS = 'fitted_canvas',

INTERACT = 'interact',
DRAW = 'draw',
MERGE = 'merge',
SPLIT = 'split',
Expand All @@ -126,6 +141,7 @@ export enum Mode {
MERGE = 'merge',
SPLIT = 'split',
GROUP = 'group',
INTERACT = 'interact',
DRAG_CANVAS = 'drag_canvas',
ZOOM_CANVAS = 'zoom_canvas',
}
Expand All @@ -139,6 +155,7 @@ export interface CanvasModel {
readonly focusData: FocusData;
readonly activeElement: ActiveElement;
readonly drawData: DrawData;
readonly interactionData: InteractionData;
readonly mergeData: MergeData;
readonly splitData: SplitData;
readonly groupData: GroupData;
Expand All @@ -162,6 +179,7 @@ export interface CanvasModel {
split(splitData: SplitData): void;
merge(mergeData: MergeData): void;
select(objectState: any): void;
interact(interactionData: InteractionData): void;

fitCanvas(width: number, height: number): void;
bitmap(enabled: boolean): void;
Expand Down Expand Up @@ -192,6 +210,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
top: number;
zLayer: number | null;
drawData: DrawData;
interactionData: InteractionData;
mergeData: MergeData;
groupData: GroupData;
splitData: SplitData;
Expand Down Expand Up @@ -242,6 +261,9 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
enabled: false,
initialState: null,
},
interactionData: {
enabled: false,
},
mergeData: {
enabled: false,
},
Expand Down Expand Up @@ -490,6 +512,27 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.notify(UpdateReasons.DRAW);
}

public interact(interactionData: InteractionData): void {
if (![Mode.IDLE, Mode.INTERACT].includes(this.data.mode)) {
throw Error(`Canvas is busy. Action: ${this.data.mode}`);
}

if (interactionData.enabled) {
if (this.data.interactionData.enabled) {
throw new Error('Interaction has been already started');
} else if (!interactionData.shapeType) {
throw new Error('A shape type was not specified');
}
}

this.data.interactionData = interactionData;
if (typeof (this.data.interactionData.crosshair) !== 'boolean') {
this.data.interactionData.crosshair = true;
}

this.notify(UpdateReasons.INTERACT);
}

public split(splitData: SplitData): void {
if (![Mode.IDLE, Mode.SPLIT].includes(this.data.mode)) {
throw Error(`Canvas is busy. Action: ${this.data.mode}`);
Expand Down Expand Up @@ -567,7 +610,7 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
}

public isAbleToChangeFrame(): boolean {
const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE].includes(this.data.mode)
const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode)
|| (this.data.mode === Mode.DRAW && typeof (this.data.drawData.redraw) === 'number');

return !isUnable;
Expand Down Expand Up @@ -647,6 +690,10 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
return { ...this.data.drawData };
}

public get interactionData(): InteractionData {
return { ...this.data.interactionData };
}

public get mergeData(): MergeData {
return { ...this.data.mergeData };
}
Expand Down
Loading

0 comments on commit 908e056

Please sign in to comment.