got a context menu for editing + deleting (todo)

This commit is contained in:
BroodjeAap 2022-09-19 18:56:29 +00:00
parent b9e7b57135
commit 3b2db2b295
2 changed files with 247 additions and 4 deletions

View file

@ -67,6 +67,103 @@ var DiagramNode = /** @class */ (function () {
};
return DiagramNode;
}());
var ContextMenuItem = /** @class */ (function () {
function ContextMenuItem(label, callback) {
this.x = 0;
this.y = 0;
this.hover = false;
this.callback = function (node) { };
this.label = label;
this.callback = callback;
}
return ContextMenuItem;
}());
var ContextMenu = /** @class */ (function () {
function ContextMenu(ctx) {
this.x = 0;
this.y = 0;
this.active = false;
this.mouseOver = false;
this.textWidth = 0;
this.textHeight = 0;
this.textMargin = 0;
this.width = 0;
this.height = 0;
this.items = new Array();
this.contextNode = null;
this.ctx = ctx;
this.ctx.font = "20px Helvetica";
var textSize = this.ctx.measureText("SomeLongerText");
this.textWidth = textSize.width;
this.textHeight = textSize.actualBoundingBoxAscent + textSize.actualBoundingBoxDescent;
this.textMargin = this.textWidth / 8;
}
ContextMenu.prototype.fitContextMenu = function () {
this.width = this.textWidth + this.textMargin * 2;
this.height = this.textHeight + this.textMargin * (this.items.length + 2);
var index = 0;
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
var item = _a[_i];
item.x = this.textMargin;
item.y = this.textHeight * index + this.textMargin * (index + 2);
index++;
}
};
ContextMenu.prototype.pointIn = function (x, y) {
if (x < this.x) {
this.mouseOver = false;
return false;
}
if (y < this.y) {
this.mouseOver = false;
return false;
}
if (x > this.x + this.width) {
this.mouseOver = false;
return false;
}
if (y > this.y + this.height) {
this.mouseOver = false;
return false;
}
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
var item = _a[_i];
if (y >= this.y + item.y - this.textHeight && y <= this.y + item.y + this.textHeight) {
item.hover = true;
}
else {
item.hover = false;
}
}
this.mouseOver = true;
return true;
};
ContextMenu.prototype.clickOn = function () {
if (this.contextNode == null) {
console.warn("No contextNode");
return;
}
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
var item = _a[_i];
console.log(item.hover);
if (item.hover) {
item.callback(this.contextNode);
}
}
};
ContextMenu.prototype.draw = function () {
var cameraX = _diagram.cameraX;
var cameraY = _diagram.cameraY;
this.ctx.fillStyle = "lightblue";
this.ctx.fillRect(this.x + cameraX, this.y + cameraY, this.width, this.height);
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
var item = _a[_i];
this.ctx.fillStyle = this.mouseOver && item.hover ? "red" : "black";
this.ctx.fillText(item.label, this.x + item.x + cameraX, this.y + item.y + cameraY);
}
};
return ContextMenu;
}());
var _diagram;
function diargramOnResize() {
_diagram.onresize();
@ -113,6 +210,10 @@ var Diagrams = /** @class */ (function () {
}
_diagram = this;
this.ctx = ctx;
this.contextMenu = new ContextMenu(this.ctx);
this.contextMenu.items.push(new ContextMenuItem("Edit", editNodeCallback));
this.contextMenu.items.push(new ContextMenuItem("Delete", editNodeCallback));
this.contextMenu.fitContextMenu();
this.ctx.font = "20px Helvetica";
this.canvas.onmousemove = diagramOnMouseMove;
this.canvas.onmousedown = diagramOnMouseDown;
@ -128,7 +229,10 @@ var Diagrams = /** @class */ (function () {
this.mouseY = ev.y - canvasRect.top;
this.worldX = this.mouseX - this.cameraX;
this.worldY = this.mouseY - this.cameraY;
if (this.nodeHover != null) {
if (this.contextMenu.active) {
this.contextMenu.pointIn(this.worldX, this.worldY);
}
else if (this.nodeHover != null) {
this.nodeHover.hover = false;
this.nodeHover.inputHover = false;
this.nodeHover.outputHover = false;
@ -172,6 +276,7 @@ var Diagrams = /** @class */ (function () {
if (ev.button != 0) {
return;
}
//this.contextMenu.active = false;
var canvasRect = this.canvas.getBoundingClientRect();
this.mouseX = ev.x - canvasRect.left;
this.mouseY = ev.y - canvasRect.top;
@ -200,7 +305,11 @@ var Diagrams = /** @class */ (function () {
for (var _i = 0, _a = this.nodes; _i < _a.length; _i++) {
var node = _a[_i];
if (node.pointInNode(this.worldX, this.worldY)) {
this.editNodeCallback(node);
this.contextMenu.x = this.worldX;
this.contextMenu.y = this.worldY;
this.contextMenu.active = true;
this.contextMenu.contextNode = node;
this.draw();
}
}
}
@ -230,6 +339,13 @@ var Diagrams = /** @class */ (function () {
}
this.makingConnectionNode = null;
}
if (this.contextMenu.active) {
if (this.contextMenu.pointIn(this.worldX, this.worldY)) {
this.contextMenu.clickOn();
this.draw();
}
this.contextMenu.active = false;
}
for (var _g = 0, _h = this.connections; _g < _h.length; _g++) {
var _j = _h[_g], output = _j[0], input = _j[1];
var _k = output.getOutputCircleXY(), outputX = _k[0], outputY = _k[1];
@ -338,6 +454,9 @@ var Diagrams = /** @class */ (function () {
this.ctx.arc(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians);
this.ctx.fill();
}
if (this.contextMenu.active) {
this.contextMenu.draw();
}
};
Diagrams.prototype.addNode = function (id, x, y, label, meta) {
if (meta === void 0) { meta = {}; }

View file

@ -91,6 +91,106 @@ class DiagramNode {
}
}
class ContextMenuItem {
x: number = 0;
y: number = 0;
hover: boolean = false;
callback: (node: DiagramNode) => void = function(node){}
label: string;
constructor(label: string, callback: (node: DiagramNode) => void){
this.label = label;
this.callback = callback;
}
}
class ContextMenu {
x: number = 0;
y: number = 0;
active: boolean = false;
mouseOver: boolean = false;
textWidth: number = 0;
textHeight: number = 0;
textMargin: number = 0;
width: number = 0;
height: number = 0;
ctx: CanvasRenderingContext2D;
items: Array<ContextMenuItem> = new Array();
contextNode: DiagramNode | null = null;
constructor(ctx: CanvasRenderingContext2D){
this.ctx = ctx;
this.ctx.font = "20px Helvetica";
let textSize = this.ctx.measureText("SomeLongerText");
this.textWidth = textSize.width;
this.textHeight = textSize.actualBoundingBoxAscent + textSize.actualBoundingBoxDescent;
this.textMargin = this.textWidth / 8;
}
fitContextMenu(){
this.width = this.textWidth + this.textMargin * 2;
this.height = this.textHeight + this.textMargin * (this.items.length + 2)
let index = 0;
for (let item of this.items){
item.x = this.textMargin;
item.y = this.textHeight * index + this.textMargin * (index + 2);
index++;
}
}
pointIn(x: number, y: number){
if (x < this.x){
this.mouseOver = false;
return false;
}
if (y < this.y){
this.mouseOver = false;
return false;
}
if (x > this.x + this.width) {
this.mouseOver = false;
return false;
}
if (y > this.y + this.height) {
this.mouseOver = false;
return false;
}
for (let item of this.items){
if (y >= this.y + item.y - this.textHeight && y <= this.y + item.y + this.textHeight){
item.hover = true;
} else {
item.hover = false;
}
}
this.mouseOver = true;
return true;
}
clickOn(){
if(this.contextNode == null){
console.warn("No contextNode");
return
}
for (let item of this.items){
console.log(item.hover);
if(item.hover){
item.callback(this.contextNode);
}
}
}
draw(){
let cameraX = _diagram.cameraX;
let cameraY = _diagram.cameraY;
this.ctx.fillStyle = "lightblue";
this.ctx.fillRect(this.x + cameraX, this.y + cameraY, this.width, this.height);
for (let item of this.items){
this.ctx.fillStyle = this.mouseOver && item.hover ? "red" : "black";
this.ctx.fillText(item.label, this.x + item.x + cameraX, this.y + item.y + cameraY);
}
}
}
let _diagram: Diagrams;
function diargramOnResize(){
_diagram.onresize();
@ -137,6 +237,8 @@ class Diagrams {
editNodeCallback: (node: DiagramNode) => void = function (){};
contextMenu: ContextMenu;
constructor(canvasId: string, editNodeCallback: (node: DiagramNode) => void = function (){}){
this.canvas = document.getElementById(canvasId) as HTMLCanvasElement;
if (this.canvas === null){
@ -148,6 +250,10 @@ class Diagrams {
}
_diagram = this;
this.ctx = ctx;
this.contextMenu = new ContextMenu(this.ctx);
this.contextMenu.items.push(new ContextMenuItem("Edit", editNodeCallback))
this.contextMenu.items.push(new ContextMenuItem("Delete", editNodeCallback))
this.contextMenu.fitContextMenu();
this.ctx.font = "20px Helvetica";
this.canvas.onmousemove = diagramOnMouseMove;
this.canvas.onmousedown = diagramOnMouseDown;
@ -165,7 +271,9 @@ class Diagrams {
this.worldX = this.mouseX - this.cameraX;
this.worldY = this.mouseY - this.cameraY;
if (this.nodeHover != null){
if (this.contextMenu.active){
this.contextMenu.pointIn(this.worldX, this.worldY);
} else if (this.nodeHover != null){
this.nodeHover.hover = false;
this.nodeHover.inputHover = false
this.nodeHover.outputHover = false
@ -207,6 +315,8 @@ class Diagrams {
if (ev.button != 0){
return;
}
//this.contextMenu.active = false;
let canvasRect = this.canvas.getBoundingClientRect();
this.mouseX = ev.x - canvasRect.left;
@ -235,7 +345,11 @@ class Diagrams {
if (ev.button == 2) {
for (let node of this.nodes){
if (node.pointInNode(this.worldX, this.worldY)){
this.editNodeCallback(node);
this.contextMenu.x = this.worldX;
this.contextMenu.y = this.worldY;
this.contextMenu.active = true;
this.contextMenu.contextNode = node;
this.draw();
}
}
}
@ -264,6 +378,13 @@ class Diagrams {
}
this.makingConnectionNode = null;
}
if (this.contextMenu.active){
if (this.contextMenu.pointIn(this.worldX, this.worldY)){
this.contextMenu.clickOn();
this.draw();
}
this.contextMenu.active = false;
}
for (let [output, input] of this.connections){
let [outputX, outputY] = output.getOutputCircleXY();
@ -399,6 +520,9 @@ class Diagrams {
this.ctx.arc(node.x + node.width + this.cameraX, node.y + node.height / 2 + this.cameraY, node.height / 3, 0, fullCircleRadians);
this.ctx.fill();
}
if (this.contextMenu.active){
this.contextMenu.draw();
}
}
addNode(id: number, x: number, y: number, label: string, meta: Object = {}){