From 7700b34d9c98b572a95cc0ae9ab91ea6689e9388 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Thu, 15 Nov 2018 23:25:01 +0100 Subject: [PATCH] wip, params --- .../behavior/static/representation.ts | 2 +- src/mol-plugin/behavior/static/state.ts | 4 ++-- src/mol-plugin/state/transforms/model.ts | 3 ++- src/mol-plugin/ui/controls/parameters.tsx | 7 +++++-- src/mol-plugin/ui/plugin.tsx | 2 +- src/mol-plugin/ui/state-tree.tsx | 8 ++++---- src/mol-plugin/ui/state/apply-action.tsx | 17 +++++++++++------ src/mol-plugin/ui/state/common.tsx | 2 +- src/mol-state/action.ts | 2 +- src/mol-state/state.ts | 2 ++ src/mol-state/transformer.ts | 4 ++-- src/mol-util/param-definition.ts | 4 ++-- 12 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/mol-plugin/behavior/static/representation.ts b/src/mol-plugin/behavior/static/representation.ts index d62cb8ea8..90b7e4738 100644 --- a/src/mol-plugin/behavior/static/representation.ts +++ b/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); } \ No newline at end of file diff --git a/src/mol-plugin/behavior/static/state.ts b/src/mol-plugin/behavior/static/state.ts index 6e6643a39..f83a7ca8d 100644 --- a/src/mol-plugin/behavior/static/state.ts +++ b/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 }) { diff --git a/src/mol-plugin/state/transforms/model.ts b/src/mol-plugin/state/transforms/model.ts index 220220e34..4c914e8ff 100644 --- a/src/mol-plugin/state/transforms/model.ts +++ b/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 }) { diff --git a/src/mol-plugin/ui/controls/parameters.tsx b/src/mol-plugin/ui/controls/parameters.tsx index d5c129e44..9a65e23bc 100644 --- a/src/mol-plugin/ui/controls/parameters.tsx +++ b/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) }); } diff --git a/src/mol-plugin/ui/plugin.tsx b/src/mol-plugin/ui/plugin.tsx index bd0435deb..bb3ff2eeb 100644 --- a/src/mol-plugin/ui/plugin.tsx +++ b/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) diff --git a/src/mol-plugin/ui/state-tree.tsx b/src/mol-plugin/ui/state-tree.tsx index 621024d58..9634c8dcf 100644 --- a/src/mol-plugin/ui/state-tree.tsx +++ b/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 <> diff --git a/src/mol-plugin/ui/state/apply-action.tsx b/src/mol-plugin/ui/state/apply-action.tsx index 2c616a6be..1af3b9071 100644 --- a/src/mol-plugin/ui/state/apply-action.tsx +++ b/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 diff --git a/src/mol-plugin/ui/state/common.tsx b/src/mol-plugin/ui/state/common.tsx index 3ce020388..b5ebc0fb5 100644 --- a/src/mol-plugin/ui/state/common.tsx +++ b/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, diff --git a/src/mol-state/action.ts b/src/mol-state/action.ts index 024fe3e0d..e230f4e07 100644 --- a/src/mol-state/action.ts +++ b/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 diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index 5c2f27e15..8385b27f9 100644 --- a/src/mol-state/state.ts +++ b/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(); } diff --git a/src/mol-state/transformer.ts b/src/mol-state/transformer.ts index 673e27869..0a68047ef 100644 --- a/src/mol-state/transformer.ts +++ b/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, diff --git a/src/mol-util/param-definition.ts b/src/mol-util/param-definition.ts index 955906abc..e53915ce0 100644 --- a/src/mol-util/param-definition.ts +++ b/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> -- GitLab