|
@@ -7,39 +7,56 @@
|
|
|
import { PluginContext } from '../../../mol-plugin/context';
|
|
|
import { StructureHierarchy, buildStructureHierarchy, ModelRef, StructureComponentRef, StructureRef, HierarchyRef, TrajectoryRef } from './hierarchy-state';
|
|
|
import { PluginComponent } from '../../component';
|
|
|
+import { StateTransform } from '../../../mol-state';
|
|
|
|
|
|
interface StructureHierarchyManagerState {
|
|
|
hierarchy: StructureHierarchy,
|
|
|
- currentTrajectories: ReadonlyArray<TrajectoryRef>,
|
|
|
- currentModels: ReadonlyArray<ModelRef>,
|
|
|
- currentStructures: ReadonlyArray<StructureRef>
|
|
|
+ current: {
|
|
|
+ trajectories: ReadonlyArray<TrajectoryRef>,
|
|
|
+ models: ReadonlyArray<ModelRef>,
|
|
|
+ structures: ReadonlyArray<StructureRef>
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class StructureHierarchyManager extends PluginComponent<StructureHierarchyManagerState> {
|
|
|
readonly behaviors = {
|
|
|
current: this.ev.behavior({
|
|
|
hierarchy: this.state.hierarchy,
|
|
|
- trajectories: this.state.currentTrajectories,
|
|
|
- models: this.state.currentModels,
|
|
|
- structures: this.state.currentStructures
|
|
|
+ trajectories: this.state.current.trajectories,
|
|
|
+ models: this.state.current.models,
|
|
|
+ structures: this.state.current.structures
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ private get dataState() {
|
|
|
+ return this.plugin.state.dataState;
|
|
|
+ }
|
|
|
+
|
|
|
private _currentComponentGroups: ReturnType<typeof StructureHierarchyManager['getComponentGroups']> | undefined = void 0;
|
|
|
|
|
|
get currentComponentGroups() {
|
|
|
if (this._currentComponentGroups) return this._currentComponentGroups;
|
|
|
- this._currentComponentGroups = StructureHierarchyManager.getComponentGroups(this.state.currentStructures);
|
|
|
+ this._currentComponentGroups = StructureHierarchyManager.getComponentGroups(this.state.current.structures);
|
|
|
return this._currentComponentGroups;
|
|
|
}
|
|
|
|
|
|
- private syncCurrentTrajectories(hierarchy: StructureHierarchy): TrajectoryRef[] {
|
|
|
- const current = this.state.currentTrajectories;
|
|
|
+ private _currentSelectionSet: Set<string> | undefined = void 0;
|
|
|
+ get currentSeletionSet() {
|
|
|
+ if (this._currentSelectionSet) return this._currentSelectionSet;
|
|
|
+ this._currentSelectionSet = new Set();
|
|
|
+ for (const r of this.state.current.trajectories) this._currentSelectionSet.add(r.cell.transform.ref);
|
|
|
+ for (const r of this.state.current.models) this._currentSelectionSet.add(r.cell.transform.ref);
|
|
|
+ for (const r of this.state.current.structures) this._currentSelectionSet.add(r.cell.transform.ref);
|
|
|
+ return this._currentSelectionSet;
|
|
|
+ }
|
|
|
+
|
|
|
+ private syncCurrentTrajectories(hierarchy: StructureHierarchy, map: Map<StateTransform.Ref, HierarchyRef>): TrajectoryRef[] {
|
|
|
+ const current = this.state.current.trajectories;
|
|
|
if (current.length === 0) return hierarchy.trajectories.length > 0 ? [hierarchy.trajectories[0]] : [];
|
|
|
|
|
|
const newCurrent: TrajectoryRef[] = [];
|
|
|
for (const c of current) {
|
|
|
- const ref = hierarchy.refs.get(c.cell.transform.ref) as TrajectoryRef;
|
|
|
+ const ref = map.get(c.cell.transform.ref) as TrajectoryRef;
|
|
|
if (ref) newCurrent.push(ref);
|
|
|
}
|
|
|
|
|
@@ -47,13 +64,13 @@ export class StructureHierarchyManager extends PluginComponent<StructureHierarch
|
|
|
return newCurrent;
|
|
|
}
|
|
|
|
|
|
- private syncCurrentModels(hierarchy: StructureHierarchy, currentTrajectories: TrajectoryRef[]): ModelRef[] {
|
|
|
- const current = this.state.currentModels;
|
|
|
+ private syncCurrentModels(hierarchy: StructureHierarchy, map: Map<StateTransform.Ref, HierarchyRef>, currentTrajectories: TrajectoryRef[]): ModelRef[] {
|
|
|
+ const current = this.state.current.models;
|
|
|
if (current.length === 0) return currentTrajectories[0]?.models || [];
|
|
|
|
|
|
const newCurrent: ModelRef[] = [];
|
|
|
for (const c of current) {
|
|
|
- const ref = hierarchy.refs.get(c.cell.transform.ref) as ModelRef;
|
|
|
+ const ref = map.get(c.cell.transform.ref) as ModelRef;
|
|
|
if (ref) newCurrent.push(ref);
|
|
|
}
|
|
|
|
|
@@ -61,13 +78,13 @@ export class StructureHierarchyManager extends PluginComponent<StructureHierarch
|
|
|
return newCurrent;
|
|
|
}
|
|
|
|
|
|
- private syncCurrentStructures(hierarchy: StructureHierarchy, currentModels: ModelRef[]): StructureRef[] {
|
|
|
- const current = this.state.currentStructures;
|
|
|
+ private syncCurrentStructures(map: Map<StateTransform.Ref, HierarchyRef>, currentModels: ModelRef[]): StructureRef[] {
|
|
|
+ const current = this.state.current.structures;
|
|
|
if (current.length === 0) return Array.prototype.concat.apply([], currentModels.map(m => m.structures));
|
|
|
|
|
|
const newCurrent: StructureRef[] = [];
|
|
|
for (const c of current) {
|
|
|
- const ref = hierarchy.refs.get(c.cell.transform.ref) as StructureRef;
|
|
|
+ const ref = map.get(c.cell.transform.ref) as StructureRef;
|
|
|
if (ref) newCurrent.push(ref);
|
|
|
}
|
|
|
|
|
@@ -81,19 +98,40 @@ export class StructureHierarchyManager extends PluginComponent<StructureHierarch
|
|
|
return;
|
|
|
}
|
|
|
this._currentComponentGroups = void 0;
|
|
|
+ this._currentSelectionSet = void 0;
|
|
|
|
|
|
- const currentTrajectories = this.syncCurrentTrajectories(update.hierarchy);
|
|
|
- const currentModels = this.syncCurrentModels(update.hierarchy, currentTrajectories);
|
|
|
- const currentStructures = this.syncCurrentStructures(update.hierarchy, currentModels);
|
|
|
- console.log(currentTrajectories, currentModels, currentStructures);
|
|
|
- this.updateState({ hierarchy: update.hierarchy, currentModels, currentStructures, currentTrajectories });
|
|
|
-
|
|
|
- this.behaviors.current.next({
|
|
|
- hierarchy: update.hierarchy,
|
|
|
- trajectories: currentTrajectories,
|
|
|
- models: currentModels,
|
|
|
- structures: currentStructures
|
|
|
- });
|
|
|
+ const trajectories = this.syncCurrentTrajectories(update.hierarchy, update.hierarchy.refs);
|
|
|
+ const models = this.syncCurrentModels(update.hierarchy, update.hierarchy.refs, trajectories);
|
|
|
+ const structures = this.syncCurrentStructures(update.hierarchy.refs, models);
|
|
|
+
|
|
|
+ this.updateState({ hierarchy: update.hierarchy, current: { trajectories, models, structures }});
|
|
|
+ this.behaviors.current.next({ hierarchy: update.hierarchy, trajectories, models, structures });
|
|
|
+ }
|
|
|
+
|
|
|
+ updateCurrent(refs: HierarchyRef[], action: 'add' | 'remove') {
|
|
|
+
|
|
|
+ console.log(refs, action);
|
|
|
+
|
|
|
+ const hierarchy = this.state.hierarchy;
|
|
|
+ const map = new Map<StateTransform.Ref, HierarchyRef>();
|
|
|
+ const set = this.currentSeletionSet;
|
|
|
+ if (action === 'add') {
|
|
|
+ set.forEach(r => map.set(r, hierarchy.refs.get(r)!))
|
|
|
+ for (const r of refs) map.set(r.cell.transform.ref, r);
|
|
|
+ } else {
|
|
|
+ set.forEach(r => map.set(r, hierarchy.refs.get(r)!))
|
|
|
+ for (const r of refs) map.delete(r.cell.transform.ref);
|
|
|
+ }
|
|
|
+
|
|
|
+ const trajectories = this.syncCurrentTrajectories(hierarchy, map);
|
|
|
+ const models = this.syncCurrentModels(hierarchy, map, trajectories);
|
|
|
+ const structures = this.syncCurrentStructures(map, models);
|
|
|
+
|
|
|
+ this.updateState({ current: { trajectories, models, structures }});
|
|
|
+
|
|
|
+ console.log(this.state.current);
|
|
|
+
|
|
|
+ this.behaviors.current.next({ hierarchy, trajectories, models, structures });
|
|
|
}
|
|
|
|
|
|
remove(refs: HierarchyRef[]) {
|
|
@@ -103,12 +141,33 @@ export class StructureHierarchyManager extends PluginComponent<StructureHierarch
|
|
|
return this.plugin.runTask(this.plugin.state.dataState.updateTree(deletes));
|
|
|
}
|
|
|
|
|
|
+ createAllModels(trajectory: TrajectoryRef) {
|
|
|
+ return this.plugin.dataTransaction(async () => {
|
|
|
+ if (trajectory.models.length > 0) {
|
|
|
+ await this.clearTrajectory(trajectory);
|
|
|
+ }
|
|
|
+
|
|
|
+ const tr = trajectory.cell.obj?.data!;
|
|
|
+ for (let i = 0; i < tr.length; i++) {
|
|
|
+ const model = await this.plugin.builders.structure.createModel(trajectory.cell, { modelIndex: i });
|
|
|
+ const structure = await this.plugin.builders.structure.createStructure(model, { name: 'deposited', params: { } });
|
|
|
+ await this.plugin.builders.structure.representation.structurePreset(structure, 'auto');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ private clearTrajectory(trajectory: TrajectoryRef) {
|
|
|
+ const builder = this.dataState.build();
|
|
|
+ for (const m of trajectory.models) {
|
|
|
+ builder.delete(m.cell);
|
|
|
+ }
|
|
|
+ return this.plugin.runTask(this.dataState.updateTree(builder));
|
|
|
+ }
|
|
|
+
|
|
|
constructor(private plugin: PluginContext) {
|
|
|
super({
|
|
|
hierarchy: StructureHierarchy(),
|
|
|
- currentTrajectories: [],
|
|
|
- currentModels: [],
|
|
|
- currentStructures: []
|
|
|
+ current: { trajectories: [], models: [], structures: [] }
|
|
|
});
|
|
|
|
|
|
plugin.state.dataState.events.changed.subscribe(e => {
|