Browse Source

custom transform controls in basic-wrapper example

David Sehnal 5 years ago
parent
commit
5016ebf140

+ 22 - 0
src/apps/basic-wrapper/controls.tsx

@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { PluginUIComponent } from 'mol-plugin/ui/base';
+import * as React from 'react';
+import { TransformUpdaterControl } from 'mol-plugin/ui/state/update-transform';
+
+export class BasicWrapperControls extends PluginUIComponent {
+
+    render() {
+        return <div style={{ overflowY: 'auto', display: 'block', height: '100%' }}>
+            <TransformUpdaterControl nodeRef='asm' />
+            <TransformUpdaterControl nodeRef='seq-visual' header={{ name: 'Sequence Visual' }} />
+            <TransformUpdaterControl nodeRef='het-visual' header={{ name: 'HET Visual' }} />
+            <TransformUpdaterControl nodeRef='water-visual' header={{ name: 'Water Visual' }} initiallyCollapsed={true} />
+            <TransformUpdaterControl nodeRef='ihm-visual' header={{ name: 'I/HM Visual' }} initiallyCollapsed={true} />
+        </div>;
+    }
+}

+ 9 - 4
src/apps/basic-wrapper/index.ts

@@ -15,6 +15,7 @@ import { PluginStateObject as PSO } from 'mol-plugin/state/objects';
 import { AnimateModelIndex } from 'mol-plugin/state/animation/built-in';
 import { StateBuilder } from 'mol-state';
 import { StripedResidues } from './coloring';
+import { BasicWrapperControls } from './controls';
 require('mol-plugin/skin/light.scss')
 
 type SupportedFormats = 'cif' | 'pdb'
@@ -30,6 +31,10 @@ class BasicWrapper {
                 initial: {
                     isExpanded: false,
                     showControls: false
+                },
+                controls: {
+                    left: 'none',
+                    right: BasicWrapperControls
                 }
             }
         });
@@ -57,16 +62,16 @@ class BasicWrapper {
     private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
         visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' })
             .apply(StateTransforms.Representation.StructureRepresentation3D,
-                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'cartoon'));
+                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'cartoon'), { ref: 'seq-visual' });
         visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
             .apply(StateTransforms.Representation.StructureRepresentation3D,
-                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick'));
+                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick'), { ref: 'het-visual' });
         visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' })
             .apply(StateTransforms.Representation.StructureRepresentation3D,
-                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick', { alpha: 0.51 }));
+                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick', { alpha: 0.51 }), { ref: 'water-visual' });
         visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' })
             .apply(StateTransforms.Representation.StructureRepresentation3D,
-                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'spacefill'));
+                StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'spacefill'), { ref: 'ihm-visual' });
         return visualRoot;
     }
 

+ 28 - 4
src/mol-plugin/ui/state/update-transform.tsx

@@ -4,19 +4,22 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { State, StateTransform } from 'mol-state';
+import { State, StateTransform, StateTransformer } from 'mol-state';
 import { memoizeLatest } from 'mol-util/memoize';
 import { StateTransformParameters, TransformContolBase } from './common';
 import { Observable } from 'rxjs';
+import * as React from 'react';
+import { PluginUIComponent } from '../base';
 
-export { UpdateTransformContol };
+export { UpdateTransformContol, TransformUpdaterControl };
 
 namespace UpdateTransformContol {
     export interface Props {
         transform: StateTransform,
         state: State,
         toggleCollapsed?: Observable<any>,
-        initiallyCollapsed?: boolean
+        initiallyCollapsed?: boolean,
+        customHeader?: StateTransformer.Definition['display']
     }
 
     export interface ComponentState extends TransformContolBase.ComponentState {
@@ -28,7 +31,7 @@ class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Pr
     applyAction() { return this.plugin.updateTransform(this.props.state, this.props.transform.ref, this.state.params); }
     getInfo() { return this._getInfo(this.props.transform); }
     getTransformerId() { return this.props.transform.transformer.id; }
-    getHeader() { return this.props.transform.transformer.definition.display; }
+    getHeader() { return this.props.customHeader || this.props.transform.transformer.definition.display; }
     canApply() { return !this.state.error && !this.state.busy && !this.state.isInitial; }
     applyText() { return this.canApply() ? 'Update' : 'Nothing to Update'; }
     isUpdate() { return true; }
@@ -74,4 +77,25 @@ class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Pr
         };
         return newState;
     }
+}
+
+class TransformUpdaterControl extends PluginUIComponent<{ nodeRef: string, initiallyCollapsed?: boolean, header?: StateTransformer.Definition['display'] }> {
+    componentDidMount() {
+        this.subscribe(this.plugin.events.state.object.updated, ({ ref, state }) => {
+            if (this.props.nodeRef !== ref || this.plugin.state.dataState !== state) return;
+            this.forceUpdate();
+        });
+    }
+
+    render() {
+        const state = this.plugin.state.dataState;
+        const ref = this.props.nodeRef;
+        const cell = state.cells.get(ref)!;
+
+        if (!cell || (cell.status !== 'ok' && cell.status !== 'error')) return null;
+
+        const transform = cell.transform;
+
+        return <UpdateTransformContol state={state} transform={transform} initiallyCollapsed={this.props.initiallyCollapsed} customHeader={this.props.header} />;
+    }
 }