From 21aae7ecbe75cc31df0eadd70f8773dc98c6f366 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Tue, 5 Feb 2019 14:01:31 +0100 Subject: [PATCH] added StateSelection.rootOfType, PluginBehavior can now "auto update" --- src/mol-plugin/behavior/behavior.ts | 4 +++- src/mol-plugin/behavior/dynamic/animation.ts | 14 ++------------ src/mol-state/state.ts | 9 +++++++++ src/mol-state/state/selection.ts | 20 +++++++++++++++++++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/mol-plugin/behavior/behavior.ts b/src/mol-plugin/behavior/behavior.ts index be542ec61..4d764da26 100644 --- a/src/mol-plugin/behavior/behavior.ts +++ b/src/mol-plugin/behavior/behavior.ts @@ -32,6 +32,7 @@ namespace PluginBehavior { export interface CreateParams<P> { name: string, ctor: Ctor<P>, + canAutoUpdate?: Transformer.Definition<Root, Behavior, P>['canAutoUpdate'], label?: (params: P) => { label: string, description?: string }, display: { name: string, @@ -59,7 +60,8 @@ namespace PluginBehavior { const updated = await b.data.update(newParams); return updated ? Transformer.UpdateResult.Updated : Transformer.UpdateResult.Unchanged; }) - } + }, + canAutoUpdate: params.canAutoUpdate }); } diff --git a/src/mol-plugin/behavior/dynamic/animation.ts b/src/mol-plugin/behavior/dynamic/animation.ts index f180f69f9..d54e53db8 100644 --- a/src/mol-plugin/behavior/dynamic/animation.ts +++ b/src/mol-plugin/behavior/dynamic/animation.ts @@ -31,6 +31,7 @@ type StructureAnimationProps = PD.Values<typeof StructureAnimationParams> export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>({ name: 'structure-animation', display: { name: 'Structure Animation', group: 'Animation' }, + canAutoUpdate: () => true, ctor: class extends PluginBehavior.Handler<StructureAnimationProps> { private tmpMat = Mat4.identity() private rotMat = Mat4.identity() @@ -186,16 +187,5 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps> // function getRootStructure(root: StateObjectCell, state: State) { - let parent: StateObjectCell | undefined - while (true) { - const _parent = StateSelection.findAncestorOfType(state.tree, state.cells, root.transform.ref, [PluginStateObject.Molecule.Structure]) - if (_parent) { - parent = _parent - root = _parent - } else { - break - } - } - return parent ? parent : - SO.Molecule.Structure.is(root.obj) ? root : undefined + return state.query(StateSelection.Generators.byValue(root).rootOfType([PluginStateObject.Molecule.Structure]))[0]; } \ No newline at end of file diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts index 9efabe810..9aa7fa3c9 100644 --- a/src/mol-state/state.ts +++ b/src/mol-state/state.ts @@ -98,6 +98,15 @@ class State { return StateSelection.select(selector(StateSelection.Generators), this) } + /** + * Select Cells using the provided selector. + * @example state.select('test') + * @example state.select(q => q.byRef('test').subtree()) + */ + query(selector: StateSelection.Selector) { + return StateSelection.select(selector, this) + } + /** If no ref is specified, apply to root */ apply<A extends StateAction>(action: A, params: StateAction.Params<A>, ref: Transform.Ref = Transform.RootRef): Task<void> { return Task.create('Apply Action', ctx => { diff --git a/src/mol-state/state/selection.ts b/src/mol-state/state/selection.ts index d25a82835..5bb6010f5 100644 --- a/src/mol-state/state/selection.ts +++ b/src/mol-state/state/selection.ts @@ -52,7 +52,8 @@ namespace StateSelection { subtree(): Builder; children(): Builder; ofType(t: StateObject.Ctor): Builder; - ancestorOfType(t: StateObject.Ctor): Builder; + ancestorOfType(t: StateObject.Ctor[]): Builder; + rootOfType(t: StateObject.Ctor[]): Builder; select(state: State): CellSeq } @@ -189,6 +190,9 @@ namespace StateSelection { registerModifier('ancestorOfType', ancestorOfType); export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s.tree, s.cells, n.transform.ref, types))); } + registerModifier('rootOfType', rootOfType); + export function rootOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findRootOfType(s.tree, s.cells, n.transform.ref, types))); } + registerModifier('parent', parent); export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.transforms.get(n.transform.ref)!.parent))); } @@ -207,6 +211,20 @@ namespace StateSelection { } } } + + export function findRootOfType(tree: StateTree, cells: State.Cells, root: Transform.Ref, types: StateObject.Ctor[]): StateObjectCell | undefined { + let parent: StateObjectCell | undefined, _root = root; + while (true) { + const _parent = StateSelection.findAncestorOfType(tree, cells, _root, types); + if (_parent) { + parent = _parent; + _root = _parent.transform.ref; + } else { + break; + } + } + return parent; + } } export { StateSelection } \ No newline at end of file -- GitLab