Browse Source

Merge branch 'master' of https://github.com/molstar/molstar

Alexander Rose 5 years ago
parent
commit
2d58ea28ea

+ 2 - 2
src/mol-canvas3d/canvas3d.ts

@@ -132,12 +132,12 @@ namespace Canvas3D {
                     if (webgl.isContextLost) return;
                     if (!e.shiftKey || !e.ctrlKey || !e.altKey) return;
 
-                    console.log('lose context');
+                    if (isDebugMode) console.log('lose context');
                     loseContextExt.loseContext();
 
                     setTimeout(() => {
                         if (!webgl.isContextLost) return;
-                        console.log('restore context');
+                        if (isDebugMode) console.log('restore context');
                         loseContextExt.restoreContext();
                     }, 1000);
                 }, false);

+ 0 - 1
src/mol-geo/geometry/mesh/builder/tube.ts

@@ -53,7 +53,6 @@ export function addTube(state: MeshBuilder.State, controlPoints: ArrayLike<numbe
             if (radialSegments === 2) {
                 // add2AndScale2(normalVector, u, v, w * Math.cos(t), h * Math.sin(t))
                 Vec3.copy(normalVector, v);
-                console.log(i, t);
                 Vec3.normalize(normalVector, normalVector);
                 if (t !== 0 || i % 2 === 0) Vec3.negate(normalVector, normalVector);
             } else {

+ 0 - 1
src/mol-model/structure/export/mmcif.ts

@@ -146,7 +146,6 @@ export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures:
     if (params?.copyAllCategories && MmcifFormat.is(models[0].sourceData)) {
         encode_mmCIF_categories_copyAll(encoder, ctx);
     } else {
-        console.log('default');
         encode_mmCIF_categories_default(encoder, ctx, params);
     }
 }

+ 1 - 1
src/mol-model/volume/data.ts

@@ -28,7 +28,7 @@ interface VolumeData extends VolumeDataBase {
 
 namespace VolumeData {
     export const One: VolumeData = {
-        transform: { kind: 'matrix', matrix: Mat4() },
+        transform: { kind: 'matrix', matrix: Mat4.identity() },
         data: Tensor.create(Tensor.Space([1, 1, 1], [0, 1, 2]), Tensor.Data1([0])),
         dataStats: { min: 0, max: 0, mean: 0, sigma: 0 }
     };

+ 66 - 29
src/mol-plugin-ui/custom/volume.tsx

@@ -8,7 +8,7 @@ import { PluginUIComponent } from '../base';
 import { StateTransformParameters } from '../state/common';
 import * as React from 'react';
 import { VolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/behavior';
-import { ExpandableControlRow } from '../controls/common';
+import { ExpandableControlRow, IconButton } from '../controls/common';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { ParameterControls, ParamOnChange } from '../controls/parameters';
 import { Slider } from '../controls/slider';
@@ -16,6 +16,10 @@ import { VolumeIsoValue, VolumeData } from '../../mol-model/volume';
 import { Vec3 } from '../../mol-math/linear-algebra';
 import { ColorNames } from '../../mol-util/color/names';
 import { toPrecision } from '../../mol-util/number';
+import VisibilityOffOutlined from '@material-ui/icons/VisibilityOffOutlined';
+import VisibilityOutlined from '@material-ui/icons/VisibilityOutlined';
+import { StateSelection, StateObjectCell } from '../../mol-state';
+import { setSubtreeVisibility } from '../../mol-plugin/behavior/static/state';
 
 const ChannelParams = {
     color: PD.Color(ColorNames.black, { description: 'Display color of the volume.' }),
@@ -24,36 +28,69 @@ const ChannelParams = {
 };
 type ChannelParams = PD.Values<typeof ChannelParams>
 
-function Channel(props: {
+class Channel extends PluginUIComponent<{
     label: string,
     name: VolumeStreaming.ChannelType,
     channels: { [k: string]: VolumeStreaming.ChannelParams },
     isRelative: boolean,
     params: StateTransformParameters.Props,
     stats: VolumeData['dataStats'],
-    changeIso: (name: string, value: number, isRelative: boolean) => void
-    changeParams: (name: string, param: string, value: any) => void
-}) {
-    const { isRelative, stats } = props;
-    const channel = props.channels[props.name]!;
-
-    const { min, max, mean, sigma } = stats;
-    const value = Math.round(100 * (channel.isoValue.kind === 'relative' ? channel.isoValue.relativeValue : channel.isoValue.absoluteValue)) / 100;
-    const relMin = (min - mean) / sigma;
-    const relMax = (max - mean) / sigma;
-    const step = toPrecision(isRelative ? Math.round(((max - min) / sigma)) / 100 : sigma / 100, 2);
-
-    return <ExpandableControlRow
-        label={props.label + (props.isRelative ? ' \u03C3' : '')}
-        colorStripe={channel.color}
-        pivot={<Slider value={value} min={isRelative ? relMin : min} max={isRelative ? relMax : max} step={step}
-            onChange={v => props.changeIso(props.name, v, isRelative)} disabled={props.params.isDisabled} onEnter={props.params.events.onEnter} />}
-        controls={<ParameterControls onChange={({ name, value }) => props.changeParams(props.name, name, value)} params={ChannelParams} values={channel} onEnter={props.params.events.onEnter} />}
-    />;
+    changeIso: (name: string, value: number, isRelative: boolean) => void,
+    changeParams: (name: string, param: string, value: any) => void,
+    bCell: StateObjectCell,
+    isDisabled?: boolean
+}> {
+    private ref = StateSelection.findTagInSubtree(this.plugin.state.data.tree, this.props.bCell!.transform.ref, this.props.name);
+
+    componentDidUpdate() {
+        this.ref = StateSelection.findTagInSubtree(this.plugin.state.data.tree, this.props.bCell!.transform.ref, this.props.name);
+    }
+
+    componentDidMount() {
+        this.subscribe(this.plugin.state.data.events.cell.stateUpdated, e => {
+            if (this.ref === e.ref) this.forceUpdate();
+        });
+    }
+
+    getVisible = () => {
+        const state = this.plugin.state.data;
+        const ref = this.ref;
+        if (!ref) return false;
+        return !state.cells.get(ref)!.state.isHidden;
+    };
+
+    toggleVisible = () => {
+        const state = this.plugin.state.data;
+        const ref = this.ref;
+        if (!ref) return;
+        setSubtreeVisibility(state, ref, !state.cells.get(ref)!.state.isHidden);
+    };
+
+    render() {
+        const props = this.props;
+        const { isRelative, stats } = props;
+        const channel = props.channels[props.name]!;
+
+        const { min, max, mean, sigma } = stats;
+        const value = Math.round(100 * (channel.isoValue.kind === 'relative' ? channel.isoValue.relativeValue : channel.isoValue.absoluteValue)) / 100;
+        const relMin = (min - mean) / sigma;
+        const relMax = (max - mean) / sigma;
+        const step = toPrecision(isRelative ? Math.round(((max - min) / sigma)) / 100 : sigma / 100, 2);
+
+        return <ExpandableControlRow
+            label={props.label + (props.isRelative ? ' \u03C3' : '')}
+            colorStripe={channel.color}
+            pivot={<div className='msp-volume-channel-inline-controls'>
+                <Slider value={value} min={isRelative ? relMin : min} max={isRelative ? relMax : max} step={step}
+                    onChange={v => props.changeIso(props.name, v, isRelative)} disabled={props.params.isDisabled} onEnter={props.params.events.onEnter} />
+                <IconButton svg={this.getVisible() ? VisibilityOutlined : VisibilityOffOutlined} onClick={this.toggleVisible} toggleState={false} disabled={props.params.isDisabled} />
+            </div>}
+            controls={<ParameterControls onChange={({ name, value }) => props.changeParams(props.name, name, value)} params={ChannelParams} values={channel} onEnter={props.params.events.onEnter} isDisabled={props.params.isDisabled} />}
+        />;
+    }
 }
 
 export class VolumeStreamingCustomControls extends PluginUIComponent<StateTransformParameters.Props> {
-
     private areInitial(params: any) {
         return PD.areEqual(this.props.info.params, params, this.props.info.initialValues);
     }
@@ -170,8 +207,8 @@ export class VolumeStreamingCustomControls extends PluginUIComponent<StateTransf
 
     render() {
         if (!this.props.b) return null;
-
         const b = (this.props.b as VolumeStreaming).data;
+
         const isEM = b.info.kind === 'em';
         const pivot = isEM ? 'em' : '2fo-fc';
 
@@ -225,16 +262,16 @@ export class VolumeStreamingCustomControls extends PluginUIComponent<StateTransf
         };
 
         if (isOff) {
-            return <ParameterControls onChange={this.changeOption} params={OptionsParams} values={options} onEnter={this.props.events.onEnter} />;
+            return <ParameterControls onChange={this.changeOption} params={OptionsParams} values={options} onEnter={this.props.events.onEnter} isDisabled={this.props.isDisabled} />;
         }
 
         return <>
-            {!isEM && <Channel label='2Fo-Fc' name='2fo-fc' channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[0]} />}
-            {!isEM && <Channel label='Fo-Fc(+ve)' name='fo-fc(+ve)' channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[1]} />}
-            {!isEM && <Channel label='Fo-Fc(-ve)' name='fo-fc(-ve)' channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[1]} />}
-            {isEM && <Channel label='EM' name='em' channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[0]} />}
+            {!isEM && <Channel label='2Fo-Fc' name='2fo-fc' bCell={this.props.bCell!} channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[0]} />}
+            {!isEM && <Channel label='Fo-Fc(+ve)' name='fo-fc(+ve)' bCell={this.props.bCell!} channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[1]} />}
+            {!isEM && <Channel label='Fo-Fc(-ve)' name='fo-fc(-ve)' bCell={this.props.bCell!} channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[1]} />}
+            {isEM && <Channel label='EM' name='em' bCell={this.props.bCell!} channels={params.entry.params.channels} changeIso={this.changeIso} changeParams={this.changeParams} isRelative={isRelative} params={this.props} stats={sampling.valuesInfo[0]} />}
 
-            <ParameterControls onChange={this.changeOption} params={OptionsParams} values={options} onEnter={this.props.events.onEnter} />
+            <ParameterControls onChange={this.changeOption} params={OptionsParams} values={options} onEnter={this.props.events.onEnter} isDisabled={this.props.isDisabled} />
         </>;
     }
 }

+ 32 - 1
src/mol-plugin-ui/skin/base/components/misc.scss

@@ -579,4 +579,35 @@
 @include accent('green', $color-accent-green);
 @include accent('purple', $color-accent-purple);
 @include accent('blue', $color-accent-blue);
-@include accent('orange', $color-accent-orange);
+@include accent('orange', $color-accent-orange);
+
+.msp-volume-channel-inline-controls {
+    > :first-child {
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: $row-height;
+        right: 32px;
+    }
+
+    .msp-slider {
+        > div:first-child() {
+            right: 42px;
+        }
+        > div:last-child() {
+            width: 30px;
+        }
+    }
+
+    > button {
+        position: absolute;
+        right: 0;
+        width: 32px;
+        top: 0;
+        padding: 0;
+
+        .msp-material-icon {
+            margin-right: 0;
+        }
+    }
+}

+ 8 - 7
src/mol-plugin-ui/state/common.tsx

@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { State, StateTransform, StateTransformer, StateAction, StateObject } from '../../mol-state';
+import { State, StateTransform, StateTransformer, StateAction, StateObject, StateObjectCell } from '../../mol-state';
 import * as React from 'react';
 import { PurePluginUIComponent } from '../base';
 import { ParameterControls, ParamOnChange } from '../controls/parameters';
@@ -56,7 +56,8 @@ namespace StateTransformParameters {
         params: any,
         isDisabled?: boolean,
         a?: StateObject,
-        b?: StateObject
+        b?: StateObject,
+        bCell?: StateObjectCell
     }
 
     export type Class = React.ComponentClass<Props>
@@ -125,7 +126,7 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
     abstract canAutoApply(newParams: any): boolean;
     abstract applyText(): string;
     abstract isUpdate(): boolean;
-    abstract getSourceAndTarget(): { a?: StateObject, b?: StateObject };
+    abstract getSourceAndTarget(): { a?: StateObject, b?: StateObject, bCell?: StateObjectCell };
     abstract state: S;
 
     private busy: Subject<boolean> = new Subject();
@@ -224,10 +225,10 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
 
         let params = null;
         if (!isEmpty && !this.state.isCollapsed) {
-            const { a, b } = this.getSourceAndTarget();
+            const { a, b, bCell } = this.getSourceAndTarget();
             const applyControl = this.renderApply();
             params = <>
-                <ParamEditor info={info} a={a} b={b} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
+                <ParamEditor info={info} a={a} b={b} bCell={bCell} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
                 {applyControl}
             </>;
         }
@@ -266,11 +267,11 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
         const ParamEditor: StateTransformParameters.Class = this.plugin.customParamEditors.has(tId)
             ? this.plugin.customParamEditors.get(tId)!
             : StateTransformParameters;
-        const { a, b } = this.getSourceAndTarget();
+        const { a, b, bCell } = this.getSourceAndTarget();
 
         return <>
             {apply}
-            <ParamEditor info={info} a={a} b={b} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
+            <ParamEditor info={info} a={a} b={b} bCell={bCell} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
         </>;
     }
 

+ 0 - 1
src/mol-plugin-ui/state/snapshots.tsx

@@ -175,7 +175,6 @@ class LocalStateSnapshotList extends PluginUIComponent<{}, {}> {
         return <ul style={{ listStyle: 'none', marginTop: '10px' }} className='msp-state-list'>
             {this.plugin.managers.snapshot.state.entries.map(e => <li key={e!.snapshot.id} className='msp-flex-row'>
                 <Button data-id={e!.snapshot.id} onClick={this.apply} className='msp-no-overflow'>
-                    {(console.log(e!.snapshot.durationInMs), false)}
                     <span style={{ fontWeight: e!.snapshot.id === current ? 'bold' : void 0 }}>
                         {e!.name || new Date(e!.timestamp).toLocaleString()}</span> <small>
                         {`${e!.snapshot.durationInMs ? formatTimespan(e!.snapshot.durationInMs, false) + `${e!.description ? ', ' : ''}` : ''}${e!.description ? e!.description : ''}`}

+ 3 - 1
src/mol-plugin-ui/state/update-transform.tsx

@@ -49,9 +49,11 @@ class UpdateTransformControl extends TransformControlBase<UpdateTransformControl
     applyText() { return this.canApply() ? 'Update' : 'Nothing to Update'; }
     isUpdate() { return true; }
     getSourceAndTarget() {
+        const bCell = this.props.state.cells.get(this.props.transform.ref);
         return {
             a: this.props.state.cells.get(this.props.transform.parent)!.obj,
-            b: this.props.state.cells.has(this.props.transform.ref)! ? this.props.state.cells.get(this.props.transform.ref)!.obj : void 0
+            b: bCell?.obj,
+            bCell
         };
     }
 

+ 0 - 1
src/mol-plugin-ui/structure/measurements.tsx

@@ -198,7 +198,6 @@ class MeasurementsOptions extends PurePluginUIComponent<{}, { isDisabled: boolea
         });
 
         this.subscribe(this.plugin.behaviors.state.isBusy, v => {
-            console.log('isBusy', 'measurement opt', v);
             this.setState({ isDisabled: v });
         });
     }

+ 4 - 4
src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts

@@ -115,11 +115,11 @@ export const InitVolumeStreaming = StateAction.build({
         { ref: params.options.behaviorRef ? params.options.behaviorRef : void 0 });
 
     if (params.method === 'em') {
-        behTree.apply(VolumeStreamingVisual, { channel: 'em' }, { state: { isGhost: true } });
+        behTree.apply(VolumeStreamingVisual, { channel: 'em' }, { state: { isGhost: true }, tags: 'em' });
     } else {
-        behTree.apply(VolumeStreamingVisual, { channel: '2fo-fc' }, { state: { isGhost: true } });
-        behTree.apply(VolumeStreamingVisual, { channel: 'fo-fc(+ve)' }, { state: { isGhost: true } });
-        behTree.apply(VolumeStreamingVisual, { channel: 'fo-fc(-ve)' }, { state: { isGhost: true } });
+        behTree.apply(VolumeStreamingVisual, { channel: '2fo-fc' }, { state: { isGhost: true }, tags: '2fo-fc' });
+        behTree.apply(VolumeStreamingVisual, { channel: 'fo-fc(+ve)' }, { state: { isGhost: true }, tags: 'fo-fc(+ve)' });
+        behTree.apply(VolumeStreamingVisual, { channel: 'fo-fc(-ve)' }, { state: { isGhost: true }, tags: 'fo-fc(-ve)' });
     }
     await state.updateTree(behTree).runInContext(taskCtx);
 }));