Browse Source

fix custom property transforms, isBusy behavior, other tweaks

David Sehnal 5 years ago
parent
commit
0f69ea197d

+ 0 - 68
src/mol-model-props/common/custom-property-registry.ts

@@ -1,68 +0,0 @@
-/**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import { CustomPropertyDescriptor, Model, Structure } from '../../mol-model/structure';
-import { OrderedMap } from 'immutable';
-import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { Task } from '../../mol-task';
-
-export { CustomPropertyRegistry }
-
-class CustomPropertyRegistry<T = never> {
-    private providers = OrderedMap<string, CustomPropertyRegistry.Provider<T>>().asMutable();
-
-    getSelect(object: T) {
-        const values = this.providers.values();
-        const options: [string, string][] = [], selected: string[] = [];
-        while (true) {
-            const v = values.next();
-            if (v.done) break;
-            if (!v.value.attachableTo(object)) continue;
-            options.push(v.value.option);
-            if (v.value.defaultSelected) selected.push(v.value.option[0]);
-        }
-        return PD.MultiSelect(selected, options);
-    }
-
-    getDefault(object: T) {
-        const values = this.providers.values();
-        const selected: string[] = [];
-        while (true) {
-            const v = values.next();
-            if (v.done) break;
-            if (!v.value.attachableTo(object)) continue;
-            if (v.value.defaultSelected) selected.push(v.value.option[0]);
-        }
-        return selected;
-    }
-
-    get(name: string) {
-        const prop = this.providers.get(name);
-        if (!prop) throw new Error(`Custom prop '${name}' is not registered.`);
-        return this.providers.get(name);
-    }
-
-    register(provider: CustomPropertyRegistry.Provider<T>) {
-        this.providers.set(provider.descriptor.name, provider);
-    }
-
-    unregister(name: string) {
-        this.providers.delete(name);
-    }
-}
-
-namespace CustomPropertyRegistry {
-    export interface Provider<T> {
-        option: [string, string],
-        defaultSelected: boolean,
-        descriptor: CustomPropertyDescriptor<any, any>,
-        attachableTo: (object: T) => boolean,
-        attach: (object: T) => Task<boolean>
-    }
-
-    export type ModelProvider = Provider<Model>
-    export type StructureProvider = Provider<Structure>
-}

+ 3 - 1
src/mol-model-props/common/custom-property.ts

@@ -77,7 +77,9 @@ namespace CustomProperty {
 
         get(name: string) {
             const prop = this.providers.get(name);
-            if (!prop) throw new Error(`Custom property '${name}' is not registered.`)
+            if (!prop) {
+                throw new Error(`Custom property '${name}' is not registered.`)
+            }
             return this.providers.get(name)
         }
 

+ 19 - 19
src/mol-plugin-state/manager/structure/component.ts

@@ -56,8 +56,10 @@ class StructureComponentManager extends PluginComponent<StructureComponentManage
             if (s.currentFocus?.surroundings) this.updateReprParams(update, s.currentFocus.surroundings);
         }
 
-        await this.plugin.runTask(this.dataState.updateTree(update));
-        await this.updateInterationProps();
+        return this.plugin.dataTransaction(async () => {
+            await this.plugin.runTask(this.dataState.updateTree(update));
+            await this.updateInterationProps();
+        });
     }
 
     private updateReprParams(update: StateBuilder.Root, component: StructureComponentRef) {
@@ -76,24 +78,22 @@ class StructureComponentManager extends PluginComponent<StructureComponentManage
         }
     }
 
-    private updateInterationProps() {
-        return this.plugin.dataTransaction(async () => {
-            for (const s of this.currentStructures) {
-                if (s.properties) {
-                    const b = this.dataState.build();
-                    b.to(s.properties.cell).update((old: StateTransformer.Params<CustomStructureProperties>) => {
-                        arraySetAdd(old.autoAttach, InteractionsProvider.descriptor.name);
-                        old.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions;
-                    });
-                    await this.plugin.runTask(this.dataState.updateTree(b));
-                } else {
-                    const params = PD.getDefaultValues(this.plugin.customStructureProperties.getParams(s.cell.obj?.data));
-                    arraySetAdd(params.autoAttach, InteractionsProvider.descriptor.name);
-                    params.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions;
-                    await this.plugin.builders.structure.insertStructureProperties(s.cell, params)
-                }
+    private async updateInterationProps() {
+        for (const s of this.currentStructures) {
+            if (s.properties) {
+                const b = this.dataState.build();
+                b.to(s.properties.cell).update((old: StateTransformer.Params<CustomStructureProperties>) => {
+                    arraySetAdd(old.autoAttach, InteractionsProvider.descriptor.name);
+                    old.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions;
+                });
+                await this.plugin.runTask(this.dataState.updateTree(b));
+            } else {
+                const params = PD.getDefaultValues(this.plugin.customStructureProperties.getParams(s.cell.obj?.data));
+                arraySetAdd(params.autoAttach, InteractionsProvider.descriptor.name);
+                params.properties[InteractionsProvider.descriptor.name] = this.state.options.interactions;
+                await this.plugin.builders.structure.insertStructureProperties(s.cell, params);
             }
-        });
+        }
     }
 
     applyPreset<P = any, S = {}>(structures: ReadonlyArray<StructureRef>, provider: StructureRepresentationProvider<P, S>, params?: P): Promise<any>  {

+ 3 - 1
src/mol-plugin-state/manager/structure/hierarchy-state.ts

@@ -222,7 +222,9 @@ function _doPreOrder(ctx: VisitorCtx, root: StateTransform) {
     for (const [t, f, l] of tagMap) {
         if (StateObject.hasTag(cell.obj!, t)) {
             const stop = f(state, cell);
-            if (stop === false) return;
+            if (stop === false) {
+                return;
+            }
             onLeave = l;
             break;
         }

+ 3 - 7
src/mol-plugin-state/transforms/model.ts

@@ -425,8 +425,6 @@ const MultiStructureSelectionFromExpression = PluginStateTransform.BuiltIn({
 
         (cache as object as any).entries = entries;
 
-        // console.log(selections);
-
         const props = { label: `${params.label || 'Multi-selection'}`, description: `${params.selections.length} source(s), ${totalSize} element(s) total` };
         return new SO.Molecule.Structure.Selections(selections, props);
     },
@@ -515,8 +513,6 @@ const MultiStructureSelectionFromExpression = PluginStateTransform.BuiltIn({
         b.label = `${newParams.label || 'Multi-selection'}`;
         b.description = `${selections.length} source(s), ${totalSize} element(s) total`;
 
-        // console.log('updated', selections);
-
         return StateTransformer.UpdateResult.Updated;
     }
 });
@@ -697,7 +693,7 @@ const CustomModelProperties = PluginStateTransform.BuiltIn({
     apply({ a, params }, ctx: PluginContext) {
         return Task.create('Custom Props', async taskCtx => {
             await attachModelProps(a.data, ctx, taskCtx, params);
-            return a;
+            return new SO.Molecule.Model(a.data, { label: a.label, description: a.description });
         });
     },
     update({ a, oldParams, newParams }, ctx: PluginContext) {
@@ -743,13 +739,13 @@ const CustomStructureProperties = PluginStateTransform.BuiltIn({
     apply({ a, params }, ctx: PluginContext) {
         return Task.create('Custom Props', async taskCtx => {
             await attachStructureProps(a.data, ctx, taskCtx, params);
-            return a;
+            return new SO.Molecule.Structure(a.data, { label: a.label, description: a.description });
         });
     },
     update({ a, oldParams, newParams }, ctx: PluginContext) {
         return Task.create('Custom Props', async taskCtx => {
             for (const name of oldParams.autoAttach) {
-                const property = ctx.customModelProperties.get(name);
+                const property = ctx.customStructureProperties.get(name);
                 if (!property) continue;
                 a.data.customPropertyDescriptors.reference(property.descriptor, false);
             }

+ 5 - 6
src/mol-plugin-ui/structure/components.tsx

@@ -57,9 +57,9 @@ class ComponentEditorControls extends PurePluginUIComponent<{}, ComponentEditorC
     }
 
     componentDidMount() {
-        this.subscribe(this.current, () => this.setState({ action: void 0 }));
+        this.subscribe(this.current, () => this.setState({ action: this.state.action !== 'options' ? void 0 : 'options' }));
         this.subscribe(this.plugin.behaviors.state.isBusy, v => {
-            this.setState({ isDisabled: v, action: void 0 })
+            this.setState({ isDisabled: v, action: this.state.action !== 'options' ? void 0 : 'options' })
         });
     }
 
@@ -112,7 +112,6 @@ class ComponentEditorControls extends PurePluginUIComponent<{}, ComponentEditorC
     }
 
     modifyComponentControls = <div className='msp-control-offset'><ModifyComponentControls onApply={this.hideAction} /></div>
-    optionsControls = <div className='msp-control-offset'><ComponentOptionsControls /></div>
 
     render() {
         return <>
@@ -123,7 +122,7 @@ class ComponentEditorControls extends PurePluginUIComponent<{}, ComponentEditorC
             </div>
             {this.state.action === 'preset' && this.presetControls}
             {this.state.action === 'modify' && this.modifyComponentControls}
-            {this.state.action === 'options' && this.optionsControls}
+            {this.state.action === 'options' && <div className='msp-control-offset'><ComponentOptionsControls isDisabled={this.state.isDisabled} /></div>}
         </>;
     }
 }
@@ -185,7 +184,7 @@ class ModifyComponentControls extends PurePluginUIComponent<{ onApply: () => voi
     }
 }
 
-class ComponentOptionsControls extends PurePluginUIComponent {
+class ComponentOptionsControls extends PurePluginUIComponent<{ isDisabled: boolean }> {
     componentDidMount() {
         this.subscribe(this.plugin.managers.structure.component.events.optionsUpdated, () => this.forceUpdate());
     }
@@ -193,7 +192,7 @@ class ComponentOptionsControls extends PurePluginUIComponent {
     update = (options: StructureComponentManager.Options) => this.plugin.managers.structure.component.setOptions(options)
 
     render() {
-        return <ParameterControls params={StructureComponentManager.OptionsParams} values={this.plugin.managers.structure.component.state.options} onChangeObject={this.update} />;
+        return <ParameterControls params={StructureComponentManager.OptionsParams} values={this.plugin.managers.structure.component.state.options} onChangeObject={this.update} isDisabled={this.props.isDisabled} />;
     }
 }
 

+ 2 - 2
src/mol-plugin/context.ts

@@ -230,10 +230,10 @@ export class PluginContext {
             this.behaviors.state.isUpdating.next(u);
         });
 
-        merge(this.behaviors.state.isAnimating, this.behaviors.state.isAnimating).subscribe(() => {
+        merge(this.behaviors.state.isUpdating, this.behaviors.state.isAnimating).subscribe(() => {
             const isUpdating = this.behaviors.state.isUpdating.value;
             const isAnimating = this.behaviors.state.isAnimating.value;
-            const isBusy = this.behaviors.state.isAnimating;
+            const isBusy = this.behaviors.state.isBusy;
 
             if ((isUpdating || isAnimating) && !isBusy.value) isBusy.next(true);
             else if (isBusy.value) isBusy.next(false);