UNPKG

@maxgraph/core

Version:

maxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.

235 lines (231 loc) 8.1 kB
"use strict"; /* Copyright 2021-present The maxGraph project Contributors Copyright (c) 2006-2015, JGraph Ltd Copyright (c) 2006-2015, Gaudenz Alder Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const EventSource_js_1 = __importDefault(require("../event/EventSource.js")); const EventObject_js_1 = __importDefault(require("../event/EventObject.js")); const InternalEvent_js_1 = __importDefault(require("../event/InternalEvent.js")); const styleUtils_js_1 = require("../../util/styleUtils.js"); /** * An event handler that manages cell handlers and invokes their mouse event processing functions. * * ### Events * * #### InternalEvent.ADD * * Fires if a cell has been added to the selection. * The `state` property contains the {@link CellState} that has been added. * * #### InternalEvent.REMOVE * * Fires if a cell has been remove from the selection. * The `state` property contains the {@link CellState} that has been removed. * * @category Plugin */ class SelectionCellsHandler extends EventSource_js_1.default { constructor(graph) { super(); /** * Specifies if events are handled. * @default true */ this.enabled = true; /** * Defines the maximum number of handlers to paint individually. * @default 100 */ this.maxHandlers = 100; this.graph = graph; this.handlers = new Map(); this.graph.addMouseListener(this); this.refreshHandler = () => { if (this.isEnabled()) { this.refresh(); } }; this.graph.getSelectionModel().addListener(InternalEvent_js_1.default.CHANGE, this.refreshHandler); this.graph.getDataModel().addListener(InternalEvent_js_1.default.CHANGE, this.refreshHandler); this.graph.getView().addListener(InternalEvent_js_1.default.SCALE, this.refreshHandler); this.graph.getView().addListener(InternalEvent_js_1.default.TRANSLATE, this.refreshHandler); this.graph .getView() .addListener(InternalEvent_js_1.default.SCALE_AND_TRANSLATE, this.refreshHandler); this.graph.getView().addListener(InternalEvent_js_1.default.DOWN, this.refreshHandler); this.graph.getView().addListener(InternalEvent_js_1.default.UP, this.refreshHandler); } /** * Returns {@link enabled}. */ isEnabled() { return this.enabled; } /** * Sets {@link enabled}. */ setEnabled(value) { this.enabled = value; } /** * Returns the handler for the given cell. */ getHandler(cell) { return this.handlers.get(cell); } /** * Returns true if the given cell has a handler. */ isHandled(cell) { return !!this.getHandler(cell); } /** * Resets all handlers. */ reset() { this.handlers.forEach((handler) => { handler.reset.apply(handler); }); } /** * Reloads or updates all handlers. */ getHandledSelectionCells() { return this.graph.getSelectionCells(); } /** * Reloads or updates all handlers. */ refresh() { // Removes all existing handlers const oldHandlers = this.handlers; this.handlers = new Map(); // Creates handles for all selection cells const tmp = (0, styleUtils_js_1.sortCells)(this.getHandledSelectionCells(), false); // Destroys or updates old handlers for (let i = 0; i < tmp.length; i += 1) { const state = this.graph.view.getState(tmp[i]); if (state) { let handler = oldHandlers.get(tmp[i]) ?? null; oldHandlers.delete(tmp[i]); if (handler) { if (handler.state !== state) { handler.onDestroy(); handler = null; } else if (!this.isHandlerActive(handler)) { // @ts-ignore refresh may exist if (handler.refresh) handler.refresh(); handler.redraw(); } } if (handler) { this.handlers.set(tmp[i], handler); } } } // Destroys unused handlers oldHandlers.forEach((handler) => { this.fireEvent(new EventObject_js_1.default(InternalEvent_js_1.default.REMOVE, { state: handler.state })); handler.onDestroy(); }); // Creates new handlers and updates parent highlight on existing handlers for (let i = 0; i < tmp.length; i += 1) { const state = this.graph.view.getState(tmp[i]); if (state) { let handler = this.handlers.get(tmp[i]); if (!handler) { handler = this.graph.createHandler(state); this.fireEvent(new EventObject_js_1.default(InternalEvent_js_1.default.ADD, { state })); this.handlers.set(tmp[i], handler); } else { handler.updateParentHighlight(); } } } } /** * Returns true if the given handler is active and should not be redrawn. */ isHandlerActive(handler) { return handler.index !== null; } /** * Updates the handler for the given shape if one exists. */ updateHandler(state) { let handler = this.handlers.get(state.cell); this.handlers.delete(state.cell); if (handler) { // Transfers the current state to the new handler const { index } = handler; const x = handler.startX; const y = handler.startY; handler.onDestroy(); handler = this.graph.createHandler(state); if (handler) { this.handlers.set(state.cell, handler); if (index !== null) { handler.start(x, y, index); } } } } /** * Redirects the given event to the handlers. */ mouseDown(sender, me) { if (this.graph.isEnabled() && this.isEnabled()) { this.handlers.forEach((handler) => { handler.mouseDown(sender, me); }); } } /** * Redirects the given event to the handlers. */ mouseMove(sender, me) { if (this.graph.isEnabled() && this.isEnabled()) { this.handlers.forEach((handler) => { handler.mouseMove(sender, me); }); } } /** * Redirects the given event to the handlers. */ mouseUp(sender, me) { if (this.graph.isEnabled() && this.isEnabled()) { this.handlers.forEach((handler) => { handler.mouseUp(sender, me); }); } } /** * Destroys the handler and all its resources and DOM nodes. */ onDestroy() { this.graph.removeMouseListener(this); this.graph.removeListener(this.refreshHandler); this.graph.getDataModel().removeListener(this.refreshHandler); this.graph.getView().removeListener(this.refreshHandler); } } SelectionCellsHandler.pluginId = 'SelectionCellsHandler'; exports.default = SelectionCellsHandler;