Skip to content

Commit

Permalink
#2370 - "Erase" tool
Browse files Browse the repository at this point in the history
#2360 - "Select" tool

- added select and erase tools
- implemented DrawingEntitiesManager and RenderersManager which controls entities parameters changes and render
  • Loading branch information
rrodionov91 committed Aug 30, 2023
1 parent 10d9c91 commit 59df6df
Show file tree
Hide file tree
Showing 33 changed files with 1,301 additions and 552 deletions.
4 changes: 4 additions & 0 deletions packages/ketcher-core/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"root": false,
"extends": "plugin:jest/recommended",
"rules": {
"@typescript-eslint/no-empty-function": "off",
"no-useless-constructor": "off"
},
"overrides": [
{
"files": [
Expand Down
56 changes: 46 additions & 10 deletions packages/ketcher-core/src/application/editor/Editor.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Subscription, DOMSubscription } from 'subscription';
import { ReStruct } from 'application/render';
import { Struct, Vec2 } from 'domain/entities';
import { Vec2 } from 'domain/entities';
import {
BaseTool,
isBaseTool,
Tool,
ToolConstructorInterface,
ToolEventHandlerName,
} from 'application/editor/tools/Tool';
import { toolsMap } from 'application/editor/tools';
import { MonomerItemType } from 'domain/types';
import { RenderersManager } from 'application/render/renderers/RenderersManager';
import { DrawingEntitiesManager } from 'domain/entities/DrawingEntitiesManager';

interface ICoreEditorConstructorParams {
theme;
Expand All @@ -18,36 +21,64 @@ function isMouseMainButtonPressed(event: MouseEvent) {
return event.button === 0;
}

let editor;

export class CoreEditor {
public events = {
selectPeptide: new Subscription(),
selectTool: new Subscription(),
error: new Subscription(),
mouseOverPolymerBond: new Subscription(),
mouseLeavePolymerBond: new Subscription(),
mouseOverMonomer: new Subscription(),
mouseLeaveMonomer: new Subscription(),
mouseOverDrawingEntity: new Subscription(),
mouseLeaveDrawingEntity: new Subscription(),
mouseUpMonomer: new Subscription(),
};

public renderersContainer: ReStruct;
public renderersContainer: RenderersManager;
public drawingEntitiesManager: DrawingEntitiesManager;
public lastCursorPosition: Vec2 = new Vec2(0, 0);
private canvas: SVGSVGElement;
public canvas: SVGSVGElement;
public canvasOffset: DOMRect;
public theme;
// private lastEvent: Event | undefined;
private tool?: Tool;
private tool?: Tool | BaseTool;

constructor({ theme, canvas }: ICoreEditorConstructorParams) {
this.theme = theme;
this.canvas = canvas;
this.subscribeEvents();
this.renderersContainer = new ReStruct(new Struct(), {
skipRaphaelInitialization: true,
theme,
});
this.renderersContainer = new RenderersManager({ theme });
this.drawingEntitiesManager = new DrawingEntitiesManager();
this.domEventSetup();
this.canvasOffset = this.canvas.getBoundingClientRect();
// eslint-disable-next-line @typescript-eslint/no-this-alias
editor = this;
}

public static provideEditorInstance() {
return editor;
}

private subscribeEvents() {
this.events.selectPeptide.add((peptide) => this.onSelectPeptide(peptide));
this.events.selectTool.add((tool) => this.onSelectTool(tool));
const renderersEvents: ToolEventHandlerName[] = [
'mouseOverPolymerBond',
'mouseLeavePolymerBond',
'mouseOverMonomer',
'mouseLeaveMonomer',
'mouseOverDrawingEntity',
'mouseLeaveDrawingEntity',
'mouseUpMonomer',
];
renderersEvents.forEach((eventName) => {
this.events[eventName].add((event) =>
this.useToolIfNeeded(eventName, event),
);
});
}

private onSelectPeptide(peptide: MonomerItemType) {
Expand All @@ -60,8 +91,13 @@ export class CoreEditor {

public selectTool(name: string, options?) {
const ToolConstructor: ToolConstructorInterface = toolsMap[name];
const oldTool = this.tool;

this.tool = new ToolConstructor(this, options);

if (isBaseTool(oldTool)) {
oldTool?.destroy();
}
}

private domEventSetup() {
Expand Down Expand Up @@ -160,7 +196,7 @@ export class CoreEditor {
}

private useToolIfNeeded(eventHandlerName: ToolEventHandlerName, event) {
const editorTool = this.tool;
const editorTool = this.tool as Tool;
if (!editorTool) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ export * from './template';
export * from './text';
export * from './utils';
export * from './highlight';
export * from './peptide';
31 changes: 0 additions & 31 deletions packages/ketcher-core/src/application/editor/actions/peptide.ts

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ export const OperationType = Object.freeze({
REMOVE_HIGHLIGHT: 'Remove highlight',
POLYMER_BOND_ADD: 'Add polymer bond',
POLYMER_BOND_DELETE: 'Remove polymer bond',
POLYMER_BOND_MOVE: 'Move polymer bond',
POLYMER_BOND_FINISH_CREATION: 'Finish polymer bond creation',
POLYMER_BOND_CANCEL_CREATION: 'Cancel polymer bond creation',
PEPTIDE_ADD: 'Add peptide',
PEPTIDE_REMOVE: 'Remove peptide',
PEPTIDE_MOVE: 'Move peptide',
PEPTIDE_HOVER: 'Hover peptide',
DRAWING_ENTITY_SELECT: 'Select drawing entity',
DRAWING_ENTITY_HOVER: 'Hover drawing entity',
SHOW_POLYMER_BOND_INFORMATION: 'Show polymer bond information',
});

export enum OperationPriority {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { RenderersManager } from 'application/render/renderers/RenderersManager';
import { Operation } from 'domain/entities/Operation';
import { DrawingEntity } from 'domain/entities/DrawingEntity';

export class DrawingEntityHoverOperation implements Operation {
constructor(private drawingEntity: DrawingEntity) {}

public execute(renderersManager: RenderersManager) {
renderersManager.hoverDrawingEntity(this.drawingEntity);
}
}

export class DrawingEntitySelectOperation implements Operation {
constructor(private drawingEntity: DrawingEntity) {}

public execute(renderersManager: RenderersManager) {
renderersManager.selectDrawingEntity(this.drawingEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,44 @@
***************************************************************************/
/* eslint-disable @typescript-eslint/no-use-before-define */

import { Vec2 } from 'domain/entities';
import { ReStruct } from '../../../render';

import { BaseOperation } from '../base';
import { OperationType } from '../OperationType';
import { Peptide } from 'domain/entities/Peptide';
import { PeptideRenderer } from 'application/render/renderers/PeptideRenderer';
import { MonomerItemType } from 'domain/types';

type Data = {
peptide: MonomerItemType;
position: Vec2;
};
import { RenderersManager } from 'application/render/renderers/RenderersManager';
import { Operation } from 'domain/entities/Operation';

class PeptideAdd extends BaseOperation {
data: Data;
export class PeptideAddOperation implements Operation {
constructor(private peptide: Peptide) {}

constructor(peptide: MonomerItemType, position: Vec2) {
super(OperationType.ATOM_ADD);
this.data = { peptide, position };
public execute(renderersManager: RenderersManager) {
renderersManager.addPeptide(this.peptide);
}
}

execute(restruct: ReStruct) {
const { peptide, position } = this.data;
export class PeptideMoveOperation implements Operation {
constructor(private peptide: Peptide) {}

const struct = restruct.molecule;
const newPeptide = new Peptide(peptide, position);
const peptideRenderer = new PeptideRenderer(newPeptide);
struct.peptides.set(newPeptide.id, newPeptide);
restruct.peptides.set(newPeptide.id, peptideRenderer);
public execute(renderersManager: RenderersManager) {
renderersManager.movePeptide(this.peptide);
}
}

invert() {
const inverted = new PeptideAdd(this.data.peptide, this.data.position);
inverted.data = this.data;
return inverted;
export class PeptideHoverOperation implements Operation {
constructor(
private peptide: Peptide,
private needRedrawAttachmentPoints: boolean,
) {}

public execute(renderersManager: RenderersManager) {
renderersManager.hoverPeptide(
this.peptide,
this.needRedrawAttachmentPoints,
);
}
}

export { PeptideAdd };
export class PeptideDeleteOperation implements Operation {
constructor(private peptide: Peptide) {}

public execute(renderersManager: RenderersManager) {
renderersManager.deletePeptide(this.peptide);
}
}
Loading

0 comments on commit 59df6df

Please sign in to comment.