Newer
Older
import Tool from "./tools/tool";
import UndoTool from "./tools/undotool";
import RedoTool from "./tools/redotool";
import SelectTool from "./tools/selecttool";
import DeleteTool from "./tools/deletetool";
import AddNodeTool from "./tools/addnodetool";
import ConnectTool from "./tools/connecttool";
import SettingsTool from "./tools/settingstool";
import SaveTool from "./tools/savetool";
import * as Graph from "./graph";
import { DRAG_THRESHOLD_2D } from "../../config";
import { Editor } from "./components/editor";
undo: new UndoTool("undo"),
redo: new RedoTool("redo"),
select: new SelectTool("select"),
delete: new DeleteTool("delete"),
nothing: "nothing",
export class State extends Tool {
this.tool = undefined;
this.setTool(TOOLS.select);
// Shared variables
this.selectedItem = undefined;
this.selectedItems = new Set();
this.itemsContext = CONTEXT.nothing;
this.tool.deactivateTool(tool);
this.previousTool = this.tool;
this.tool = tool;
this.display.setSelectedTool(tool);
}
setSelectedItem(item) {
this.selectedItem = item;
}
addSelectedItem(item) {
this.selectedItems.add(item);
}
addSelectedItems(items) {
Object.values(items).forEach((item) => {
this.selectedItems.add(item);
});
}
removeSelectedItem(item) {
this.selectedItems.delete(item);
}
clearSelectedItems() {
this.selectedItems.clear();
this.itemsContext = CONTEXT.nothing;
}
onNodeClick(node) {
this.tool.onNodeClick(node);
}
onNodeDragEnd(node, translate) {
// Handle as click event, if drag distance under a certain threshold
var distanceDragged = Math.sqrt(
Math.pow(translate.x, 2) + Math.pow(translate.y, 2)
);
if (distanceDragged < DRAG_THRESHOLD_2D) {
this.onNodeClick(node);
return;
} else {
this.tool.onNodeDragEnd(node, translate);
}
}
onLinkClick(link) {
this.tool.onLinkClick(link);
}
return "red";
}
nodeColor(node) {
return "black";
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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, globalScale) {
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, 4 * 0.6, 0, 2 * Math.PI, false);
ctx.fillStyle = this.selectedItem === node ? "red" : "white";
if (node[Graph.NODE_IMAGE] !== undefined) {
var path = node[Graph.NODE_IMAGE];
if (!path.includes("/")) {
path = Graph.IMAGE_SRC + path;
}
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
if (this.labelVisible) {
const label = node[Graph.NODE_LABEL];
const fontSize = 11 / globalScale;
ctx.font = `${fontSize}px Sans-Serif`;
const textWidth = ctx.measureText(label).width;
const bckgDimensions = [textWidth, fontSize].map(
(n) => n + fontSize * 0.2
); // some padding
const nodeHeightOffset = Graph.IMAGE_SIZE / 3 + bckgDimensions[1];
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
ctx.fillRect(
node.x - bckgDimensions[0] / 2,
node.y - bckgDimensions[1] / 2 + nodeHeightOffset,
...bckgDimensions
);
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "white";
ctx.fillText(label, node.x, node.y + nodeHeightOffset);
}
// 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";
}
linkCanvasObjectMode(link) {
var toolValue = this.tool.linkCanvasObjectMode(link);
if (toolValue !== undefined) {
return toolValue;
}
return "replace";
}
linkCanvasObject(link, ctx, globalScale) {
var toolValue = this.tool.linkCanvasObject(link, ctx);
if (toolValue !== undefined) {
return toolValue;
}
// Links already initialized?
if (link.source.x === undefined) {
return undefined;
}
// Draw gradient link
var gradient = ctx.createLinearGradient(
link.source.x,
link.source.y,
link.target.x,
link.target.y
);
// Have reversed colors
// Color at source node referencing the target node and vice versa
gradient.addColorStop("0", Editor.globalGraph.getNodeColor(link.target));
gradient.addColorStop("1", Editor.globalGraph.getNodeColor(link.source));
ctx.beginPath();
ctx.moveTo(link.source.x, link.source.y);
ctx.lineTo(link.target.x, link.target.y);
ctx.strokeStyle = gradient;
ctx.stroke();
// Only render strokes on last link
// var lastLink = graph.data[Graph.GRAPH_LINKS][graph.data[Graph.GRAPH_LINKS].length - 1];
// if (link === lastLink) {
// ctx.stroke();
// }
linkWidth(link) {
var toolValue = this.tool.linkWidth(link);
if (toolValue !== undefined) {
return toolValue;
}
return this.isLinkHighlighted(link) ? 2 : 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);
}
isLinkHighlighted(link) {
return (
this.selectedItem === link ||
Editor.globalGraph.isLinkOnNode(link, this.selectedItem)
setLabelVisibility(visibility) {
this.labelVisible = visibility;
}