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: Added shortcuts #1230

Merged
merged 27 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bac5529
Initial version of shortcuts
bsekachev Mar 2, 2020
a6c4548
Added shortcut to open settings page
bsekachev Mar 3, 2020
b90c5c9
Added hideAll, lockAll hotkeys
bsekachev Mar 3, 2020
97283d9
Added lock and hide an object shortcuts
bsekachev Mar 3, 2020
5a7ada4
Added occluded/keyframe/outside hotkeys
bsekachev Mar 3, 2020
54c21d8
Typos
bsekachev Mar 3, 2020
2b50344
Added shortcuts to delete, to background and to foreground
bsekachev Mar 3, 2020
a5f81e6
Added shortcut to copy shape
bsekachev Mar 3, 2020
fec5ff2
Merged develop
bsekachev Mar 4, 2020
0a11bfc
Propagate shortcut
bsekachev Mar 4, 2020
7ec6ceb
Undo/redo shortcuts
bsekachev Mar 4, 2020
d9721f7
Save job shortcut moved to a container
bsekachev Mar 4, 2020
163a35b
Removed some extra containers
bsekachev Mar 4, 2020
2fc0ddb
Merge, group, draw, paste, cancel, rotation shortcutsw
bsekachev Mar 4, 2020
bda12b8
Prev, next keyframes shortcuts
bsekachev Mar 4, 2020
4276584
Frame changing
bsekachev Mar 4, 2020
2bd55f2
Added reset group shortcut
bsekachev Mar 4, 2020
8c42cbd
Focus to frame shortcut
bsekachev Mar 4, 2020
952597f
Search annotations shortcut
bsekachev Mar 4, 2020
95a6ae9
Shortcuts to change image parameters and grid
bsekachev Mar 4, 2020
43c0abe
Fixed saturation range
bsekachev Mar 4, 2020
17bc395
A bit improved performance
bsekachev Mar 4, 2020
e07a238
Added button to close shortcuts dialog
bsekachev Mar 4, 2020
17174a2
Fixed nested dispatching
bsekachev Mar 4, 2020
928b7df
Improved UX when changing frames
bsekachev Mar 4, 2020
85e01de
working with canvas moved to actions
bsekachev Mar 5, 2020
11f3850
Crosshair and pasted shape under the cursor
bsekachev Mar 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 64 additions & 60 deletions cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export class DrawHandlerImpl implements DrawHandler {
private onDrawDone: (data: object, continueDraw?: boolean) => void;
private canvas: SVG.Container;
private text: SVG.Container;
private cursorPosition: {
x: number;
y: number;
};
private crosshair: {
x: SVG.Line;
y: SVG.Line;
Expand Down Expand Up @@ -96,12 +100,13 @@ export class DrawHandlerImpl implements DrawHandler {
}

private addCrosshair(): void {
const { x, y } = this.cursorPosition;
this.crosshair = {
x: this.canvas.line(0, 0, this.canvas.node.clientWidth, 0).attr({
x: this.canvas.line(0, y, this.canvas.node.clientWidth, y).attr({
'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale),
zOrder: Number.MAX_SAFE_INTEGER,
}).addClass('cvat_canvas_crosshair'),
y: this.canvas.line(0, 0, 0, this.canvas.node.clientHeight).attr({
y: this.canvas.line(x, 0, x, this.canvas.node.clientHeight).attr({
'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale),
zOrder: Number.MAX_SAFE_INTEGER,
}).addClass('cvat_canvas_crosshair'),
Expand Down Expand Up @@ -181,7 +186,6 @@ export class DrawHandlerImpl implements DrawHandler {
this.shapeSizeElement.update(this.drawInstance);
}).addClass('cvat_canvas_shape_drawing').attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
z_order: Number.MAX_SAFE_INTEGER,
});
}

Expand Down Expand Up @@ -222,10 +226,6 @@ export class DrawHandlerImpl implements DrawHandler {
}

private drawPolyshape(): void {
this.drawInstance.attr({
z_order: Number.MAX_SAFE_INTEGER,
});

let size = this.drawData.numberOfPoints;
const sizeDecrement = function sizeDecrement(): void {
if (!--size) {
Expand Down Expand Up @@ -371,18 +371,17 @@ export class DrawHandlerImpl implements DrawHandler {

// Common settings for rectangle and polyshapes
private pasteShape(): void {
this.drawInstance.attr({
z_order: Number.MAX_SAFE_INTEGER,
});
function moveShape(shape: SVG.Shape, x: number, y: number): void {
const bbox = shape.bbox();
shape.move(x - bbox.width / 2, y - bbox.height / 2);
}

this.canvas.on('mousemove.draw', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);
const { x: initialX, y: initialY } = this.cursorPosition;
moveShape(this.drawInstance, initialX, initialY);

const bbox = this.drawInstance.bbox();
this.drawInstance.move(x - bbox.width / 2, y - bbox.height / 2);
this.canvas.on('mousemove.draw', (): void => {
const { x, y } = this.cursorPosition; // was computer in another callback
moveShape(this.drawInstance, x, y);
});
}

Expand Down Expand Up @@ -429,45 +428,53 @@ export class DrawHandlerImpl implements DrawHandler {
this.pastePolyshape();
}

private pastePoints(points: string): void {
this.drawInstance = (this.canvas as any).polyline(points)
private pastePoints(initialPoints: string): void {
function moveShape(
shape: SVG.PolyLine,
group: SVG.G,
x: number,
y: number,
scale: number,
): void {
const bbox = shape.bbox();
shape.move(x - bbox.width / 2, y - bbox.height / 2);

const points = shape.attr('points').split(' ');
const radius = consts.BASE_POINT_SIZE / scale;

group.children().forEach((child: SVG.Element, idx: number): void => {
const [px, py] = points[idx].split(',');
child.move(px - radius / 2, py - radius / 2);
});
}

const { x: initialX, y: initialY } = this.cursorPosition;
this.pointsGroup = this.canvas.group();
this.drawInstance = (this.canvas as any).polyline(initialPoints)
.addClass('cvat_canvas_shape_drawing').style({
'stroke-width': 0,
});

this.pointsGroup = this.canvas.group();
for (const point of points.split(' ')) {
let numOfPoints = initialPoints.split(' ').length;
while (numOfPoints) {
numOfPoints--;
const radius = consts.BASE_POINT_SIZE / this.geometry.scale;
const stroke = consts.POINTS_STROKE_WIDTH / this.geometry.scale;
const [x, y] = point.split(',').map((coord: string): number => +coord);
this.pointsGroup.circle().move(x - radius / 2, y - radius / 2)
.fill('white').stroke('black').attr({
r: radius,
'stroke-width': stroke,
});
this.pointsGroup.circle().fill('white').stroke('black').attr({
r: radius,
'stroke-width': stroke,
});
}

this.pointsGroup.attr({
z_order: Number.MAX_SAFE_INTEGER,
});
moveShape(
this.drawInstance, this.pointsGroup, initialX, initialY, this.geometry.scale,
);

this.canvas.on('mousemove.draw', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
this.canvas.on('mousemove.draw', (): void => {
const { x, y } = this.cursorPosition; // was computer in another callback
moveShape(
this.drawInstance, this.pointsGroup, x, y, this.geometry.scale,
);

const bbox = this.drawInstance.bbox();
this.drawInstance.move(x - bbox.width / 2, y - bbox.height / 2);
const radius = consts.BASE_POINT_SIZE / this.geometry.scale;
const newPoints = this.drawInstance.attr('points').split(' ');
if (this.pointsGroup) {
this.pointsGroup.children()
.forEach((child: SVG.Element, idx: number): void => {
const [px, py] = newPoints[idx].split(',');
child.move(px - radius / 2, py - radius / 2);
});
}
});

this.pastePolyshape();
Expand Down Expand Up @@ -593,23 +600,20 @@ export class DrawHandlerImpl implements DrawHandler {
this.crosshair = null;
this.drawInstance = null;
this.pointsGroup = null;
this.cursorPosition = {
x: 0,
y: 0,
};

this.canvas.on('mousemove.crosshair', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);
this.cursorPosition = { x, y };
if (this.crosshair) {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);

this.crosshair.x.attr({
y1: y,
y2: y,
});

this.crosshair.y.attr({
x1: x,
x2: x,
});
this.crosshair.x.attr({ y1: y, y2: y });
this.crosshair.y.attr({ x1: x, x2: x });
}
});
}
Expand Down
7 changes: 5 additions & 2 deletions cvat-core/src/annotations-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@
: (frame) => frame - 1;
for (let frame = frameFrom; predicate(frame); frame = update(frame)) {
// First prepare all data for the frame
// Consider all shapes, tags, and tracks that have keyframe here
// Consider all shapes, tags, and not outside tracks that have keyframe here
// In particular consider first and last frame as keyframes for all frames
const statesData = [].concat(
(frame in this.shapes ? this.shapes[frame] : [])
Expand All @@ -876,7 +876,10 @@
|| frame === frameFrom
|| frame === frameTo
));
statesData.push(...tracks.map((track) => track.get(frame)));
statesData.push(
...tracks.map((track) => track.get(frame))
.filter((state) => !state.outside),
);

// Nothing to filtering, go to the next iteration
if (!statesData.length) {
Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@
return annotationsData;
};

Job.prototype.annotations.search.implementation = async function (filters, frameFrom, frameTo) {
Job.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) {
if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) {
throw new ArgumentError(
'The filters argument must be an array of strings',
Expand Down Expand Up @@ -1555,7 +1555,7 @@
return result;
};

Job.prototype.annotations.search.implementation = async function (filters, frameFrom, frameTo) {
Task.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) {
if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) {
throw new ArgumentError(
'The filters argument must be an array of strings',
Expand Down
10 changes: 9 additions & 1 deletion cvat-ui/package-lock.json

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

1 change: 1 addition & 0 deletions cvat-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-hotkeys": "^2.0.0",
"react-redux": "^7.1.1",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand Down
Loading