molstar
Version:
A comprehensive macromolecular library.
268 lines (267 loc) • 13.7 kB
JavaScript
"use strict";
/**
* Copyright (c) 2019-2021 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.InteractivityManager = void 0;
var tslib_1 = require("tslib");
var loci_1 = require("../../mol-model/loci");
var structure_1 = require("../../mol-model/structure");
var representation_1 = require("../../mol-repr/representation");
var marker_action_1 = require("../../mol-util/marker-action");
var object_1 = require("../../mol-util/object");
var param_definition_1 = require("../../mol-util/param-definition");
var component_1 = require("../component");
// TODO: make this customizable somewhere?
var DefaultInteractivityFocusOptions = {
minRadius: 6,
extraRadius: 6,
durationMs: 250,
};
var InteractivityManager = /** @class */ (function (_super) {
tslib_1.__extends(InteractivityManager, _super);
function InteractivityManager(plugin, props) {
if (props === void 0) { props = {}; }
var _this = _super.call(this, { props: tslib_1.__assign(tslib_1.__assign({}, param_definition_1.ParamDefinition.getDefaultValues(InteractivityManager.Params)), props) }) || this;
_this.plugin = plugin;
_this._props = param_definition_1.ParamDefinition.getDefaultValues(InteractivityManager.Params);
_this.events = {
propsUpdated: _this.ev()
};
_this.lociSelects = new InteractivityManager.LociSelectManager(plugin, _this._props);
_this.lociHighlights = new InteractivityManager.LociHighlightManager(plugin, _this._props);
return _this;
}
Object.defineProperty(InteractivityManager.prototype, "props", {
get: function () { return tslib_1.__assign({}, this.state.props); },
enumerable: false,
configurable: true
});
InteractivityManager.prototype.setProps = function (props) {
var old = this.props;
var _new = tslib_1.__assign(tslib_1.__assign({}, this.state.props), props);
if ((0, object_1.shallowEqual)(old, _new))
return;
this.updateState({ props: _new });
this.lociSelects.setProps(_new);
this.lociHighlights.setProps(_new);
this.events.propsUpdated.next(void 0);
};
return InteractivityManager;
}(component_1.StatefulPluginComponent));
exports.InteractivityManager = InteractivityManager;
(function (InteractivityManager) {
InteractivityManager.Params = {
granularity: param_definition_1.ParamDefinition.Select('residue', loci_1.Loci.GranularityOptions, { label: 'Picking Level', description: 'Controls if selections are expanded upon picking to whole residues, chains, structures, instances, or left as atoms and coarse elements' }),
};
var LociMarkManager = /** @class */ (function () {
function LociMarkManager(ctx, props) {
if (props === void 0) { props = {}; }
this.ctx = ctx;
this.providers = [];
this.props = param_definition_1.ParamDefinition.getDefaultValues(InteractivityManager.Params);
this.sel = ctx.managers.structure.selection;
this.setProps(props);
}
LociMarkManager.prototype.setProps = function (props) {
Object.assign(this.props, props);
};
LociMarkManager.prototype.addProvider = function (provider) {
this.providers.push(provider);
};
LociMarkManager.prototype.removeProvider = function (provider) {
this.providers = this.providers.filter(function (p) { return p !== provider; });
// TODO clear, then re-apply remaining providers
};
LociMarkManager.prototype.normalizedLoci = function (reprLoci, applyGranularity, alwaysConvertBonds) {
if (alwaysConvertBonds === void 0) { alwaysConvertBonds = false; }
var loci = reprLoci.loci, repr = reprLoci.repr;
var granularity = applyGranularity ? this.props.granularity : undefined;
return { loci: loci_1.Loci.normalize(loci, granularity, alwaysConvertBonds), repr: repr };
};
LociMarkManager.prototype.mark = function (current, action, noRender) {
if (noRender === void 0) { noRender = false; }
if (!loci_1.Loci.isEmpty(current.loci)) {
for (var _i = 0, _a = this.providers; _i < _a.length; _i++) {
var p = _a[_i];
p(current, action, noRender);
}
}
};
return LociMarkManager;
}());
InteractivityManager.LociMarkManager = LociMarkManager;
//
var LociHighlightManager = /** @class */ (function (_super) {
tslib_1.__extends(LociHighlightManager, _super);
function LociHighlightManager() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.prev = [];
_this.clearHighlights = function (noRender) {
if (noRender === void 0) { noRender = false; }
for (var _i = 0, _a = _this.prev; _i < _a.length; _i++) {
var p = _a[_i];
_this.mark(p, marker_action_1.MarkerAction.RemoveHighlight, noRender);
}
_this.prev.length = 0;
};
return _this;
}
LociHighlightManager.prototype.isHighlighted = function (loci) {
for (var _i = 0, _a = this.prev; _i < _a.length; _i++) {
var p = _a[_i];
if (representation_1.Representation.Loci.areEqual(p, loci))
return true;
}
return false;
};
LociHighlightManager.prototype.addHighlight = function (loci) {
this.mark(loci, marker_action_1.MarkerAction.Highlight);
this.prev.push(loci);
};
LociHighlightManager.prototype.highlight = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity);
if (!this.isHighlighted(normalized)) {
this.addHighlight(normalized);
}
};
LociHighlightManager.prototype.highlightOnly = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity);
if (!this.isHighlighted(normalized)) {
if (loci_1.Loci.isEmpty(normalized.loci)) {
this.clearHighlights();
}
else {
this.clearHighlights(true);
this.addHighlight(normalized);
}
}
};
LociHighlightManager.prototype.highlightOnlyExtend = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
var extended = {
loci: this.sel.tryGetRange(normalized.loci) || normalized.loci,
repr: normalized.repr
};
if (!this.isHighlighted(extended)) {
if (loci_1.Loci.isEmpty(extended.loci)) {
this.clearHighlights();
}
else {
this.clearHighlights(true);
this.addHighlight(extended);
}
}
}
};
return LociHighlightManager;
}(LociMarkManager));
InteractivityManager.LociHighlightManager = LociHighlightManager;
//
var LociSelectManager = /** @class */ (function (_super) {
tslib_1.__extends(LociSelectManager, _super);
function LociSelectManager() {
return _super !== null && _super.apply(this, arguments) || this;
}
LociSelectManager.prototype.toggle = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
if (loci_1.Loci.isEmpty(current.loci))
return;
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
this.toggleSel(normalized);
}
else {
_super.prototype.mark.call(this, normalized, marker_action_1.MarkerAction.Toggle);
}
};
LociSelectManager.prototype.toggleExtend = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
if (loci_1.Loci.isEmpty(current.loci))
return;
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
var loci = this.sel.tryGetRange(normalized.loci) || normalized.loci;
this.toggleSel({ loci: loci, repr: normalized.repr });
}
};
LociSelectManager.prototype.select = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('add', normalized.loci);
}
this.mark(normalized, marker_action_1.MarkerAction.Select);
};
LociSelectManager.prototype.selectJoin = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('intersect', normalized.loci);
}
this.mark(normalized, marker_action_1.MarkerAction.Select);
};
LociSelectManager.prototype.selectOnly = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
// only deselect for the structure of the given loci
this.deselect({ loci: structure_1.Structure.toStructureElementLoci(normalized.loci.structure), repr: normalized.repr }, false);
this.sel.modify('set', normalized.loci);
}
this.mark(normalized, marker_action_1.MarkerAction.Select);
};
LociSelectManager.prototype.deselect = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (structure_1.StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('remove', normalized.loci);
}
this.mark(normalized, marker_action_1.MarkerAction.Deselect);
};
LociSelectManager.prototype.deselectAll = function () {
this.sel.clear();
this.mark({ loci: loci_1.EveryLoci }, marker_action_1.MarkerAction.Deselect);
};
LociSelectManager.prototype.deselectAllOnEmpty = function (current) {
if ((0, loci_1.isEmptyLoci)(current.loci))
this.deselectAll();
};
LociSelectManager.prototype.mark = function (current, action) {
var loci = current.loci;
if (!loci_1.Loci.isEmpty(loci)) {
if (structure_1.StructureElement.Loci.is(loci)) {
// do a full deselect/select for the current structure so visuals that are
// marked with granularity unequal to 'element' and join/intersect operations
// are handled properly
var selLoci = this.sel.getLoci(loci.structure);
_super.prototype.mark.call(this, { loci: structure_1.Structure.Loci(loci.structure) }, marker_action_1.MarkerAction.Deselect, !loci_1.Loci.isEmpty(selLoci));
_super.prototype.mark.call(this, { loci: selLoci }, marker_action_1.MarkerAction.Select);
}
else {
_super.prototype.mark.call(this, current, action);
}
}
};
LociSelectManager.prototype.toggleSel = function (current) {
if (this.sel.has(current.loci)) {
this.sel.modify('remove', current.loci);
this.mark(current, marker_action_1.MarkerAction.Deselect);
}
else {
this.sel.modify('add', current.loci);
this.mark(current, marker_action_1.MarkerAction.Select);
}
};
return LociSelectManager;
}(LociMarkManager));
InteractivityManager.LociSelectManager = LociSelectManager;
})(InteractivityManager || (InteractivityManager = {}));
exports.InteractivityManager = InteractivityManager;