molstar
Version:
A comprehensive macromolecular library.
301 lines • 18.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultStructureTools = exports.CustomStructureControls = exports.LociLabels = exports.SelectionViewportControls = exports.AnimationViewportControls = exports.StateSnapshotViewportControls = exports.TrajectoryViewportControls = void 0;
var tslib_1 = require("tslib");
var jsx_runtime_1 = require("react/jsx-runtime");
var structure_1 = require("../mol-plugin-state/actions/structure");
var transforms_1 = require("../mol-plugin-state/transforms");
var commands_1 = require("../mol-plugin/commands");
var base_1 = require("./base");
var common_1 = require("./controls/common");
var icons_1 = require("./controls/icons");
var animation_1 = require("./state/animation");
var components_1 = require("./structure/components");
var measurements_1 = require("./structure/measurements");
var selection_1 = require("./structure/selection");
var source_1 = require("./structure/source");
var volume_1 = require("./structure/volume");
var config_1 = require("../mol-plugin/config");
var superposition_1 = require("./structure/superposition");
var TrajectoryViewportControls = /** @class */ (function (_super) {
(0, tslib_1.__extends)(TrajectoryViewportControls, _super);
function TrajectoryViewportControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = { show: false, label: '' };
_this.update = function () {
var state = _this.plugin.state.data;
var models = state.selectQ(function (q) { return q.ofTransformer(transforms_1.StateTransforms.Model.ModelFromTrajectory); });
if (models.length === 0) {
_this.setState({ show: false });
return;
}
var label = '', count = 0;
var parents = new Set();
for (var _i = 0, models_1 = models; _i < models_1.length; _i++) {
var m = models_1[_i];
if (!m.sourceRef)
continue;
var parent_1 = state.cells.get(m.sourceRef).obj;
if (!parent_1)
continue;
if (parent_1.data.frameCount > 1) {
if (parents.has(m.sourceRef)) {
// do not show the controls if there are 2 models of the same trajectory present
_this.setState({ show: false });
return;
}
parents.add(m.sourceRef);
count++;
if (!label) {
var idx = m.transform.params.modelIndex;
label = "Model " + (idx + 1) + " / " + parent_1.data.frameCount;
}
}
}
if (count > 1)
label = '';
_this.setState({ show: count > 0, label: label });
};
_this.reset = function () { return commands_1.PluginCommands.State.ApplyAction(_this.plugin, {
state: _this.plugin.state.data,
action: structure_1.UpdateTrajectory.create({ action: 'reset' })
}); };
_this.prev = function () { return commands_1.PluginCommands.State.ApplyAction(_this.plugin, {
state: _this.plugin.state.data,
action: structure_1.UpdateTrajectory.create({ action: 'advance', by: -1 })
}); };
_this.next = function () { return commands_1.PluginCommands.State.ApplyAction(_this.plugin, {
state: _this.plugin.state.data,
action: structure_1.UpdateTrajectory.create({ action: 'advance', by: 1 })
}); };
return _this;
}
TrajectoryViewportControls.prototype.componentDidMount = function () {
this.subscribe(this.plugin.state.data.events.changed, this.update);
this.subscribe(this.plugin.behaviors.state.isAnimating, this.update);
};
TrajectoryViewportControls.prototype.render = function () {
var isAnimating = this.plugin.behaviors.state.isAnimating.value;
if (!this.state.show || (isAnimating && !this.state.label))
return null;
return (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-traj-controls' }, { children: [!isAnimating && (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.SkipPreviousSvg, title: 'First Model', onClick: this.reset, disabled: isAnimating }, void 0), !isAnimating && (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.NavigateBeforeSvg, title: 'Previous Model', onClick: this.prev, disabled: isAnimating }, void 0), !isAnimating && (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.NavigateNextSvg, title: 'Next Model', onClick: this.next, disabled: isAnimating }, void 0), !!this.state.label && (0, jsx_runtime_1.jsx)("span", { children: this.state.label }, void 0)] }), void 0);
};
return TrajectoryViewportControls;
}(base_1.PluginUIComponent));
exports.TrajectoryViewportControls = TrajectoryViewportControls;
var StateSnapshotViewportControls = /** @class */ (function (_super) {
(0, tslib_1.__extends)(StateSnapshotViewportControls, _super);
function StateSnapshotViewportControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = { isBusy: false, show: true };
_this.keyUp = function (e) {
if (!e.ctrlKey || _this.state.isBusy || e.target !== document.body)
return;
var snapshots = _this.plugin.managers.snapshot;
if (e.keyCode === 37 || e.key === 'ArrowLeft') {
if (snapshots.state.isPlaying)
snapshots.stop();
_this.prev();
}
else if (e.keyCode === 38 || e.key === 'ArrowUp') {
if (snapshots.state.isPlaying)
snapshots.stop();
if (snapshots.state.entries.size === 0)
return;
var e_1 = snapshots.state.entries.get(0);
_this.update(e_1.snapshot.id);
}
else if (e.keyCode === 39 || e.key === 'ArrowRight') {
if (snapshots.state.isPlaying)
snapshots.stop();
_this.next();
}
else if (e.keyCode === 40 || e.key === 'ArrowDown') {
if (snapshots.state.isPlaying)
snapshots.stop();
if (snapshots.state.entries.size === 0)
return;
var e_2 = snapshots.state.entries.get(snapshots.state.entries.size - 1);
_this.update(e_2.snapshot.id);
}
};
_this.change = function (e) {
if (e.target.value === 'none')
return;
_this.update(e.target.value);
};
_this.prev = function () {
var s = _this.plugin.managers.snapshot;
var id = s.getNextId(s.state.current, -1);
if (id)
_this.update(id);
};
_this.next = function () {
var s = _this.plugin.managers.snapshot;
var id = s.getNextId(s.state.current, 1);
if (id)
_this.update(id);
};
_this.togglePlay = function () {
_this.plugin.managers.snapshot.togglePlay();
};
return _this;
}
StateSnapshotViewportControls.prototype.componentDidMount = function () {
var _this = this;
// TODO: this needs to be diabled when the state is updating!
this.subscribe(this.plugin.managers.snapshot.events.changed, function () { return _this.forceUpdate(); });
this.subscribe(this.plugin.behaviors.state.isBusy, function (isBusy) { return _this.setState({ isBusy: isBusy }); });
this.subscribe(this.plugin.behaviors.state.isAnimating, function (isBusy) { return _this.setState({ isBusy: isBusy }); });
window.addEventListener('keyup', this.keyUp, false);
};
StateSnapshotViewportControls.prototype.componentWillUnmount = function () {
_super.prototype.componentWillUnmount.call(this);
window.removeEventListener('keyup', this.keyUp, false);
};
StateSnapshotViewportControls.prototype.update = function (id) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0:
this.setState({ isBusy: true });
return [4 /*yield*/, commands_1.PluginCommands.State.Snapshots.Apply(this.plugin, { id: id })];
case 1:
_a.sent();
this.setState({ isBusy: false });
return [2 /*return*/];
}
});
});
};
StateSnapshotViewportControls.prototype.render = function () {
var snapshots = this.plugin.managers.snapshot;
var count = snapshots.state.entries.size;
if (count < 2 || !this.state.show) {
return null;
}
var current = snapshots.state.current;
var isPlaying = snapshots.state.isPlaying;
return (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-state-snapshot-viewport-controls' }, { children: [(0, jsx_runtime_1.jsxs)("select", (0, tslib_1.__assign)({ className: 'msp-form-control', value: current || 'none', onChange: this.change, disabled: this.state.isBusy || isPlaying }, { children: [!current && (0, jsx_runtime_1.jsx)("option", { value: 'none' }, 'none'), snapshots.state.entries.valueSeq().map(function (e, i) { return (0, jsx_runtime_1.jsxs)("option", (0, tslib_1.__assign)({ value: e.snapshot.id }, { children: ["[" + (i + 1) + "/" + count + "]", " ", e.name || new Date(e.timestamp).toLocaleString()] }), e.snapshot.id); })] }), void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: isPlaying ? icons_1.StopSvg : icons_1.PlayArrowSvg, title: isPlaying ? 'Pause' : 'Cycle States', onClick: this.togglePlay, disabled: isPlaying ? false : this.state.isBusy }, void 0), !isPlaying && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.NavigateBeforeSvg, title: 'Previous State', onClick: this.prev, disabled: this.state.isBusy || isPlaying }, void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.NavigateNextSvg, title: 'Next State', onClick: this.next, disabled: this.state.isBusy || isPlaying }, void 0)] }, void 0)] }), void 0);
};
return StateSnapshotViewportControls;
}(base_1.PluginUIComponent));
exports.StateSnapshotViewportControls = StateSnapshotViewportControls;
var AnimationViewportControls = /** @class */ (function (_super) {
(0, tslib_1.__extends)(AnimationViewportControls, _super);
function AnimationViewportControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = { isEmpty: true, isExpanded: false, isBusy: false, isAnimating: false, isPlaying: false };
_this.toggleExpanded = function () { return _this.setState({ isExpanded: !_this.state.isExpanded }); };
_this.stop = function () {
_this.plugin.managers.animation.stop();
_this.plugin.managers.snapshot.stop();
};
return _this;
}
AnimationViewportControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.managers.snapshot.events.changed, function () {
if (_this.plugin.managers.snapshot.state.isPlaying)
_this.setState({ isPlaying: true, isExpanded: false });
else
_this.setState({ isPlaying: false });
});
this.subscribe(this.plugin.behaviors.state.isBusy, function (isBusy) {
if (isBusy)
_this.setState({ isBusy: true, isExpanded: false, isEmpty: _this.plugin.state.data.tree.transforms.size < 2 });
else
_this.setState({ isBusy: false, isEmpty: _this.plugin.state.data.tree.transforms.size < 2 });
});
this.subscribe(this.plugin.behaviors.state.isAnimating, function (isAnimating) {
if (isAnimating)
_this.setState({ isAnimating: true, isExpanded: false });
else
_this.setState({ isAnimating: false });
});
};
AnimationViewportControls.prototype.render = function () {
var isPlaying = this.plugin.managers.snapshot.state.isPlaying;
if (isPlaying || this.state.isEmpty || this.plugin.managers.animation.isEmpty || !this.plugin.config.get(config_1.PluginConfig.Viewport.ShowAnimation))
return null;
var isAnimating = this.state.isAnimating;
return (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-animation-viewport-controls' }, { children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: 'msp-semi-transparent-background' }, void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: isAnimating || isPlaying ? icons_1.StopSvg : icons_1.SubscriptionsOutlinedSvg, transparent: true, title: isAnimating ? 'Stop' : 'Select Animation', onClick: isAnimating || isPlaying ? this.stop : this.toggleExpanded, toggleState: this.state.isExpanded, disabled: isAnimating || isPlaying ? false : this.state.isBusy || this.state.isPlaying || this.state.isEmpty }, void 0)] }, void 0), (this.state.isExpanded && !this.state.isBusy) && (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-animation-viewport-controls-select' }, { children: (0, jsx_runtime_1.jsx)(animation_1.AnimationControls, { onStart: this.toggleExpanded }, void 0) }), void 0)] }), void 0);
};
return AnimationViewportControls;
}(base_1.PluginUIComponent));
exports.AnimationViewportControls = AnimationViewportControls;
var SelectionViewportControls = /** @class */ (function (_super) {
(0, tslib_1.__extends)(SelectionViewportControls, _super);
function SelectionViewportControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.onMouseMove = function (e) {
// ignore mouse moves when no button is held
if (e.buttons === 0)
e.stopPropagation();
};
return _this;
}
SelectionViewportControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.behaviors.interaction.selectionMode, function () { return _this.forceUpdate(); });
};
SelectionViewportControls.prototype.render = function () {
if (!this.plugin.selectionMode)
return null;
return (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-selection-viewport-controls', onMouseMove: this.onMouseMove }, { children: (0, jsx_runtime_1.jsx)(selection_1.StructureSelectionActionsControls, {}, void 0) }), void 0);
};
return SelectionViewportControls;
}(base_1.PluginUIComponent));
exports.SelectionViewportControls = SelectionViewportControls;
var LociLabels = /** @class */ (function (_super) {
(0, tslib_1.__extends)(LociLabels, _super);
function LociLabels() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = { labels: [] };
return _this;
}
LociLabels.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.behaviors.labels.highlight, function (e) { return _this.setState({ labels: e.labels }); });
};
LociLabels.prototype.render = function () {
if (this.state.labels.length === 0) {
return null;
}
return (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-highlight-info' }, { children: this.state.labels.map(function (e, i) { return (0, jsx_runtime_1.jsx)("div", { dangerouslySetInnerHTML: { __html: e } }, '' + i); }) }), void 0);
};
return LociLabels;
}(base_1.PluginUIComponent));
exports.LociLabels = LociLabels;
var CustomStructureControls = /** @class */ (function (_super) {
(0, tslib_1.__extends)(CustomStructureControls, _super);
function CustomStructureControls() {
return _super !== null && _super.apply(this, arguments) || this;
}
CustomStructureControls.prototype.componentDidMount = function () {
var _this = this;
this.subscribe(this.plugin.state.behaviors.events.changed, function () { return _this.forceUpdate(); });
};
CustomStructureControls.prototype.render = function () {
var _this = this;
var controls = [];
this.plugin.customStructureControls.forEach(function (Controls, key) {
controls.push((0, jsx_runtime_1.jsx)(Controls, { initiallyCollapsed: _this.props.initiallyCollapsed }, key));
});
return controls.length > 0 ? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: controls }, void 0) : null;
};
return CustomStructureControls;
}(base_1.PluginUIComponent));
exports.CustomStructureControls = CustomStructureControls;
var DefaultStructureTools = /** @class */ (function (_super) {
(0, tslib_1.__extends)(DefaultStructureTools, _super);
function DefaultStructureTools() {
return _super !== null && _super.apply(this, arguments) || this;
}
DefaultStructureTools.prototype.render = function () {
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-section-header' }, { children: [(0, jsx_runtime_1.jsx)(icons_1.Icon, { svg: icons_1.BuildSvg }, void 0), "Structure Tools"] }), void 0), (0, jsx_runtime_1.jsx)(source_1.StructureSourceControls, {}, void 0), (0, jsx_runtime_1.jsx)(measurements_1.StructureMeasurementsControls, {}, void 0), (0, jsx_runtime_1.jsx)(superposition_1.StructureSuperpositionControls, {}, void 0), (0, jsx_runtime_1.jsx)(components_1.StructureComponentControls, {}, void 0), this.plugin.config.get(config_1.PluginConfig.VolumeStreaming.Enabled) && (0, jsx_runtime_1.jsx)(volume_1.VolumeStreamingControls, {}, void 0), (0, jsx_runtime_1.jsx)(volume_1.VolumeSourceControls, {}, void 0), (0, jsx_runtime_1.jsx)(CustomStructureControls, {}, void 0)] }, void 0);
};
return DefaultStructureTools;
}(base_1.PluginUIComponent));
exports.DefaultStructureTools = DefaultStructureTools;
//# sourceMappingURL=controls.js.map