diff --git a/example/src/App.tsx b/example/src/App.tsx
index 34edde9461..be5c8a6662 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -67,7 +67,16 @@ const App = () => {
/>
{polymerEditor && }
{hasError && (
- setHasError(false)} />
+ {
+ setHasError(false)
+
+ // Focus on editor after modal is closed
+ const cliparea: HTMLElement = document.querySelector('.cliparea')!
+ cliparea?.focus()
+ }}
+ />
)}
>
)
diff --git a/packages/ketcher-core/package.json b/packages/ketcher-core/package.json
index 3dd99a889e..bd91d809a1 100644
--- a/packages/ketcher-core/package.json
+++ b/packages/ketcher-core/package.json
@@ -1,6 +1,6 @@
{
"name": "ketcher-core",
- "version": "1.2.1",
+ "version": "1.3.0",
"description": "Web-based molecule sketcher",
"license": "Apache-2.0",
"homepage": "http://lifescience.opensource.epam.com/ketcher",
diff --git a/packages/ketcher-core/src/application/editor/actions/highlight.ts b/packages/ketcher-core/src/application/editor/actions/highlight.ts
new file mode 100644
index 0000000000..9b07ffca10
--- /dev/null
+++ b/packages/ketcher-core/src/application/editor/actions/highlight.ts
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * Copyright 2021 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+import { ReStruct } from '../../render'
+
+import { HighlightAdd, HighlightDelete } from '../operations/highlight'
+
+import { Action } from './action'
+
+type HighlightType = {
+ atoms: number[]
+ bonds: number[]
+ color: string
+}
+
+export function fromHighlightCreate(
+ restruct: ReStruct,
+ highlights: HighlightType[]
+): Action {
+ const action = new Action()
+
+ highlights.forEach((highlight) => {
+ const { atoms, bonds, color } = highlight
+
+ action.addOp(new HighlightAdd(atoms, bonds, color))
+ })
+ return action.perform(restruct)
+}
+
+export function fromHighlightClear(restruct: ReStruct): Action {
+ const action = new Action()
+
+ const highlights = restruct.molecule.highlights
+
+ highlights.forEach((_, key) => {
+ action.addOp(new HighlightDelete(key))
+ })
+
+ return action.perform(restruct)
+}
+
+/*
+// Update highlight by placing new one on the given id
+export function fromHighlightUpdate(
+ highlightId: number,
+ restruct: ReStruct,
+ atoms: number[],
+ bonds: number[],
+ color: string
+): Action {
+ const action = new Action()
+
+ const highlights = restruct.molecule.highlights
+
+ const selectedHighlight = highlights.get(highlightId)
+ if (!selectedHighlight) {
+ return action
+ }
+
+ const updateOperation = new HighlightUpdate(highlightId, atoms, bonds, color)
+ action.addOp(updateOperation)
+
+ return action.perform(restruct)
+}
+*/
+
+/*
+// Delete single highlight by id
+export function fromHighlightDelete(
+ restruct: ReStruct,
+ highlightId: number
+): Action {
+ const action = new Action()
+
+ const highlights = restruct.molecule.highlights
+ if (highlights.has(highlightId)) {
+ action.addOp(new HighlightDelete(highlightId))
+
+ return action.perform(restruct)
+ }
+ return action
+}
+*/
diff --git a/packages/ketcher-core/src/application/editor/actions/index.ts b/packages/ketcher-core/src/application/editor/actions/index.ts
index 36a0b16ec7..d59659c3ba 100644
--- a/packages/ketcher-core/src/application/editor/actions/index.ts
+++ b/packages/ketcher-core/src/application/editor/actions/index.ts
@@ -16,3 +16,4 @@ export * from './simpleobject'
export * from './template'
export * from './text'
export * from './utils'
+export * from './highlight'
diff --git a/packages/ketcher-core/src/application/editor/editor.types.ts b/packages/ketcher-core/src/application/editor/editor.types.ts
index e9ef302614..c2a003011a 100644
--- a/packages/ketcher-core/src/application/editor/editor.types.ts
+++ b/packages/ketcher-core/src/application/editor/editor.types.ts
@@ -29,8 +29,22 @@ export interface LoadOptions {
fragment: boolean
}
+interface Selection {
+ atoms?: Array
+ bonds?: Array
+ enhancedFlags?: Array
+ rxnPluses?: Array
+ rxnArrows?: Array
+}
+
export interface Editor {
isDitrty: () => boolean
setOrigin: () => void
struct: (struct?: Struct) => Struct
+ subscribe: (eventName: string, handler: (data?: any) => any) => any
+ unsubscribe: (eventName: string, subscriber: any) => void
+ selection: (arg?: Selection | 'all' | null) => Selection | null
+ undo: () => void
+ redo: () => void
+ clear: () => void
}
diff --git a/packages/ketcher-core/src/application/editor/operations/OperationType.ts b/packages/ketcher-core/src/application/editor/operations/OperationType.ts
index c920b96080..9270527299 100644
--- a/packages/ketcher-core/src/application/editor/operations/OperationType.ts
+++ b/packages/ketcher-core/src/application/editor/operations/OperationType.ts
@@ -60,5 +60,8 @@ export const OperationType = Object.freeze({
TEXT_CREATE: 'Add text',
TEXT_UPDATE: 'Edit text',
TEXT_DELETE: 'Delete text',
- TEXT_MOVE: 'Move text'
+ TEXT_MOVE: 'Move text',
+ ADD_HIGHLIGHT: 'Highlight',
+ UPDATE_HIGHLIGHT: 'Update highlight',
+ REMOVE_HIGHLIGHT: 'Remove highlight'
})
diff --git a/packages/ketcher-core/src/application/editor/operations/highlight.ts b/packages/ketcher-core/src/application/editor/operations/highlight.ts
new file mode 100644
index 0000000000..b1edaad189
--- /dev/null
+++ b/packages/ketcher-core/src/application/editor/operations/highlight.ts
@@ -0,0 +1,224 @@
+/****************************************************************************
+ * Copyright 2021 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+import { Highlight } from 'domain/entities'
+import { ReStruct } from '../../render'
+
+import { BaseOperation } from './base'
+import { OperationType } from './OperationType'
+
+type Data = {
+ atoms: Array
+ bonds: Array
+ color: string
+ highlightId?: number
+}
+
+export class HighlightAdd extends BaseOperation {
+ data: Data
+
+ constructor(
+ atoms: Array,
+ bonds: Array,
+ color: string,
+ highlightId?: number
+ ) {
+ super(OperationType.ADD_HIGHLIGHT)
+ this.data = {
+ atoms: atoms,
+ bonds: bonds,
+ color: color,
+ highlightId: highlightId
+ }
+ }
+
+ execute(restruct: ReStruct) {
+ const { atoms, bonds, color } = this.data
+
+ if (!color) {
+ return
+ }
+
+ const struct = restruct.molecule
+ const highlight = new Highlight({
+ atoms,
+ bonds,
+ color
+ })
+
+ if (typeof this.data.highlightId !== 'number') {
+ this.data.highlightId = struct.highlights.add(highlight)
+ } else {
+ struct.highlights.set(this.data.highlightId, highlight)
+ }
+
+ notifyChanged(restruct, atoms, bonds)
+ }
+
+ invert() {
+ const { atoms, bonds, color, highlightId } = this.data
+ const inverted = new HighlightDelete(highlightId, atoms, bonds, color)
+ return inverted
+ }
+}
+
+export class HighlightDelete extends BaseOperation {
+ data: Data
+
+ constructor(
+ highlightId?: number,
+ atoms?: Array,
+ bonds?: Array,
+ color?: string
+ ) {
+ super(OperationType.REMOVE_HIGHLIGHT, 5)
+ this.data = {
+ highlightId: highlightId,
+ atoms: atoms || [],
+ bonds: bonds || [],
+ color: color || 'white'
+ }
+ }
+
+ execute(restruct: ReStruct) {
+ if (typeof this.data.highlightId === 'number') {
+ const struct = restruct.molecule
+
+ const highlightToRemove = struct.highlights.get(this.data.highlightId)
+ if (typeof highlightToRemove === 'undefined') {
+ return
+ }
+
+ const { atoms, bonds, color } = highlightToRemove
+
+ this.data.atoms = atoms
+ this.data.bonds = bonds
+ this.data.color = color
+
+ struct.highlights.delete(this.data.highlightId)
+ notifyChanged(restruct, atoms, bonds)
+ }
+ }
+
+ invert() {
+ const { atoms, bonds, color, highlightId } = this.data
+ const inverted = new HighlightAdd(atoms, bonds, color, highlightId)
+ inverted.data = this.data
+ return inverted
+ }
+}
+
+export class HighlightUpdate extends BaseOperation {
+ // making sure highlightId is not optional
+ newData: Data & { highlightId: number }
+ oldData: Data & { highlightId: number }
+
+ constructor(
+ highlightId: number,
+ atoms: Array,
+ bonds: Array,
+ color: string
+ ) {
+ super(OperationType.UPDATE_HIGHLIGHT)
+ this.newData = {
+ atoms: atoms,
+ bonds: bonds,
+ color: color,
+ highlightId: highlightId
+ }
+
+ // pre-filling with new data. Upon execution this will be replaced
+ this.oldData = {
+ atoms: atoms,
+ bonds: bonds,
+ color: color,
+ highlightId: highlightId
+ }
+ }
+
+ execute(restruct: ReStruct) {
+ const { atoms, bonds, color } = this.newData
+ if (!color) {
+ return
+ }
+
+ const highlightId = this.newData.highlightId
+ const struct = restruct.molecule
+
+ const highlightToUpdate = struct.highlights.get(highlightId)
+
+ if (highlightToUpdate) {
+ // saving data of existing highlight
+ const {
+ atoms: oldAtoms,
+ bonds: oldBonds,
+ color: oldColor
+ } = highlightToUpdate
+ this.oldData = {
+ atoms: oldAtoms,
+ bonds: oldBonds,
+ color: oldColor,
+ highlightId
+ }
+
+ // creating new highlight with new data
+ const updatedHighlight = new Highlight({
+ atoms,
+ bonds,
+ color
+ })
+
+ // setting the new highlight
+ struct.highlights.set(this.newData.highlightId, updatedHighlight)
+
+ // notify atoms from both collections that repaint is needed
+ notifyChanged(restruct, [...atoms, ...oldAtoms], [...bonds, ...oldBonds])
+ }
+ }
+
+ invert() {
+ const { atoms, bonds, color } = this.oldData
+ const inverted = new HighlightUpdate(
+ this.newData.highlightId,
+ atoms,
+ bonds,
+ color
+ )
+ return inverted
+ }
+}
+
+function notifyChanged(restruct: ReStruct, atoms?: number[], bonds?: number[]) {
+ // Notifying ReStruct that repaint needed
+ const reAtoms = restruct.atoms
+ const reBonds = restruct.bonds
+
+ if (atoms) {
+ atoms.forEach((atomId) => {
+ if (typeof reAtoms.get(atomId) !== 'undefined') {
+ restruct.markAtom(atomId, 1)
+ }
+ })
+ }
+
+ if (bonds) {
+ bonds.forEach((bondId) => {
+ if (typeof reBonds.get(bondId) !== 'undefined') {
+ restruct.markBond(bondId, 1)
+ }
+ })
+ }
+}
diff --git a/packages/ketcher-core/src/application/render/options.js b/packages/ketcher-core/src/application/render/options.js
index 3c27e300fd..899be3806d 100644
--- a/packages/ketcher-core/src/application/render/options.js
+++ b/packages/ketcher-core/src/application/render/options.js
@@ -74,7 +74,7 @@ function defaultOptions(opt) {
fill: '#7f7',
stroke: 'none'
},
- highlightStyle: {
+ hoverStyle: {
stroke: '#0c0',
'stroke-width': (0.6 * scaleFactor) / 20
},
@@ -86,7 +86,7 @@ function defaultOptions(opt) {
stroke: 'gray',
'stroke-width': '1px'
},
- highlightStyleSimpleObject: {
+ hoverStyleSimpleObject: {
stroke: '#0c0',
'stroke-width': scaleFactor / 4,
'stroke-linecap': 'round',
diff --git a/packages/ketcher-core/src/application/render/restruct/generalEnumTypes.ts b/packages/ketcher-core/src/application/render/restruct/generalEnumTypes.ts
index 629a73933c..5d1dae37fe 100644
--- a/packages/ketcher-core/src/application/render/restruct/generalEnumTypes.ts
+++ b/packages/ketcher-core/src/application/render/restruct/generalEnumTypes.ts
@@ -17,7 +17,7 @@
export enum LayerMap {
background = 'background',
selectionPlate = 'selectionPlate',
- highlighting = 'highlighting',
+ hovering = 'hovering',
warnings = 'warnings',
data = 'data',
indices = 'indices'
diff --git a/packages/ketcher-core/src/application/render/restruct/reatom.ts b/packages/ketcher-core/src/application/render/restruct/reatom.ts
index c1b5d2d8b4..0ae11471fd 100644
--- a/packages/ketcher-core/src/application/render/restruct/reatom.ts
+++ b/packages/ketcher-core/src/application/render/restruct/reatom.ts
@@ -84,13 +84,13 @@ class ReAtom extends ReObject {
return new Box2Abs(this.a.pp, this.a.pp)
}
- drawHighlight(render: Render) {
- const ret = this.makeHighlightPlate(render)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ drawHover(render: Render) {
+ const ret = this.makeHoverPlate(render)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
- makeHighlightPlate(render: Render) {
+ makeHoverPlate(render: Render) {
const paper = render.paper
const options = render.options
const ps = Scale.obj2scaled(this.a.pp, options)
@@ -109,7 +109,7 @@ class ReAtom extends ReObject {
}
return paper
.circle(ps.x, ps.y, options.atomSelectionPlateRadius)
- .attr(options.highlightStyle)
+ .attr(options.hoverStyle)
}
makeSelectionPlate(restruct: ReStruct, paper: any, styles: any) {
@@ -185,7 +185,6 @@ class ReAtom extends ReObject {
implh = Math.floor(this.a.implicitH)
isHydrogen = label.text === 'H'
restruct.addReObjectPath(LayerMap.data, this.visel, label.path, ps, true)
- this.setHighlight(this.highlight, render)
}
if (options.showAtomIds) {
index = {}
@@ -205,6 +204,7 @@ class ReAtom extends ReObject {
draw.recenterText(index.path, index.rbb)
restruct.addReObjectPath(LayerMap.indices, this.visel, index.path, ps)
}
+ this.setHover(this.hover, render)
if (this.showLabel && !this.a.pseudo) {
let hydroIndex: any = null
@@ -376,6 +376,30 @@ class ReAtom extends ReObject {
pathAndRBoxTranslate(aamPath, aamBox, dir.x, dir.y)
restruct.addReObjectPath(LayerMap.data, this.visel, aamPath, ps, true)
}
+
+ // Checking whether atom is highlighted and what's the last color
+ const highlights = restruct.molecule.highlights
+ let isHighlighted = false
+ let highlightColor = ''
+ highlights.forEach((highlight) => {
+ const hasCurrentHighlight = highlight.atoms?.includes(aid)
+ isHighlighted = isHighlighted || hasCurrentHighlight
+ if (hasCurrentHighlight) {
+ highlightColor = highlight.color
+ }
+ })
+
+ // Drawing highlight
+ if (isHighlighted) {
+ const style = { fill: highlightColor, stroke: 'none' }
+
+ const ps = Scale.obj2scaled(this.a.pp, restruct.render.options)
+ const path = render.paper
+ .circle(ps.x, ps.y, options.atomSelectionPlateRadius * 0.8)
+ .attr(style)
+
+ restruct.addReObjectPath(LayerMap.hovering, this.visel, path)
+ }
}
}
diff --git a/packages/ketcher-core/src/application/render/restruct/rebond.ts b/packages/ketcher-core/src/application/render/restruct/rebond.ts
index d37c53f96d..dbf67940c6 100644
--- a/packages/ketcher-core/src/application/render/restruct/rebond.ts
+++ b/packages/ketcher-core/src/application/render/restruct/rebond.ts
@@ -51,13 +51,13 @@ class ReBond extends ReObject {
return true
}
- drawHighlight(render: Render) {
- const ret = this.makeHighlightPlate(render)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ drawHover(render: Render) {
+ const ret = this.makeHoverPlate(render)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
- makeHighlightPlate(render: Render) {
+ makeHoverPlate(render: Render) {
const options = render.options
bondRecalc(this, render.ctab, options)
const bond = this.b
@@ -77,7 +77,7 @@ class ReBond extends ReObject {
const c = Scale.obj2scaled(this.b.center, options)
return render.paper
.circle(c.x, c.y, 0.8 * options.atomSelectionPlateRadius)
- .attr(options.highlightStyle)
+ .attr(options.hoverStyle)
}
makeSelectionPlate(restruct: ReStruct, paper: any, options: any) {
@@ -157,7 +157,7 @@ class ReBond extends ReObject {
true
)
}
- this.setHighlight(this.highlight, render)
+ this.setHover(this.hover, render)
let ipath = null
const bondIdxOff = options.subFontSize * 0.6
@@ -213,9 +213,57 @@ class ReBond extends ReObject {
)
restruct.addReObjectPath(LayerMap.indices, this.visel, ipath)
}
+
+ // Checking whether bond is highlighted and what is the last color
+ const highlights = restruct.molecule.highlights
+ let isHighlighted = false
+ let highlightColor = ''
+ highlights.forEach((highlight) => {
+ const hasCurrentHighlight = highlight.bonds?.includes(bid)
+ isHighlighted = isHighlighted || hasCurrentHighlight
+ if (hasCurrentHighlight) {
+ highlightColor = highlight.color
+ }
+ })
+
+ // Drawing highlight
+ if (isHighlighted) {
+ const style = {
+ fill: highlightColor,
+ stroke: highlightColor,
+ 'stroke-width': options.lineattr['stroke-width'] * 7,
+ 'stroke-linecap': 'round'
+ }
+
+ const c = Scale.obj2scaled(this.b.center, restruct.render.options)
+
+ const highlightPath = getHighlightPath(restruct, hb1, hb2)
+ highlightPath.attr(style)
+
+ restruct.addReObjectPath(
+ LayerMap.hovering,
+ this.visel,
+ highlightPath,
+ c,
+ true
+ )
+ }
}
}
+function getHighlightPath(restruct: ReStruct, hb1: HalfBond, hb2: HalfBond) {
+ const beginning = { x: hb1.p.x, y: hb1.p.y }
+ const end = { x: hb2.p.x, y: hb2.p.y }
+
+ const paper = restruct.render.paper
+
+ const pathString = `M${beginning.x},${beginning.y} L${end.x},${end.y}`
+
+ const path = paper.path(pathString)
+
+ return path
+}
+
function findIncomingStereoUpBond(
atom: Atom,
bid0: number,
diff --git a/packages/ketcher-core/src/application/render/restruct/redatasgroupdata.js b/packages/ketcher-core/src/application/render/restruct/redatasgroupdata.js
index 3460196f0b..92124f0709 100644
--- a/packages/ketcher-core/src/application/render/restruct/redatasgroupdata.js
+++ b/packages/ketcher-core/src/application/render/restruct/redatasgroupdata.js
@@ -28,22 +28,22 @@ class ReDataSGroupData extends ReObject {
return true
}
- highlightPath(render) {
+ hoverPath(render) {
const box = this.sgroup.dataArea
const p0 = Scale.obj2scaled(box.p0, render.options)
const sz = Scale.obj2scaled(box.p1, render.options).sub(p0)
return render.paper.rect(p0.x, p0.y, sz.x, sz.y)
}
- drawHighlight(render) {
- const ret = this.highlightPath(render).attr(render.options.highlightStyle)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ drawHover(render) {
+ const ret = this.hoverPath(render).attr(render.options.hoverStyle)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
makeSelectionPlate(restruct, paper, styles) {
// TODO [MK] review parameters
- return this.highlightPath(restruct.render).attr(styles.selectionStyle)
+ return this.hoverPath(restruct.render).attr(styles.selectionStyle)
}
}
diff --git a/packages/ketcher-core/src/application/render/restruct/reenhancedFlag.ts b/packages/ketcher-core/src/application/render/restruct/reenhancedFlag.ts
index 78ec95506e..54ae8fe3ff 100644
--- a/packages/ketcher-core/src/application/render/restruct/reenhancedFlag.ts
+++ b/packages/ketcher-core/src/application/render/restruct/reenhancedFlag.ts
@@ -33,25 +33,25 @@ class ReEnhancedFlag extends ReObject {
return true
}
- highlightPath(render: Render): any {
+ hoverPath(render: Render): any {
const box = Box2Abs.fromRelBox(this.#path.getBBox())
const sz = box.p1.sub(box.p0)
const p0 = box.p0.sub(render.options.offset)
return render.paper.rect(p0.x, p0.y, sz.x, sz.y)
}
- drawHighlight(render: Render): any {
+ drawHover(render: Render): any {
// TODO: after the enhanced flag stops being displayed, need to remove the reEnhancedflag object from ctab
if (!this.#path?.attrs) return null
- const ret = this.highlightPath(render).attr(render.options.highlightStyle)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ const ret = this.hoverPath(render).attr(render.options.hoverStyle)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
makeSelectionPlate(restruct: ReStruct, _paper: any, options: any): any {
// TODO: after the enhanced flag stops being displayed, need to remove the reEnhancedflag object from ctab
if (!this.#path?.attrs) return null
- return this.highlightPath(restruct.render).attr(options.selectionStyle)
+ return this.hoverPath(restruct.render).attr(options.selectionStyle)
}
show(restruct: ReStruct, fragmentId: number, options: any): void {
diff --git a/packages/ketcher-core/src/application/render/restruct/refrag.js b/packages/ketcher-core/src/application/render/restruct/refrag.js
index 3ea04cad1a..8392393ef7 100644
--- a/packages/ketcher-core/src/application/render/restruct/refrag.js
+++ b/packages/ketcher-core/src/application/render/restruct/refrag.js
@@ -91,12 +91,12 @@ class ReFrag extends ReObject {
return null // this._draw(render, fid, { 'stroke' : 'lightgray' }); // [RB] for debugging only
}
- drawHighlight(render) {
+ drawHover(render) {
// eslint-disable-line no-unused-vars
// Do nothing. This method shouldn't actually be called.
}
- setHighlight(highLight, render) {
+ setHover(hover, render) {
let fid = render.ctab.frags.keyOf(this)
if (!fid && fid !== 0) {
@@ -107,12 +107,12 @@ class ReFrag extends ReObject {
fid = parseInt(fid, 10)
render.ctab.atoms.forEach((atom) => {
- if (atom.a.fragment === fid) atom.setHighlight(highLight, render)
+ if (atom.a.fragment === fid) atom.setHover(hover, render)
})
render.ctab.bonds.forEach((bond) => {
if (render.ctab.atoms.get(bond.b.begin).a.fragment === fid) {
- bond.setHighlight(highLight, render)
+ bond.setHover(hover, render)
}
})
}
diff --git a/packages/ketcher-core/src/application/render/restruct/reobject.ts b/packages/ketcher-core/src/application/render/restruct/reobject.ts
index 1fa7cbf9c8..330a6f6529 100644
--- a/packages/ketcher-core/src/application/render/restruct/reobject.ts
+++ b/packages/ketcher-core/src/application/render/restruct/reobject.ts
@@ -22,8 +22,8 @@ import Visel from './visel'
class ReObject {
public visel: Visel
- public highlight = false
- public highlighting: any = null
+ public hover = false
+ public hovering: any = null
public selected = false
public selectionPlate: any = null
@@ -40,34 +40,34 @@ class ReObject {
return vbox.transform(Scale.scaled2obj, render.options)
}
- setHighlight(highLight: boolean, render: Render): void {
+ setHover(hover: boolean, render: Render): void {
// TODO render should be field
- if (highLight) {
- let noredraw = 'highlighting' in this && this.highlighting !== null // && !this.highlighting.removed;
+ if (hover) {
+ let noredraw = 'hovering' in this && this.hovering !== null // && !this.highlighting.removed;
if (noredraw) {
- if (this.highlighting.type === 'set') {
- if (!this.highlighting[0]) return
- noredraw = !this.highlighting[0].removed
+ if (this.hovering.type === 'set') {
+ if (!this.hovering[0]) return
+ noredraw = !this.hovering[0].removed
} else {
- noredraw = !this.highlighting.removed
+ noredraw = !this.hovering.removed
}
}
if (noredraw) {
- this.highlighting.show()
+ this.hovering.show()
} else {
render.paper.setStart()
- this.drawHighlight(render)
- this.highlighting = render.paper.setFinish()
+ this.drawHover(render)
+ this.hovering = render.paper.setFinish()
}
- } else if (this.highlighting) {
- this.highlighting.hide()
+ } else if (this.hovering) {
+ this.hovering.hide()
}
- this.highlight = highLight
+ this.hover = hover
}
- drawHighlight(_render: Render): any {
- throw new Error('ReObject.drawHighlight is not overridden.')
+ drawHover(_render: Render): any {
+ throw new Error('ReObject.drawHover is not overridden.')
}
makeSelectionPlate(_restruct: ReStruct, _paper: any, _styles: any): any {
diff --git a/packages/ketcher-core/src/application/render/restruct/rergroup.js b/packages/ketcher-core/src/application/render/restruct/rergroup.js
index 9cc3934fc1..4855bfad40 100644
--- a/packages/ketcher-core/src/application/render/restruct/rergroup.js
+++ b/packages/ketcher-core/src/application/render/restruct/rergroup.js
@@ -144,7 +144,7 @@ class ReRGroup extends ReObject {
.attr(attrs)
}
- drawHighlight(render) {
+ drawHover(render) {
const rgid = render.ctab.rgroups.keyOf(this)
if (!rgid) {
@@ -157,12 +157,12 @@ class ReRGroup extends ReObject {
const ret = this._draw(
render,
rgid,
- render.options.highlightStyle /* { 'fill' : 'red' } */
+ render.options.hoverStyle /* { 'fill' : 'red' } */
) // eslint-disable-line no-underscore-dangle
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
this.item.frags.forEach((fnum, fid) => {
- render.ctab.frags.get(fid).drawHighlight(render)
+ render.ctab.frags.get(fid).drawHover(render)
})
return ret
diff --git a/packages/ketcher-core/src/application/render/restruct/rerxnarrow.ts b/packages/ketcher-core/src/application/render/restruct/rerxnarrow.ts
index 78071e72f7..628868eb54 100644
--- a/packages/ketcher-core/src/application/render/restruct/rerxnarrow.ts
+++ b/packages/ketcher-core/src/application/render/restruct/rerxnarrow.ts
@@ -96,15 +96,15 @@ class ReRxnArrow extends ReObject {
return minDist
}
- highlightPath(render: Render) {
+ hoverPath(render: Render) {
const path = this.generatePath(render, render.options, 'selection')
return render.paper.path(path)
}
- drawHighlight(render: Render) {
- const ret = this.highlightPath(render).attr(render.options.highlightStyle)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ drawHover(render: Render) {
+ const ret = this.hoverPath(render).attr(render.options.hoverStyle)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
diff --git a/packages/ketcher-core/src/application/render/restruct/rerxnplus.js b/packages/ketcher-core/src/application/render/restruct/rerxnplus.js
index 46d7ae0052..f12e13ab42 100644
--- a/packages/ketcher-core/src/application/render/restruct/rerxnplus.js
+++ b/packages/ketcher-core/src/application/render/restruct/rerxnplus.js
@@ -31,7 +31,7 @@ class ReRxnPlus extends ReObject {
return true
}
- highlightPath(render) {
+ hoverPath(render) {
const p = Scale.obj2scaled(this.item.pp, render.options)
const s = render.options.scale
/* eslint-disable no-mixed-operators */
@@ -39,15 +39,15 @@ class ReRxnPlus extends ReObject {
/* eslint-enable no-mixed-operators */
}
- drawHighlight(render) {
- const ret = this.highlightPath(render).attr(render.options.highlightStyle)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ drawHover(render) {
+ const ret = this.hoverPath(render).attr(render.options.hoverStyle)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
makeSelectionPlate(restruct, paper, styles) {
// TODO [MK] review parameters
- return this.highlightPath(restruct.render).attr(styles.selectionStyle)
+ return this.hoverPath(restruct.render).attr(styles.selectionStyle)
}
show(restruct, id, options) {
diff --git a/packages/ketcher-core/src/application/render/restruct/resgroup.js b/packages/ketcher-core/src/application/render/restruct/resgroup.js
index abfbba5e50..1577e2aff1 100644
--- a/packages/ketcher-core/src/application/render/restruct/resgroup.js
+++ b/packages/ketcher-core/src/application/render/restruct/resgroup.js
@@ -130,7 +130,7 @@ class ReSGroup extends ReObject {
}
}
- drawHighlight(render) {
+ drawHover(render) {
// eslint-disable-line max-statements
const options = render.options
const paper = render.paper
@@ -146,11 +146,11 @@ class ReSGroup extends ReObject {
)
) {
const { startX, startY, size } = getHighlighPathInfo(sGroupItem, options)
- sGroupItem.highlighting = paper
+ sGroupItem.hovering = paper
.rect(startX, startY, size, size)
- .attr(options.highlightStyle)
+ .attr(options.hoverStyle)
} else {
- sGroupItem.highlighting = paper
+ sGroupItem.hovering = paper
.path(
'M{0},{1}L{2},{3}L{4},{5}L{6},{7}L{0},{1}',
tfx(a0.x),
@@ -162,17 +162,17 @@ class ReSGroup extends ReObject {
tfx(b0.x),
tfx(b0.y)
)
- .attr(options.highlightStyle)
+ .attr(options.hoverStyle)
}
- set.push(sGroupItem.highlighting)
+ set.push(sGroupItem.hovering)
SGroup.getAtoms(render.ctab.molecule, sGroupItem).forEach((aid) => {
- set.push(render.ctab.atoms.get(aid).makeHighlightPlate(render))
+ set.push(render.ctab.atoms.get(aid).makeHoverPlate(render))
}, this)
SGroup.getBonds(render.ctab.molecule, sGroupItem).forEach((bid) => {
- set.push(render.ctab.bonds.get(bid).makeHighlightPlate(render))
+ set.push(render.ctab.bonds.get(bid).makeHoverPlate(render))
}, this)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, set)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, set)
}
show(restruct) {
@@ -182,7 +182,7 @@ class ReSGroup extends ReObject {
const remol = render.ctab
const path = this.draw(remol, sgroup)
restruct.addReObjectPath(LayerMap.data, this.visel, path, null, true)
- this.setHighlight(this.highlight, render) // TODO: fix this
+ this.setHover(this.hover, render) // TODO: fix this
}
}
}
@@ -458,9 +458,9 @@ function getHighlighPathInfo(sgroup, options) {
let startY = (a1.y + a0.y) / 2 - size / 2
if (sgroup.firstSgroupAtom) {
const shift = new Vec2(size / 2, size / 2, 0)
- const highlightPp = Vec2.diff(sgroup.firstSgroupAtom.pp.scaled(40), shift)
- startX = highlightPp.x
- startY = highlightPp.y
+ const hoverPp = Vec2.diff(sgroup.firstSgroupAtom.pp.scaled(40), shift)
+ startX = hoverPp.x
+ startY = hoverPp.y
}
return {
a0,
diff --git a/packages/ketcher-core/src/application/render/restruct/resimpleObject.ts b/packages/ketcher-core/src/application/render/restruct/resimpleObject.ts
index db88ac329f..a6a5c63a7b 100644
--- a/packages/ketcher-core/src/application/render/restruct/resimpleObject.ts
+++ b/packages/ketcher-core/src/application/render/restruct/resimpleObject.ts
@@ -189,7 +189,7 @@ class ReSimpleObject extends ReObject {
return refPoints
}
- highlightPath(render: Render): Array {
+ hoverPath(render: Render): Array {
const point: Array = []
this.item.pos.forEach((p, index) => {
@@ -336,15 +336,15 @@ class ReSimpleObject extends ReObject {
return enhPaths
}
- drawHighlight(render: Render): Array {
- const paths: Array = this.highlightPath(render).map((enhPath) => {
+ drawHover(render: Render): Array {
+ const paths: Array = this.hoverPath(render).map((enhPath) => {
if (!enhPath.stylesApplied) {
- return enhPath.path.attr(render.options.highlightStyle)
+ return enhPath.path.attr(render.options.hoverStyle)
}
return enhPath.path
})
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, paths)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, paths)
return paths
}
@@ -358,7 +358,7 @@ class ReSimpleObject extends ReObject {
const selectionSet = restruct.render.paper.set()
selectionSet.push(
generatePath(this.item.mode, paper, pos).attr(
- styles.highlightStyleSimpleObject
+ styles.hoverStyleSimpleObject
)
)
refPoints.forEach((rp) => {
diff --git a/packages/ketcher-core/src/application/render/restruct/restruct.ts b/packages/ketcher-core/src/application/render/restruct/restruct.ts
index 907e5871a7..81b964eb1c 100644
--- a/packages/ketcher-core/src/application/render/restruct/restruct.ts
+++ b/packages/ketcher-core/src/application/render/restruct/restruct.ts
@@ -389,7 +389,7 @@ class ReStruct {
// TODO: when to update sgroup?
this.sgroups.forEach((sgroup) => {
this.clearVisel(sgroup.visel)
- sgroup.highlighting = null
+ sgroup.hovering = null
sgroup.selectionPlate = null
})
diff --git a/packages/ketcher-core/src/application/render/restruct/retext.ts b/packages/ketcher-core/src/application/render/restruct/retext.ts
index ade0e91f77..44f694d1bc 100644
--- a/packages/ketcher-core/src/application/render/restruct/retext.ts
+++ b/packages/ketcher-core/src/application/render/restruct/retext.ts
@@ -69,7 +69,7 @@ class ReText extends ReObject {
return refPoints
}
- highlightPath(render: any): any {
+ hoverPath(render: any): any {
const { p0, p1 } = this.getRelBox(this.paths)
const topLeft = p0.sub(render.options.offset)
const { x: width, y: height } = p1.sub(p0)
@@ -115,16 +115,16 @@ class ReText extends ReObject {
}, 0)
}
- drawHighlight(render: any): any {
+ drawHover(render: any): any {
if (!this.paths.length) return null
- const ret = this.highlightPath(render).attr(render.options.highlightStyle)
- render.ctab.addReObjectPath(LayerMap.highlighting, this.visel, ret)
+ const ret = this.hoverPath(render).attr(render.options.hoverStyle)
+ render.ctab.addReObjectPath(LayerMap.hovering, this.visel, ret)
return ret
}
makeSelectionPlate(restruct: ReStruct, paper: any, options: any): any {
if (!this.paths.length || !paper) return null
- return this.highlightPath(restruct.render).attr(options.selectionStyle)
+ return this.hoverPath(restruct.render).attr(options.selectionStyle)
}
show(restruct: ReStruct, _id: number, options: any): void {
diff --git a/packages/ketcher-core/src/domain/entities/highlight.ts b/packages/ketcher-core/src/domain/entities/highlight.ts
new file mode 100644
index 0000000000..1037bb21ec
--- /dev/null
+++ b/packages/ketcher-core/src/domain/entities/highlight.ts
@@ -0,0 +1,34 @@
+/****************************************************************************
+ * Copyright 2021 EPAM Systems
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+
+export interface HighlightAttributes {
+ atoms: Array
+ bonds: Array
+ color: string
+}
+
+export class Highlight {
+ atoms: Array
+ bonds: Array
+ color: string
+
+ constructor(attributes: HighlightAttributes) {
+ const { atoms, bonds, color } = attributes
+ this.color = color
+ this.atoms = atoms
+ this.bonds = bonds
+ }
+}
diff --git a/packages/ketcher-core/src/domain/entities/index.ts b/packages/ketcher-core/src/domain/entities/index.ts
index 699a55d257..989caf00d6 100644
--- a/packages/ketcher-core/src/domain/entities/index.ts
+++ b/packages/ketcher-core/src/domain/entities/index.ts
@@ -33,3 +33,4 @@ export * from './pile'
export * from './vec2'
export * from './box2Abs'
export * from './pool'
+export * from './highlight'
diff --git a/packages/ketcher-core/src/domain/entities/sgroup.ts b/packages/ketcher-core/src/domain/entities/sgroup.ts
index b7faf7bb95..b9b631b8d3 100644
--- a/packages/ketcher-core/src/domain/entities/sgroup.ts
+++ b/packages/ketcher-core/src/domain/entities/sgroup.ts
@@ -62,8 +62,8 @@ export class SGroup {
bracketBox: any
bracketDir: Vec2
areas: any
- highlight: boolean
- highlighting: any
+ hover: boolean
+ hovering: any
selected: boolean
selectionPlate: any
atoms: any
@@ -85,8 +85,8 @@ export class SGroup {
this.bracketDir = new Vec2(1, 0)
this.areas = []
- this.highlight = false
- this.highlighting = null
+ this.hover = false
+ this.hovering = null
this.selected = false
this.selectionPlate = null
diff --git a/packages/ketcher-core/src/domain/entities/struct.ts b/packages/ketcher-core/src/domain/entities/struct.ts
index 2141230c61..feb7159636 100644
--- a/packages/ketcher-core/src/domain/entities/struct.ts
+++ b/packages/ketcher-core/src/domain/entities/struct.ts
@@ -33,6 +33,7 @@ import { SGroupForest } from './sgroupForest'
import { SimpleObject } from './simpleObject'
import { Text } from './text'
import { Vec2 } from './vec2'
+import { Highlight } from './highlight'
export type Neighbor = {
aid: number
@@ -63,6 +64,7 @@ export class Struct {
simpleObjects: Pool
texts: Pool
functionalGroups: Pool
+ highlights: Pool
constructor() {
this.atoms = new Pool()
@@ -80,6 +82,7 @@ export class Struct {
this.simpleObjects = new Pool()
this.texts = new Pool()
this.functionalGroups = new Pool()
+ this.highlights = new Pool()
}
hasRxnProps(): boolean {
diff --git a/packages/ketcher-polymer-editor-react/src/__snapshots__/Editor.test.tsx.snap b/packages/ketcher-polymer-editor-react/src/__snapshots__/Editor.test.tsx.snap
index b0332121fe..45e27f8e30 100644
--- a/packages/ketcher-polymer-editor-react/src/__snapshots__/Editor.test.tsx.snap
+++ b/packages/ketcher-polymer-editor-react/src/__snapshots__/Editor.test.tsx.snap
@@ -309,7 +309,7 @@ Object {
class="css-1il5ut8"
>
@@ -763,7 +763,7 @@ Object {
class="css-1il5ut8"
>
diff --git a/packages/ketcher-polymer-editor-react/src/components/modal/Open/__snapshots__/Open.test.tsx.snap b/packages/ketcher-polymer-editor-react/src/components/modal/Open/__snapshots__/Open.test.tsx.snap
index 0dcda5c68e..6dbf2f30c2 100644
--- a/packages/ketcher-polymer-editor-react/src/components/modal/Open/__snapshots__/Open.test.tsx.snap
+++ b/packages/ketcher-polymer-editor-react/src/components/modal/Open/__snapshots__/Open.test.tsx.snap
@@ -59,7 +59,7 @@ Object {