Skip to content

Commit

Permalink
#4884 – Implement basic preview display for monomer bonds
Browse files Browse the repository at this point in the history
  • Loading branch information
svvald committed Aug 21, 2024
1 parent 4dc3168 commit 428d2af
Show file tree
Hide file tree
Showing 38 changed files with 710 additions and 376 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Nucleotide } from 'domain/entities/Nucleotide';
import { SequenceMode } from '../modes';
import { isMacOs } from 'react-device-detect';
import { EraserTool } from './Erase';
import { PolymerBondRenderer } from 'application/render';

class SelectRectangle implements BaseTool {
private brush;
Expand Down Expand Up @@ -269,6 +270,31 @@ class SelectRectangle implements BaseTool {
this.editor.renderersContainer.update(modelChanges);
}

public mouseOverPolymerBond(event) {
const renderer: PolymerBondRenderer = event.target.__data__;

const modelChanges =
this.editor.drawingEntitiesManager.showPolymerBondInformation(
renderer.polymerBond,
);
this.editor.renderersContainer.markForRecalculateBegin();
this.editor.renderersContainer.update(modelChanges);
}

public mouseLeavePolymerBond(event) {
const renderer: PolymerBondRenderer = event.target.__data__;
if (!renderer.polymerBond) {
return;
}

const modelChanges =
this.editor.drawingEntitiesManager.hidePolymerBondInformation(
renderer.polymerBond,
);
this.editor.renderersContainer.markForRecalculateBegin();
this.editor.renderersContainer.update(modelChanges);
}

setSelectedEntities() {
this.previousSelectedEntities =
this.editor.drawingEntitiesManager.allEntities.filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export interface KetVariantMonomerTemplateOption {

export interface IKetMonomerTemplate {
type: KetTemplateType.MONOMER_TEMPLATE;
class?: monomerClass;
class?: KetMonomerClass;
monomerSubClass?:
| 'AminoAcid'
| 'Sugar'
Expand Down
26 changes: 10 additions & 16 deletions packages/ketcher-core/src/domain/entities/BaseMonomer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { DrawingEntity, DrawingEntityConfig } from './DrawingEntity';
import { Vec2 } from 'domain/entities/vec2';
import { AttachmentPointName, MonomerItemType } from 'domain/types';
import {
AttachmentPointName,
AttachmentPointsToBonds,
MonomerItemType,
} from 'domain/types';
import { PolymerBond } from 'domain/entities/PolymerBond';
import { BaseMonomerRenderer } from 'application/render/renderers/BaseMonomerRenderer';
import { BaseRenderer } from 'application/render/renderers/BaseRenderer';
Expand All @@ -22,17 +26,13 @@ export type BaseMonomerConfig = DrawingEntityConfig;

export abstract class BaseMonomer extends DrawingEntity {
public renderer?: BaseMonomerRenderer | BaseSequenceItemRenderer = undefined;
public attachmentPointsToBonds: Partial<
Record<AttachmentPointName, PolymerBond | null>
> = {};
public attachmentPointsToBonds: AttachmentPointsToBonds = {};

public chosenFirstAttachmentPointForBond: AttachmentPointName | null;
public potentialSecondAttachmentPointForBond: AttachmentPointName | null;
public chosenSecondAttachmentPointForBond: AttachmentPointName | null;

public potentialAttachmentPointsToBonds: {
[key: string]: PolymerBond | null | undefined;
} = {};
public potentialAttachmentPointsToBonds: AttachmentPointsToBonds = {};

public attachmentPointsVisible = false;
public monomerItem: MonomerItemType;
Expand Down Expand Up @@ -318,9 +318,7 @@ export abstract class BaseMonomer extends DrawingEntity {
return Boolean(this.getPotentialBondByAttachmentPoint(attachmentPointName));
}

private getAttachmentPointDict(): Partial<
Record<AttachmentPointName, PolymerBond | null>
> {
private getAttachmentPointDict(): AttachmentPointsToBonds {
if (this.monomerItem.attachmentPoints) {
const { attachmentPointDictionary } =
BaseMonomer.getAttachmentPointDictFromMonomerDefinition(
Expand All @@ -335,9 +333,7 @@ export abstract class BaseMonomer extends DrawingEntity {
public static getAttachmentPointDictFromMonomerDefinition(
attachmentPoints: IKetAttachmentPoint[],
): {
attachmentPointDictionary: Partial<
Record<AttachmentPointName, PolymerBond | null>
>;
attachmentPointDictionary: AttachmentPointsToBonds;
attachmentPointsList: AttachmentPointName[];
} {
const attachmentPointDictionary = {};
Expand Down Expand Up @@ -440,9 +436,7 @@ export abstract class BaseMonomer extends DrawingEntity {
return superatomWithoutLabel.getAttachmentPoints();
}

public getAttachmentPointDictFromAtoms(): Partial<
Record<AttachmentPointName, PolymerBond | null>
> {
public getAttachmentPointDictFromAtoms(): AttachmentPointsToBonds {
const attachmentPointNameToBond = {};

this.superatomAttachmentPoints.forEach((superatomAttachmentPoint) => {
Expand Down
9 changes: 7 additions & 2 deletions packages/ketcher-core/src/domain/types/monomers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import {
RNABase,
Struct,
Sugar,
PolymerBond,
} from 'domain/entities';
import {
IKetAttachmentPoint,
IKetIdtAliases,
KetVariantMonomerTemplateOption,
KetVariantMonomerTemplateSubType,
KetMonomerClass,
} from 'application/formatters/types/ket';
import { D3SvgElementSelection } from 'application/render/types';

Expand All @@ -36,8 +38,7 @@ export type MonomerItemType = {
MonomerCaps?: { [key: string]: string };
MonomerCode?: string;
MonomerType?: string;
// TODO: Specify the type. `readonly MonomerClass: KetMonomerClass`?
MonomerClass?: string;
MonomerClass?: KetMonomerClass;
isMicromoleculeFragment?: boolean;
idtAliases?: IKetIdtAliases;
unresolved?: boolean;
Expand Down Expand Up @@ -92,3 +93,7 @@ export type AttachmentPointConstructorParams = {
};

export type ConcreteMonomer = Peptide | Sugar | RNABase | Phosphate | Chem;

export type AttachmentPointsToBonds = Partial<
Record<AttachmentPointName, PolymerBond | null>
>;
2 changes: 1 addition & 1 deletion packages/ketcher-macromolecules/src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import { useContextMenu } from 'react-contexify';
import { CONTEXT_MENU_ID } from 'components/contextMenu/types';
import { SequenceItemContextMenu } from 'components/contextMenu/SequenceItemContextMenu/SequenceItemContextMenu';
import { SequenceStartArrow } from 'components/shared/monomerOnCanvas/SequenceStartArrow';
import { Preview } from 'components/shared/Preview';
import { Preview } from 'components/preview/Preview';
import { SequenceTypeDropdown } from 'components/SequenceTypeButton';
import { TopMenuComponent } from 'components/TopMenuComponent';
import { LeftMenuComponent } from 'components/LeftMenuComponent';
Expand Down
71 changes: 59 additions & 12 deletions packages/ketcher-macromolecules/src/EditorEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
***************************************************************************/
import { useCallback, useEffect } from 'react';
import {
BondPreviewState,
MonomerPreviewState,
PresetPosition,
PresetPreviewState,
PreviewStyle,
PreviewType,
selectEditor,
selectEditorActiveTool,
selectTool,
Expand All @@ -34,6 +39,7 @@ import {
calculateNucleoElementPreviewTop,
} from 'helpers';
import { selectAllPresets } from 'state/rna-builder';
import { PolymerBond } from 'ketcher-core/dist/domain/entities/PolymerBond';

const noPreviewTools = ['bond-single'];

Expand Down Expand Up @@ -136,11 +142,44 @@ export const EditorEvents = () => {
};
}, [editor]);

const handleOpenBondPreview = useCallback(
(polymerBond: PolymerBond, style: PreviewStyle) => {
const previewData: BondPreviewState = {
type: PreviewType.Bond,
polymerBond,
style,
};

debouncedShowPreview(previewData);
},
[debouncedShowPreview],
);

const handleOpenPreview = useCallback(
(e) => {
const polymerBond = e.target.__data__?.polymerBond;
if (polymerBond) {
const polymerCoordinates = e.target.getBoundingClientRect();
const { width, height, top, left } = polymerCoordinates;
let style = { top: '', left: '' };
if (width > height) {
style = {
top: `${top + height + 10}px`,
left: `${left + width / 2}px`,
};
} else {
style = {
top: `${top + height / 2}px`,
left: `${left + width + 10}px`,
};
}
handleOpenBondPreview(polymerBond, style);
return;
}

// TODO: Split to separate functions for monomers and presets
const cardCoordinates = e.target.getBoundingClientRect();
const left = `${cardCoordinates.left + cardCoordinates.width / 2}px`;

const sequenceNode = e.target.__data__?.node;
const monomer = e.target.__data__?.monomer || sequenceNode?.monomer;
const monomerItem = monomer.monomerItem;
Expand Down Expand Up @@ -180,34 +219,38 @@ export const EditorEvents = () => {
position = PresetPosition.ChainMiddle;
}

debouncedShowPreview({
preset: {
monomers,
name: existingPreset?.name,
idtAliases: existingPreset?.idtAliases,
position,
},
const presetPreviewData: PresetPreviewState = {
type: PreviewType.Preset,
monomers,
name: existingPreset?.name,
idtAliases: existingPreset?.idtAliases,
position,
style: {
left,
top: monomerItem
? calculateNucleoElementPreviewTop(cardCoordinates)
: '',
transform: 'translate(-50%, 0)',
},
});
};

debouncedShowPreview(presetPreviewData);
return;
}

debouncedShowPreview({
const monomerPreviewData: MonomerPreviewState = {
type: PreviewType.Monomer,
monomer: monomerItem,
attachmentPointsToBonds,
style: {
left,
top: monomerItem ? calculateMonomerPreviewTop(cardCoordinates) : '',
},
});
};

debouncedShowPreview(monomerPreviewData);
},
[debouncedShowPreview, presets],
[handleOpenBondPreview, debouncedShowPreview, presets],
);

const handleClosePreview = useCallback(() => {
Expand All @@ -220,6 +263,8 @@ export const EditorEvents = () => {
editor?.events.mouseLeaveMonomer.add(handleClosePreview);
editor?.events.mouseOverSequenceItem.add(handleOpenPreview);
editor?.events.mouseLeaveSequenceItem.add(handleClosePreview);
editor?.events.mouseOverPolymerBond.add(handleOpenPreview);
editor?.events.mouseLeavePolymerBond.add(handleClosePreview);

const onMoveHandler = (e) => {
handleClosePreview();
Expand All @@ -238,6 +283,8 @@ export const EditorEvents = () => {
editor?.events.mouseOnMoveSequenceItem.remove(onMoveHandler);
editor?.events.mouseOverSequenceItem.remove(handleOpenPreview);
editor?.events.mouseLeaveSequenceItem.remove(handleClosePreview);
editor?.events.mouseOverPolymerBond.remove(handleOpenPreview);
editor?.events.mouseLeavePolymerBond.remove(handleClosePreview);
};
}, [editor, activeTool, handleOpenPreview, handleClosePreview]);

Expand Down
Loading

0 comments on commit 428d2af

Please sign in to comment.