Bladeren bron

wip, params

David Sehnal 6 jaren geleden
bovenliggende
commit
7700b34d9c

+ 1 - 1
src/mol-plugin/behavior/static/representation.ts

@@ -53,5 +53,5 @@ export function UpdateRepresentationVisibility(ctx: PluginContext) {
 }
 
 function updateVisibility(e: State.ObjectEvent, r: Representation<any>) {
-    r.setVisibility(!e.state.tree.cellStates.get(e.ref).isHidden);
+    r.setVisibility(!e.state.cellStates.get(e.ref).isHidden);
 }

+ 2 - 2
src/mol-plugin/behavior/static/state.ts

@@ -64,11 +64,11 @@ export function ToggleExpanded(ctx: PluginContext) {
 }
 
 export function ToggleVisibility(ctx: PluginContext) {
-    PluginCommands.State.ToggleVisibility.subscribe(ctx, ({ state, ref }) => setVisibility(state, ref, !state.tree.cellStates.get(ref).isHidden));
+    PluginCommands.State.ToggleVisibility.subscribe(ctx, ({ state, ref }) => setVisibility(state, ref, !state.cellStates.get(ref).isHidden));
 }
 
 function setVisibility(state: State, root: Transform.Ref, value: boolean) {
-    StateTree.doPreOrder(state.tree, state.tree.transforms.get(root), { state, value }, setVisibilityVisitor);
+    StateTree.doPreOrder(state.tree, state.transforms.get(root), { state, value }, setVisibilityVisitor);
 }
 
 function setVisibilityVisitor(t: Transform, tree: StateTree, ctx: { state: State, value: boolean }) {

+ 2 - 1
src/mol-plugin/state/transforms/model.ts

@@ -47,6 +47,7 @@ const ParseTrajectoryFromMmCif = PluginStateTransform.Create<SO.Data.Cif, SO.Mol
 });
 
 export { CreateModelFromTrajectory }
+const plus1 = (v: number) => v + 1, minus1 = (v: number) => v - 1;
 namespace CreateModelFromTrajectory { export interface Params { modelIndex: number } }
 const CreateModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajectory, SO.Molecule.Model, CreateModelFromTrajectory.Params>({
     name: 'create-model-from-trajectory',
@@ -58,7 +59,7 @@ const CreateModelFromTrajectory = PluginStateTransform.Create<SO.Molecule.Trajec
     to: [SO.Molecule.Model],
     params: {
         default: () => ({ modelIndex: 0 }),
-        definition: a => ({ modelIndex: PD.Numeric(0, { min: 0, max: Math.max(0, a.data.length - 1), step: 1 }, { description: 'Model Index' }) })
+        definition: a => ({ modelIndex: PD.Converted(plus1, minus1, PD.Numeric(1, { min: 1, max: a.data.length, step: 1 }, { description: 'Model Index' })) })
     },
     isApplicable: a => a.data.length > 0,
     apply({ a, params }) {

+ 5 - 2
src/mol-plugin/ui/controls/parameters.tsx

@@ -87,7 +87,10 @@ export class BoolControl extends SimpleParam<PD.Boolean> {
 export class NumberControl extends SimpleParam<PD.Numeric> {
     onChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.update(+e.target.value); }
     renderControl() {
-        return <input type='range' value={'' + this.props.value} min={this.props.param.min} max={this.props.param.max} step={this.props.param.step} onChange={this.onChange} disabled={this.props.isDisabled} />;
+        return <span>
+            <input type='range' value={'' + this.props.value} min={this.props.param.min} max={this.props.param.max} step={this.props.param.step} onChange={this.onChange} disabled={this.props.isDisabled} />
+            <br />{this.props.value}
+        </span>
     }
 }
 
@@ -243,7 +246,7 @@ export class ConvertedControl extends React.PureComponent<ParamProps<PD.Converte
         this.props.onChange({
             name: this.props.name,
             param: this.props.param,
-            value: { name: e.value, params: this.props.param.toValue(e.value) }
+            value: this.props.param.toValue(e.value)
         });
     }
 

+ 1 - 1
src/mol-plugin/ui/plugin.tsx

@@ -129,7 +129,7 @@ export class CurrentObject extends PluginComponent {
 
         const type = obj && obj.obj ? obj.obj.type : void 0;
 
-        const transform = current.state.tree.transforms.get(ref);
+        const transform = current.state.transforms.get(ref);
 
         const actions = type
             ? current.state.actions.fromType(type)

+ 4 - 4
src/mol-plugin/ui/state-tree.tsx

@@ -33,7 +33,7 @@ class StateTreeNode extends PluginComponent<{ nodeRef: string, state: State }, {
     }
 
     get cellState() {
-        return this.props.state.tree.cellStates.get(this.props.nodeRef);
+        return this.props.state.cellStates.get(this.props.nodeRef);
     }
 
     componentDidMount() {
@@ -104,7 +104,7 @@ class StateTreeNodeLabel extends PluginComponent<{ nodeRef: string, state: State
             } else if (isCurrent) {
                 isCurrent = false;
                 // have to check the node wasn't remove
-                if (e.state.tree.transforms.has(this.props.nodeRef)) this.forceUpdate();
+                if (e.state.transforms.has(this.props.nodeRef)) this.forceUpdate();
             }
         });
     }
@@ -125,7 +125,7 @@ class StateTreeNodeLabel extends PluginComponent<{ nodeRef: string, state: State
     }
 
     render() {
-        const n = this.props.state.tree.transforms.get(this.props.nodeRef)!;
+        const n = this.props.state.transforms.get(this.props.nodeRef)!;
         const cell = this.props.state.cells.get(this.props.nodeRef)!;
 
         const isCurrent = this.is(this.props.state.behaviors.currentObject.value);
@@ -141,7 +141,7 @@ class StateTreeNodeLabel extends PluginComponent<{ nodeRef: string, state: State
             label = <><a href='#' onClick={this.setCurrent}>{obj.label}</a> {obj.description ? <small>{obj.description}</small> : void 0}</>;
         }
 
-        const cellState = this.props.state.tree.cellStates.get(this.props.nodeRef);
+        const cellState = this.props.state.cellStates.get(this.props.nodeRef);
         const visibility = <>[<a href='#' onClick={this.toggleVisible}>{cellState.isHidden ? 'H' : 'V'}</a>]</>;
 
         return <>

+ 11 - 6
src/mol-plugin/ui/state/apply-action.tsx

@@ -22,7 +22,8 @@ namespace ApplyActionContol {
     }
 
     export interface ComponentState {
-        nodeRef: Transform.Ref,
+        ref: Transform.Ref,
+        version: string,
         params: any,
         error?: string,
         busy: boolean,
@@ -38,24 +39,28 @@ class ApplyActionContol extends TransformContolBase<ApplyActionContol.Props, App
             ref: this.props.nodeRef
         });
     }
-    getInfo() { return this._getInfo(this.props.nodeRef); }
+    getInfo() { return this._getInfo(this.props.nodeRef, this.props.state.transforms.get(this.props.nodeRef).version); }
     getHeader() { return this.props.action.definition.display; }
     getHeaderFallback() { return this.props.action.id; }
     isBusy() { return !!this.state.error || this.state.busy; }
     applyText() { return 'Apply'; }
 
-    private _getInfo = memoizeOne((t: Transform.Ref) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
+    private _getInfo = memoizeOne((t: Transform.Ref, v: string) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
 
-    state = { nodeRef: this.props.nodeRef, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false };
+    state = { ref: this.props.nodeRef, version: this.props.state.transforms.get(this.props.nodeRef).version, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false };
 
     static getDerivedStateFromProps(props: ApplyActionContol.Props, state: ApplyActionContol.ComponentState) {
-        if (props.nodeRef === state.nodeRef) return null;
+        if (props.nodeRef === state.ref) return null;
+        const version = props.state.transforms.get(props.nodeRef).version;
+        if (version === state.version) return null;
+
         const source = props.state.cells.get(props.nodeRef)!.obj!;
         const definition = props.action.definition.params || { };
         const initialValues = definition.default ? definition.default(source, props.plugin) : {};
 
         const newState: Partial<ApplyActionContol.ComponentState> = {
-            nodeRef: props.nodeRef,
+            ref: props.nodeRef,
+            version,
             params: initialValues,
             isInitial: true,
             error: void 0

+ 1 - 1
src/mol-plugin/ui/state/common.tsx

@@ -45,7 +45,7 @@ class StateTransformParameters extends PurePluginComponent<StateTransformParamet
 namespace StateTransformParameters {
     export interface Props {
         info: {
-            definition: Transformer.ParamsProvider,
+            definition: Transformer.ParamsDefinition,
             params: PD.Params,
             initialValues: any,
             source: StateObject,

+ 1 - 1
src/mol-state/action.ts

@@ -46,7 +46,7 @@ namespace StateAction {
          */
         apply(params: ApplyParams<A, P>, globalCtx: unknown): T | Task<T>,
 
-        readonly params?: Transformer.ParamsProvider<A, P>
+        readonly params?: Transformer.ParamsDefinition<A, P>
 
         /** Test if the transform can be applied to a given node */
         isApplicable?(a: A, globalCtx: unknown): boolean

+ 2 - 0
src/mol-state/state.ts

@@ -52,6 +52,8 @@ class State {
     readonly actions = new StateActionManager();
 
     get tree(): StateTree { return this._tree; }
+    get transforms() { return (this._tree as StateTree).transforms; }
+    get cellStates() { return (this._tree as StateTree).cellStates; }
     get current() { return this.behaviors.currentObject.value.ref; }
 
     build() { return this._tree.build(); }

+ 2 - 2
src/mol-state/transformer.ts

@@ -47,7 +47,7 @@ export namespace Transformer {
 
     export enum UpdateResult { Unchanged, Updated, Recreate }
 
-    export interface ParamsProvider<A extends StateObject = StateObject, P = any> {
+    export interface ParamsDefinition<A extends StateObject = StateObject, P = any> {
         /** Check the parameters and return a list of errors if the are not valid. */
         default?(a: A, globalCtx: unknown): P,
         /** Specify default control descriptors for the parameters */
@@ -75,7 +75,7 @@ export namespace Transformer {
          */
         update?(params: UpdateParams<A, B, P>, globalCtx: unknown): Task<UpdateResult> | UpdateResult,
 
-        readonly params?: ParamsProvider<A, P>,
+        readonly params?: ParamsDefinition<A, P>,
 
         /** Test if the transform can be applied to a given node */
         isApplicable?(a: A, globalCtx: unknown): boolean,

+ 2 - 2
src/mol-util/param-definition.ts

@@ -138,8 +138,8 @@ export namespace ParamDefinition {
         fromValue(v: T): C,
         toValue(v: C): T
     }
-    export function Converted<T, C extends Any>(defaultValue: T, converted: C, fromValue: (v: T) => C, toValue: (v: C) => T): Converted<T, C> {
-        return { type: 'converted', defaultValue, converted, fromValue, toValue };
+    export function Converted<T, C extends Any>(fromValue: (v: T) => C['defaultValue'], toValue: (v: C['defaultValue']) => T, converted: C): Converted<T, C['defaultValue']> {
+        return { type: 'converted', defaultValue: toValue(converted.defaultValue), converted, fromValue, toValue };
     }
 
     export type Any = Value<any> | Select<any> | MultiSelect<any> | Boolean | Text | Color | Numeric | Interval | LineGraph | Group<any> | Mapped<any> | Converted<any, any>