Skip to content

Commit

Permalink
fixing bug with fullscreen in structure page
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavo-salazar committed Oct 20, 2020
1 parent 646598a commit e1725ec
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 165 deletions.
47 changes: 28 additions & 19 deletions src/components/SimpleCommonComponents/FullScreenButton/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,49 @@
import React, { useState, useEffect } from 'react';
import T from 'prop-types';

import Tooltip from 'components/SimpleCommonComponents/Tooltip';
import { noop } from 'lodash-es';

import fonts from 'EBI-Icon-fonts/fonts.css';
import Tooltip from 'components/SimpleCommonComponents/Tooltip';

import { foundationPartial } from 'styles/foundation';
import { requestFullScreen, exitFullScreen } from 'utils/fullscreen';

import fonts from 'EBI-Icon-fonts/fonts.css';

const f = foundationPartial(fonts);

const FullScreenButton = (
{
handleFullScreen,
element,
tooltip,
className,
dataIcon,
} /*: {handleFullScreen?: function, element?: any, tooltip: string, className?: string, dataIcon?: string} */,
onFullScreenHook = noop,
onExitFullScreenHook = noop,
} /*: {onFullScreenHook?: function,onExitFullScreenHook?: function, element?: any, tooltip: string, className?: string, dataIcon?: string} */,
) => {
const [isFull, setFull] = useState(false);
const handleFullscreen = () => setFull(!!document.fullscreenElement);
const onFullscreen = () => {
if (document.fullscreenElement === null) {
setFull(false);
onExitFullScreenHook();
}
};
useEffect(() => {
document.addEventListener('fullscreenchange', handleFullscreen);
return () =>
document.removeEventListener('fullscreenchange', handleFullscreen);
document.addEventListener('fullscreenchange', onFullscreen);
return () => document.removeEventListener('fullscreenchange', onFullscreen);
}, []);
if (!handleFullScreen && !element) return null;
const _handleFullScreen =
handleFullScreen ||
(() => {
if (isFull) {
exitFullScreen();
} else {
requestFullScreen(element);
}
setFull(!isFull);
});
if (!element) return null;
const _handleFullScreen = () => {
if (isFull) {
exitFullScreen();
onExitFullScreenHook();
} else {
requestFullScreen(element);
onFullScreenHook();
}
setFull(!isFull);
};
const _className =
className || f('margin-bottom-none', 'icon', 'icon-common');
const icon = dataIcon || (isFull ? 'G' : 'F');
Expand All @@ -55,6 +62,8 @@ const FullScreenButton = (

FullScreenButton.propTypes = {
handleFullScreen: T.func,
onFullScreenHook: T.func,
onExitFullScreenHook: T.func,
element: T.any,
tooltip: T.string,
className: T.string,
Expand Down
180 changes: 34 additions & 146 deletions src/components/Structure/Viewer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ import fonts from 'EBI-Icon-fonts/fonts.css';

import { foundationPartial } from 'styles/foundation';

import {
requestFullScreen,
exitFullScreen,
onFullScreenChange,
} from '../../../utils/fullscreen';

import style from './style.css';

const f = foundationPartial(style, fonts);
Expand Down Expand Up @@ -63,10 +57,7 @@ const optionsForObserver = {
(n) => (n + 1) / NUMBER_OF_CHECKS,
),
};
const SPLIT_REQUESTER = 1;
const FULL_REQUESTER = 2;

let fullScreenRequester = null;
class StructureView extends PureComponent /*:: <Props, State> */ {
/*:: _structureViewer: { current: ?HTMLElement }; */
/*:: stage: Object; */
Expand All @@ -76,8 +67,6 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
/*:: _structureSection: Object; */
/*:: _protvista: Object; */
/*:: _splitView: Object; */
/*:: _viewerControls: Object; */
/*:: _poppableViewer: Object; */
/*:: splitViewStyle: Object; */
/*:: observer: IntersectionObserver; */
/*:: handlingSequenceHighlight: bool; */
Expand Down Expand Up @@ -113,34 +102,11 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
this._structureSection = React.createRef();
this._protvista = React.createRef();
this._splitView = React.createRef();
this._viewerControls = React.createRef();
this._poppableViewer = React.createRef();
this.splitViewStyle = {};
}
async componentDidMount() {
await intersectionObserverPolyfill();

const element = this._splitView.current;
onFullScreenChange(element, () => {
const {
isSplitScreen: prevSplit,
isStructureFullScreen: prevFull,
} = this.state;
const willBeFull = !(prevSplit || prevFull);
if (willBeFull) {
if (fullScreenRequester === SPLIT_REQUESTER) {
this.setState({ isSplitScreen: true });
}
if (fullScreenRequester === FULL_REQUESTER) {
this.setState({ isStructureFullScreen: true });
}
} else {
this.setState({ isSplitScreen: false, isStructureFullScreen: false });
}
fullScreenRequester = null;
this._toggleSplit(willBeFull && !prevSplit, element);
});

const pdbid = this.props.id;
this.stage = new Stage(this._structurevViewer.current);
this.stage.setParameters({ backgroundColor: 0xfcfcfc });
Expand All @@ -158,31 +124,6 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
}
});

// TODO connect onclick to protvista
this.stage.signals.clicked.add((picked) => {
if (picked) {
// const residue = picked.atom;
// const index = residue.residueIndex;
// const name = residue.resname;
// const chain = residue.chainid;
// console.log(`clicked: ${index} ${name} ${chain}`, picked);
} else {
// console.log(`clicked: nothing`);
}
});

// TODO connect hover to protvista
this.stage.signals.hovered.add((picked) => {
if (picked) {
// const residue = picked.atom;
// const index = residue.residueIndex;
// const name = residue.resname;
// console.log(`mouseover: ${index} ${name}`);
} else {
// console.log('mouseover: nothing');
}
});

const threshold = 0.4;
this.observer = new IntersectionObserver((entries) => {
this.setState({
Expand Down Expand Up @@ -292,69 +233,6 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
this.observer.disconnect();
}

_toggleSplit = (isSplit, element) => {
const protvistaElement = this._protvista.current;
const structureContainer = this._structureSection.current;
const structureViewer = this._structurevViewer.current;
const structureControls = this._viewerControls.current;
// const isSplitScreen = !this.state.isSplitScreen;
if (isSplit) {
this.splitViewStyle.display = element.style.display;
this.splitViewStyle.backgroundColor = element.style.backgroundColor;
this.splitViewStyle.protvistaOverflow = protvistaElement.style.overflow;
this.splitViewStyle.protvistaWidth = protvistaElement.style.width;
this.splitViewStyle.viewControlsHeight = structureControls.style.height;
this.splitViewStyle.viewElementHeight = structureViewer.style.height;
this.splitViewStyle.viewContainerWidth = structureContainer.style.width;
this.splitViewStyle.viewContainerHeight = structureContainer.style.height;

element.style.display = 'flex';
element.style.backgroundColor = '#FFFFFF';
protvistaElement.style.overflow = 'scroll';
protvistaElement.style.width = '50vw';
structureControls.style.height = '5vh';
structureViewer.style.height = '95vh';
structureContainer.style.width = '50vw';
structureContainer.style.height = 'initial';
} else {
element.style.display = this.splitViewStyle.display;
element.style.backgroundColor = this.splitViewStyle.backgroundColor;
protvistaElement.style.overflow = this.splitViewStyle.protvistaOverflow;
structureControls.style.height = this.splitViewStyle.viewControlsHeight;
structureViewer.style.height = this.splitViewStyle.viewElementHeight;
structureContainer.style.width = this.splitViewStyle.viewContainerWidth;
structureContainer.style.height = this.splitViewStyle.viewContainerHeight;
protvistaElement.style.width = this.splitViewStyle.protvistaWidth;
}
};

_toggleStructureFullScreen = () => {
const section = this._structureSection.current;
section.scrollIntoView(false);
fullScreenRequester = FULL_REQUESTER;
if (this.stage) {
this.stage.toggleFullscreen();
this.stage.handleResize();
}
// const isStructureFullScreen = !this.state.isStructureFullScreen;
};

_toggleSplitView = () => {
if (this.stage) {
const element = this._splitView.current;
const isSplitScreen = this.state.isSplitScreen;
fullScreenRequester = SPLIT_REQUESTER;
if (isSplitScreen) {
exitFullScreen(element);
} else {
const section = this._structureSection.current;
section.scrollIntoView(false);
requestFullScreen(element);
}
this.stage.handleResize();
}
};

_toggleStructureSpin = () => {
if (this.stage) {
const isSpinning = !this.state.isSpinning;
Expand Down Expand Up @@ -620,17 +498,20 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
isSpinning,
isSplitScreen,
isMinimized,
isStructureFullScreen,
} = this.state;
return (
<>
<div ref={this._splitView}>
<div
ref={this._splitView}
className={f({ 'split-view': isSplitScreen })}
>
<div ref={this._structureSection} className={f('structure-wrapper')}>
<div
className={f('structure-viewer', {
'is-stuck': isStuck,
'is-minimized': isMinimized,
})}
ref={this._poppableViewer}
data-testid="structure-3d-viewer"
>
<ResizeObserverComponent
Expand All @@ -650,18 +531,19 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
);
}}
</ResizeObserverComponent>
<div className={f('viewer-control-bar')}>
<div
className={f('viewer-control-bar', {
hide: isStructureFullScreen,
})}
>
{this.props.matches ? (
<EntrySelection
entryMap={entryMap}
updateStructure={this.showEntryInStructure}
selectedEntry={selectedEntry}
/>
) : null}
<div
ref={this._viewerControls}
className={f('viewer-controls')}
>
<div className={f('viewer-controls')}>
<button
className={f('structure-icon', 'icon', 'icon-common')}
onClick={this._toggleStructureSpin}
Expand All @@ -675,34 +557,40 @@ class StructureView extends PureComponent /*:: <Props, State> */ {
title="Reset image"
/>
<FullScreenButton
handleFullScreen={this._toggleSplitView}
element={this._splitView.current}
className={f('structure-icon', 'icon', 'icon-common')}
tooltip={
isSplitScreen ? 'Exit full screen' : 'Split full screen'
}
dataIcon={isSplitScreen ? 'G' : '\uF0DB'}
onFullScreenHook={() =>
this.setState({ isSplitScreen: true })
}
onExitFullScreenHook={() =>
this.setState({ isSplitScreen: false })
}
/>

{isSplitScreen ? null : (
<FullScreenButton
className={f('structure-icon', 'icon', 'icon-common')}
handleFullScreen={this._toggleStructureFullScreen}
tooltip="View the structure in full screen mode"
/>
)}
{isStuck && (
<button
data-icon={isMinimized ? '\uF2D0' : '\uF2D1'}
title={'Minimize'}
onClick={this._toggleMinimize}
className={f('structure-icon', 'icon', 'icon-common')}
/>
)}
<FullScreenButton
className={f('structure-icon', 'icon', 'icon-common')}
tooltip="View the structure in full screen mode"
element={this._structureSection.current}
onFullScreenHook={() =>
this.setState({ isStructureFullScreen: true })
}
onExitFullScreenHook={() =>
this.setState({ isStructureFullScreen: false })
}
/>
</div>
</div>
</div>
</div>
<div ref={this._protvista} data-testid="structure-protvista">
<div
ref={this._protvista}
data-testid="structure-protvista"
className={f('protvista-container')}
>
<ProtVistaForStructure />
</div>
</div>
Expand Down
19 changes: 19 additions & 0 deletions src/components/Structure/Viewer/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,22 @@
}
}
}

.split-view {
display: flex;
background-color: #ffffff;
& .protvista-container {
overflow: scroll;
width: 50vw;
}
& .structure-wrapper {
width: 50vw;
height: initial;
& .structure-viewer-ref {
height: 95vh;
}
& .viewer-controls {
height: 5vh;
}
}
}

0 comments on commit e1725ec

Please sign in to comment.