@3dbionotes/pdbe-molstar
Version:
Molstar implementation for PDBe
142 lines (141 loc) • 9.39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VolumeSourceCustomControls = void 0;
var tslib_1 = require("tslib");
var jsx_runtime_1 = require("react/jsx-runtime");
var mol_state_1 = require("molstar/lib/mol-state");
var base_1 = require("molstar/lib/mol-plugin-ui/base");
var action_menu_1 = require("molstar/lib/mol-plugin-ui/controls/action-menu");
var common_1 = require("molstar/lib/mol-plugin-ui/controls/common");
var update_transform_1 = require("molstar/lib/mol-plugin-ui/state/update-transform");
var commands_1 = require("molstar/lib/mol-plugin/commands");
var slider_1 = require("molstar/lib/mol-plugin-ui/controls/slider");
var objects_1 = require("molstar/lib/mol-plugin-state/objects");
var volume_1 = require("molstar/lib/mol-plugin-ui/structure/volume");
/* Custom volume button with EMDB url, base code from mol-plugin-ui/structure/volume.tsx */
var VolumeSourceCustomControls = /** @class */ (function (_super) {
tslib_1.__extends(VolumeSourceCustomControls, _super);
function VolumeSourceCustomControls() {
return _super !== null && _super.apply(this, arguments) || this;
}
VolumeSourceCustomControls.prototype.renderControls = function () {
var disabled = this.state.isBusy || this.isEmpty;
var label = this.label;
var selected = this.plugin.managers.volume.hierarchy.selection;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: "msp-flex-row", style: { marginTop: "1px" } }, { children: (0, jsx_runtime_1.jsx)(common_1.Button, tslib_1.__assign({ noOverflow: true, flex: true, onClick: this.toggleHierarchy, disabled: disabled, title: label }, { children: label })) })), this.state.show === "hierarchy" && ((0, jsx_runtime_1.jsx)(action_menu_1.ActionMenu, { items: this.hierarchyItems, onSelect: this.selectCurrent })), this.state.show === "add-repr" && (0, jsx_runtime_1.jsx)(action_menu_1.ActionMenu, { items: this.addActions, onSelect: this.selectAdd }), selected && selected.representations.length > 0 && ((0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { marginTop: "6px" } }, { children: selected.representations.map(function (r) { return ((0, jsx_runtime_1.jsx)(VolumeRepresentationCustomControls, { representation: r }, r.cell.transform.ref)); }) })))] }));
};
return VolumeSourceCustomControls;
}(volume_1.VolumeSourceControls));
exports.VolumeSourceCustomControls = VolumeSourceCustomControls;
/* Custom PDBe volume controls:
- Assume format 'dscif', binary.
- Assume volume URL contains detail=N
*/
var config = {
detail: { min: 0, max: 6, default: 3 },
};
var VolumeRepresentationCustomControls = /** @class */ (function (_super) {
tslib_1.__extends(VolumeRepresentationCustomControls, _super);
function VolumeRepresentationCustomControls() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = { action: undefined, detail: config.detail.default };
_this.remove = function () {
return _this.plugin.managers.volume.hierarchy.remove([_this.props.representation], true);
};
_this.toggleVisible = function (e) {
e.preventDefault();
e.currentTarget.blur();
_this.plugin.managers.volume.hierarchy.toggleVisibility([_this.props.representation]);
};
_this.highlight = function (e) {
e.preventDefault();
if (!_this.props.representation.cell.parent)
return;
commands_1.PluginCommands.Interactivity.Object.Highlight(_this.plugin, {
state: _this.props.representation.cell.parent,
ref: _this.props.representation.cell.transform.ref,
});
};
_this.clearHighlight = function (e) {
e.preventDefault();
commands_1.PluginCommands.Interactivity.ClearHighlights(_this.plugin);
};
_this.focus = function () {
var _a;
var repr = _this.props.representation;
var objects = (_a = _this.props.representation.cell.obj) === null || _a === void 0 ? void 0 : _a.data.repr.renderObjects;
if (repr.cell.state.isHidden)
_this.plugin.managers.volume.hierarchy.toggleVisibility([_this.props.representation], "show");
_this.plugin.managers.camera.focusRenderObjects(objects, { extraRadius: 1 });
};
_this.getInfo = function () {
var _a, _b, _c, _d, _e;
var state = _this.plugin.state.data;
var sourceRef = _this.props.representation.cell.sourceRef;
var base = {
dataCell: undefined,
url: undefined,
detail: undefined,
emdbId: undefined,
};
if (!sourceRef)
return base;
var dataCell = mol_state_1.StateSelection.findAncestorOfType(state.tree, state.cells, sourceRef, [
objects_1.PluginStateObject.Data.Binary,
]);
var url = (_b = (_a = dataCell === null || dataCell === void 0 ? void 0 : dataCell.params) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.url;
if (!dataCell) {
console.error("Cannot find data node for volume");
return base;
}
else if (!url) {
console.error("Cannot get URL for volume");
return tslib_1.__assign(tslib_1.__assign({}, base), { url: undefined });
}
else {
var detailStr = (_c = url.match(/detail=(\d+)/)) === null || _c === void 0 ? void 0 : _c[1];
var detailN = detailStr ? parseInt(detailStr) : NaN;
var detail = !Number.isNaN(detailN) ? detailN : undefined;
var emdbId = (_e = (_d = url.match(/emd-\d+/i)) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.toUpperCase();
return { dataCell: dataCell, url: url, detail: detail, emdbId: emdbId };
}
};
_this.setDetail = function (detail) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _a, url, dataCell, newUrl, params, state;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = this.getInfo(), url = _a.url, dataCell = _a.dataCell;
if (!dataCell || !url)
return [2 /*return*/];
this.setState({ detail: detail });
newUrl = url.replace(/detail=\d+/, "detail=".concat(detail));
params = { url: newUrl, isBinary: true, format: "dscif" };
state = this.plugin.state;
return [4 /*yield*/, state.updateTransform(state.data, dataCell.transform.ref, params)];
case 1:
_b.sent();
return [2 /*return*/];
}
});
}); };
return _this;
}
VolumeRepresentationCustomControls.prototype.componentDidMount = function () {
var _this = this;
var detail = this.getInfo().detail;
if (detail)
this.setState({ detail: detail });
this.subscribe(this.plugin.state.events.cell.stateUpdated, function (e) {
if (mol_state_1.State.ObjectEvent.isCell(e, _this.props.representation.cell))
_this.forceUpdate();
});
};
VolumeRepresentationCustomControls.prototype.render = function () {
var _a, _b, _c;
var repr = this.props.representation.cell;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(common_1.ControlRow, { label: "Detail", control: (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { display: "flex", textAlignLast: "center" } }, { children: (0, jsx_runtime_1.jsx)(slider_1.Slider, { value: this.state.detail, min: config.detail.min, max: config.detail.max, step: 1, onChange: this.setDetail }) })) }), (0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ className: "msp-flex-row" }, { children: (0, jsx_runtime_1.jsxs)(common_1.Button, tslib_1.__assign({ noOverflow: true, className: "msp-control-button-label", title: "".concat((_a = repr.obj) === null || _a === void 0 ? void 0 : _a.label, ". Click to focus."), onClick: this.focus, onMouseEnter: this.highlight, onMouseLeave: this.clearHighlight, style: { textAlign: "left" } }, { children: [(_b = repr.obj) === null || _b === void 0 ? void 0 : _b.label, (0, jsx_runtime_1.jsx)("small", tslib_1.__assign({ className: "msp-25-lower-contrast-text", style: { float: "right" } }, { children: (_c = repr.obj) === null || _c === void 0 ? void 0 : _c.description }))] })) })), repr.parent && ((0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ style: { marginBottom: "6px" }, className: "msp-accent-offset" }, { children: (0, jsx_runtime_1.jsx)(update_transform_1.UpdateTransformControl, { state: repr.parent, transform: repr.transform, customHeader: "none", noMargin: true }) })))] }));
};
return VolumeRepresentationCustomControls;
}(base_1.PurePluginUIComponent));
//# sourceMappingURL=pdbe-volume.js.map