Skip to content

Commit

Permalink
Merge branch 'master' into #1954-draw-selected-structure-at-mouse-cur…
Browse files Browse the repository at this point in the history
…sor-as-pasting-does
  • Loading branch information
yuleicul committed Jan 18, 2023
2 parents de9ce17 + 14844ad commit 86dea5e
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 126 deletions.
2 changes: 1 addition & 1 deletion packages/ketcher-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ketcher-core",
"version": "2.6.4",
"version": "2.7.0-rc.10",
"description": "Web-based molecule sketcher",
"license": "Apache-2.0",
"homepage": "http://lifescience.opensource.epam.com/ketcher",
Expand Down
2 changes: 1 addition & 1 deletion packages/ketcher-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ketcher-react",
"version": "2.6.4",
"version": "2.7.0-rc.10",
"description": "Web-based molecule sketcher",
"license": "Apache-2.0",
"homepage": "http://lifescience.opensource.epam.com/ketcher",
Expand Down
53 changes: 41 additions & 12 deletions packages/ketcher-react/src/script/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,17 @@ function isMouseRight(event) {
)
}

function resetSelectionOnCanvasClick(editor: Editor, eventName: string) {
if (eventName === 'mouseup' && editor.selection()) {
function resetSelectionOnCanvasClick(
editor: Editor,
eventName: string,
clientArea: HTMLElement,
event
) {
if (
eventName === 'mouseup' &&
editor.selection() &&
clientArea.contains(event.target)
) {
editor.selection(null)
}
}
Expand All @@ -613,7 +622,30 @@ function updateLastCursorPosition(editor: Editor, event) {
}
}

function domEventSetup(editor: Editor, clientArea) {
function useToolIfNeeded(
editor: Editor,
eventName: string,
clientArea: HTMLElement,
event
) {
const EditorTool = editor.tool()
editor.lastEvent = event

const conditions = [
!!EditorTool,
eventName in EditorTool,
clientArea.contains(event.target) || EditorTool.isSelectionRunning?.()
]

if (conditions.every((condition) => condition)) {
EditorTool[eventName](event)
return true
}

return false
}

function domEventSetup(editor: Editor, clientArea: HTMLElement) {
// TODO: addEventListener('resize', ...);
;[
{ target: clientArea, eventName: 'click' },
Expand Down Expand Up @@ -643,17 +675,14 @@ function domEventSetup(editor: Editor, clientArea) {
return true
}
}
const EditorTool = editor.tool()
editor.lastEvent = event
if (
EditorTool &&
eventName in EditorTool &&
clientArea.contains(event.target)
) {
EditorTool[eventName](event)

const isToolUsed = useToolIfNeeded(editor, eventName, clientArea, event)
if (isToolUsed) {
return true
}
resetSelectionOnCanvasClick(editor, eventName)

resetSelectionOnCanvasClick(editor, eventName, clientArea, event)

return true
}, -1)
})
Expand Down
4 changes: 4 additions & 0 deletions packages/ketcher-react/src/script/editor/tool/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class SelectTool {
)
}

isSelectionRunning() {
return this.#lassoHelper.running()
}

mousedown(event) {
const rnd = this.editor.render
const ctab = rnd.ctab
Expand Down
9 changes: 3 additions & 6 deletions packages/ketcher-react/src/script/editor/tool/sgroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,10 @@ class SGroupTool {
}

// TODO: handle click on an existing group?
if (id !== null || (selection && selection.atoms))
if (id !== null || (selection && selection.atoms)) {
this.editor.selection(selection)
SGroupTool.sgroupDialog(this.editor, id, this.type)
}
}

cancel() {
Expand All @@ -461,11 +463,6 @@ class SGroupTool {
const type = sg ? sg.type : defaultType
const eventName = type === 'DAT' ? 'sdataEdit' : 'sgroupEdit'

if (!selection.atoms && !selection.bonds && !sg) {
console.info('There is no selection or sgroup')
return
}

let attrs
if (sg) {
attrs = sg.getAttrs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@
import { Menu } from 'react-contexify'
import 'react-contexify/ReactContexify.css'
import styles from './ContextMenu.module.less'
import {
AtomBatchEdit,
AtomStereoBatchEdit,
AtomBatchDelete
} from './items/AtomBatchOperations'
import { AtomBatchEdit, AtomStereoBatchEdit } from './items/AtomBatchOperations'
import AtomSingleOperations from './items/AtomSingleOperations'
import {
BondBatchEdit,
BondTypeBatchChange,
BondBatchDelete
} from './items/BondBatchOperations'
import { BatchDelete } from './items/BatchDelete'
import { BondBatchEdit, BondTypeBatchChange } from './items/BondBatchOperations'
import BondSingleOperations from './items/BondSingleOperations'

export const CONTEXT_MENU_ID = 'ketcherBondAndAtomContextMenu'
Expand All @@ -42,8 +35,7 @@ const ContextMenu: React.FC = () => {
<AtomBatchEdit />
<BondTypeBatchChange />
<AtomStereoBatchEdit />
<BondBatchDelete />
<AtomBatchDelete />
<BatchDelete />
</Menu>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@
* limitations under the License.
***************************************************************************/

import {
Action,
findStereoAtoms,
fromAtomsAttrs,
fromOneAtomDeletion
} from 'ketcher-core'
import { findStereoAtoms, fromAtomsAttrs } from 'ketcher-core'
import { useCallback, useRef } from 'react'
import type { PredicateParams } from 'react-contexify'
import { Item } from 'react-contexify'
Expand All @@ -33,10 +28,7 @@ import type {
ContextMenuShowProps,
CustomItemProps
} from '../contextMenu.types'
import { noOperation } from './utils'

const isHidden = ({ props }: PredicateParams<ContextMenuShowProps, ItemData>) =>
!props?.selected
import { noOperation, isBatchOperationHidden } from './utils'

const useDisabled = () => {
const { getKetcherInstance } = useAppContext()
Expand All @@ -46,7 +38,7 @@ const useDisabled = () => {
props,
triggerEvent
}: PredicateParams<ContextMenuShowProps, ItemData>) => {
if (isHidden({ props, triggerEvent })) {
if (isBatchOperationHidden({ props, triggerEvent })) {
return true
}

Expand Down Expand Up @@ -99,11 +91,11 @@ export const AtomBatchEdit: React.FC<CustomItemProps> = (props) => {
return (
<Item
{...props}
hidden={isHidden}
hidden={isBatchOperationHidden}
disabled={isDisabled}
onClick={handleClick}
>
Edit selected atom(s)
Edit selected atom(s)...
</Item>
)
}
Expand Down Expand Up @@ -161,39 +153,11 @@ export const AtomStereoBatchEdit: React.FC<CustomItemProps> = (props) => {
return (
<Item
{...props}
hidden={isHidden}
hidden={isBatchOperationHidden}
disabled={isStereoDisabled}
onClick={handleClick}
>
Enhanced stereochemistry
</Item>
)
}

export const AtomBatchDelete: React.FC<CustomItemProps> = (props) => {
const { getKetcherInstance } = useAppContext()
const isDisabled = useDisabled()

const handleClick = useCallback(() => {
const editor = getKetcherInstance().editor as Editor
const action = new Action()
const selectedAtomIds = editor.selection()?.atoms

selectedAtomIds?.forEach((atomId) => {
action.mergeWith(fromOneAtomDeletion(editor.render.ctab, atomId))
})

editor.update(action)
}, [getKetcherInstance])

return (
<Item
{...props}
hidden={isHidden}
disabled={isDisabled}
onClick={handleClick}
>
Delete selected atom(s)
Enhanced stereochemistry...
</Item>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const AtomSingleOperations: React.FC = (props) => {
return (
<>
<Item {...props} hidden={isHidden} onClick={handleEdit}>
Edit
Edit...
</Item>

<Item
Expand All @@ -124,7 +124,7 @@ const AtomSingleOperations: React.FC = (props) => {
disabled={isStereoDisabled}
onClick={handleStereoEdit}
>
Enhanced stereochemistry
Enhanced stereochemistry...
</Item>

<Item {...props} hidden={isHidden} onClick={handleDelete}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useCallback } from 'react'
import { Item } from 'react-contexify'
import { useAppContext } from 'src/hooks'
import Editor from 'src/script/editor'
import EraserTool from 'src/script/editor/tool/eraser'
import { CustomItemProps } from '../contextMenu.types'
import { isBatchOperationHidden } from './utils'

export const BatchDelete: React.FC<CustomItemProps> = (props) => {
const { getKetcherInstance } = useAppContext()

const handleClick = useCallback(() => {
const editor = getKetcherInstance().editor as Editor

// eslint-disable-next-line no-new
new EraserTool(editor, 0)
}, [getKetcherInstance])

return (
<Item {...props} hidden={isBatchOperationHidden} onClick={handleClick}>
Delete
</Item>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
***************************************************************************/

import { Action, fromBondsAttrs, fromOneBondDeletion } from 'ketcher-core'
import { fromBondsAttrs } from 'ketcher-core'
import { useCallback } from 'react'
import type { ItemParams, PredicateParams } from 'react-contexify'
import { Item, Submenu } from 'react-contexify'
Expand All @@ -31,13 +31,15 @@ import type {
CustomItemProps,
CustomSubMenuProps
} from '../contextMenu.types'
import { formatTitle, getBondNames, noOperation } from './utils'
import {
formatTitle,
getBondNames,
noOperation,
isBatchOperationHidden
} from './utils'

const bondNames = getBondNames(tools)

const isHidden = ({ props }: PredicateParams<ContextMenuShowProps, ItemData>) =>
!props?.selected

const useDisabled = () => {
const { getKetcherInstance } = useAppContext()

Expand All @@ -46,7 +48,7 @@ const useDisabled = () => {
props,
triggerEvent
}: PredicateParams<ContextMenuShowProps, ItemData>) => {
if (isHidden({ props, triggerEvent })) {
if (isBatchOperationHidden({ props, triggerEvent })) {
return true
}

Expand Down Expand Up @@ -89,11 +91,11 @@ export const BondBatchEdit: React.FC<CustomItemProps> = (props) => {
return (
<Item
{...props}
hidden={isHidden}
hidden={isBatchOperationHidden}
disabled={isDisabled}
onClick={handleClick}
>
Edit selected bond(s)
Edit selected bond(s)...
</Item>
)
}
Expand All @@ -120,7 +122,7 @@ export const BondTypeBatchChange: React.FC<CustomSubMenuProps> = (props) => {
<Submenu
{...props}
label="Bond type"
hidden={isHidden}
hidden={isBatchOperationHidden}
disabled={isDisabled}
className={styles.subMenu}
>
Expand All @@ -133,31 +135,3 @@ export const BondTypeBatchChange: React.FC<CustomSubMenuProps> = (props) => {
</Submenu>
)
}

export const BondBatchDelete: React.FC<CustomItemProps> = (props) => {
const { getKetcherInstance } = useAppContext()
const isDisabled = useDisabled()

const handleClick = useCallback(() => {
const editor = getKetcherInstance().editor as Editor
const action = new Action()
const selectedBonds = editor.selection()?.bonds

selectedBonds?.forEach((bondId) => {
action.mergeWith(fromOneBondDeletion(editor.render.ctab, bondId))
})

editor.update(action)
}, [getKetcherInstance])

return (
<Item
{...props}
hidden={isHidden}
disabled={isDisabled}
onClick={handleClick}
>
Delete selected bond(s)
</Item>
)
}
Loading

0 comments on commit 86dea5e

Please sign in to comment.