import Tool from "./tools/tool"; import UndoTool from "./tools/undotool"; import RedoTool from "./tools/redotool"; import SelectTool from "./tools/selecttool"; import CollectTool from "./tools/collecttool"; import DeleteTool from "./tools/deletetool"; import AddNodeTool from "./tools/addnodetool"; import ConnectTool from "./tools/connecttool"; import { graph } from "./editor"; import Display from "./display"; import * as Graph from "./graph"; export const TOOLS = { undo: new UndoTool("undo"), redo: new RedoTool("redo"), select: new SelectTool("select"), collect: new CollectTool("collect"), delete: new DeleteTool("delete"), addnode: new AddNodeTool("addnode"), connect: new ConnectTool("connect"), }; export const CONTEXT = { node: "node", link: "link", mixed: "mixed", }; export class State extends Tool { constructor() { super("State"); this.display = new Display(TOOLS); this.tool = undefined; this.setTool(TOOLS.select); // Shared variables this.selectedItem = undefined; this.selectedItems = new Set(); this.itemsContext = undefined; this.keyStates = {}; } setTool(tool) { if (this.tool === tool) { return; } if (this.tool !== undefined) { this.tool.onToolDeactivate(tool); } this.previousTool = this.tool; this.tool = tool; this.display.setSelectedTool(tool); if (this.tool !== undefined) { this.tool.onToolActivate(); } } setSelectedItem(item) { this.selectedItem = item; this.display.setSelectedItem(item); } addSelectedItem(item) { this.selectedItems.add(item); this.display.setSelectedItems(this.selectedItems, this.itemsContext); } removeSelectedItem(item) { this.selectedItems.delete(item); this.display.setSelectedItems(this.selectedItems, this.itemsContext); } clearSelectedItems() { this.selectedItems.clear(); this.itemsContext = undefined; this.display.setSelectedItems(this.selectedItems, this.itemsContext); } onNodeClick(node) { this.tool.onNodeClick(node); } onLinkClick(link) { this.tool.onLinkClick(link); } onKeyDown(key) { var id = this.getKeyId(key); var previous = this.keyStates[id]; this.keyStates[id] = true; if (previous !== true) { this.tool.onKeyDown(key); } } onKeyUp(key) { var id = this.getKeyId(key); var previous = this.keyStates[id]; this.keyStates[id] = false; if (previous !== false) { this.tool.onKeyUp(key); } } getKeyId(key) { return key.keyCode; } nodeCanvasObject(node, ctx) { var toolValue = this.tool.nodeCanvasObject(node, ctx); if (toolValue !== undefined) { return toolValue; } // TODO: Clean up function // add ring just for highlighted nodes if (this.selectedItem === node || this.selectedItems.has(node)) { ctx.beginPath(); ctx.arc(node.x, node.y, 5 * 1.4, 0, 2 * Math.PI, false); ctx.fillStyle = this.selectedItem === node ? "red" : "green"; ctx.fill(); } // Draw image if (node[Graph.NODE_IMAGE] !== undefined) { var path = Graph.IMAGE_SRC + node[Graph.NODE_IMAGE]; var img = new Image(); img.src = path; ctx.drawImage( img, node.x - Graph.IMAGE_SIZE / 2, node.y - Graph.IMAGE_SIZE / 2, Graph.IMAGE_SIZE, Graph.IMAGE_SIZE ); } // TODO: Render label as always visible } nodePointerAreaPaint(node, color, ctx) { var toolValue = this.tool.nodePointerAreaPaint(node, color, ctx); if (toolValue !== undefined) { return toolValue; } ctx.fillStyle = color; ctx.fillRect( node.x - Graph.IMAGE_SIZE / 2, node.y - Graph.IMAGE_SIZE / 2, Graph.IMAGE_SIZE, Graph.IMAGE_SIZE ); // draw square as pointer trap } nodeCanvasObjectMode(node) { var toolValue = this.tool.nodeCanvasObjectMode(node); if (toolValue !== undefined) { return toolValue; } return "after"; } linkWidth(link) { var toolValue = this.tool.linkWidth(link); if (toolValue !== undefined) { return toolValue; } return this.isLinkHighlighted(link) ? 5 : 1; } linkDirectionalParticles() { var toolValue = this.tool.linkDirectionalParticles(); if (toolValue !== undefined) { return toolValue; } return 4; } linkDirectionalParticleWidth(link) { var toolValue = this.tool.linkDirectionalParticleWidth(link); if (toolValue !== undefined) { return toolValue; } return this.isLinkHighlighted(link) ? Graph.LINK_PARTICLE_COUNT : 0; } onBackgroundClick(event, positions) { this.tool.onBackgroundClick(event, positions); } redraw() { this.display.setSelectedTool(this.tool); this.display.setSelectedItem(this.selectedItem); this.display.setSelectedItems(this.selectedItems, this.itemsContext); } isLinkHighlighted(link) { return ( this.selectedItem === link || graph.isLinkOnNode(link, this.selectedItem) ); } }