Skip to content

Commit

Permalink
feat: print spectra
Browse files Browse the repository at this point in the history
feat: prepare NMRium structure for printing

fix: trigger printing after the NMRium viewer is rendered and rescaled to an A4 page
  • Loading branch information
hamed-musallam committed Jul 10, 2024
1 parent d43911d commit 33d5535
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 56 deletions.
138 changes: 82 additions & 56 deletions src/component/main/InnerNMRiumContents.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -67,6 +64,12 @@ const containerStyles = css`
padding: 5px;
box-shadow: none;
}
@page {
size: a4 landscape;
margin: 0;
padding: 0;
}
`;

interface InnerNMRiumContentsProps {
Expand All @@ -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(
Expand All @@ -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 (
<>
<StateError />
Expand All @@ -112,66 +137,67 @@ export function InnerNMRiumContents(props: InnerNMRiumContentsProps) {
onContextMenu={preventContextMenuHandler}
style={{ height: '100%', width: '100%' }}
>
<DropZone>
<div
style={{
display: 'flex',
flexDirection: 'column',
backgroundColor: 'white',
width: '100%',
}}
>
<Header />

{!printFlag && (
<DropZone>
<div
style={{
display: 'flex',
flexDirection: 'row',
height: '100%',
flexDirection: 'column',
backgroundColor: 'white',
width: '100%',
}}
>
<ToolBar />
<SplitPaneWrapper>
<div css={viewerContainerStyle}>
<KeysListenerTracker mainDivRef={mainDivRef} />
<div
id="nmrium-viewer"
data-testid="viewer"
ref={viewerRef}
style={{
width: '100%',
height: '100%',
position: 'relative',
}}
>
<FloatMoleculeStructures />
{displayerMode === '1D' ? (
<Viewer1D emptyText={emptyText} />
) : (
<Viewer2D emptyText={emptyText} />
)}
</div>
</div>
<Panels />
</SplitPaneWrapper>
<Header />

<div
ref={elementsWrapperRef}
key={String(isFullScreen)}
id="main-wrapper"
style={{
position: 'absolute',
pointerEvents: 'none',
zIndex: 10,
left: 0,
right: 0,
top: 0,
bottom: 0,
display: 'flex',
flexDirection: 'row',
height: '100%',
}}
/>
>
<ToolBar />
<SplitPaneWrapper>
<div css={viewerContainerStyle}>
<KeysListenerTracker mainDivRef={mainDivRef} />

<NMRiumViewer emptyText={emptyText} viewerRef={viewerRef} />
</div>
<Panels />
</SplitPaneWrapper>

<div
ref={elementsWrapperRef}
key={String(isFullScreen)}
id="main-wrapper"
style={{
position: 'absolute',
pointerEvents: 'none',
zIndex: 10,
left: 0,
right: 0,
top: 0,
bottom: 0,
}}
/>
</div>
</div>
</div>
</DropZone>
</DropZone>
)}
{printFlag && (
<NMRiumViewer
emptyText={emptyText}
viewerRef={viewerRef}
style={{
width: '297mm',
height: '210mm',
padding: '0.5cm',
}}
onRender={() => {
window.print();
}}
/>
)}
</div>
</>
);
Expand Down
59 changes: 59 additions & 0 deletions src/component/main/NMRiumViewer.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>;
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 (
<div
id="nmrium-viewer"
data-testid="viewer"
ref={viewerRef}
style={{
width: '100%',
height: '100%',
position: 'relative',
backgroundColor: 'white',
...style,
}}
>
<FloatMoleculeStructures />
{displayerMode === '1D' ? (
<Viewer1D emptyText={emptyText} />
) : (
<Viewer2D emptyText={emptyText} />
)}
</div>
);
}
1 change: 1 addition & 0 deletions src/demo/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function Sidebar(props) {

return (
<div
className="demo-side-bar"
css={css(
sidebarCss,
props.menuIsClosed ? sidebarClosedCss : sidebarOpenCss,
Expand Down
14 changes: 14 additions & 0 deletions src/demo/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
@media print {
.demo-main-container,
.demo-main-container > 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;
Expand Down
1 change: 1 addition & 0 deletions src/demo/layouts/Admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function Dashboard(props: DashboardProps) {
onMenuToggle={toggleMenu}
/>
<div
className="demo-main-container"
css={css(
mainPanelCss,
menuIsClosed ? mainPanelClosedCss : mainPanelOpenCss,
Expand Down

0 comments on commit 33d5535

Please sign in to comment.