Browse Source

mol-plugin: basic layout state support

David Sehnal 6 years ago
parent
commit
b0fa414595

+ 8 - 1
src/apps/viewer/index.html

@@ -25,11 +25,18 @@
             button {
                 padding: 2px;
             }
+            #app {
+                position: absolute;
+                left: 100px;
+                top: 100px;
+                width: 800px;
+                height: 600px;
+            }
         </style>
         <link rel="stylesheet" type="text/css" href="app.css" />
     </head>
     <body>
-        <div id="app" style="position: absolute; width: 100%; height: 100%"></div>
+        <div id="app"></div>
         <script type="text/javascript" src="./index.js"></script>
     </body>
 </html>

+ 8 - 2
src/apps/viewer/index.ts

@@ -4,8 +4,14 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { createPlugin } from 'mol-plugin';
+import { createPlugin, DefaultPluginSpec } from 'mol-plugin';
 import './index.html'
 require('mol-plugin/skin/light.scss')
 
-createPlugin(document.getElementById('app')!);
+createPlugin(document.getElementById('app')!, {
+    ...DefaultPluginSpec,
+    initialLayout: {
+        isExpanded: true,
+        showControls: true
+    }
+});

+ 3 - 3
src/mol-plugin/index.ts

@@ -20,7 +20,7 @@ function getParam(name: string, regex: string): string {
     return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
 }
 
-const DefaultSpec: PluginSpec = {
+export const DefaultPluginSpec: PluginSpec = {
     actions: [
         PluginSpec.Action(DownloadStructure),
         PluginSpec.Action(OpenStructure),
@@ -49,8 +49,8 @@ const DefaultSpec: PluginSpec = {
     ]
 }
 
-export function createPlugin(target: HTMLElement): PluginContext {
-    const ctx = new PluginContext(DefaultSpec);
+export function createPlugin(target: HTMLElement, spec?: PluginSpec): PluginContext {
+    const ctx = new PluginContext(spec || DefaultPluginSpec);
     ReactDOM.render(React.createElement(Plugin, { plugin: ctx }), target);
 
     trySetSnapshot(ctx);

+ 4 - 2
src/mol-plugin/layout.ts

@@ -9,6 +9,7 @@ import { PluginComponent } from './component';
 import { PluginContext } from './context';
 import { PluginCommands } from './command';
 
+// TODO: support collapsed state control orientation
 export const PluginLayoutStateParams = {
     isExpanded: PD.Boolean(false),
     showControls: PD.Boolean(true)
@@ -120,7 +121,8 @@ export class PluginLayout extends PluginComponent<PluginLayoutStateProps> {
                 s.marginTop = '0';
                 s.marginBottom = '0';
 
-                this.root.style.zIndex = '2147483647';
+                // TODO: setting this breaks viewport controls for some reason. Is there a fix?
+                // this.root.style.zIndex = '100000';
             } else {
                 let children = head.children;
                 for (let i = 0; i < children.length; i++) {
@@ -166,7 +168,7 @@ export class PluginLayout extends PluginComponent<PluginLayoutStateProps> {
     }
 
     constructor(context: PluginContext) {
-        super(context, PD.getDefaultValues(PluginLayoutStateParams));
+        super(context, { ...PD.getDefaultValues(PluginLayoutStateParams), ...context.spec.initialLayout });
 
         PluginCommands.Layout.Update.subscribe(context, e => this.updateProps(e.state));
 

+ 6 - 7
src/mol-plugin/ui/plugin.tsx

@@ -52,20 +52,19 @@ class Layout extends PluginComponent {
     }
 
     render() {
-        const showControls = this.plugin.layout.latestState.showControls;
-
+        const layout = this.plugin.layout.latestState;
         return <div className='msp-plugin'>
-            <div className='msp-plugin-content msp-layout-expanded'>
-                <div className={showControls ? 'msp-layout-hide-top' : 'msp-layout-hide-top msp-layout-hide-right msp-layout-hide-bottom msp-layout-hide-left'}>
+            <div className={`msp-plugin-content ${layout.isExpanded ? 'msp-layout-expanded' : 'msp-layout-standard msp-layout-standard-outside'}`}>
+                <div className={layout.showControls ? 'msp-layout-hide-top' : 'msp-layout-hide-top msp-layout-hide-right msp-layout-hide-bottom msp-layout-hide-left'}>
                     {this.region('main', <ViewportWrapper />)}
-                    {showControls && this.region('left', <State />)}
-                    {showControls && this.region('right', <div className='msp-scrollable-container msp-right-controls'>
+                    {layout.showControls && this.region('left', <State />)}
+                    {layout.showControls && this.region('right', <div className='msp-scrollable-container msp-right-controls'>
                         <CurrentObject />
                         <Controls />
                         <CameraSnapshots />
                         <StateSnapshots />
                     </div>)}
-                    {showControls && this.region('bottom', <Log />)}
+                    {layout.showControls && this.region('bottom', <Log />)}
                 </div>
             </div>
         </div>;

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

@@ -38,6 +38,10 @@ export class ViewportControls extends PluginComponent {
         PluginCommands.Layout.Update.dispatch(this.plugin, { state: { showControls: !this.plugin.layout.latestState.showControls } });
     }
 
+    toggleExpanded = () => {
+        PluginCommands.Layout.Update.dispatch(this.plugin, { state: { isExpanded: !this.plugin.layout.latestState.isExpanded } });
+    }
+
     setSettings = (p: { param: PD.Base<any>, name: string, value: any }) => {
         PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: { [p.name]: p.value } });
     }
@@ -56,13 +60,23 @@ export class ViewportControls extends PluginComponent {
         });
     }
 
+    icon(name: string, onClick: (e: React.MouseEvent<HTMLButtonElement>) => void, title: string, isOn = true) {
+        return <button
+            className={`msp-btn msp-btn-link msp-btn-link-toggle-${isOn ? 'on' : 'off'}`}
+            onClick={onClick}
+            title={title}>
+                <span className={`msp-icon msp-icon-${name}`}/>
+            </button>
+    }
+
     render() {
         // TODO: show some icons dimmed etc..
         return <div className={'msp-viewport-controls'}>
             <div className='msp-viewport-controls-buttons'>
-                <button className='msp-btn msp-btn-link' onClick={this.toggleControls} title='Show/Hide Controls'><span className='msp-icon msp-icon-tools'/></button>
-                <button className='msp-btn msp-btn-link' onClick={this.toggleSettingsExpanded}><span className='msp-icon msp-icon-settings'/></button>
-                <button className='msp-btn msp-btn-link' title='Reset Camera' onClick={this.resetCamera}><span className='msp-icon msp-icon-reset-scene'/></button>
+                {this.icon('tools', this.toggleControls, 'Toggle Controls', this.plugin.layout.latestState.showControls)}
+                {this.icon('expand-layout', this.toggleExpanded, 'Toggle Expanded', this.plugin.layout.latestState.isExpanded)}
+                {this.icon('settings', this.toggleSettingsExpanded, 'Settings', this.state.isSettingsExpanded)}
+                {this.icon('reset-scene', this.resetCamera, 'Reset Camera')}
             </div>
             {this.state.isSettingsExpanded &&
             <div className='msp-viewport-controls-scene-options'>