From 96595fa874bdb35e6d96a961cea2ff2e5a366ebf Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Fri, 23 Nov 2018 16:36:17 +0100 Subject: [PATCH] mol-state & plugin: transform auto-update support --- .../skin/base/components/controls-base.scss | 2 +- .../state/transforms/representation.ts | 4 ++++ src/mol-plugin/ui/state/apply-action.tsx | 1 + src/mol-plugin/ui/state/common.tsx | 16 +++++++++++++++- src/mol-plugin/ui/state/update-transform.tsx | 12 ++++++++++++ src/mol-state/transformer.ts | 10 ++++++++++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/mol-plugin/skin/base/components/controls-base.scss b/src/mol-plugin/skin/base/components/controls-base.scss index 4d9573ce7..4bd3f6c21 100644 --- a/src/mol-plugin/skin/base/components/controls-base.scss +++ b/src/mol-plugin/skin/base/components/controls-base.scss @@ -90,7 +90,7 @@ -webkit-appearance: none; -moz-appearance: none; appearance: none; - box-shadow: none; // !important; + box-shadow: none !important; &:hover { color: $hover-font-color; diff --git a/src/mol-plugin/state/transforms/representation.ts b/src/mol-plugin/state/transforms/representation.ts index 168481fc2..c0e2dc23b 100644 --- a/src/mol-plugin/state/transforms/representation.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -44,6 +44,10 @@ const StructureRepresentation3D = PluginStateTransform.Create<SO.Molecule.Struct name => PD.Group<any>(ctx.structureRepresentation.themeCtx.sizeThemeRegistry.get(name).getParams({ structure: a.data })) ), }), + canAutoUpdate({ oldParams, newParams }) { + // TODO: allow for small molecules + return oldParams.type.name === newParams.type.name; + }, apply({ a, params }, plugin: PluginContext) { return Task.create('Structure Representation', async ctx => { const provider = plugin.structureRepresentation.registry.get(params.type.name) diff --git a/src/mol-plugin/ui/state/apply-action.tsx b/src/mol-plugin/ui/state/apply-action.tsx index cfc0157dc..c78e3cf11 100644 --- a/src/mol-plugin/ui/state/apply-action.tsx +++ b/src/mol-plugin/ui/state/apply-action.tsx @@ -44,6 +44,7 @@ class ApplyActionContol extends TransformContolBase<ApplyActionContol.Props, App getHeader() { return this.props.action.definition.display; } getHeaderFallback() { return this.props.action.id; } canApply() { return !this.state.error && !this.state.busy; } + canAutoApply() { return false; } applyText() { return 'Apply'; } isUpdate() { return false; } diff --git a/src/mol-plugin/ui/state/common.tsx b/src/mol-plugin/ui/state/common.tsx index faa468f19..5934dcdd0 100644 --- a/src/mol-plugin/ui/state/common.tsx +++ b/src/mol-plugin/ui/state/common.tsx @@ -101,6 +101,7 @@ abstract class TransformContolBase<P, S extends TransformContolBase.ControlState abstract getHeader(): Transformer.Definition['display']; abstract getHeaderFallback(): string; abstract canApply(): boolean; + abstract canAutoApply(newParams: any): boolean; abstract applyText(): string; abstract isUpdate(): boolean; abstract state: S; @@ -112,12 +113,25 @@ abstract class TransformContolBase<P, S extends TransformContolBase.ControlState this.apply(); } + private autoApplyHandle: number | undefined = void 0; + events: StateTransformParameters.Props['events'] = { onEnter: this.onEnter, - onChange: (params, isInitial, errors) => this.setState({ params, isInitial, error: errors && errors[0] }) + onChange: (params, isInitial, errors) => { + this.setState({ params, isInitial, error: errors && errors[0] }, () => { + if (!isInitial && !this.state.error && this.canAutoApply(params)) { + if (this.autoApplyHandle) clearTimeout(this.autoApplyHandle); + this.autoApplyHandle = setTimeout(this.apply, 50) as any as number; + } + }); + } } apply = async () => { + if (this.autoApplyHandle !== void 0) { + clearTimeout(this.autoApplyHandle); + this.autoApplyHandle = void 0; + } this.setState({ busy: true }); try { await this.applyAction(); diff --git a/src/mol-plugin/ui/state/update-transform.tsx b/src/mol-plugin/ui/state/update-transform.tsx index 40b61774d..d31f378fc 100644 --- a/src/mol-plugin/ui/state/update-transform.tsx +++ b/src/mol-plugin/ui/state/update-transform.tsx @@ -34,6 +34,18 @@ class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Pr applyText() { return this.canApply() ? 'Update' : 'Nothing to Update'; } isUpdate() { return true; } + canAutoApply(newParams: any) { + const autoUpdate = this.props.transform.transformer.definition.canAutoUpdate + if (!autoUpdate) return false; + + const { state } = this.props; + const cell = state.cells.get(this.props.transform.ref); + if (!cell || !cell.sourceRef || cell.status !== 'ok') return false; + const parentCell = state.cells.get(cell.sourceRef)!; + + return autoUpdate({ a: cell.obj!, b: parentCell.obj!, oldParams: this.props.transform.params, newParams }, this.plugin); + } + private _getInfo = memoizeOne((t: Transform) => StateTransformParameters.infoFromTransform(this.plugin, this.props.state, this.props.transform)); state: UpdateTransformContol.ComponentState = { transform: this.props.transform, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false }; diff --git a/src/mol-state/transformer.ts b/src/mol-state/transformer.ts index 950e1b376..a8b95195c 100644 --- a/src/mol-state/transformer.ts +++ b/src/mol-state/transformer.ts @@ -44,6 +44,13 @@ export namespace Transformer { cache: unknown } + export interface AutoUpdateParams<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = {}> { + a: A, + b: B, + oldParams: P, + newParams: P + } + export enum UpdateResult { Unchanged, Updated, Recreate } /** Specify default control descriptors for the parameters */ @@ -68,6 +75,9 @@ export namespace Transformer { */ update?(params: UpdateParams<A, B, P>, globalCtx: unknown): Task<UpdateResult> | UpdateResult, + /** Determine if the transformer can be applied automatically on UI change. Default is false. */ + canAutoUpdate?(params: AutoUpdateParams<A, B, P>, globalCtx: unknown): boolean, + params?(a: A, globalCtx: unknown): { [K in keyof P]: PD.Any }, /** Test if the transform can be applied to a given node */ -- GitLab