Skip to content

Commit

Permalink
#2229: Bond between Functional Group and structure disappears after a…
Browse files Browse the repository at this point in the history
…dding Functional Group again (#2230) (#2231)

* #1990 - Detect if group is attached to smth + get attachment atom

* #2229 - Bond between Functional Group and structure disappears after adding Functional Group again

* #2229 - rename pos0/pos1

* #2229 - more clear logic when replacing group

---------

Co-authored-by: Stanislav Permiakov <Stanislav.Permiakov@primark.onmicrosoft.com>
Co-authored-by: Stanislav Permiakov <stanislav_permiakov@epam.com>
  • Loading branch information
3 people committed Feb 16, 2023
1 parent cedf2a9 commit 67a0af0
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 17 deletions.
17 changes: 17 additions & 0 deletions packages/ketcher-core/src/domain/entities/sgroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@ export class SGroup {
this.pp = topLeftPoint
}

getAttAtomId(struct: Struct): number {
for (const atomId of this.atoms) {
const atom = struct.atoms.get(atomId)
if (!atom) continue
if (Number.isInteger(atom.attpnt)) return atomId
}
// in normal circumstances this should never be invoked
return this.atoms[0]
}

isGroupAttached(struct: Struct): boolean {
const attachPointId = this.getAttAtomId(struct)
const neighbours = struct.atomGetNeighbors(attachPointId)

return !neighbours?.every(({ aid }) => this.atoms.includes(aid))
}

static getOffset(sgroup: SGroup): null | Vec2 {
if (!sgroup?.pp) return null
return Vec2.diff(sgroup.pp, sgroup.bracketBox.p1)
Expand Down
62 changes: 45 additions & 17 deletions packages/ketcher-react/src/script/editor/tool/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,14 @@ class TemplateTool {

const dragCtx = this.dragCtx
const ci = dragCtx.item
let pos0: Vec2 | null | undefined = null
const pos1 = this.editor.render.page2obj(event)
let targetPos: Vec2 | null | undefined = null
const eventPos = this.editor.render.page2obj(event)
const struct = restruct.molecule

/* moving when attached to bond */
if (ci && ci.map === 'bonds' && this.mode !== 'fg') {
const bond = struct.bonds.get(ci.id)
let sign = getSign(struct, bond, pos1)
let sign = getSign(struct, bond, eventPos)

if (dragCtx.sign1 * this.template.sign > 0) {
sign = -sign
Expand Down Expand Up @@ -296,21 +296,22 @@ class TemplateTool {
// calc initial pos and is extra bond needed
if (!ci) {
// ci.type == 'Canvas'
pos0 = dragCtx.xy0
targetPos = dragCtx.xy0
} else if (ci.map === 'atoms') {
pos0 = struct.atoms.get(ci.id)?.pp
targetPos = struct.atoms.get(ci.id)?.pp

if (pos0) {
extraBond = this.mode === 'fg' ? true : Vec2.dist(pos0, pos1) > 1
if (targetPos) {
extraBond =
this.mode === 'fg' ? true : Vec2.dist(targetPos, eventPos) > 1
}
}

if (!pos0) {
if (!targetPos) {
return true
}

// calc angle
let angle = utils.calcAngle(pos0, pos1)
let angle = utils.calcAngle(targetPos, eventPos)

if (!event.ctrlKey) {
angle = utils.fracAngle(angle, null)
Expand Down Expand Up @@ -373,9 +374,8 @@ class TemplateTool {
delete this.dragCtx

const restruct = this.editor.render.ctab
const sgroups = restruct.sgroups
const struct = restruct.molecule
const ci = dragCtx.item
let ci = dragCtx.item
const functionalGroups = struct.functionalGroups

/* after moving around bond */
Expand All @@ -402,7 +402,6 @@ class TemplateTool {

let action
let pasteItems = null
let isFunctionalGroupReplace = false

if (SGroup.isSaltOrSolvent(this.template.molecule.name)) {
addSaltsAndSolventsOnCanvasWithoutMerge(
Expand All @@ -417,18 +416,47 @@ class TemplateTool {
FunctionalGroup.isContractedFunctionalGroup(ci.id, functionalGroups) &&
this.mode === 'fg'
) {
const sGroup = sgroups.get(ci.id)
const closestGroup = this.editor.struct().sgroups.get(ci.id)
const isClosestGroupAttached =
closestGroup && closestGroup.isGroupAttached(this.editor.struct())

if (isClosestGroupAttached) {
const groupAttachmentAtomId = this.editor
.struct()
.atoms.find((atomId) => {
return !!this.editor
.struct()
.atomGetNeighbors(atomId)
?.find(
(neighbor) =>
neighbor.aid ===
closestGroup.getAttAtomId(this.editor.struct())
)
})

if (groupAttachmentAtomId !== null) {
const targetPos =
this.editor.struct().atoms.get(groupAttachmentAtomId)?.pp ||
dragCtx.xy0
const eventPos = this.editor.render.page2obj(event)

const dist = Vec2.dist(targetPos, eventPos)
ci = { map: 'atoms', dist, id: groupAttachmentAtomId }
}
}

this.editor.update(
fromFragmentDeletion(this.editor.render.ctab, {
atoms: [...SGroup.getAtoms(struct, sGroup?.item)],
bonds: [...SGroup.getBonds(struct, sGroup?.item)]
atoms: [...SGroup.getAtoms(struct, closestGroup)],
bonds: [...SGroup.getBonds(struct, closestGroup)]
})
)
isFunctionalGroupReplace = true

if (!isClosestGroupAttached) ci = null
}

if (!dragCtx.action) {
if (!ci || isFunctionalGroupReplace) {
if (!ci) {
// ci.type == 'Canvas'
;[action, pasteItems] = fromTemplateOnCanvas(
restruct,
Expand Down

0 comments on commit 67a0af0

Please sign in to comment.