molstar
Version:
A comprehensive macromolecular library.
264 lines • 13 kB
JavaScript
/**
* 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>
*/
import { __assign, __extends } from "tslib";
import { EveryLoci, isEmptyLoci, Loci } from '../../mol-model/loci';
import { Structure, StructureElement } from '../../mol-model/structure';
import { Representation } from '../../mol-repr/representation';
import { MarkerAction } from '../../mol-util/marker-action';
import { shallowEqual } from '../../mol-util/object';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { StatefulPluginComponent } from '../component';
export { InteractivityManager };
// TODO: make this customizable somewhere?
var DefaultInteractivityFocusOptions = {
minRadius: 6,
extraRadius: 6,
durationMs: 250,
};
var InteractivityManager = /** @class */ (function (_super) {
__extends(InteractivityManager, _super);
function InteractivityManager(plugin, props) {
if (props === void 0) { props = {}; }
var _this = _super.call(this, { props: __assign(__assign({}, PD.getDefaultValues(InteractivityManager.Params)), props) }) || this;
_this.plugin = plugin;
_this._props = PD.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 __assign({}, this.state.props); },
enumerable: false,
configurable: true
});
InteractivityManager.prototype.setProps = function (props) {
var old = this.props;
var _new = __assign(__assign({}, this.state.props), props);
if (shallowEqual(old, _new))
return;
this.updateState({ props: _new });
this.lociSelects.setProps(_new);
this.lociHighlights.setProps(_new);
this.events.propsUpdated.next(void 0);
};
return InteractivityManager;
}(StatefulPluginComponent));
(function (InteractivityManager) {
InteractivityManager.Params = {
granularity: PD.Select('residue', 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 = PD.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.normalize(loci, granularity, alwaysConvertBonds), repr: repr };
};
LociMarkManager.prototype.mark = function (current, action, noRender) {
if (noRender === void 0) { noRender = false; }
if (!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) {
__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, 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.Loci.areEqual(p, loci))
return true;
}
return false;
};
LociHighlightManager.prototype.addHighlight = function (loci) {
this.mark(loci, 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.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 (StructureElement.Loci.is(normalized.loci)) {
var extended = {
loci: this.sel.tryGetRange(normalized.loci) || normalized.loci,
repr: normalized.repr
};
if (!this.isHighlighted(extended)) {
if (Loci.isEmpty(extended.loci)) {
this.clearHighlights();
}
else {
this.clearHighlights(true);
this.addHighlight(extended);
}
}
}
};
return LociHighlightManager;
}(LociMarkManager));
InteractivityManager.LociHighlightManager = LociHighlightManager;
//
var LociSelectManager = /** @class */ (function (_super) {
__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.isEmpty(current.loci))
return;
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (StructureElement.Loci.is(normalized.loci)) {
this.toggleSel(normalized);
}
else {
_super.prototype.mark.call(this, normalized, MarkerAction.Toggle);
}
};
LociSelectManager.prototype.toggleExtend = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
if (Loci.isEmpty(current.loci))
return;
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (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 (StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('add', normalized.loci);
}
this.mark(normalized, MarkerAction.Select);
};
LociSelectManager.prototype.selectJoin = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('intersect', normalized.loci);
}
this.mark(normalized, MarkerAction.Select);
};
LociSelectManager.prototype.selectOnly = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (StructureElement.Loci.is(normalized.loci)) {
// only deselect for the structure of the given loci
this.deselect({ loci: Structure.toStructureElementLoci(normalized.loci.structure), repr: normalized.repr }, false);
this.sel.modify('set', normalized.loci);
}
this.mark(normalized, MarkerAction.Select);
};
LociSelectManager.prototype.deselect = function (current, applyGranularity) {
if (applyGranularity === void 0) { applyGranularity = true; }
var normalized = this.normalizedLoci(current, applyGranularity, true);
if (StructureElement.Loci.is(normalized.loci)) {
this.sel.modify('remove', normalized.loci);
}
this.mark(normalized, MarkerAction.Deselect);
};
LociSelectManager.prototype.deselectAll = function () {
this.sel.clear();
this.mark({ loci: EveryLoci }, MarkerAction.Deselect);
};
LociSelectManager.prototype.deselectAllOnEmpty = function (current) {
if (isEmptyLoci(current.loci))
this.deselectAll();
};
LociSelectManager.prototype.mark = function (current, action) {
var loci = current.loci;
if (!Loci.isEmpty(loci)) {
if (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.Loci(loci.structure) }, MarkerAction.Deselect, !Loci.isEmpty(selLoci));
_super.prototype.mark.call(this, { loci: selLoci }, 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, MarkerAction.Deselect);
}
else {
this.sel.modify('add', current.loci);
this.mark(current, MarkerAction.Select);
}
};
return LociSelectManager;
}(LociMarkManager));
InteractivityManager.LociSelectManager = LociSelectManager;
})(InteractivityManager || (InteractivityManager = {}));
//# sourceMappingURL=interactivity.js.map