Browse Source

updated molstar and improve panel collapse/expand state

Alexander Rose 5 years ago
parent
commit
740389a324

File diff suppressed because it is too large
+ 7 - 739
package-lock.json


+ 2 - 1
package.json

@@ -50,13 +50,14 @@
         "extra-watch-webpack-plugin": "^1.0.3",
         "file-loader": "^6.0.0",
         "mini-css-extract-plugin": "^0.9.0",
-        "molstar": "^0.6.1",
+        "molstar": "^0.6.2",
         "node-fetch": "^2.6.0",
         "node-sass": "^4.13.1",
         "raw-loader": "^4.0.0",
         "react": "^16.13.1",
         "react-dom": "^16.13.1",
         "resolve-url-loader": "^3.1.1",
+        "rxjs": "^6.5.5",
         "sass-loader": "^8.0.2",
         "style-loader": "^1.1.3",
         "tslib": "^1.11.1",

+ 18 - 5
src/structure-viewer/helpers/preset.ts

@@ -17,6 +17,9 @@ import { StructureRepresentationPresetProvider } from 'molstar/lib/mol-plugin-st
 import { Structure, StructureSelection, QueryContext, StructureElement } from 'molstar/lib/mol-model/structure';
 import { compile } from 'molstar/lib/mol-script/runtime/query/compiler';
 import { InitVolumeStreaming } from 'molstar/lib/mol-plugin/behavior/dynamic/volume-streaming/transformers';
+import { StructureViewerState } from '../types';
+import { StateSelection } from 'molstar/lib/mol-state';
+import { VolumeStreaming } from 'molstar/lib/mol-plugin/behavior/dynamic/volume-streaming/behavior';
 
 type Target = {
     readonly auth_seq_id?: number
@@ -133,22 +136,32 @@ export const RcsbPreset = TrajectoryHierarchyPresetProvider({
             representation = await plugin.builders.structure.representation.applyPreset(structureProperties, ValidationReportGeometryQualityPreset);
         } else if (p.kind === 'symmetry') {
             representation = await plugin.builders.structure.representation.applyPreset<any>(structureProperties, AssemblySymmetryPreset, { symmetryIndex: p.symmetryIndex });
+
+            StructureViewerState(plugin).collapsed.next({
+                ...StructureViewerState(plugin).collapsed.value,
+                custom: false
+            })
         } else {
             representation = await plugin.builders.structure.representation.applyPreset(structureProperties, 'auto');
         }
 
-        if (p.kind === 'feature') {
-            const loci = targetToLoci(p.target, structure.obj!.data)
+        if (p.kind === 'feature' && structure.obj) {
+            const loci = targetToLoci(p.target, structure.obj.data)
             const firstResidue = StructureElement.Loci.firstResidue(loci)
             plugin.managers.structure.focus.setFromLoci(firstResidue)
         }
 
-        if (p.kind === 'density') {
-            const structureRef = plugin.managers.structure.hierarchy.selection.structures.filter(s => s.cell.obj === structure.obj)[0]
-            if (structureRef && !structureRef.volumeStreaming) {
+        if (p.kind === 'density' && structure.cell?.parent) {
+            const volumeRoot = StateSelection.findTagInSubtree(structure.cell.parent.tree, structure.cell.transform.ref, VolumeStreaming.RootTag);
+            if (!volumeRoot) {
                 const params = PD.getDefaultValues(InitVolumeStreaming.definition.params!(structure.obj!, plugin))
                 await plugin.runTask(plugin.state.data.applyAction(InitVolumeStreaming, params, structure.ref))
             }
+
+            StructureViewerState(plugin).collapsed.next({
+                ...StructureViewerState(plugin).collapsed.value,
+                volume: false
+            })
         }
 
         return {

+ 10 - 2
src/structure-viewer/index.ts

@@ -4,6 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
+import { BehaviorSubject } from 'rxjs';
 import { DefaultPluginSpec } from 'molstar/lib/mol-plugin';
 import { Plugin } from 'molstar/lib/mol-plugin-ui/plugin'
 import './index.html'
@@ -12,7 +13,7 @@ import { PluginContext } from 'molstar/lib/mol-plugin/context';
 import { PluginCommands } from 'molstar/lib/mol-plugin/commands';
 import { PluginBehaviors } from 'molstar/lib/mol-plugin/behavior';
 import { AnimateModelIndex } from 'molstar/lib/mol-plugin-state/animation/built-in';
-import { SupportedFormats, StructureViewerState, StructureViewerProps } from './types';
+import { StructureViewerState, StructureViewerProps, CollapsedState } from './types';
 import { PluginSpec } from 'molstar/lib/mol-plugin/spec';
 import { StructureFocusRepresentation } from 'molstar/lib/mol-plugin/behavior/dynamic/selection/structure-focus-representation';
 
@@ -109,6 +110,13 @@ export class StructureViewer {
         (this.plugin.customState as StructureViewerState) = {
             props: this.props,
             modelLoader: new ModelLoader(this.plugin),
+            collapsed: new BehaviorSubject<CollapsedState>({
+                selection: true,
+                measurements: true,
+                component: false,
+                volume: true,
+                custom: true,
+            }),
         }
 
         ReactDOM.render(React.createElement(Plugin, { plugin: this.plugin }), target)
@@ -130,7 +138,7 @@ export class StructureViewer {
         for (const provider of this.props.modelUrlProviders) {
             try {
                 const p = provider(pdbId)
-        await this.customState.modelLoader.load({ fileOrUrl: p.url, format: p.format }, props)
+                await this.customState.modelLoader.load({ fileOrUrl: p.url, format: p.format }, props)
                 break
             } catch (e) {
                 console.warn(`loading '${pdbId}' failed with '${e}', trying next model-loader-provider`)

+ 11 - 2
src/structure-viewer/types.ts

@@ -4,12 +4,13 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
+import { BehaviorSubject } from 'rxjs';
 import { ModelLoader } from './helpers/model';
 import { PluginContext } from 'molstar/lib/mol-plugin/context';
 
 export type ModelUrlProvider = (pdbId: string) => {
-        url: string,
-        format: SupportedFormats
+    url: string,
+    format: SupportedFormats
 }
 
 export interface StructureViewerProps {
@@ -26,9 +27,17 @@ export interface LoadParams {
     format?: SupportedFormats,
 }
 
+export type CollapsedState = {
+    selection: boolean
+    measurements: boolean
+    component: boolean
+    volume: boolean
+    custom: boolean
+}
 export interface StructureViewerState {
     props: StructureViewerProps
     modelLoader: ModelLoader
+    collapsed: BehaviorSubject<CollapsedState>
 }
 export function StructureViewerState(plugin: PluginContext) {
     return plugin.customState as StructureViewerState

+ 15 - 8
src/structure-viewer/ui/controls.tsx

@@ -9,29 +9,35 @@ import { PluginUIComponent } from 'molstar/lib/mol-plugin-ui/base';
 import { StructureViewerState } from '../types';
 import { Viewport, ViewportControls } from 'molstar/lib/mol-plugin-ui/viewport';
 import { BackgroundTaskProgress } from 'molstar/lib/mol-plugin-ui/task';
-import { LociLabels, CustomStructureControls } from 'molstar/lib/mol-plugin-ui/controls';
+import { LociLabels, CustomStructureControls, SelectionViewportControls } from 'molstar/lib/mol-plugin-ui/controls';
 import { Toasts } from 'molstar/lib/mol-plugin-ui/toast';
 import { OpenFile } from './open';
 import { Icon } from 'molstar/lib/mol-plugin-ui/controls/icons';
 import { StructureSourceControls } from 'molstar/lib/mol-plugin-ui/structure/source';
-import { StructureSelectionControls } from 'molstar/lib/mol-plugin-ui/structure/selection';
 import { StructureMeasurementsControls } from 'molstar/lib/mol-plugin-ui/structure/measurements';
 import { StructureComponentControls } from 'molstar/lib/mol-plugin-ui/structure/components';
 import { VolumeStreamingControls } from 'molstar/lib/mol-plugin-ui/structure/volume';
 
-
 export class StructureTools extends PluginUIComponent {
+    get customState() {
+        return StructureViewerState(this.plugin)
+    }
+
+    componentDidMount() {
+        this.subscribe(this.customState.collapsed, () => this.forceUpdate())
+    }
+
     render() {
+        const collapsed = this.customState.collapsed.value
         return <>
             <div className='msp-section-header'><Icon name='tools' />Structure Tools</div>
 
             <StructureSourceControls />
-            <StructureSelectionControls initiallyCollapsed />
-            <StructureMeasurementsControls initiallyCollapsed />
-            <StructureComponentControls initiallyCollapsed />
-            <VolumeStreamingControls initiallyCollapsed />
+            <StructureMeasurementsControls initiallyCollapsed={collapsed.measurements}  />
+            <StructureComponentControls initiallyCollapsed={collapsed.component}  />
+            <VolumeStreamingControls initiallyCollapsed={collapsed.volume}  />
 
-            <CustomStructureControls initiallyCollapsed />
+            <CustomStructureControls initiallyCollapsed={collapsed.custom} />
         </>;
     }
 }
@@ -54,6 +60,7 @@ export class ViewportWrapper extends PluginUIComponent {
     render() {
         return <>
             <Viewport />
+            <SelectionViewportControls />
             <ViewportControls />
             <div style={{ position: 'absolute', left: '10px', bottom: '10px' }}>
                 <BackgroundTaskProgress />

Some files were not shown because too many files changed in this diff