import styled from '@emotion/styled'; import type { MoleculeView } from '@zakodium/nmrium-core'; import { useEffect, useState } from 'react'; import { ResponsiveChart } from 'react-d3-utils'; import { BsArrowsMove } from 'react-icons/bs'; import { FaRegBookmark, FaTimes } from 'react-icons/fa'; import { MdFormatColorText, MdNumbers } from 'react-icons/md'; import { Rnd } from 'react-rnd'; import type { MoleculeBoundingRect, StateMoleculeExtended, } from '../../../../data/molecules/Molecule.js'; import { useDispatch } from '../../../context/DispatchContext.js'; import { useGlobal } from '../../../context/GlobalContext.js'; import type { ActionsButtonsPopoverProps } from '../../../elements/ActionsButtonsPopover.js'; import { ActionsButtonsPopover } from '../../../elements/ActionsButtonsPopover.js'; import { useSVGUnitConverter } from '../../../hooks/useSVGUnitConverter.js'; import { useCheckExportStatus } from '../../../hooks/useViewportSize.js'; import { useMoleculeEditor } from '../../../modal/MoleculeStructureEditorModal.js'; import { MoleculeStructure } from '../../../panels/MoleculesPanel/MoleculeStructure.js'; import { useMoleculeAnnotationCore } from '../../../panels/hooks/useMoleculeAnnotationCore.js'; import { booleanToString } from '../../../utility/booleanToString.js'; interface DraggableStructureProps { moleculeView: MoleculeView; index?: number; molecule: StateMoleculeExtended; } const ReactRnd = styled(Rnd)` border: 1px solid transparent; .content { height: 100%; width: 100%; } :hover { background-color: white; border: 1px solid #ebecf1; } form { z-index: 1; } `; export function DraggableStructure(props: DraggableStructureProps) { const { molecule, moleculeView } = props; const { viewerRef } = useGlobal(); const isExportProcessStart = useCheckExportStatus(); const dispatch = useDispatch(); const { modal, openMoleculeEditor } = useMoleculeEditor(); const { percentToPixel, pixelToPercent } = useSVGUnitConverter(); const [bounding, setBounding] = useState( moleculeView.floating.bounding, ); const [isMoveActive, setIsMoveActive] = useState(false); useEffect(() => { setBounding({ ...moleculeView.floating.bounding }); }, [moleculeView.floating.bounding]); function floatMoleculeHandler() { dispatch({ type: 'FLOAT_MOLECULE_OVER_SPECTRUM', payload: { id: molecule.id }, }); } function dragFloatMoleculeHandler(bounding: Partial) { if ( typeof bounding?.width === 'number' && typeof bounding?.height === 'number' ) { const { width, height } = moleculeView.floating.bounding; bounding.width += width; bounding.height += height; } dispatch({ type: 'CHANGE_FLOAT_MOLECULE_POSITION', payload: { id: molecule.id, bounding: bounding as MoleculeBoundingRect }, }); } function handleDrag(internalBounding: Pick) { setBounding((prevBounding) => ({ ...prevBounding, ...convertPositionToPercent(internalBounding), })); } function convertPositionToPercent({ x, y, }: Pick) { return { x: pixelToPercent(x, 'x'), y: pixelToPercent(y, 'y') }; } const { handleChangeAtomAnnotation, isAnnotation, handleToggleMoleculeLabel, } = useMoleculeAnnotationCore(molecule.id, moleculeView); if (!viewerRef) return null; const actionsButtons: ActionsButtonsPopoverProps['buttons'] = [ { icon: , intent: 'none', title: 'Move molecule', style: { cursor: 'move' }, className: 'handle', }, { icon: , intent: 'danger', title: 'Hide molecule', onClick: floatMoleculeHandler, }, { elementType: 'separator', }, { icon: , title: `${booleanToString(!moleculeView.showLabel)} molecule label`, onClick: handleToggleMoleculeLabel, active: moleculeView.showLabel, }, { elementType: 'separator', }, { icon: , title: `${booleanToString(!isAnnotation('atom-numbers'))} atom number`, onClick: () => handleChangeAtomAnnotation('atom-numbers'), active: isAnnotation('atom-numbers'), }, { icon: , title: `${booleanToString(!isAnnotation('custom-labels'))} custom labels`, onClick: () => handleChangeAtomAnnotation('custom-labels'), active: isAnnotation('custom-labels'), }, ]; const { x: xInPercent, y: yInPercent, width, height } = bounding; const x = percentToPixel(xInPercent, 'x'); const y = percentToPixel(yInPercent, 'y'); if (isExportProcessStart) { return ( ); } return ( setIsMoveActive(true)} onResizeStop={(e, dir, eRef, { width, height }) => dragFloatMoleculeHandler({ width, height }) } onDrag={(e, { x, y }) => { handleDrag({ x, y }); }} onDragStop={(e, { x, y }) => { dragFloatMoleculeHandler(convertPositionToPercent({ x, y })); setIsMoveActive(false); }} resizeHandleWrapperStyle={{ backgroundColor: 'white' }} >
{ if ((e.target as HTMLElement).closest('form')) { return; } openMoleculeEditor(molecule); }} > {({ width, height }) => { return ; }}
{modal}
); }