diff --git a/lib/network/modules/components/NavigationHandler.js b/lib/network/modules/components/NavigationHandler.js index bab6612ea2..60eee9ee84 100644 --- a/lib/network/modules/components/NavigationHandler.js +++ b/lib/network/modules/components/NavigationHandler.js @@ -3,6 +3,12 @@ import "./NavigationHandler.css"; import { Hammer } from "vis-util/esnext"; import { onRelease, onTouch } from "../../../hammerUtil"; import keycharm from "keycharm"; +import LayoutEngine from "../../modules/LayoutEngine"; +import NodesHandler from "../../modules/NodesHandler"; +import Canvas from "../../modules/Canvas"; +import SelectionHandler from "../SelectionHandler"; +import Images from "../../Images"; +import { Groups } from "../../modules/Groups"; /** * Navigation Handler @@ -21,6 +27,18 @@ class NavigationHandler { this.boundFunctions = {}; this.touchTime = 0; this.activated = false; + this.selectionHandler = new SelectionHandler(body, canvas); + this.images = new Images(() => this.body.emitter.emit("_requestRedraw")); // object with images + this.groups = new Groups(); // object with groups + this.layoutEngine = new LayoutEngine(this.body); // layout engine for inital layout and hierarchical layout + this.nodesHandler = new NodesHandler( + this.body, + this.images, + this.groups, + this.layoutEngine + ); // Handle adding, deleting and updating of nodes as well as global options + this.canvas = new Canvas(body); + this.index = -1; this.body.emitter.on("activate", () => { this.activated = true; @@ -307,6 +325,89 @@ class NavigationHandler { this.keycharm.reset(); if (this.activated === true) { + this.keycharm.bind( + "n", + () => { + this.index += 1; + if (this.index >= this.body.nodeIndices.length) { + this.index = 0; + } + this.selectionHandler.selectNodes([ + this.body.nodeIndices[this.index], + ]); + }, + "keydown" + ); + this.keycharm.bind( + "p", + () => { + this.index -= 1; + if (this.index < 0) { + this.index = this.body.nodeIndices.length - 1; + } + this.selectionHandler.selectNodes([ + this.body.nodeIndices[this.index], + ]); + }, + "keydown" + ); + this.keycharm.bind( + "s", + () => { + const nodeId = this.selectionHandler.getSelectedNodeIds()[0]; + const canvasPosition = this.nodesHandler.getPosition(nodeId); + const DOMPosition = this.canvas.canvasToDOM(canvasPosition); + this.selectionHandler.generateClickEvent( + "click", + { + center: { + x: Math.floor(DOMPosition.x), + y: Math.floor(DOMPosition.y), + }, + }, + { x: DOMPosition.x, y: DOMPosition.y } + ); + }, + "keydown" + ); + this.keycharm.bind( + "d", + () => { + const nodeId = this.selectionHandler.getSelectedNodeIds()[0]; + const canvasPosition = this.nodesHandler.getPosition(nodeId); + const DOMPosition = this.canvas.canvasToDOM(canvasPosition); + this.selectionHandler.generateClickEvent( + "doubleClick", + { + center: { + x: Math.floor(DOMPosition.x), + y: Math.floor(DOMPosition.y), + }, + }, + { x: DOMPosition.x, y: DOMPosition.y } + ); + }, + "keydown" + ); + this.keycharm.bind( + "c", + () => { + const nodeId = this.selectionHandler.getSelectedNodeIds()[0]; + const canvasPosition = this.nodesHandler.getPosition(nodeId); + const DOMPosition = this.canvas.canvasToDOM(canvasPosition); + this.selectionHandler.generateClickEvent( + "oncontext", + { + center: { + x: Math.floor(DOMPosition.x), + y: Math.floor(DOMPosition.y), + }, + }, + { x: DOMPosition.x, y: DOMPosition.y } + ); + }, + "keydown" + ); this.keycharm.bind( "up", () => { diff --git a/package-lock.json b/package-lock.json index ed2481dee6..e83c4b76b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3865,9 +3865,9 @@ } }, "node_modules/assets/node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "peer": true, "dependencies": { @@ -5630,7 +5630,7 @@ "node_modules/css-modules-require-hook": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz", - "integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=", + "integrity": "sha512-y3eGHAqmDl8JQdr1LYTwBkMxy7CSHCMy9YwpSjDqtGqCCEy9lKq/x/nmHVs+G7C1+xXmyIXjRu0q/MMn8w01mg==", "dev": true, "peer": true, "dependencies": { @@ -21884,9 +21884,9 @@ }, "dependencies": { "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "peer": true, "requires": { @@ -23231,7 +23231,7 @@ "css-modules-require-hook": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz", - "integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=", + "integrity": "sha512-y3eGHAqmDl8JQdr1LYTwBkMxy7CSHCMy9YwpSjDqtGqCCEy9lKq/x/nmHVs+G7C1+xXmyIXjRu0q/MMn8w01mg==", "dev": true, "peer": true, "requires": {