UNPKG

molstar

Version:

A comprehensive macromolecular library.

176 lines (175 loc) 8.08 kB
"use strict"; /** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.StructureFocusManager = void 0; var tslib_1 = require("tslib"); var component_1 = require("../../component"); var array_1 = require("../../../mol-util/array"); var structure_1 = require("../../../mol-model/structure"); var loci_1 = require("../../../mol-model/loci"); var label_1 = require("../../../mol-theme/label"); var objects_1 = require("../../objects"); var mol_state_1 = require("../../../mol-state"); var linear_algebra_1 = require("../../../mol-math/linear-algebra"); var geometry_1 = require("../../../mol-math/geometry"); var HISTORY_CAPACITY = 8; var StructureFocusManager = /** @class */ (function (_super) { tslib_1.__extends(StructureFocusManager, _super); function StructureFocusManager(plugin) { var _this = _super.call(this, { history: [] }) || this; _this.plugin = plugin; _this.events = { historyUpdated: _this.ev() }; _this.behaviors = { current: _this.ev.behavior(void 0) }; plugin.state.data.events.object.removed.subscribe(function (_a) { var _b; var _c; var obj = _a.obj; if (!objects_1.PluginStateObject.Molecule.Structure.is(obj)) return; if (((_c = _this.current) === null || _c === void 0 ? void 0 : _c.loci.structure) === obj.data) { _this.clear(); } var keep = []; for (var _i = 0, _d = _this.history; _i < _d.length; _i++) { var e = _d[_i]; if (e.loci.structure === obj.data) keep.push(e); } if (keep.length !== _this.history.length) { _this.history.length = 0; (_b = _this.history).push.apply(_b, keep); _this.events.historyUpdated.next(void 0); } }); var sphere = (0, geometry_1.Sphere3D)(); plugin.state.data.events.object.updated.subscribe(function (_a) { var _b; var oldData = _a.oldData, obj = _a.obj, action = _a.action; if (!objects_1.PluginStateObject.Molecule.Structure.is(obj)) return; // structure NOT changed, keep everything as is; fixes #123 if (oldData === obj.data) return; // structure changed (e.g. coordinates), try to remap and re-focus if (action === 'in-place') { var current = _this.state.current; var structure = obj.data; if (current && current.loci.structure === oldData) { var loci = structure_1.StructureElement.Loci.remap(current.loci, structure); _this.state.current = tslib_1.__assign(tslib_1.__assign({}, current), { loci: loci }); _this.behaviors.current.next(_this.state.current); loci_1.Loci.getBoundingSphere(loci, sphere); var camera = (_b = _this.plugin.canvas3d) === null || _b === void 0 ? void 0 : _b.camera; var d = camera.getTargetDistance(sphere.radius + 4); // default extraRadius if (linear_algebra_1.Vec3.distance(camera.target, sphere.center) > sphere.radius || d > camera.viewport.height / camera.zoom) { _this.plugin.managers.camera.focusSphere(sphere, { durationMs: 0 }); } } // TODO remap history as well } }); return _this; } Object.defineProperty(StructureFocusManager.prototype, "current", { get: function () { return this.state.current; }, enumerable: false, configurable: true }); Object.defineProperty(StructureFocusManager.prototype, "history", { get: function () { return this.state.history; }, enumerable: false, configurable: true }); StructureFocusManager.prototype.tryAddHistory = function (entry) { if (structure_1.StructureElement.Loci.isEmpty(entry.loci)) return; var idx = 0, existingEntry = void 0; for (var _i = 0, _a = this.state.history; _i < _a.length; _i++) { var e = _a[_i]; if (structure_1.StructureElement.Loci.areEqual(e.loci, entry.loci)) { existingEntry = e; break; } idx++; } if (existingEntry) { // move to top, use new (0, array_1.arrayRemoveAtInPlace)(this.state.history, idx); this.state.history.unshift(entry); this.events.historyUpdated.next(void 0); return; } this.state.history.unshift(entry); if (this.state.history.length > HISTORY_CAPACITY) this.state.history.pop(); this.events.historyUpdated.next(void 0); }; StructureFocusManager.prototype.set = function (entry) { this.tryAddHistory(entry); if (!this.state.current || !structure_1.StructureElement.Loci.areEqual(this.state.current.loci, entry.loci)) { this.state.current = entry; this.behaviors.current.next(entry); } }; StructureFocusManager.prototype.setFromLoci = function (anyLoci) { var loci = loci_1.Loci.normalize(anyLoci); if (!structure_1.StructureElement.Loci.is(loci) || structure_1.StructureElement.Loci.isEmpty(loci)) { this.clear(); return; } this.set({ loci: loci, label: (0, label_1.lociLabel)(loci, { reverse: true, hidePrefix: true, htmlStyling: false }) }); }; StructureFocusManager.prototype.addFromLoci = function (anyLoci) { var union = this.state.current && structure_1.StructureElement.Loci.is(anyLoci) && anyLoci.structure === this.state.current.loci.structure ? structure_1.StructureElement.Loci.union(anyLoci, this.state.current.loci) : anyLoci; this.setFromLoci(union); }; StructureFocusManager.prototype.clear = function () { if (this.state.current) { this.state.current = undefined; this.behaviors.current.next(void 0); } }; StructureFocusManager.prototype.getSnapshot = function () { if (!this.current) return {}; var node = this.plugin.helpers.substructureParent.get(this.current.loci.structure); var ref = node === null || node === void 0 ? void 0 : node.transform.ref; if (!ref) return {}; return { current: { label: this.current.label, ref: ref, bundle: structure_1.StructureElement.Bundle.fromLoci(this.current.loci), category: this.current.category } }; }; StructureFocusManager.prototype.setSnapshot = function (snapshot) { var _a, _b; if (!snapshot.current) { this.clear(); return; } var _c = snapshot.current, label = _c.label, ref = _c.ref, bundle = _c.bundle, category = _c.category; var structure = (_b = (_a = this.plugin.state.data.select(mol_state_1.StateSelection.Generators.byRef(ref))[0]) === null || _a === void 0 ? void 0 : _a.obj) === null || _b === void 0 ? void 0 : _b.data; if (!structure) return; var loci = structure_1.StructureElement.Bundle.toLoci(bundle, structure); this.set({ label: label, loci: loci, category: category }); }; return StructureFocusManager; }(component_1.StatefulPluginComponent)); exports.StructureFocusManager = StructureFocusManager;