Alexander Rose 5 лет назад
Родитель
Сommit
94cd2b618c

+ 2 - 2
src/mol-plugin-state/manager/structure/measurement.ts

@@ -60,7 +60,7 @@ class StructureMeasurementManager extends PluginComponent<StructureMeasurementMa
 
         const update = this.plugin.state.data.build();
         for (const cell of this.state.distances) {
-            update.to(cell).update((old: any) => { 
+            update.to(cell).update((old: any) => {
                 old.unitLabel = options.distanceUnitLabel;
                 old.textColor = options.textColor;
             });
@@ -74,7 +74,7 @@ class StructureMeasurementManager extends PluginComponent<StructureMeasurementMa
         for (const cell of this.state.dihedrals) {
             update.to(cell).update((old: any) => { old.textColor = options.textColor; });
         }
-        
+
         if (update.editInfo.count === 0) return;
 
         await PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree: update, options: { doNotLogTiming: true } });

+ 2 - 2
src/mol-plugin-ui/structure/measurements.tsx

@@ -276,7 +276,7 @@ class MeasurementEntry extends PurePluginUIComponent<{ cell: StructureMeasuremen
         this.props.cell.sourceRef
         return [ActionMenu.Item('Select This', 'flash', () => this.plugin.managers.structure.selection.fromSelections(this.props.cell.sourceRef!))];
     }
-    
+
     selectAction: ActionMenu.OnSelect = item => {
         if (!item) return;
         this.setState({ showUpdate: false });
@@ -295,7 +295,7 @@ class MeasurementEntry extends PurePluginUIComponent<{ cell: StructureMeasuremen
                 </button>
                 <IconButton small={true} customClass='msp-form-control' onClick={this.toggleVisibility} icon='eye' style={{ flex: '0 0 32px' }} title={cell.state.isHidden ? 'Show' : 'Hide'} toggleState={!cell.state.isHidden} />
                 <IconButton small={true} customClass='msp-form-control' onClick={this.delete} icon='remove' style={{ flex: '0 0 32px' }} title='Delete' />
-                <IconButton small={true} customClass='msp-form-control' onClick={this.toggleUpdate} icon='dot-3' style={{ flex: '0 0 32px' }} title={cell.state.isHidden ? 'Show' : 'Hide'} toggleState={this.state.showUpdate} />
+                <IconButton small={true} customClass='msp-form-control' onClick={this.toggleUpdate} icon='dot-3' style={{ flex: '0 0 32px' }} title='Actions' toggleState={this.state.showUpdate} />
             </div>
             {this.state.showUpdate && <>
                 <ActionMenu items={this.actions} onSelect={this.selectAction} />

+ 88 - 5
src/mol-plugin-ui/structure/objects.tsx

@@ -5,12 +5,15 @@
  */
 
 import * as React from 'react';
-import { CollapsableControls, CollapsableState } from '../base';
-import { StateTransformer, StateTransform } from '../../mol-state';
-import { ModelRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
+import { CollapsableControls, CollapsableState, PurePluginUIComponent } from '../base';
+import { StateTransformer, StateTransform, StateObjectCell } from '../../mol-state';
+import { ModelRef, GenericRepresentationRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
 import { StateTransforms } from '../../mol-plugin-state/transforms';
 import { StructureBuilderTags } from '../../mol-plugin-state/builder/structure';
 import { IconButton } from '../controls/common';
+import { UpdateTransformControl } from '../state/update-transform';
+import { PluginStateObject } from '../../mol-plugin-state/objects';
+import { PluginCommands } from '../../mol-plugin/commands';
 
 interface ObjectControlState extends CollapsableState {
     isBusy: boolean,
@@ -98,9 +101,10 @@ export class ObjectControls extends CollapsableControls<{}, ObjectControlState>
         this.setState({ showOptions: !this.state.showOptions })
     }
 
-    renderControls() {
+    renderUnitcell(unitcell: GenericRepresentationRef) {
         const label = 'Unitcell'
-        const isVisible = this.isVisible()
+        const isVisible = unitcell.cell.state.isHidden
+
         return <>
             <div className='msp-control-row'>
                 <button className='msp-control-button-label' title={`${label}. Click to focus.`} onClick={this.focus} onMouseEnter={this.highlight} onMouseLeave={this.clearHighlight} style={{ textAlign: 'left' }}>
@@ -111,6 +115,23 @@ export class ObjectControls extends CollapsableControls<{}, ObjectControlState>
                     <IconButton onClick={this.toggleOptions} icon='cog' title='Options' toggleState={this.state.showOptions} disabled={this.state.isBusy} style={{ flex: '0 0 40px' }} />
                 </div>
             </div>
+            {this.state.showOptions && unitcell && <>
+                <div className='msp-control-offset'>
+                    <UpdateTransformControl state={unitcell.cell.parent} transform={unitcell.cell.transform} customHeader='none' />
+                </div>
+            </>}
+        </>;
+    }
+
+    renderControls() {
+        const objects: JSX.Element[] = [];
+        for (const model of this.plugin.managers.structure.hierarchy.current.models) {
+            const cell = this.getUnitcell(model)?.cell
+            if (cell && cell.obj) objects.push(<UnitcellEntry key={cell.obj.id} cell={cell} />)
+        }
+
+        return <>
+            <>{objects}</>
             <div className='msp-control-group-header msp-flex-row' style={{ marginTop: '1px' }}>
                 <button className='msp-btn msp-form-control msp-flex-item msp-no-overflow' onClick={this.ensureUnitcell}>
                     Unitcell
@@ -118,4 +139,66 @@ export class ObjectControls extends CollapsableControls<{}, ObjectControlState>
             </div>
         </>;
     }
+}
+
+export type UnitcellCell = StateObjectCell<PluginStateObject.Shape.Representation3D, StateTransform<StateTransformer<PluginStateObject.Molecule.Structure.Selections, PluginStateObject.Shape.Representation3D, any>>>
+
+export class UnitcellEntry extends PurePluginUIComponent<{ cell: UnitcellCell }, { showOptions: boolean }> {
+    state = { showOptions: false }
+
+    componentDidMount() {
+        this.subscribe(this.plugin.events.state.cell.stateUpdated, e => {
+            this.forceUpdate();
+        });
+    }
+
+
+    toggleVisibility = (e: React.MouseEvent<HTMLElement>) => {
+        e.preventDefault();
+        PluginCommands.State.ToggleVisibility(this.plugin, { state: this.props.cell.parent, ref: this.props.cell.transform.ref });
+        e.currentTarget.blur();
+    }
+
+    highlight = (e: React.MouseEvent<HTMLElement>) => {
+        e.preventDefault();
+        // TODO
+        // PluginCommands.Interactivity.Object.Highlight(this.plugin, { state: this.props.group[0].cell.parent, ref: this.props.group.map(c => c.cell.transform.ref) });
+    }
+
+    clearHighlight = (e: React.MouseEvent<HTMLElement>) => {
+        e.preventDefault();
+        // TODO
+        // PluginCommands.Interactivity.ClearHighlights(this.plugin);
+    }
+
+    focus = () => {
+        // TODO
+        // const sphere = this.pivot.cell.obj?.data.boundary.sphere;
+        // if (sphere) this.plugin.managers.camera.focusSphere(sphere);
+    }
+
+    toggleOptions = () => this.setState({ showOptions: !this.state.showOptions })
+
+    render() {
+        const { cell } = this.props;
+        const { obj } = cell;
+        if (!obj) return null;
+
+        return <>
+            <div className='msp-control-row'>
+                <button className='msp-control-button-label' title={`Unitcell. Click to focus.`} onClick={this.focus} onMouseEnter={this.highlight} onMouseLeave={this.clearHighlight} style={{ textAlign: 'left' }}>
+                    Unitcell
+                </button>
+                <div className='msp-select-row'>
+                    <IconButton onClick={this.toggleVisibility} icon='visual-visibility' toggleState={!cell.state.isHidden} title={`${cell.state.isHidden ? 'Show' : 'Hide'}`} style={{ flex: '0 0 40px' }} />
+                    <IconButton onClick={this.toggleOptions} icon='cog' title='Options' toggleState={this.state.showOptions} style={{ flex: '0 0 40px' }} />
+                </div>
+            </div>
+            {this.state.showOptions && <>
+                <div className='msp-control-offset'>
+                    <UpdateTransformControl state={cell.parent} transform={cell.transform} customHeader='none' />
+                </div>
+            </>}
+        </>;
+    }
 }