diff --git a/src/mol-plugin/behavior/behavior.ts b/src/mol-plugin/behavior/behavior.ts index be542ec6132a939d98e9e56769fe8ec7114de197..4d764da26697e3d69b3422a2787baabfb1e802a9 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 f180f69f92c4fe65816b555a018d96c970d36e7a..d54e53db816499d74d497d28afd9e842eb6a386f 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 9efabe8107c2970be0e9cec8d87be17892976e35..9aa7fa3c958495f109e00ee7bab624bff98f8c46 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 d25a82835478a7ea909a0f6b30e63d2203f9b7a0..5bb6010f5805c52ee41a79c8d31eac078229d648 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