UNPKG

molstar

Version:

A comprehensive macromolecular library.

291 lines 19.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MeasurementControls = exports.MeasurementList = exports.StructureMeasurementsControls = void 0; var tslib_1 = require("tslib"); var jsx_runtime_1 = require("react/jsx-runtime"); var loci_1 = require("../../mol-model/loci"); var measurement_1 = require("../../mol-plugin-state/manager/structure/measurement"); var commands_1 = require("../../mol-plugin/commands"); var label_1 = require("../../mol-theme/label"); var base_1 = require("../base"); var action_menu_1 = require("../controls/action-menu"); var common_1 = require("../controls/common"); var icons_1 = require("../controls/icons"); var parameters_1 = require("../controls/parameters"); var update_transform_1 = require("../state/update-transform"); var selection_1 = require("./selection"); // TODO details, options (e.g. change text for labels) var StructureMeasurementsControls = /** @class */ (function (_super) { (0, tslib_1.__extends)(StructureMeasurementsControls, _super); function StructureMeasurementsControls() { return _super !== null && _super.apply(this, arguments) || this; } StructureMeasurementsControls.prototype.defaultState = function () { return { isCollapsed: false, header: 'Measurements', brand: { accent: 'gray', svg: icons_1.PencilRulerSvg } }; }; StructureMeasurementsControls.prototype.renderControls = function () { return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MeasurementControls, {}, void 0), (0, jsx_runtime_1.jsx)(MeasurementList, {}, void 0)] }, void 0); }; return StructureMeasurementsControls; }(base_1.CollapsableControls)); exports.StructureMeasurementsControls = StructureMeasurementsControls; var MeasurementList = /** @class */ (function (_super) { (0, tslib_1.__extends)(MeasurementList, _super); function MeasurementList() { return _super !== null && _super.apply(this, arguments) || this; } MeasurementList.prototype.componentDidMount = function () { var _this = this; this.subscribe(this.plugin.managers.structure.measurement.behaviors.state, function () { _this.forceUpdate(); }); }; MeasurementList.prototype.renderGroup = function (cells, header) { var group = []; for (var _a = 0, cells_1 = cells; _a < cells_1.length; _a++) { var cell = cells_1[_a]; if (cell.obj) group.push((0, jsx_runtime_1.jsx)(MeasurementEntry, { cell: cell }, cell.obj.id)); } return group.length ? (0, jsx_runtime_1.jsx)(common_1.ExpandGroup, (0, tslib_1.__assign)({ header: header, initiallyExpanded: true }, { children: group }), void 0) : null; }; MeasurementList.prototype.render = function () { var measurements = this.plugin.managers.structure.measurement.state; return (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ style: { marginTop: '6px' } }, { children: [this.renderGroup(measurements.labels, 'Labels'), this.renderGroup(measurements.distances, 'Distances'), this.renderGroup(measurements.angles, 'Angles'), this.renderGroup(measurements.dihedrals, 'Dihedrals')] }), void 0); }; return MeasurementList; }(base_1.PurePluginUIComponent)); exports.MeasurementList = MeasurementList; var MeasurementControls = /** @class */ (function (_super) { (0, tslib_1.__extends)(MeasurementControls, _super); function MeasurementControls() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { isBusy: false, action: void 0 }; _this.measureDistance = function () { var loci = _this.plugin.managers.structure.selection.additionsHistory; _this.plugin.managers.structure.measurement.addDistance(loci[0].loci, loci[1].loci); }; _this.measureAngle = function () { var loci = _this.plugin.managers.structure.selection.additionsHistory; _this.plugin.managers.structure.measurement.addAngle(loci[0].loci, loci[1].loci, loci[2].loci); }; _this.measureDihedral = function () { var loci = _this.plugin.managers.structure.selection.additionsHistory; _this.plugin.managers.structure.measurement.addDihedral(loci[0].loci, loci[1].loci, loci[2].loci, loci[3].loci); }; _this.addLabel = function () { var loci = _this.plugin.managers.structure.selection.additionsHistory; _this.plugin.managers.structure.measurement.addLabel(loci[0].loci); }; _this.selectAction = function (item) { _this.toggleAdd(); if (!item) return; (item === null || item === void 0 ? void 0 : item.value)(); }; _this.toggleAdd = function () { return _this.setState({ action: _this.state.action === 'add' ? void 0 : 'add' }); }; _this.toggleOptions = function () { return _this.setState({ action: _this.state.action === 'options' ? void 0 : 'options' }); }; return _this; } MeasurementControls.prototype.componentDidMount = function () { var _this = this; this.subscribe(this.selection.events.additionsHistoryUpdated, function () { _this.forceUpdate(); }); this.subscribe(this.plugin.behaviors.state.isBusy, function (v) { _this.setState({ isBusy: v }); }); }; Object.defineProperty(MeasurementControls.prototype, "selection", { get: function () { return this.plugin.managers.structure.selection; }, enumerable: false, configurable: true }); Object.defineProperty(MeasurementControls.prototype, "actions", { get: function () { var history = this.selection.additionsHistory; var ret = [ { kind: 'item', label: "Label " + (history.length === 0 ? ' (1 selection required)' : ' (1st selection)'), value: this.addLabel, disabled: history.length === 0 }, { kind: 'item', label: "Distance " + (history.length < 2 ? ' (2 selections required)' : ' (top 2 selections)'), value: this.measureDistance, disabled: history.length < 2 }, { kind: 'item', label: "Angle " + (history.length < 3 ? ' (3 selections required)' : ' (top 3 selections)'), value: this.measureAngle, disabled: history.length < 3 }, { kind: 'item', label: "Dihedral " + (history.length < 4 ? ' (4 selections required)' : ' (top 4 selections)'), value: this.measureDihedral, disabled: history.length < 4 }, ]; return ret; }, enumerable: false, configurable: true }); MeasurementControls.prototype.highlight = function (loci) { this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci: loci }, false); }; MeasurementControls.prototype.moveHistory = function (e, direction) { this.plugin.managers.structure.selection.modifyHistory(e, direction, 4); }; MeasurementControls.prototype.focusLoci = function (loci) { this.plugin.managers.camera.focusLoci(loci); }; MeasurementControls.prototype.historyEntry = function (e, idx) { var _this = this; var history = this.plugin.managers.structure.selection.additionsHistory; return (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-flex-row' }, { children: [(0, jsx_runtime_1.jsxs)(common_1.Button, (0, tslib_1.__assign)({ noOverflow: true, title: 'Click to focus. Hover to highlight.', onClick: function () { return _this.focusLoci(e.loci); }, style: { width: 'auto', textAlign: 'left' }, onMouseEnter: function () { return _this.highlight(e.loci); }, onMouseLeave: function () { return _this.plugin.managers.interactivity.lociHighlights.clearHighlights(); } }, { children: [idx, ". ", (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: e.label } }, void 0)] }), void 0), history.length > 1 && (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.ArrowUpwardSvg, small: true, className: 'msp-form-control', onClick: function () { return _this.moveHistory(e, 'up'); }, flex: '20px', title: 'Move up' }, void 0), history.length > 1 && (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.ArrowDownwardSvg, small: true, className: 'msp-form-control', onClick: function () { return _this.moveHistory(e, 'down'); }, flex: '20px', title: 'Move down' }, void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.DeleteOutlinedSvg, small: true, className: 'msp-form-control', onClick: function () { return _this.plugin.managers.structure.selection.modifyHistory(e, 'remove'); }, flex: true, title: 'Remove' }, void 0)] }), e.id); }; MeasurementControls.prototype.add = function () { var history = this.plugin.managers.structure.selection.additionsHistory; var entries = []; for (var i = 0, _i = Math.min(history.length, 4); i < _i; i++) { entries.push(this.historyEntry(history[i], i + 1)); } return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(action_menu_1.ActionMenu, { items: this.actions, onSelect: this.selectAction }, void 0), entries.length > 0 && (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-control-offset' }, { children: entries }), void 0), entries.length === 0 && (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-control-offset msp-help-text' }, { children: (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-help-description' }, { children: [(0, jsx_runtime_1.jsx)(icons_1.Icon, { svg: icons_1.HelpOutlineSvg, inline: true }, void 0), "Add one or more selections (toggle ", (0, jsx_runtime_1.jsx)(selection_1.ToggleSelectionModeButton, { inline: true }, void 0), " mode)"] }), void 0) }), void 0)] }, void 0); }; MeasurementControls.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-flex-row' }, { children: [(0, jsx_runtime_1.jsx)(common_1.ToggleButton, { icon: icons_1.AddSvg, label: 'Add', toggle: this.toggleAdd, isSelected: this.state.action === 'add', disabled: this.state.isBusy, className: 'msp-btn-apply-simple' }, void 0), (0, jsx_runtime_1.jsx)(common_1.ToggleButton, { icon: icons_1.TuneSvg, label: '', title: 'Options', toggle: this.toggleOptions, isSelected: this.state.action === 'options', disabled: this.state.isBusy, style: { flex: '0 0 40px', padding: 0 } }, void 0)] }), void 0), this.state.action === 'add' && this.add(), this.state.action === 'options' && (0, jsx_runtime_1.jsx)(MeasurementsOptions, {}, void 0)] }, void 0); }; return MeasurementControls; }(base_1.PurePluginUIComponent)); exports.MeasurementControls = MeasurementControls; var MeasurementsOptions = /** @class */ (function (_super) { (0, tslib_1.__extends)(MeasurementsOptions, _super); function MeasurementsOptions() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { isDisabled: false }; _this.changed = function (options) { _this.plugin.managers.structure.measurement.setOptions(options); }; return _this; } MeasurementsOptions.prototype.componentDidMount = function () { var _this = this; this.subscribe(this.plugin.managers.structure.measurement.behaviors.state, function () { _this.forceUpdate(); }); this.subscribe(this.plugin.behaviors.state.isBusy, function (v) { _this.setState({ isDisabled: v }); }); }; MeasurementsOptions.prototype.render = function () { var measurements = this.plugin.managers.structure.measurement.state; return (0, jsx_runtime_1.jsx)("div", (0, tslib_1.__assign)({ className: 'msp-control-offset' }, { children: (0, jsx_runtime_1.jsx)(parameters_1.ParameterControls, { params: measurement_1.StructureMeasurementParams, values: measurements.options, onChangeValues: this.changed, isDisabled: this.state.isDisabled }, void 0) }), void 0); }; return MeasurementsOptions; }(base_1.PurePluginUIComponent)); var MeasurementEntry = /** @class */ (function (_super) { (0, tslib_1.__extends)(MeasurementEntry, _super); function MeasurementEntry() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { showUpdate: false }; _this.delete = function () { commands_1.PluginCommands.State.RemoveObject(_this.plugin, { state: _this.props.cell.parent, ref: _this.props.cell.transform.parent, removeParentGhosts: true }); }; _this.toggleVisibility = function (e) { e.preventDefault(); commands_1.PluginCommands.State.ToggleVisibility(_this.plugin, { state: _this.props.cell.parent, ref: _this.props.cell.transform.parent }); e.currentTarget.blur(); }; _this.highlight = function () { var _a; var selections = _this.selections; if (!selections) return; _this.plugin.managers.interactivity.lociHighlights.clearHighlights(); for (var _b = 0, _c = _this.lociArray; _b < _c.length; _b++) { var loci = _c[_b]; _this.plugin.managers.interactivity.lociHighlights.highlight({ loci: loci }, false); } _this.plugin.managers.interactivity.lociHighlights.highlight({ loci: (_a = _this.props.cell.obj) === null || _a === void 0 ? void 0 : _a.data.repr.getLoci() }, false); }; _this.clearHighlight = function () { _this.plugin.managers.interactivity.lociHighlights.clearHighlights(); }; _this.toggleUpdate = function () { return _this.setState({ showUpdate: !_this.state.showUpdate }); }; _this.focus = function () { var selections = _this.selections; if (!selections) return; var sphere = loci_1.Loci.getBundleBoundingSphere({ loci: _this.lociArray }); if (sphere) { _this.plugin.managers.camera.focusSphere(sphere); } }; _this.selectAction = function (item) { if (!item) return; _this.setState({ showUpdate: false }); (item === null || item === void 0 ? void 0 : item.value)(); }; return _this; } MeasurementEntry.prototype.componentDidMount = function () { var _this = this; this.subscribe(this.plugin.state.events.cell.stateUpdated, function (e) { _this.forceUpdate(); }); }; Object.defineProperty(MeasurementEntry.prototype, "selections", { get: function () { var _a; return (_a = this.props.cell.obj) === null || _a === void 0 ? void 0 : _a.data.sourceData; }, enumerable: false, configurable: true }); Object.defineProperty(MeasurementEntry.prototype, "lociArray", { get: function () { var selections = this.selections; if (!selections) return []; if (selections.infos) return [selections.infos[0].loci]; if (selections.pairs) return selections.pairs[0].loci; if (selections.triples) return selections.triples[0].loci; if (selections.quads) return selections.quads[0].loci; return []; }, enumerable: false, configurable: true }); Object.defineProperty(MeasurementEntry.prototype, "label", { get: function () { var selections = this.selections; if (!selections) return '<empty>'; if (selections.infos) return (0, label_1.lociLabel)(selections.infos[0].loci, { condensed: true }); if (selections.pairs) return (0, label_1.distanceLabel)(selections.pairs[0], { condensed: true, unitLabel: this.plugin.managers.structure.measurement.state.options.distanceUnitLabel }); if (selections.triples) return (0, label_1.angleLabel)(selections.triples[0], { condensed: true }); if (selections.quads) return (0, label_1.dihedralLabel)(selections.quads[0], { condensed: true }); return '<empty>'; }, enumerable: false, configurable: true }); Object.defineProperty(MeasurementEntry.prototype, "actions", { get: function () { var _this = this; this.props.cell.sourceRef; return [action_menu_1.ActionMenu.Item('Select This', function () { return _this.plugin.managers.structure.selection.fromSelections(_this.props.cell.sourceRef); }, { icon: icons_1.SetSvg })]; }, enumerable: false, configurable: true }); MeasurementEntry.prototype.render = function () { var cell = this.props.cell; var obj = cell.obj; if (!obj) return null; return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-flex-row', onMouseEnter: this.highlight, onMouseLeave: this.clearHighlight }, { children: [(0, jsx_runtime_1.jsx)("button", (0, tslib_1.__assign)({ className: 'msp-form-control msp-control-button-label msp-no-overflow', title: 'Click to focus. Hover to highlight.', onClick: this.focus, style: { width: 'auto', textAlign: 'left' } }, { children: (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: this.label } }, void 0) }), void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: cell.state.isHidden ? icons_1.VisibilityOffOutlinedSvg : icons_1.VisibilityOutlinedSvg, toggleState: false, small: true, className: 'msp-form-control', onClick: this.toggleVisibility, flex: true, title: cell.state.isHidden ? 'Show' : 'Hide' }, void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.DeleteOutlinedSvg, small: true, className: 'msp-form-control', onClick: this.delete, flex: true, title: 'Delete', toggleState: false }, void 0), (0, jsx_runtime_1.jsx)(common_1.IconButton, { svg: icons_1.MoreHorizSvg, className: 'msp-form-control', onClick: this.toggleUpdate, flex: true, title: 'Actions', toggleState: this.state.showUpdate }, void 0)] }), obj.id), this.state.showUpdate && cell.parent && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("div", (0, tslib_1.__assign)({ className: 'msp-accent-offset' }, { children: [(0, jsx_runtime_1.jsx)(action_menu_1.ActionMenu, { items: this.actions, onSelect: this.selectAction, noOffset: true }, void 0), (0, jsx_runtime_1.jsx)(common_1.ExpandGroup, (0, tslib_1.__assign)({ header: 'Options', noOffset: true }, { children: (0, jsx_runtime_1.jsx)(update_transform_1.UpdateTransformControl, { state: cell.parent, transform: cell.transform, customHeader: 'none', autoHideApply: true }, void 0) }), void 0)] }), void 0) }, void 0)] }, void 0); }; return MeasurementEntry; }(base_1.PurePluginUIComponent)); //# sourceMappingURL=measurements.js.map