Browse Source

mol-plugin: wip measurements

David Sehnal 5 years ago
parent
commit
32a91ca98c

+ 3 - 1
src/mol-plugin/context.ts

@@ -41,6 +41,7 @@ import { StructureRepresentationHelper } from './util/structure-representation-h
 import { StructureSelectionHelper } from './util/structure-selection-helper';
 import { StructureOverpaintHelper } from './util/structure-overpaint-helper';
 import { PluginToastManager } from './state/toast';
+import { StructureMeasurementManager } from './util/structure-measurement';
 
 interface Log {
     entries: List<LogEntry>
@@ -130,7 +131,8 @@ export class PluginContext {
         structureSelection: new StructureSelectionHelper(this),
         structureRepresentation: new StructureRepresentationHelper(this),
         structureOverpaint: new StructureOverpaintHelper(this),
-        substructureParent: new SubstructureParentHelper(this)
+        substructureParent: new SubstructureParentHelper(this),
+        measurement: new StructureMeasurementManager(this)
     } as const;
 
     /**

+ 13 - 1
src/mol-plugin/ui/structure/selection.tsx

@@ -77,6 +77,11 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
         }
     }
 
+    measureDistance = () => {
+        const loci = this.plugin.helpers.structureSelectionManager.latestLoci;
+        this.plugin.helpers.measurement.addDistance(loci[0].loci, loci[1].loci);
+    }
+
     setProps = (p: { param: PD.Base<any>, name: string, value: any }) => {
         if (p.name === 'granularity') {
             PluginCommands.Interactivity.SetProps.dispatch(this.plugin, { props: { granularity: p.value } });
@@ -166,10 +171,17 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
             {this.controls}
             { latest.length > 0 &&
             <>
-                <div className='msp-control-group-header' style={{ marginTop: '1px' }}><span>Latest Selections</span></div>
+                <div className='msp-control-group-header' style={{ marginTop: '1px' }}><span>Latest Selections &amp; Measurement</span></div>
                 <ul style={{ listStyle: 'none', marginTop: '1px', marginBottom: '0' }} className='msp-state-list'>
                     {latest}
                 </ul>
+                {latest.length >= 2 &&
+                    <div className='msp-control-row msp-row-text'>
+                    <button className='msp-btn msp-btn-block' onClick={this.measureDistance} title='Measure distance between latest 2 selections'>
+                        Measure Distance
+                    </button>
+                </div>
+                }
             </>}
         </div>
     }

+ 44 - 0
src/mol-plugin/util/structure-measurement.ts

@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { StructureElement } from '../../mol-model/structure';
+import { PluginContext } from '../context';
+import { StateSelection, StateTransform } from '../../mol-state';
+import { StateTransforms } from '../state/transforms';
+import { PluginCommands } from '../command';
+
+export { StructureMeasurementManager }
+
+const MeasurementGroupTag = 'measurement-group';
+
+class StructureMeasurementManager {
+    private getGroup() {
+        const state = this.context.state.dataState;
+        const groupRef = StateSelection.findTagInSubtree(state.tree, StateTransform.RootRef, MeasurementGroupTag);
+        const builder = this.context.state.dataState.build();
+
+        if (groupRef) return builder.to(groupRef);
+        return builder.toRoot().group(StateTransforms.Misc.CreateGroup, { label: `Measurements` }, { tags: MeasurementGroupTag });
+    }
+
+    async addDistance(a: StructureElement.Loci, b: StructureElement.Loci) {
+        const cellA = this.context.helpers.substructureParent.get(a.structure);
+        const cellB = this.context.helpers.substructureParent.get(b.structure);
+
+        if (!cellA || !cellB) return;
+
+        const update = this.getGroup();
+
+        console.log({ cellA, cellB });
+
+        const state = this.context.state.dataState;
+        await PluginCommands.State.Update.dispatch(this.context, { state, tree: update, options: { doNotLogTiming: true } });
+    }
+
+    constructor(private context: PluginContext) {
+
+    }
+}