UNPKG

@itwin/unified-selection

Version:

Package for managing unified selection in iTwin.js applications.

150 lines 5.59 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.IMODEL_CLOSE_SELECTION_CLEAR_SOURCE = void 0; exports.createStorage = createStorage; const core_bentley_1 = require("@itwin/core-bentley"); const Selectable_js_1 = require("./Selectable.js"); /** * Creates a selection storage which stores and allows managing application-level selection. * * **Note:** `clearSelection` should be called upon iModel close to free-up memory: * * ```ts * import { IModelConnection } from "@itwin/core-frontend"; * import { createIModelKey } from "@itwin/presentation-core-interop"; * * IModelConnection.onClose.addListener((imodel) => { * storage.clearStorage(createIModelKey(imodel)); * }); * ``` * * @public */ function createStorage() { return new SelectionStorageImpl(); } /** @internal */ exports.IMODEL_CLOSE_SELECTION_CLEAR_SOURCE = "Unified selection storage: clear"; class SelectionStorageImpl { _storage = new Map(); selectionChangeEvent; constructor() { this.selectionChangeEvent = new core_bentley_1.BeEvent(); } getSelectionLevels(props) { return this.getContainer(getIModelKey(props)).getSelectionLevels(); } getSelection(props) { return this.getContainer(getIModelKey(props)).getSelection(props.level ?? 0); } addToSelection(props) { this.handleChange({ ...props, changeType: "add" }); } removeFromSelection(props) { this.handleChange({ ...props, changeType: "remove" }); } replaceSelection(props) { this.handleChange({ ...props, changeType: "replace" }); } clearSelection(props) { this.handleChange({ ...props, changeType: "clear", selectables: [] }); } clearStorage(props) { const imodelKey = getIModelKey(props); this.clearSelection({ source: exports.IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, imodelKey }); this._storage.delete(imodelKey); } getContainer(imodelKey) { let selectionContainer = this._storage.get(imodelKey); if (!selectionContainer) { selectionContainer = new MultiLevelSelectablesContainer(); this._storage.set(imodelKey, selectionContainer); } return selectionContainer; } handleChange(props) { const { source, level: inLevel, changeType, selectables: change } = props; const imodelKey = getIModelKey(props); const container = this.getContainer(imodelKey); const level = inLevel ?? 0; const selectables = container.getSelection(level); const selected = Selectable_js_1.Selectables.create(change); switch (changeType) { case "add": if (!Selectable_js_1.Selectables.add(selectables, change)) { return; } break; case "remove": if (!Selectable_js_1.Selectables.remove(selectables, change)) { return; } break; case "replace": if (Selectable_js_1.Selectables.size(selectables) === Selectable_js_1.Selectables.size(selected) && Selectable_js_1.Selectables.hasAll(selectables, change)) { return; } Selectable_js_1.Selectables.clear(selectables); Selectable_js_1.Selectables.add(selectables, change); break; case "clear": if (!Selectable_js_1.Selectables.clear(selectables)) { return; } break; } container.clear(level + 1); const event = { source, level, imodelKey, iModelKey: imodelKey, changeType, selectables: selected, timestamp: new Date(), storage: this, }; this.selectionChangeEvent.raiseEvent(event, this); } } function getIModelKey(props) { // eslint-disable-next-line @typescript-eslint/no-deprecated return ("imodelKey" in props ? props.imodelKey : props.iModelKey) ?? ""; } class MultiLevelSelectablesContainer { _selectablesContainers; constructor() { this._selectablesContainers = new Map(); } getSelection(level) { let selectables = this._selectablesContainers.get(level); if (!selectables) { selectables = Selectable_js_1.Selectables.create([]); this._selectablesContainers.set(level, selectables); } return selectables; } getSelectionLevels() { const levels = new Array(); for (const entry of this._selectablesContainers.entries()) { if (!Selectable_js_1.Selectables.isEmpty(entry[1])) { levels.push(entry[0]); } } return levels.sort(); } clear(level) { const storedLevels = this._selectablesContainers.keys(); for (const storedLevel of storedLevels) { if (storedLevel >= level) { const selectables = this._selectablesContainers.get(storedLevel); Selectable_js_1.Selectables.clear(selectables); } } } } //# sourceMappingURL=SelectionStorage.js.map