Disabled ability to edit positions in attribute anntation mode

main
Boris Sekachev 5 years ago
parent 3bd06603c5
commit a53bd6c44d

@ -14,6 +14,7 @@ import {
GroupData, GroupData,
Mode, Mode,
InteractionData, InteractionData,
Configuration,
} from './canvasModel'; } from './canvasModel';
export interface CanvasController { export interface CanvasController {
@ -27,6 +28,7 @@ export interface CanvasController {
readonly splitData: SplitData; readonly splitData: SplitData;
readonly groupData: GroupData; readonly groupData: GroupData;
readonly selected: any; readonly selected: any;
readonly configuration: Configuration;
mode: Mode; mode: Mode;
geometry: Geometry; geometry: Geometry;
@ -151,6 +153,10 @@ export class CanvasControllerImpl implements CanvasController {
return this.model.selected; return this.model.selected;
} }
public get configuration(): Configuration {
return this.model.configuration;
}
public set mode(value: Mode) { public set mode(value: Mode) {
this.model.mode = value; this.model.mode = value;
} }

@ -56,6 +56,7 @@ export interface Configuration {
displayAllText?: boolean; displayAllText?: boolean;
undefinedAttrValue?: string; undefinedAttrValue?: string;
showProjections?: boolean; showProjections?: boolean;
forceDisableEditing?: boolean;
} }
export interface DrawData { export interface DrawData {
@ -288,15 +289,15 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
const mutiplier = Math.sin((angle * Math.PI) / 180) + Math.cos((angle * Math.PI) / 180); const mutiplier = Math.sin((angle * Math.PI) / 180) + Math.cos((angle * Math.PI) / 180);
if ((angle / 90) % 2) { if ((angle / 90) % 2) {
// 90, 270, .. // 90, 270, ..
this.data.top += const topMultiplier = (x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1);
mutiplier * ((x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1)) * this.data.scale; const leftMultiplier = (y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1);
this.data.left -= this.data.top += mutiplier * topMultiplier * this.data.scale;
mutiplier * ((y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1)) * this.data.scale; this.data.left -= mutiplier * leftMultiplier * this.data.scale;
} else { } else {
this.data.left += const leftMultiplier = (x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1);
mutiplier * ((x - this.data.imageSize.width / 2) * (oldScale / this.data.scale - 1)) * this.data.scale; const topMultiplier = (y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1);
this.data.top += this.data.left += mutiplier * leftMultiplier * this.data.scale;
mutiplier * ((y - this.data.imageSize.height / 2) * (oldScale / this.data.scale - 1)) * this.data.scale; this.data.top += mutiplier * topMultiplier * this.data.scale;
} }
this.notify(UpdateReasons.IMAGE_ZOOMED); this.notify(UpdateReasons.IMAGE_ZOOMED);
@ -599,13 +600,16 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.data.configuration.undefinedAttrValue = configuration.undefinedAttrValue; this.data.configuration.undefinedAttrValue = configuration.undefinedAttrValue;
} }
if (typeof configuration.forceDisableEditing !== 'undefined') {
this.data.configuration.forceDisableEditing = configuration.forceDisableEditing;
}
this.notify(UpdateReasons.CONFIG_UPDATED); this.notify(UpdateReasons.CONFIG_UPDATED);
} }
public isAbleToChangeFrame(): boolean { public isAbleToChangeFrame(): boolean {
const isUnable = const isUnable = [Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode)
[Mode.DRAG, Mode.EDIT, Mode.RESIZE, Mode.INTERACT].includes(this.data.mode) || || (this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number');
(this.data.mode === Mode.DRAW && typeof this.data.drawData.redraw === 'number');
return !isUnable; return !isUnable;
} }

@ -94,6 +94,11 @@ export class CanvasViewImpl implements CanvasView, Listener {
return this.serviceFlags.drawHidden[clientID] || false; return this.serviceFlags.drawHidden[clientID] || false;
} }
private stateIsLocked(state: any): boolean {
const { configuration } = this.controller;
return state.lock || configuration.forceDisableEditing;
}
private setupServiceHidden(clientID: number, value: boolean): void { private setupServiceHidden(clientID: number, value: boolean): void {
this.serviceFlags.drawHidden[clientID] = value; this.serviceFlags.drawHidden[clientID] = value;
const shape = this.svgShapes[clientID]; const shape = this.svgShapes[clientID];
@ -455,8 +460,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Transform all text // Transform all text
for (const key in this.svgShapes) { for (const key in this.svgShapes) {
if ( if (
Object.prototype.hasOwnProperty.call(this.svgShapes, key) && Object.prototype.hasOwnProperty.call(this.svgShapes, key)
Object.prototype.hasOwnProperty.call(this.svgTexts, key) && Object.prototype.hasOwnProperty.call(this.svgTexts, key)
) { ) {
this.updateTextPosition(this.svgTexts[key], this.svgShapes[key]); this.updateTextPosition(this.svgTexts[key], this.svgShapes[key]);
} }
@ -874,9 +879,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.content.addEventListener('mousedown', (event): void => { this.content.addEventListener('mousedown', (event): void => {
if ([0, 1].includes(event.button)) { if ([0, 1].includes(event.button)) {
if ( if (
[Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT].includes(this.mode) || [Mode.IDLE, Mode.DRAG_CANVAS, Mode.MERGE, Mode.SPLIT].includes(this.mode)
event.button === 1 || || event.button === 1
event.altKey || event.altKey
) { ) {
self.controller.enableDrag(event.clientX, event.clientY); self.controller.enableDrag(event.clientX, event.clientY);
} }
@ -1325,8 +1330,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
if ( if (
state.points.length !== drawnState.points.length || state.points.length !== drawnState.points.length
state.points.some((p: number, id: number): boolean => p !== drawnState.points[id]) || state.points.some((p: number, id: number): boolean => p !== drawnState.points[id])
) { ) {
const translatedPoints: number[] = translate(state.points); const translatedPoints: number[] = translate(state.points);
@ -1542,7 +1547,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
if (state && state.shapeType === 'points') { if (state && state.shapeType === 'points') {
this.svgShapes[clientID] this.svgShapes[clientID]
.remember('_selectHandler') .remember('_selectHandler')
.nested.style('pointer-events', state.lock ? 'none' : ''); .nested.style('pointer-events', this.stateIsLocked(state) ? 'none' : '');
} }
if (!state || state.hidden || state.outside) { if (!state || state.hidden || state.outside) {
@ -1550,8 +1555,14 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
const shape = this.svgShapes[clientID]; const shape = this.svgShapes[clientID];
let text = this.svgTexts[clientID];
if (!text) {
text = this.addText(state);
this.svgTexts[state.clientID] = text;
}
this.updateTextPosition(text, shape);
if (state.lock) { if (this.stateIsLocked(state)) {
return; return;
} }
@ -1567,12 +1578,6 @@ export class CanvasViewImpl implements CanvasView, Listener {
(shape as any).attr('projections', true); (shape as any).attr('projections', true);
} }
let text = this.svgTexts[clientID];
if (!text) {
text = this.addText(state);
this.svgTexts[state.clientID] = text;
}
const hideText = (): void => { const hideText = (): void => {
if (text) { if (text) {
text.addClass('cvat_canvas_hidden'); text.addClass('cvat_canvas_hidden');
@ -1601,12 +1606,14 @@ export class CanvasViewImpl implements CanvasView, Listener {
const p2 = e.detail.p; const p2 = e.detail.p;
const delta = 1; const delta = 1;
const { offset } = this.controller.geometry; const { offset } = this.controller.geometry;
if (Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) >= delta) { const dx2 = (p1.x - p2.x) ** 2;
const dy2 = (p1.y - p2.y) ** 2;
if (Math.sqrt(dx2 + dy2) >= delta) {
const points = pointsToNumberArray( const points = pointsToNumberArray(
shape.attr('points') || shape.attr('points')
`${shape.attr('x')},${shape.attr('y')} ` + || `${shape.attr('x')},${shape.attr('y')} `
`${shape.attr('x') + shape.attr('width')},` + + `${shape.attr('x') + shape.attr('width')},`
`${shape.attr('y') + shape.attr('height')}`, + `${shape.attr('y') + shape.attr('height')}`,
).map((x: number): number => x - offset); ).map((x: number): number => x - offset);
this.drawnStates[state.clientID].points = points; this.drawnStates[state.clientID].points = points;
@ -1677,10 +1684,10 @@ export class CanvasViewImpl implements CanvasView, Listener {
const { offset } = this.controller.geometry; const { offset } = this.controller.geometry;
const points = pointsToNumberArray( const points = pointsToNumberArray(
shape.attr('points') || shape.attr('points')
`${shape.attr('x')},${shape.attr('y')} ` + || `${shape.attr('x')},${shape.attr('y')} `
`${shape.attr('x') + shape.attr('width')},` + + `${shape.attr('x') + shape.attr('width')},`
`${shape.attr('y') + shape.attr('height')}`, + `${shape.attr('y') + shape.attr('height')}`,
).map((x: number): number => x - offset); ).map((x: number): number => x - offset);
this.drawnStates[state.clientID].points = points; this.drawnStates[state.clientID].points = points;
@ -1697,7 +1704,6 @@ export class CanvasViewImpl implements CanvasView, Listener {
} }
}); });
this.updateTextPosition(text, shape);
this.canvas.dispatchEvent( this.canvas.dispatchEvent(
new CustomEvent('canvas.activated', { new CustomEvent('canvas.activated', {
bubbles: false, bubbles: false,
@ -1757,8 +1763,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
// Find the best place for a text // Find the best place for a text
let [clientX, clientY]: number[] = [box.x + box.width, box.y]; let [clientX, clientY]: number[] = [box.x + box.width, box.y];
if ( if (
clientX + ((text.node as any) as SVGTextElement).getBBox().width + consts.TEXT_MARGIN > clientX + ((text.node as any) as SVGTextElement).getBBox().width + consts.TEXT_MARGIN
this.canvas.offsetWidth > this.canvas.offsetWidth
) { ) {
[clientX, clientY] = [box.x, box.y]; [clientX, clientY] = [box.x, box.y];
} }
@ -1778,7 +1784,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
private addText(state: any): SVG.Text { private addText(state: any): SVG.Text {
const { undefinedAttrValue } = this.configuration; const { undefinedAttrValue } = this.configuration;
const { label, clientID, attributes, source } = state; const {
label, clientID, attributes, source,
} = state;
const attrNames = label.attributes.reduce((acc: any, val: any): void => { const attrNames = label.attributes.reduce((acc: any, val: any): void => {
acc[val.id] = val.name; acc[val.id] = val.name;
return acc; return acc;

@ -93,7 +93,9 @@ interface Props {
export default class CanvasWrapperComponent extends React.PureComponent<Props> { export default class CanvasWrapperComponent extends React.PureComponent<Props> {
public componentDidMount(): void { public componentDidMount(): void {
const { automaticBordering, showObjectsTextAlways, canvasInstance } = this.props; const {
automaticBordering, showObjectsTextAlways, canvasInstance, workspace,
} = this.props;
// It's awful approach from the point of view React // It's awful approach from the point of view React
// But we do not have another way because cvat-canvas returns regular DOM element // But we do not have another way because cvat-canvas returns regular DOM element
@ -104,6 +106,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
autoborders: automaticBordering, autoborders: automaticBordering,
undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE, undefinedAttrValue: consts.UNDEFINED_ATTRIBUTE_VALUE,
displayAllText: showObjectsTextAlways, displayAllText: showObjectsTextAlways,
forceDisableEditing: workspace === Workspace.ATTRIBUTE_ANNOTATION,
}); });
this.initialSetup(); this.initialSetup();
@ -247,6 +250,18 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
canvasInstance.rotate(frameAngle); canvasInstance.rotate(frameAngle);
} }
if (prevProps.workspace !== workspace) {
if (workspace === Workspace.ATTRIBUTE_ANNOTATION) {
canvasInstance.configure({
forceDisableEditing: true,
});
} else if (prevProps.workspace === Workspace.ATTRIBUTE_ANNOTATION) {
canvasInstance.configure({
forceDisableEditing: false,
});
}
}
const loadingAnimation = window.document.getElementById('cvat_canvas_loading_animation'); const loadingAnimation = window.document.getElementById('cvat_canvas_loading_animation');
if (loadingAnimation && frameFetching !== prevProps.frameFetching) { if (loadingAnimation && frameFetching !== prevProps.frameFetching) {
if (frameFetching) { if (frameFetching) {

Loading…
Cancel
Save