BrowserLogic/js/baseclasses.js

256 lines
9.6 KiB
JavaScript

class CanvasTools {
constructor() {
}
textSize(ctx,text,fontStyle) {
ctx.save();
ctx.font = fontStyle;
let tHeight = Math.round(ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent);
let tWidth = Math.round(ctx.measureText(text).width);
ctx.restore();
return {
width: tWidth,
height: tHeight
};
}
drawBorderBox(ctx,x,y,drawWidth,drawHeight,borderWidth=1,borderColor="#000",fillColor="#f7e979",shadowColor = "transparent") {
ctx.save();
ctx.beginPath();
ctx.fillStyle = borderColor;
if (shadowColor != "transparent") {
ctx.shadowBlur = "6";
ctx.shadowColor = shadowColor;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.stroke();
}
ctx.fillRect(x,y,drawWidth,drawHeight);
ctx.fillStyle = fillColor;
ctx.fillRect(x+borderWidth,y+borderWidth,drawWidth-(borderWidth*2),drawHeight-(borderWidth*2));
ctx.restore();
}
drawTextCentered(ctx,x,y,x2,y2,text,fontStyle="24px Console",fontColor = "#555") {
ctx.save();
ctx.font = fontStyle;
ctx.fillStyle = fontColor;
let tHeight = ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent;
let tX = x+((x2/2)-(ctx.measureText(text).width/2));
let tY = y+tHeight+((y2/2)-(tHeight/2));
ctx.fillText(text,tX,tY);
ctx.restore();
}
drawText(ctx,x,y,text,fontStyle="24px Console",fontColor = "#555") {
ctx.save();
ctx.font = fontStyle;
ctx.fillStyle = fontColor;
ctx.fillText(text,x,y);
ctx.restore();
}
}
class ContainerConnection {
constructor(fromElementContainer,toElementContainer,fromElement,toElement,input) {
this.fromElementContainer = fromElementContainer;
this.toElementContainer = toElementContainer;
this.fromElement = fromElement;
this.toElement = toElement;
this.Input = input;
}
toJSON(key) {
return {
fromElement: (this.fromElement) ? this.fromElement.Designator : null,
toElement: (this.toElement) ? this.toElement.Designator : null,
Input: parseInt(this.Input)
};
}
}
class elementContainer {
constructor() {
this.Elements = new Array();
this.Selected = false;
this.Inputs = new Array();
this.Outputs = new Array();
this.ICOutputs = 0;
}
toJSON(key) {
let elements = new Array();
for (let a = 0; a < this.Elements.length; a++) {
elements.push(this.Elements[a].toJSON());
}
return elements;
}
AddElement(element) {
let designatorNumber = 1;
let designatorTest = element.Name + designatorNumber;
let unused = false;
while (!unused) {
let foundMatch = false;
for (let a=0;a < this.Elements.length;a++) {
if (this.Elements[a].Designator == designatorTest) foundMatch = true;
}
if (foundMatch) {
designatorNumber++;
designatorTest = element.Name + designatorNumber;
} else {
unused = true;
element.Designator = designatorTest;
this.Elements.push(element);
}
}
}
DeleteElement(element) {
// Can pass object or Designator
for (let a = 0; a < this.Elements.length; a++) {
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
this.Elements[a].Delete();
this.Elements.splice(a,1);
return true;
}
}
return false;
}
HasElement(element) {
// Can pass object or Designator
for (let a = 0; a < this.Elements.length; a++) {
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
return this.Elements[a];
}
}
return false;
}
DrawAll(ctx,settings) {
let ICOuts = 0;
for (let a = 0; a < this.Elements.length; a++) {
ctx.save();
if (this.Elements[a] instanceof ICOutput) ICOuts++;
if (this.Elements[a] == this.Selected) this.Elements[a].drawBorderBox(ctx, this.Elements[a].X - 2, this.Elements[a].Y - 2, this.Elements[a].Width + 4, this.Elements[a].Height + 4, 1, "rgba(100,200,255,0.25)", "rgba(100,200,255,0.25)");
this.Elements[a].drawElement(this.Elements[a].X, this.Elements[a].Y, ctx);
ctx.font = "10px Console";
let x = this.Elements[a].X;
let y = this.Elements[a].Y + (this.Elements[a].Height - 12);
let x2 = this.Elements[a].Width;
let y2 = 10;
//this.Elements[a].drawTextCentered(ctx, x, y, x2, y2, this.Elements[a].Designator, ctx.font, "#000");
ctx.restore();
}
this.ICOutputs = ICOuts;
if (!this.Selected) {
let PropertiesBox = document.getElementById("PropertiesBox");
if (PropertiesBox.style.display != "none") PropertiesBox.style.display = "none";
}
for (let a = 0; a < this.Elements.length; a++) {
// Not ideal to loop twice but we need the connections drawn all at once to prevent layer issues
this.Elements[a].drawConnections(ctx, settings);
}
}
Select(element) {
this.Selected = element;
let PropertiesBox = document.getElementById("PropertiesBox");
let PropertiesBoxTitle = document.getElementById("PropertiesBoxTitle");
let PropertiesBoxContent = document.getElementById("PropertiesBoxContent");
PropertiesBoxTitle.innerText = this.Selected.Designator + " Properties";
let contentString = "<table id='propertiesTable'>";
for (let a = 0; a < this.Selected.Properties.length;a++) {
contentString += "<tr><td>" + this.Selected.Properties[a].Name + "</td><td>";
switch (this.Selected.Properties[a].Type) {
case "int":
contentString += "<input type='number' id='prop_" + this.Selected.Properties[a].Name + "' min='" + this.Selected.Properties[a].Minimium + "' max='" + this.Selected.Properties[a].Maximium + "' value='" + this.Selected.Properties[a].CurrentValue + "' onchange='logicEngine.PropertyChange(" + String.fromCharCode(34) + this.Selected.Properties[a].Name + String.fromCharCode(34) +");'>";
break;
case "string":
contentString += '<input type="text" id="prop_' + this.Selected.Properties[a].Name + '" minlength="' + this.Selected.Properties[a].Minimium + '" maxlength="' + this.Selected.Properties[a].Maximium + '" value="' + this.Selected.Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
break;
case "color":
contentString += '<input type="color" id="prop_' + this.Selected.Properties[a].Name + '" value="' + this.Selected.Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
break;
case "list":
contentString += '<select id="prop_' + this.Selected.Properties[a].Name + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
for (let b = 0; b < this.Selected.Properties[a].Values.length; b++) {
contentString += '<option value="' + this.Selected.Properties[a].Values[b].Value + '" '+ ((this.Selected.Properties[a].Values[b].Value == this.Selected.Properties[a].CurrentValue) ? ' selected' : '') + '>' + this.Selected.Properties[a].Values[b].String + '</option>';
}
contentString += '</select>';
break;
}
contentString += "</td></tr>";
}
PropertiesBoxContent.innerHTML = contentString;
PropertiesBox.style.display = "block";
}
checkMouseBounds(mousePos) {
// We go backwards so that the newest (highest drawn) element is clicked before one lower.
for (let a = (this.Elements.length - 1); a >= 0; a--) {
if (this.Elements[a].mouseInside(mousePos)) return this.Elements[a];
}
return false;
}
checkOverlayBounds(x,y,width,height) {
for (let a = 0; a < this.Elements.length; a++) {
if ((x >= this.Elements[a].X) && (x <= (this.Elements[a].X + this.Elements[a].Width)) && (y >= this.Elements[a].Y) && (y <= (this.Elements[a].Y + this.Elements[a].Height))) return this.Elements[a];
if (((x + width) >= this.Elements[a].X) && ((x + width) <= (this.Elements[a].X + this.Elements[a].Width)) && (y >= this.Elements[a].Y) && (y <= (this.Elements[a].Y + this.Elements[a].Height))) return this.Elements[a];
if ((x >= this.Elements[a].X) && (x <= (this.Elements[a].X + this.Elements[a].Width)) && ((y + height) >= this.Elements[a].Y) && ((y + height) <= (this.Elements[a].Y + this.Elements[a].Height))) return this.Elements[a];
if (((x + width) >= this.Elements[a].X) && ((x + width) <= (this.Elements[a].X + this.Elements[a].Width)) && ((y + height) >= this.Elements[a].Y) && ((y + height) <= (this.Elements[a].Y + this.Elements[a].Height))) return this.Elements[a];
}
return false;
}
}
class ElementCatalog_Category {
constructor(name,icon) {
this.Name = name;
this.Icon = icon;
this.Elements = new Array();
}
addElement(element) {
if (element instanceof ElementCatalog_Element) {
this.Elements.push(element);
}
}
}
class ElementCatalog_Element {
constructor(name,description,icon,classref,args) {
this.Name = name;
this.Description = description;
this.Icon = icon;
this.Class = classref;
this.Args = args;
}
}
class ElementCatalog {
constructor(categories = new Array()) {
this.Categories = categories;
for (let a = 0; a < this.Categories.length; a++) {
if (!this.Categories[a] instanceof ElementCatalog_Category) {
this.Categories.splice(a,1);
a--;
}
}
}
addCategory(category) {
if (category instanceof ElementCatalog_Category) {
this.Categories.push(category);
}
}
}