BrowserLogic/js/baseclasses.js

330 lines
12 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;
}
isSelected(element) {
if (this.Selected) {
for (let a = 0; a < this.Selected.length; a++) {
if (this.Selected[a] == element) return true;
}
}
return false;
}
isHigh(element,input) {
let isHigh = false;
for (let a = 0; a < this.Elements.length; a++) {
let conn = this.Elements[a].ConnectsTo(element,input);
if (conn !== false) {
if (this.Elements[a].getOutput(conn)) isHigh = true;
}
}
return isHigh;
}
clearRedraw() {
for (let a = 0; a < this.Elements.length; a++) {
this.Elements[a].redraw = false;
}
}
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, or array
if (Array.isArray(element)) {
let returnval = false;
for (let a = 0; a < element.length; a++) {
for (let b = 0; b < this.Elements.length; b++) {
if ((this.Elements[b] == element[a]) || (this.Elements[b].Designator == element[a])) {
this.Elements[b].Delete();
this.Elements.splice(b, 1);
b--;
returnval = true;
}
}
}
return returnval;
} else {
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;
}
Disconnect(element) {
if (!element) return false;
if (Array.isArray(element)) {
for (let a = 0; a < this.Elements.length; a++) {
for (let b = 0; b < element.length; b++) {
this.Elements[a].Disconnect(element[b]);
}
}
} else {
for (let a = 0; a < this.Elements.length; a++) {
this.Elements[a].Disconnect(element);
}
}
}
DrawAll(ctx,settings) {
let ICOuts = 0;
if (!logicEngine.Settings.TopConnections && !logicEngine.Settings.HideConnections) {
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);
}
}
for (let a = 0; a < this.Elements.length; a++) {
if (this.Elements[a] instanceof ICOutput) ICOuts++;
if (this.Elements[a].isVisible()) {
ctx.save();
if (this.isSelected(this.Elements[a])) 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.restore();
}
}
this.ICOutputs = ICOuts;
if (!this.Selected) {
if (this.Selected.length == 1) {
let PropertiesBox = document.getElementById("PropertiesBox");
if (PropertiesBox.style.display != "none") PropertiesBox.style.display = "none";
}
}
if (logicEngine.Settings.TopConnections && !logicEngine.Settings.HideConnections) {
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);
}
}
}
SelectWithin(x1,y1,x2,y2) {
let selectedArray = new Array();
for (let a = 0; a < this.Elements.length; a++) {
if ((this.Elements[a].X >= x1) && ((this.Elements[a].X + this.Elements[a].Width) <= x2) && (this.Elements[a].Y >= y1) && ((this.Elements[a].Y + this.Elements[a].Height) <= y2)) selectedArray.push(this.Elements[a]);
}
this.Selected = selectedArray;
}
Select(element) {
this.Selected = new Array(element);
let PropertiesBox = document.getElementById("PropertiesBox");
let PropertiesBoxTitle = document.getElementById("PropertiesBoxTitle");
let PropertiesBoxContent = document.getElementById("PropertiesBoxContent");
PropertiesBoxTitle.innerText = this.Selected[0].Designator + " Properties";
let contentString = "<table id='propertiesTable'>";
for (let a = 0; a < this.Selected[0].Properties.length;a++) {
contentString += "<tr><td>" + this.Selected[0].Properties[a].Name + "</td><td>";
switch (this.Selected[0].Properties[a].Type) {
case "int":
contentString += "<input type='number' id='prop_" + this.Selected[0].Properties[a].Name + "' min='" + this.Selected[0].Properties[a].Minimium + "' max='" + this.Selected[0].Properties[a].Maximium + "' value='" + this.Selected[0].Properties[a].CurrentValue + "' onchange='logicEngine.PropertyChange(" + String.fromCharCode(34) + this.Selected[0].Properties[a].Name + String.fromCharCode(34) +");'>";
break;
case "string":
contentString += '<input type="text" id="prop_' + this.Selected[0].Properties[a].Name + '" minlength="' + this.Selected[0].Properties[a].Minimium + '" maxlength="' + this.Selected[0].Properties[a].Maximium + '" value="' + this.Selected[0].Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
break;
case "color":
contentString += '<input type="color" id="prop_' + this.Selected[0].Properties[a].Name + '" value="' + this.Selected[0].Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
break;
case "list":
contentString += '<select id="prop_' + this.Selected[0].Properties[a].Name + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
for (let b = 0; b < this.Selected[0].Properties[a].Values.length; b++) {
contentString += '<option value="' + this.Selected[0].Properties[a].Values[b].Value + '" '+ ((this.Selected[0].Properties[a].Values[b].Value == this.Selected[0].Properties[a].CurrentValue) ? ' selected' : '') + '>' + this.Selected[0].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);
}
}
}