Skip to content

Commit

Permalink
#2367 - Ability to move items on the canvas (#3286)
Browse files Browse the repository at this point in the history
* #2367 - add ability to move items on the canvas

---------

Co-authored-by: Olga Mazurina <olga_mazurina@epam.com>
Co-authored-by: Roman Rodionov <roman_rodionov@epam.com>
  • Loading branch information
3 people authored Sep 13, 2023
1 parent ada37e4 commit a553367
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { test } from '@playwright/test';
import {
addMonomerToCanvas,
dragMouseTo,
selectEraseTool,
selectRectangleArea,
selectRectangleSelectionTool,
selectSingleBondTool,
takeEditorScreenshot,
} from '@utils';
import { turnOnMacromoleculesEditor } from '@utils/macromolecules';
import { bondTwoMonomers } from '@utils/macromolecules/polymerBond';
Expand Down Expand Up @@ -69,4 +71,46 @@ test.describe('Rectangle Selection Tool', () => {
path: 'tests/Macromolecule-editor/screenshots/rectangle-selection-tool3.png',
});
});

test.skip('Move monomer bonded with another monomers', async ({ page }) => {
/*
Test case: #2367 - move items on the canvas
Description: check ability to move items on the canvas
*/

// Choose peptide
await page.getByText('Tza').click();

// Create 4 peptides on canvas
await page.mouse.click(300, 300);
await page.mouse.click(400, 400);
await page.mouse.click(500, 500);
await page.mouse.click(600, 600);

// Get 4 peptides locators
const peptides = await page.getByText('Tza').locator('..');
const peptide1 = peptides.nth(0);
const peptide2 = peptides.nth(1);
const peptide3 = peptides.nth(2);
const peptide4 = peptides.nth(3);

// Select bond tool
await selectSingleBondTool(page);

// Create bonds between peptides
await bondTwoMonomers(page, peptide1, peptide2);
await bondTwoMonomers(page, peptide3, peptide2);
await bondTwoMonomers(page, peptide3, peptide4);

await takeEditorScreenshot(page);

// Move selected monomer
await selectRectangleSelectionTool(page);
await page.mouse.move(400, 400);
await dragMouseTo(500, 500, page);
await page.mouse.move(400, 400);
await dragMouseTo(200, 400, page);

await takeEditorScreenshot(page);
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from '../../../mock-data';
import { createPolymerEditorCanvas } from '../../../helpers/dom';
import { SelectRectangle } from 'application/editor/tools/SelectRectangle';
import { Vec2 } from 'domain/entities/vec2';
import { BaseMonomerRenderer } from 'application/render/renderers';

jest.mock('d3', () => {
return {
Expand Down Expand Up @@ -69,4 +71,44 @@ describe('Select Rectangle Tool', () => {
canvas.dispatchEvent(new Event('mouseover', { bubbles: true }));
expect(onShow).toHaveBeenCalled();
});

it('should move selected entity', () => {
const canvas: SVGSVGElement = createPolymerEditorCanvas();
const editor = new CoreEditor({
theme: polymerEditorTheme,
canvas,
});

const modelChanges = editor.drawingEntitiesManager.addMonomer(
peptideMonomerItem,
new Vec2(0, 0),
);
editor.renderersContainer.update(modelChanges);
const peptide = Array.from(editor.drawingEntitiesManager.monomers)[0][1];
const onMove = jest.fn();
jest
.spyOn(BaseMonomerRenderer.prototype, 'moveSelection')
.mockImplementation(onMove);

const selectRectangleTool = new SelectRectangle(editor);

const initialPosition = peptide.position;
const event = {
target: {
__data__: peptide.renderer,
},
pageX: initialPosition.x,
pageY: initialPosition.y,
};

editor.drawingEntitiesManager.selectDrawingEntity(peptide);
selectRectangleTool.mousedown(event);
editor.lastCursorPosition.x = initialPosition.x + 100;
editor.lastCursorPosition.y = initialPosition.y + 100;

selectRectangleTool.mousemove();
selectRectangleTool.mouseup(event);

expect(onMove).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ export class DrawingEntitySelectOperation implements Operation {
renderersManager.selectDrawingEntity(this.drawingEntity);
}
}
export class DrawingEntityMoveOperation implements Operation {
constructor(private drawingEntity: DrawingEntity) {}

public execute(renderersManager: RenderersManager) {
renderersManager.moveDrawingEntity(this.drawingEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { BaseTool } from 'application/editor/tools/Tool';
class SelectRectangle implements BaseTool {
private brush;
private brushArea;
private moveStarted;
private mousePositionAfterMove;

constructor(private editor: CoreEditor) {
this.editor = editor;
Expand Down Expand Up @@ -69,16 +71,49 @@ class SelectRectangle implements BaseTool {
const renderer = event.target.__data__;
let modelChanges: Command;
if (renderer instanceof BaseRenderer) {
modelChanges = this.editor.drawingEntitiesManager.selectDrawingEntity(
renderer.drawingEntity,
);
if (renderer.drawingEntity.selected) {
this.moveStarted = true;
this.mousePositionAfterMove = [
this.editor.lastCursorPosition.x,
this.editor.lastCursorPosition.y,
];
return;
} else {
modelChanges = this.editor.drawingEntitiesManager.selectDrawingEntity(
renderer.drawingEntity,
);
}
} else {
modelChanges =
this.editor.drawingEntitiesManager.unselectAllDrawingEntities();
}
this.editor.renderersContainer.update(modelChanges);
}

mousemove() {
if (this.moveStarted) {
const modelChanges =
this.editor.drawingEntitiesManager.moveSelectedDrawingEntities(
new Vec2(
this.editor.lastCursorPosition.x - this.mousePositionAfterMove[0],
this.editor.lastCursorPosition.y - this.mousePositionAfterMove[1],
),
);
this.mousePositionAfterMove = [
this.editor.lastCursorPosition.x,
this.editor.lastCursorPosition.y,
];
this.editor.renderersContainer.update(modelChanges);
}
}

mouseup(event) {
const renderer = event.target.__data__;
if (this.moveStarted && renderer.drawingEntity.selected) {
this.moveStarted = false;
}
}

mouseOverDrawingEntity(event) {
const renderer = event.target.__data__;
const modelChanges =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ export abstract class BaseMonomerRenderer extends BaseRenderer {
}
}

public moveSelection() {
assert(this.rootElement);
this.appendSelection();
this.move();
}

public move() {
this.rootElement?.attr(
'transform',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export abstract class BaseRenderer implements IBaseRenderer {

public abstract show(theme): void;
public abstract drawSelection(): void;
public abstract moveSelection(): void;
protected abstract appendHover(
hoverArea,
): D3SvgElementSelection<SVGUseElement, void> | void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export class PolymerBondRenderer extends BaseRenderer {
return this.rootBBox?.height || 0;
}

public moveSelection() {
assert(this.rootElement);
this.moveStart();
this.moveEnd();
}

public appendBond(rootElement) {
this.bodyElement = rootElement
.append('line')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export class RenderersManager {
drawingEntity.baseRenderer.drawSelection();
}

public moveDrawingEntity(drawingEntity: DrawingEntity) {
assert(drawingEntity.baseRenderer);
drawingEntity.baseRenderer.moveSelection();
}

public addMonomer(monomer: BaseMonomer, callback?: () => void) {
const [, MonomerRenderer] = monomerFactory(monomer.monomerItem);
const monomerRenderer = new MonomerRenderer(monomer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import {
DrawingEntityHoverOperation,
DrawingEntitySelectOperation,
DrawingEntityMoveOperation,
} from 'application/editor/operations/drawingEntity';
import {
PolymerBondAddOperation,
Expand Down Expand Up @@ -116,6 +117,38 @@ export class DrawingEntitiesManager {
return command;
}

public moveSelectedDrawingEntities(offset: Vec2) {
const command = new Command();

this.monomers.forEach((drawingEntity) => {
if (drawingEntity.selected) {
drawingEntity.moveRelative(offset);
command.merge(this.createDrawingEntityMovingCommand(drawingEntity));
}
});

this.polymerBonds.forEach((drawingEntity) => {
if (
drawingEntity.selected ||
drawingEntity.firstMonomer.selected ||
drawingEntity.secondMonomer?.selected
) {
drawingEntity.moveToLinkedMonomers();
command.merge(this.createDrawingEntityMovingCommand(drawingEntity));
}
});
return command;
}

public createDrawingEntityMovingCommand(drawingEntity: DrawingEntity) {
const command = new Command();

const movingCommand = new DrawingEntityMoveOperation(drawingEntity);
command.addOperation(movingCommand);

return command;
}

public deleteMonomer(monomer: BaseMonomer) {
this.monomers.delete(monomer.id);
const command = new Command();
Expand Down Expand Up @@ -402,6 +435,7 @@ export class DrawingEntitiesManager {
let monomerAddOperation;
if (previousMonomer) {
const polymerBond = new PolymerBond(previousMonomer);
this.polymerBonds.set(polymerBond.id, polymerBond);
monomerAddOperation = new MonomerAddOperation(monomer, () => {
polymerBond.moveToLinkedMonomers();
});
Expand Down

0 comments on commit a553367

Please sign in to comment.