Browse Source

mol-plugin-ui: added ViewportCanvas component

David Sehnal 4 years ago
parent
commit
6b73361963
2 changed files with 106 additions and 78 deletions
  1. 3 78
      src/mol-plugin-ui/viewport.tsx
  2. 103 0
      src/mol-plugin-ui/viewport/canvas.tsx

+ 3 - 78
src/mol-plugin-ui/viewport.tsx

@@ -6,18 +6,16 @@
  */
 
 import * as React from 'react';
-import { Subject } from 'rxjs';
-import { debounceTime } from 'rxjs/operators';
-import { resizeCanvas } from '../mol-canvas3d/util';
 import { PluginCommands } from '../mol-plugin/commands';
 import { PluginConfig } from '../mol-plugin/config';
 import { ParamDefinition as PD } from '../mol-util/param-definition';
 import { PluginUIComponent } from './base';
 import { ControlGroup, IconButton } from './controls/common';
+import { AutorenewSvg, BuildOutlinedSvg, CameraOutlinedSvg, CloseSvg, FullscreenSvg, TuneSvg } from './controls/icons';
 import { ToggleSelectionModeButton } from './structure/selection';
+import { ViewportCanvas } from './viewport/canvas';
 import { DownloadScreenshotControls } from './viewport/screenshot';
 import { SimpleSettingsControl } from './viewport/simple-settings';
-import { AutorenewSvg, CameraOutlinedSvg, BuildOutlinedSvg, FullscreenSvg, TuneSvg, CloseSvg } from './controls/icons';
 
 interface ViewportControlsState {
     isSettingsExpanded: boolean,
@@ -124,77 +122,4 @@ export class ViewportControls extends PluginUIComponent<ViewportControlsProps, V
 export const Logo = () =>
     <a className='msp-logo' href='https://molstar.org' target='_blank' />;
 
-interface ViewportState {
-    noWebGl: boolean
-    showLogo: boolean
-}
-
-export class Viewport extends PluginUIComponent<{ }, ViewportState> {
-    private container = React.createRef<HTMLDivElement>();
-    private canvas = React.createRef<HTMLCanvasElement>();
-
-    state: ViewportState = {
-        noWebGl: false,
-        showLogo: true
-    };
-
-    private handleLogo = () => {
-        this.setState({ showLogo: !this.plugin.canvas3d?.reprCount.value });
-    }
-
-    private handleResize = () => {
-        const container = this.container.current;
-        const canvas = this.canvas.current;
-        if (container && canvas) {
-            resizeCanvas(canvas, container);
-            this.plugin.canvas3d!.handleResize();
-        }
-    }
-
-    componentDidMount() {
-        if (!this.canvas.current || !this.container.current || !this.plugin.initViewer(this.canvas.current!, this.container.current!)) {
-            this.setState({ noWebGl: true });
-            return;
-        }
-        this.handleLogo();
-        this.handleResize();
-
-        const canvas3d = this.plugin.canvas3d!;
-        this.subscribe(canvas3d.reprCount, this.handleLogo);
-
-        const resized = new Subject();
-        const resize = () => resized.next();
-
-        this.subscribe(resized.pipe(debounceTime(1000 / 24)), () => this.handleResize());
-        this.subscribe(canvas3d.input.resize, resize);
-        this.subscribe(canvas3d.interaction.click, e => this.plugin.behaviors.interaction.click.next(e));
-        this.subscribe(canvas3d.interaction.hover, e => this.plugin.behaviors.interaction.hover.next(e));
-        this.subscribe(this.plugin.layout.events.updated, resize);
-    }
-
-    componentWillUnmount() {
-        super.componentWillUnmount();
-        // TODO viewer cleanup
-    }
-
-    renderMissing() {
-        return <div className='msp-no-webgl'>
-            <div>
-                <p><b>WebGL does not seem to be available.</b></p>
-                <p>This can be caused by an outdated browser, graphics card driver issue, or bad weather. Sometimes, just restarting the browser helps.</p>
-                <p>For a list of supported browsers, refer to <a href='http://caniuse.com/#feat=webgl' target='_blank'>http://caniuse.com/#feat=webgl</a>.</p>
-            </div>
-        </div>;
-    }
-
-    render() {
-        if (this.state.noWebGl) return this.renderMissing();
-
-        return <div className='msp-viewport'>
-            <div className='msp-viewport-host3d' ref={this.container}>
-                <canvas ref={this.canvas} />
-            </div>
-            {this.state.showLogo && <Logo />}
-        </div>;
-    }
-}
+export const Viewport = () => <ViewportCanvas logo={Logo} />;

+ 103 - 0
src/mol-plugin-ui/viewport/canvas.tsx

@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import * as React from 'react';
+import { PluginUIComponent } from '../base';
+import { resizeCanvas } from '../../mol-canvas3d/util';
+import { Subject } from 'rxjs';
+import { debounceTime } from 'rxjs/internal/operators/debounceTime';
+
+interface ViewportCanvasState {
+    noWebGl: boolean
+    showLogo: boolean
+}
+
+export interface ViewportCanvasParams {
+    logo?: React.FC,
+    noWebGl?: React.FC,
+
+    parentClassName?: string,
+    parentStyle?: React.CSSProperties,
+    hostClassName?: string,
+    hostStyle?: React.CSSProperties
+}
+
+export class ViewportCanvas extends PluginUIComponent<ViewportCanvasParams, ViewportCanvasState> {
+    private container = React.createRef<HTMLDivElement>();
+    private canvas = React.createRef<HTMLCanvasElement>();
+
+    state: ViewportCanvasState = {
+        noWebGl: false,
+        showLogo: true
+    };
+
+    private handleLogo = () => {
+        this.setState({ showLogo: !this.plugin.canvas3d?.reprCount.value });
+    }
+
+    private handleResize = () => {
+        const container = this.container.current;
+        const canvas = this.canvas.current;
+        if (container && canvas) {
+            resizeCanvas(canvas, container);
+            this.plugin.canvas3d!.handleResize();
+        }
+    }
+
+    componentDidMount() {
+        if (!this.canvas.current || !this.container.current || !this.plugin.initViewer(this.canvas.current!, this.container.current!)) {
+            this.setState({ noWebGl: true });
+            return;
+        }
+        this.handleLogo();
+        this.handleResize();
+
+        const canvas3d = this.plugin.canvas3d!;
+        this.subscribe(canvas3d.reprCount, this.handleLogo);
+
+        const resized = new Subject();
+        const resize = () => resized.next();
+
+        this.subscribe(resized.pipe(debounceTime(1000 / 24)), () => this.handleResize());
+        this.subscribe(canvas3d.input.resize, resize);
+        this.subscribe(canvas3d.interaction.click, e => this.plugin.behaviors.interaction.click.next(e));
+        this.subscribe(canvas3d.interaction.hover, e => this.plugin.behaviors.interaction.hover.next(e));
+        this.subscribe(this.plugin.layout.events.updated, resize);
+    }
+
+    componentWillUnmount() {
+        super.componentWillUnmount();
+        // TODO viewer cleanup
+    }
+
+    renderMissing() {
+        if (this.props.noWebGl) {
+            const C = this.props.noWebGl;
+            return <C />;
+        }
+
+        return <div className='msp-no-webgl'>
+            <div>
+                <p><b>WebGL does not seem to be available.</b></p>
+                <p>This can be caused by an outdated browser, graphics card driver issue, or bad weather. Sometimes, just restarting the browser helps.</p>
+                <p>For a list of supported browsers, refer to <a href='http://caniuse.com/#feat=webgl' target='_blank'>http://caniuse.com/#feat=webgl</a>.</p>
+            </div>
+        </div>;
+    }
+
+    render() {
+        if (this.state.noWebGl) return this.renderMissing();
+
+        const Logo = this.props.logo;
+
+        return <div className={this.props.parentClassName || 'msp-viewport'} style={this.props.parentStyle}>
+            <div className={this.props.hostClassName || 'msp-viewport-host3d'} style={this.props.hostStyle} ref={this.container}>
+                <canvas ref={this.canvas} />
+            </div>
+            {(this.state.showLogo && Logo) && <Logo />}
+        </div>;
+    }
+}