Skip to content
Snippets Groups Projects
deletetool.js 5.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • import Tool from "./tool";
    import * as Graph from "../graph";
    
    import jquery from "jquery";
    
    import ToolMenu from "./menus/toolmenu";
    
    import DeleteIcon from "../../images/tools/delete.png";
    
    import { Editor } from "../components/editor";
    
    const BOX_SELECT_LAYER_ID = "#box-select-layer";
    const BOX_SELECT_ID_WH = "box-select";
    const SELECT_BOX_SELECTOR = BOX_SELECT_LAYER_ID + " #" + BOX_SELECT_ID_WH;
    
    
    /**
     * Only one instance of this should exist, since box-delete has to work on a global scale.
     */
    
    var deleteToolInstance = undefined; // Used for box delete
    
    export default class DeleteTool extends Tool {
    
    Maximilian Giller's avatar
    Maximilian Giller committed
        constructor(key) {
    
            super("Delete", DeleteIcon, key, new ToolMenu());
    
            this.setupBoxSelect();
    
            this.isActive = false;
    
    
            if (deleteToolInstance === undefined) {
                deleteToolInstance = this;
            }
        }
    
        onBoxSelect(left, bottom, top, right) {
            // Filter out selected nodes
    
            const selectedNodes = [];
    
            const tl = Editor.globalRenderer.screen2GraphCoords(left, top);
            const br = Editor.globalRenderer.screen2GraphCoords(right, bottom);
            Editor.globalGraph.data[Graph.GRAPH_NODES].forEach((node) => {
    
                if (
                    tl.x < node.x &&
                    node.x < br.x &&
                    br.y > node.y &&
                    node.y > tl.y
                ) {
    
                    selectedNodes.push(node);
    
            // Was anything even selected?
            if (selectedNodes.length <= 0) {
                return;
            }
    
            // Ask for confirmation to delete
            var nodeNames = selectedNodes.map((n) => n[Graph.NODE_LABEL]);
            //! Problem: If browser is not actually showing the alerts, it always returns false!
    
                "Are you sure you want to delete all these nodes?\n\n" +
                    nodeNames.join("\n")
    
            // Delete if confirmed
            if (shouldDelete) {
                var nodeIds = selectedNodes.map((n) => n[Graph.NODE_ID]);
    
                Editor.globalGraph.deleteNodes(nodeIds);
    
    Maximilian Giller's avatar
    Maximilian Giller committed
        }
    
        onNodeClick(node) {
    
            Editor.globalGraph.deleteNode(node[Graph.NODE_ID]);
    
            if (Editor.globalState.selectedItem == node) {
                Editor.globalState.setSelectedItem(undefined);
    
    Maximilian Giller's avatar
    Maximilian Giller committed
        }
    
        onLinkClick(link) {
    
            Editor.globalGraph.deleteLink(
    
                link[Graph.LINK_SOURCE][Graph.NODE_ID],
                link[Graph.LINK_TARGET][Graph.NODE_ID]
            );
    
            if (Editor.globalState.selectedItem == link) {
                Editor.globalState.setSelectedItem(undefined);
    
    Maximilian Giller's avatar
    Maximilian Giller committed
        }
    
    
        setupBoxSelect() {
            window.addEventListener("load", () => {
                // Source: https://github.com/vasturiano/force-graph/issues/151#issuecomment-735850938
    
                // forceGraph element is the element provided to the Force Graph Library
    
                jquery("#2d-graph").on("pointerdown", this.boxSelectOnPointerDown);
                jquery("#2d-graph").on("pointermove", this.boxSelectOnPointerMove);
                jquery("#2d-graph").on("pointerup", this.boxSelectOnPointerUp);
    
            });
        }
    
        boxSelectOnPointerDown(e) {
    
            // Only do anything if delete tool is also active
    
            if (
                deleteToolInstance === undefined ||
                deleteToolInstance.isActive == false
            ) {
    
            if (!e.shiftKey) {
                return;
            }
    
            e.preventDefault();
            this.boxSelect = document.createElement("div");
    
            this.boxSelect.id = BOX_SELECT_ID_WH;
    
            this.boxSelect.style.left = e.offsetX.toString() + "px";
            this.boxSelect.style.top = e.offsetY.toString() + "px";
            this.boxSelectStart = {
                x: e.offsetX,
                y: e.offsetY,
            };
            // app element is the element just above the forceGraph element.
    
            jquery(BOX_SELECT_LAYER_ID).append(this.boxSelect);
    
        }
    
        boxSelectOnPointerMove(e) {
            if (!this.boxSelect) {
                return;
            }
    
            if (!e.shiftKey) {
    
                jquery(SELECT_BOX_SELECTOR).remove();
    
                return;
            }
    
            e.preventDefault();
            if (e.offsetX < this.boxSelectStart.x) {
                this.boxSelect.style.left = e.offsetX.toString() + "px";
                this.boxSelect.style.width =
                    (this.boxSelectStart.x - e.offsetX).toString() + "px";
            } else {
                this.boxSelect.style.left = this.boxSelectStart.x.toString() + "px";
                this.boxSelect.style.width =
                    (e.offsetX - this.boxSelectStart.x).toString() + "px";
            }
            if (e.offsetY < this.boxSelectStart.y) {
                this.boxSelect.style.top = e.offsetY.toString() + "px";
                this.boxSelect.style.height =
                    (this.boxSelectStart.y - e.offsetY).toString() + "px";
            } else {
                this.boxSelect.style.top = this.boxSelectStart.y.toString() + "px";
                this.boxSelect.style.height =
                    (e.offsetY - this.boxSelectStart.y).toString() + "px";
            }
        }
    
        boxSelectOnPointerUp(e) {
            if (!this.boxSelect) {
                return;
            }
    
            if (!e.shiftKey) {
    
                jquery(SELECT_BOX_SELECTOR).remove();
    
                return;
            }
    
            e.preventDefault();
            let left, bottom, top, right;
            if (e.offsetX < this.boxSelectStart.x) {
                left = e.offsetX;
                right = this.boxSelectStart.x;
            } else {
                left = this.boxSelectStart.x;
                right = e.offsetX;
            }
            if (e.offsetY < this.boxSelectStart.y) {
                top = e.offsetY;
                bottom = this.boxSelectStart.y;
            } else {
                top = this.boxSelectStart.y;
                bottom = e.offsetY;
            }
            this.boxSelect.remove();
            deleteToolInstance.onBoxSelect(left, bottom, top, right);
        }