From 33d55359c69ac3d3ee501790a2ffea11d6dbb84b Mon Sep 17 00:00:00 2001 From: hamed musallam Date: Mon, 4 Dec 2023 13:26:51 +0100 Subject: [PATCH] feat: print spectra feat: prepare NMRium structure for printing fix: trigger printing after the NMRium viewer is rendered and rescaled to an A4 page --- src/component/main/InnerNMRiumContents.tsx | 138 ++++++++++++--------- src/component/main/NMRiumViewer.tsx | 59 +++++++++ src/demo/Sidebar.tsx | 1 + src/demo/index.css | 14 +++ src/demo/layouts/Admin.tsx | 1 + 5 files changed, 157 insertions(+), 56 deletions(-) create mode 100644 src/component/main/NMRiumViewer.tsx diff --git a/src/component/main/InnerNMRiumContents.tsx b/src/component/main/InnerNMRiumContents.tsx index be0d5b7a3d..daac68a155 100644 --- a/src/component/main/InnerNMRiumContents.tsx +++ b/src/component/main/InnerNMRiumContents.tsx @@ -1,20 +1,17 @@ /** @jsxImportSource @emotion/react */ import { Global, css } from '@emotion/react'; -import { MouseEvent, RefObject, useCallback } from 'react'; +import { MouseEvent, RefObject, useCallback, useEffect, useState } from 'react'; import { useFullscreen } from 'react-science/ui'; import checkModifierKeyActivated from '../../data/utilities/checkModifierKeyActivated'; -import Viewer1D from '../1d/Viewer1D'; -import FloatMoleculeStructures from '../1d-2d/components/FloatMoleculeStructures'; -import Viewer2D from '../2d/Viewer2D'; import KeysListenerTracker from '../EventsTrackers/KeysListenerTracker'; -import { useChartData } from '../context/ChartContext'; import Header from '../header/Header'; import DropZone from '../loader/DropZone'; import Panels from '../panels/Panels'; import ToolBar from '../toolbar/ToolBar'; +import { NMRiumViewer } from './NMRiumViewer'; import { SplitPaneWrapper } from './SplitPaneWrapper'; import { StateError } from './StateError'; @@ -67,6 +64,12 @@ const containerStyles = css` padding: 5px; box-shadow: none; } + + @page { + size: a4 landscape; + margin: 0; + padding: 0; + } `; interface InnerNMRiumContentsProps { @@ -81,7 +84,6 @@ export function InnerNMRiumContents(props: InnerNMRiumContentsProps) { const { emptyText, mainDivRef, elementsWrapperRef, rootRef, viewerRef } = props; - const { displayerMode } = useChartData(); const { isFullScreen } = useFullscreen(); const preventContextMenuHandler = useCallback( @@ -93,6 +95,29 @@ export function InnerNMRiumContents(props: InnerNMRiumContentsProps) { [], ); + const [printFlag, setPrintFlag] = useState(false); + + useEffect(() => { + function handleAfterPrint() { + setPrintFlag(false); + } + + function handleKeyDow(event) { + if ((event.ctrlKey || event.metaKey) && event.key === 'p') { + event.preventDefault(); + setPrintFlag(true); + } + } + + window.addEventListener('keydown', handleKeyDow); + window.addEventListener('afterprint', handleAfterPrint); + + return () => { + window.removeEventListener('afterprint', handleAfterPrint); + window.removeEventListener('keydown', handleKeyDow); + }; + }, []); + return ( <> @@ -112,66 +137,67 @@ export function InnerNMRiumContents(props: InnerNMRiumContentsProps) { onContextMenu={preventContextMenuHandler} style={{ height: '100%', width: '100%' }} > - -
-
- + {!printFlag && ( +
- - -
- -
- - {displayerMode === '1D' ? ( - - ) : ( - - )} -
-
- -
+
+ > + + +
+ + + +
+ +
+ +
+
-
-
+ + )} + {printFlag && ( + { + window.print(); + }} + /> + )}
); diff --git a/src/component/main/NMRiumViewer.tsx b/src/component/main/NMRiumViewer.tsx new file mode 100644 index 0000000000..9123398c9f --- /dev/null +++ b/src/component/main/NMRiumViewer.tsx @@ -0,0 +1,59 @@ +import { CSSProperties, RefObject, useDeferredValue, useEffect } from 'react'; + +import Viewer1D from '../1d/Viewer1D'; +import FloatMoleculeStructures from '../1d-2d/components/FloatMoleculeStructures'; +import Viewer2D from '../2d/Viewer2D'; +import { useChartData } from '../context/ChartContext'; + +import { NMRiumProps } from './NMRium'; + +interface NMRiumViewerProps { + emptyText: NMRiumProps['emptyText']; + viewerRef: RefObject; + style?: CSSProperties; + onRender?: () => void; +} + +export function NMRiumViewer(props: NMRiumViewerProps) { + const { emptyText, viewerRef, onRender, style = {} } = props; + const { displayerMode, width, height } = useChartData(); + const renderDimension = useDeferredValue({ width, height }); + useEffect(() => { + if (typeof onRender !== 'function') { + return; + } + + requestAnimationFrame(() => { + setTimeout(() => { + if ( + renderDimension.width !== width || + renderDimension.height !== height + ) { + onRender(); + } + }, 0); + }); + }, [onRender, width, height, renderDimension.width, renderDimension.height]); + + return ( +
+ + {displayerMode === '1D' ? ( + + ) : ( + + )} +
+ ); +} diff --git a/src/demo/Sidebar.tsx b/src/demo/Sidebar.tsx index c8abf61e95..ca20e16d2e 100644 --- a/src/demo/Sidebar.tsx +++ b/src/demo/Sidebar.tsx @@ -102,6 +102,7 @@ function Sidebar(props) { return (
div { + width: 100% !important; + margin: 0 !important; + padding: 0 !important; + } + + .demo-side-bar, + .demo-main-container > div > div:first-child { + display: none !important; + } +} + .rc-menu { border: none !important; box-shadow: none !important; diff --git a/src/demo/layouts/Admin.tsx b/src/demo/layouts/Admin.tsx index d3bd4f7168..1d6bfb6fa4 100644 --- a/src/demo/layouts/Admin.tsx +++ b/src/demo/layouts/Admin.tsx @@ -71,6 +71,7 @@ export function Dashboard(props: DashboardProps) { onMenuToggle={toggleMenu} />