From 131cf088db60db81ba89ebb30b80ca6ef4ffbbc4 Mon Sep 17 00:00:00 2001 From: MatCat Date: Sun, 7 Mar 2021 01:01:37 -0800 Subject: [PATCH] 0.4.0: Release --- README.md | 5 +- css/main.css | 15 +++ index.html | 22 +++-- js/baseclasses.js | 27 +++++- js/elements.js | 215 ++++++++++++++++++++++++++---------------- js/globalfunctions.js | 11 ++- js/logicengine.js | 12 ++- js/main.js | 64 ++++++++++++- 8 files changed, 270 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index f313df3..e7d6427 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,15 @@ To be decided, but at this moment this code is open source and free to use for n * You can now pan the work area, hold ctrl key while mouse dragging an empty area. * Right Click Menu - * If an item is selected you can delete or disconnect them (BUG WIP: Doesn't disconnect IC's) + * If an item is selected you can delete or disconnect them * Top menu * New / Open / Save moved to File menu + * You can now disable connection drawing, or put them above or below elements in View menu * There is now a pan to center feature in View menu * Create IC has been moved to Tools menu * Help menu -> About opens the Welcome Window * Save dialog -* Fixed bug +* Fixed various small bugs ### 0.3.10 * Added BCD and Decimal options to the 4 bit output display, as well as bit labels in inputs diff --git a/css/main.css b/css/main.css index ace2903..8c82bf1 100644 --- a/css/main.css +++ b/css/main.css @@ -339,6 +339,21 @@ textarea { padding: 5px; } +.TOOLBOX_CATEGORY_BODY input { + font-size: 0.9em; + padding: 1px; + text-shadow: 0 1px 0 rgba(180, 180, 180, 0.4), + 1px 0 0 rgba(180, 180, 180, 0.4); + + /* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#f5f6f6+0,dbdce2+21,b8bac6+49,dddfe3+80,f5f6f6+100;Grey+Pipe */ + background: rgb(245,246,246); /* Old browsers */ + background: -moz-linear-gradient(top, rgba(245,246,246,1) 0%, rgba(219,220,226,1) 21%, rgba(184,186,198,1) 49%, rgba(221,223,227,1) 80%, rgba(245,246,246,1) 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(top, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to bottom, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f6f6', endColorstr='#f5f6f6',GradientType=0 ); /* IE6-9 */ + +} + #darkout-overlay { position: absolute; left: 0px; diff --git a/index.html b/index.html index 74eb6d1..2cd94bb 100644 --- a/index.html +++ b/index.html @@ -26,6 +26,7 @@

MatCat BrowserLogic Engine

Welcome to logic.parts, a free to use logic simulator for anyone to use. This is opensource software, you can find the project at https://www.mygit.space/MatCat.OpenSource/BrowserLogic. This is an early development project, so expect bugs and some things to not work :) If you would like to contribute please feel free to find me on IRC on Freenode in channel #LogicParts.

+

Now on Version 0.4! This new version brings an improved UI, panning, more settings options, and much more!


@@ -42,24 +43,24 @@
  • New
  • Open
  • Save
  • -
  • Save As
  • +
  • Save As
  • Edit
      -
    • Undo
    • -
    • Redo
    • +
    • Undo
    • +
    • Redo
    • -
    • Cut
    • -
    • Copy
    • -
    • Paste
    • +
    • Cut
    • +
    • Copy
    • +
    • Paste
    • Delete
    • Disconnect
    • -
    • Select All
    • +
    • Select All
  • @@ -68,16 +69,21 @@
  • Tools
      -
    • Create IC
    • +
    • Create IC
  • diff --git a/js/baseclasses.js b/js/baseclasses.js index 9403d14..988224c 100644 --- a/js/baseclasses.js +++ b/js/baseclasses.js @@ -80,6 +80,17 @@ class elementContainer { this.ICOutputs = 0; } + 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; + } + toJSON(key) { let elements = new Array(); for (let a = 0; a < this.Elements.length; a++) { @@ -140,6 +151,14 @@ class elementContainer { 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()) { @@ -156,9 +175,11 @@ class elementContainer { 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); + 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); + } } } diff --git a/js/elements.js b/js/elements.js index 42bce78..4ebdd41 100644 --- a/js/elements.js +++ b/js/elements.js @@ -76,7 +76,7 @@ class ElementConnection { class Element extends CanvasTools { - constructor(RestoreData = null,logicengine,Inputs) { + constructor(_Container,RestoreData = null,logicengine,Inputs) { super(); this.Name = "Element"; this.Designator = ""; @@ -97,6 +97,7 @@ class Element extends CanvasTools { this.OutputLabels = new Array(1); this.NoOutput = false; this.OutputLink = 0; + this._Container = _Container; let inputProperty = new ElementProperty("Inputs","int",{CBObject: this,CBFunction: "ChangeInputs"},2,Inputs,false,2); this.Properties.push(inputProperty); @@ -120,25 +121,42 @@ class Element extends CanvasTools { } } + ConnectsTo(element,input = false) { + for (let a = 0; a < this.OutputConnections.length; a++) { + if (this.OutputConnections[a].Element == element || this.OutputConnections[a].Element.Designator == element) { + if (input !== false) { + if (this.OutputConnections[a].Input == input) return this.OutputConnections[a].Output; + } else { + return 0; + } + } + } + return false; + } + isVisible() { let isvisible = false; - let LeftX = this.LogicEngine.Panning.OffsetX; - if (LeftX < 0) { - LeftX = Math.abs(LeftX); - } else { - LeftX = -Math.abs(LeftX); + if (this.LogicEngine) { + let LeftX = this.LogicEngine.Panning.OffsetX; + if (LeftX < 0) { + LeftX = Math.abs(LeftX); + } else { + LeftX = -Math.abs(LeftX); + } + let RightX = LeftX + this.LogicEngine.Canvas.width; + let TopY = this.LogicEngine.Panning.OffsetY; + if (TopY < 0) { + TopY = Math.abs(TopY); + } else { + TopY = -Math.abs(TopY); + } + let BottomY = TopY + this.LogicEngine.Canvas.height; + if (((this.X + this.Width) >= LeftX) && ((this.X) <= RightX) && ((this.Y + this.Height) >= TopY) && ((this.Y) <= BottomY)) isvisible = true; } - let RightX = LeftX + this.LogicEngine.Canvas.width; - let TopY = this.LogicEngine.Panning.OffsetY; - if (TopY < 0) { - TopY = Math.abs(TopY); - } else { - TopY = -Math.abs(TopY); - } - let BottomY = TopY + this.LogicEngine.Canvas.height; - if (((this.X + this.Width) >= LeftX) && ((this.X) <= RightX) && ((this.Y + this.Height) >= TopY) && ((this.Y) <= BottomY)) isvisible = true; return isvisible; + } + toJSON(key) { return { Name: this.Name, @@ -195,8 +213,10 @@ class Element extends CanvasTools { for (let a = 0; a < this.OutputConnections.length; a++) { if (this.OutputConnections[a].Element == element) { this.LogicEngine.RecursionCount = 0; - this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, false); + let element = this.OutputConnections[a].Element; + let input = this.OutputConnections[a].Input; this.OutputConnections.splice(a,1); + element.setInput(input, false); a--; } } @@ -259,7 +279,6 @@ class Element extends CanvasTools { firstY+ (a*24), ctxMousePos.x, ctxMousePos.y); - console.log("Distance from " + a + ": " + mouseDist); if (mouseDist <= (this.outputCircleRadius)) { this.OutputLink = {Output: a,x: this.X+(this.Width-10), y: firstY+ (a*24)}; this.LogicEngine.Link(); @@ -414,6 +433,9 @@ class Element extends CanvasTools { } else { return; } + let isHigh = this._Container.isHigh(this,Input); + if (isHigh !== false) this.Inputs[Input] = true; + if (isHigh === false) this.Inputs[Input] = false; this.setConnections(); } @@ -437,8 +459,8 @@ class Element extends CanvasTools { } class LabelElement extends Element { - constructor(RestoreData = null,logicengine) { - super(RestoreData,logicengine,0); + constructor(_Container, RestoreData = null,logicengine) { + super(_Container, RestoreData,logicengine,0); this.removeProperty("Inputs"); this.Name = "Label"; this.Font = "48px Console"; @@ -485,7 +507,7 @@ class LabelElement extends Element { this.drawTextCentered(ctx,x,y,textWidth.width,textWidth.height,this.Label,this.Font,this.FontStyle); } } -let ElementCatalog_Label = new ElementCatalog_Element("Label","Allows you to place a label","abc",LabelElement,[]); +let ElementCatalog_Label = new ElementCatalog_Element("Label","Allows you to place a label","🏷",LabelElement,[]); ElementReferenceTable.push(ElementCatalog_Label); ElementCategory_Other.addElement(ElementCatalog_Label); @@ -497,8 +519,8 @@ class ICInput extends Element { this.Output = false; } - constructor(RestoreData = null,logicengine) { - super(RestoreData ,logicengine,0); + constructor(_Container, RestoreData = null,logicengine) { + super(_Container, RestoreData ,logicengine,0); this.removeProperty("Inputs"); this.Task = new Task("ICInputTask","CLOCK",0,1,this.ClockTick.bind(this)); this.Name = "ICInput"; @@ -526,8 +548,9 @@ class ICInput extends Element { setInput(notused = 0,value) { if (notused > 0) return; - if (!value) this.Input = false; - if (value) this.Input = true; + + if (value === false) this.Input = false; + if (value !== false) this.Input = true; if (!this.Task.Enabled) { this.Task.LastCall = 0; @@ -577,8 +600,8 @@ class ICOutput extends Element { this.Output = false; } - constructor(RestoreData = null,logicengine) { - super(RestoreData ,logicengine,1); + constructor(_Container, RestoreData = null,logicengine) { + super(_Container, RestoreData ,logicengine,1); this.removeProperty("Inputs"); this.Task = new Task("ICOutputTask","CLOCK",0,1,this.ClockTick.bind(this)); this.Name = "ICOutput"; @@ -607,12 +630,12 @@ class ICOutput extends Element { setInput(notused = 0,value) { if (notused > 0) return; - if (!value) this.Input = false; - if (value) this.Input = true; + value = this._Container.isHigh(this,0); + if (value === false) this.Input = false; + if (value !== false) this.Input = true; this.Inputs[0] = this.Input; if (!this.Task.Enabled) { - console.log("Starting timer"); this.Task.LastCall = 0; this.Task.Enabled = true; } @@ -657,7 +680,7 @@ ElementReferenceTable.push(ElementCatalog_ICOutput); ElementCategory_ICs.addElement(ElementCatalog_ICOutput); class ICElement extends Element { - constructor(RestoreData = null, logicengine,ICSettings = null) { + constructor(_Container, RestoreData = null, logicengine,ICSettings = null) { let newContainer = false; @@ -686,7 +709,7 @@ class ICElement extends Element { let totalInputs = ICSettings.Inputs.length; let totalOutputs = ICSettings.Outputs.length; - super(RestoreData, logicengine, totalInputs); + super(_Container, RestoreData, logicengine, totalInputs); this.removeProperty("Inputs"); this.ICBlueprint = icContainer; this.Outputs = ICSettings.Outputs; @@ -715,10 +738,28 @@ class ICElement extends Element { return superjson; } + Disconnect(element = false) { + super.Disconnect(element); + if (element) { + for (let a = 0; a < this.Outputs.length; a++) { + if (this.Outputs[a].toElement == element || this.Outputs[a].fromElement == element) { + if (this.Outputs[a].toElement == element) { + // It's a too element, we need to tell it we are not high anymore + } else { + // Its a from element, we need to tell it's too element + } + } + } + } else { + // We are disconnecting all of our own connections + for (let a = 0; a < this.Outputs.length; a++) { + + } + } + } + addConnection(container, element, input, output = 0) { - console.log("IC Add Connection " + element.Designator + " I:" + input + " O:"+output); super.addConnection(container, element, input, output); - console.log(this.OutputConnections); this.Outputs[output].toElementContainer = container; this.Outputs[output].toElement = element; this.Outputs[output].Input = input; @@ -728,7 +769,7 @@ class ICElement extends Element { setInput(Input, Value) { if (this.InputConnections.length >= Input) { // No need to worry about recursion as this goes to an input element which is buffered - this.Inputs[Input] = Value; + this.Inputs[Input] = (Value === false) ? false : true; //console.log("Calling " + this.InputConnections[Input].toElement.Designator); this.InputConnections[Input].toElement.setInput(this.InputConnections[Input].Input,Value); } @@ -824,7 +865,9 @@ class ClockElement extends Element { } setInput(Input, Value) { + console.log(this.Designator + " got told to set " + Input + " to value " + Value); super.setInput(Input, Value); + if (!this.Inputs[0]) { this.Output = false; this.Task.LastCall = 0; @@ -838,8 +881,8 @@ class ClockElement extends Element { } } - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,1); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,1); this.removeProperty("Inputs"); this.Name = "Clock"; this.Period = 1000; @@ -937,8 +980,10 @@ class PulseElement extends Element { setInput(Input, Value) { if (Input > 0) return; + + Value = this._Container.isHigh(this,Input); //super.setInput(Input, Value); - this.Inputs[Input] = Value; + this.Inputs[Input] = (Value === false) ? false : true; if (this.Inputs[0] && !this.Task.Enabled) { this.Output = true; for (let a = 0; a < this.OutputConnections.length;a++) { @@ -950,8 +995,8 @@ class PulseElement extends Element { } } - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,1); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,1); this.removeProperty("Inputs"); this.Name = "Pulse"; this.Period = 100; @@ -1058,7 +1103,8 @@ class DelayElement extends Element { setInput(Input, Value) { if (Input > 0) return; - if (this.Inputs[Input] == Value) return; + Value = this._Container.isHigh(this,Input); + if (this.Inputs[Input] == (Value === false) ? false : true) return; //super.setInput(Input, Value); this.Inputs[Input] = Value; if (this.Inputs[0] && !this.Task.Enabled) { @@ -1094,8 +1140,8 @@ class DelayElement extends Element { } } - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,1); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,1); this.removeProperty("Inputs"); this.Name = "Delay"; this.Period = 100; @@ -1164,8 +1210,8 @@ ElementReferenceTable.push(ElementCatalog_DELAY); ElementCategory_Timing.addElement(ElementCatalog_DELAY); class output4bitDisplay extends Element { - constructor(RestoreData = null,logicengine) { - super(RestoreData,logicengine,4); + constructor(_Container, RestoreData = null,logicengine) { + super(_Container, RestoreData,logicengine,4); this.Name = "4B Display"; this.Output = false; this.OutputChar = "0"; @@ -1206,7 +1252,8 @@ class output4bitDisplay extends Element { } setInput(Input, Value) { - this.Inputs[Input] = (Value) ? 1 : 0; + Value = this._Container.isHigh(this,Input); + this.Inputs[Input] = (Value !== false) ? 1 : 0; let outchar = (this.Inputs[0] << 3) + (this.Inputs[1] << 2) + (this.Inputs[2] << 1) + (this.Inputs[3]); this.OutputChar = (outchar); @@ -1259,8 +1306,8 @@ ElementCategory_Outputs.addElement(ElementCatalog_Output_4BDisplay); class inputElement extends Element { - constructor(RestoreData = null,logicengine) { - super(RestoreData,logicengine,0); + constructor(_Container, RestoreData = null,logicengine) { + super(_Container, RestoreData,logicengine,0); this.Name = "InputElement"; this.Output = false; this.Width = 100; @@ -1279,8 +1326,8 @@ class inputElement extends Element { } class InputSwitch extends inputElement { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine); this.Name = "Switch"; this.Height = 70; if (RestoreData) this.Output = RestoreData.Output; @@ -1318,8 +1365,8 @@ ElementReferenceTable.push(ElementCatalog_SWITCH); ElementCategory_Inputs.addElement(ElementCatalog_SWITCH); class InputButton extends inputElement { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine); this.Name = "Button"; this.Height = 70; } @@ -1362,8 +1409,8 @@ ElementReferenceTable.push(ElementCatalog_BUTTON); ElementCategory_Inputs.addElement(ElementCatalog_BUTTON); class FlipFlopJK extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,3); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,3); this.Name = "JK-FF"; this.Outputs = new Array(2); this.InputLabels = new Array("J","CLK","K"); @@ -1385,6 +1432,8 @@ class FlipFlopJK extends Element { setInput(Input, Value) { if (Input >= this.Inputs.length) return false; + Value = this._Container.isHigh(this,Input); + if (Value !== false) Value = true; let oldOutput = this.Outputs[0]; let oldOutput2 = this.Outputs[1]; this.Inputs[Input] = Value; @@ -1419,13 +1468,13 @@ class FlipFlopJK extends Element { this.drawOutputs(ctx,x,y); } } -let ElementCatalog_JKFlipFlop = new ElementCatalog_Element("JK-FF","The JK Flip-Flop is a common type of flip-flop that allows for either setting in a specific state, or toggling state.","JK",FlipFlopJK,[]); +let ElementCatalog_JKFlipFlop = new ElementCatalog_Element("JK-FF","The JK Flip-Flop is a common type of flip-flop that allows for either setting in a specific state, or toggling state.","",FlipFlopJK,[]); ElementReferenceTable.push(ElementCatalog_JKFlipFlop); ElementCategory_FlipFlop.addElement(ElementCatalog_JKFlipFlop); class FlipFlopSR extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,3); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,3); this.Name = "SR-FF"; this.Outputs = new Array(2); this.InputLabels = new Array("S","CLK","R"); @@ -1447,6 +1496,8 @@ class FlipFlopSR extends Element { setInput(Input, Value) { if (Input >= this.Inputs.length) return false; + Value = this._Container.isHigh(this,Input); + if (Value !== false) Value = true; let oldOutput = this.Outputs[0]; let oldOutput2 = this.Outputs[1]; this.Inputs[Input] = Value; @@ -1477,13 +1528,13 @@ class FlipFlopSR extends Element { this.drawOutputs(ctx,x,y); } } -let ElementCatalog_SRFlipFlop = new ElementCatalog_Element("SR-FF","The SR Flip-Flop is a common type of flip-flop that allows for either setting, or resetting the output state.","SR",FlipFlopSR,[]); +let ElementCatalog_SRFlipFlop = new ElementCatalog_Element("SR-FF","The SR Flip-Flop is a common type of flip-flop that allows for either setting, or resetting the output state.","",FlipFlopSR,[]); ElementReferenceTable.push(ElementCatalog_SRFlipFlop); ElementCategory_FlipFlop.addElement(ElementCatalog_SRFlipFlop); class FlipFlopT extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,2); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,2); this.Name = "T-FF"; this.Outputs = new Array(2); this.InputLabels = new Array("T","CLK"); @@ -1505,6 +1556,8 @@ class FlipFlopT extends Element { setInput(Input, Value) { if (Input >= this.Inputs.length) return false; + Value = this._Container.isHigh(this,Input); + if (Value !== false) Value = true; let oldOutput = this.Outputs[0]; let oldOutput2 = this.Outputs[1]; this.Inputs[Input] = Value; @@ -1528,13 +1581,13 @@ class FlipFlopT extends Element { this.drawOutputs(ctx,x,y); } } -let ElementCatalog_TFlipFlop = new ElementCatalog_Element("T-FF","The T Flip-Flop is a common type of flip-flop that toggles the output when T is high and CLK goes high.","T",FlipFlopT,[]); +let ElementCatalog_TFlipFlop = new ElementCatalog_Element("T-FF","The T Flip-Flop is a common type of flip-flop that toggles the output when T is high and CLK goes high.","",FlipFlopT,[]); ElementReferenceTable.push(ElementCatalog_TFlipFlop); ElementCategory_FlipFlop.addElement(ElementCatalog_TFlipFlop); class FlipFlopD extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,2); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,2); this.Name = "D-FF"; this.Outputs = new Array(2); this.InputLabels = new Array("D","CLK"); @@ -1556,6 +1609,8 @@ class FlipFlopD extends Element { setInput(Input, Value) { if (Input >= this.Inputs.length) return false; + Value = this._Container.isHigh(this,Input); + if (Value !== false) Value = true; let oldOutput = this.Outputs[0]; let oldOutput2 = this.Outputs[1]; let oldInput = this.Inputs[1]; @@ -1580,14 +1635,14 @@ class FlipFlopD extends Element { this.drawOutputs(ctx,x,y); } } -let ElementCatalog_DFlipFlop = new ElementCatalog_Element("D-FF","The D Flip-Flop is a common type of flip-flop that sets the output to equal D if the clock goes high","D",FlipFlopD,[]); +let ElementCatalog_DFlipFlop = new ElementCatalog_Element("D-FF","The D Flip-Flop is a common type of flip-flop that sets the output to equal D if the clock goes high","",FlipFlopD,[]); ElementReferenceTable.push(ElementCatalog_DFlipFlop); ElementCategory_FlipFlop.addElement(ElementCatalog_DFlipFlop); class LogicAND extends Element { - constructor(RestoreData = null, logicengine,Inputs) { - super(RestoreData,logicengine,Inputs); + constructor(_Container, RestoreData = null, logicengine,Inputs) { + super(_Container, RestoreData,logicengine,Inputs); this.Name = "AND"; } @@ -1629,8 +1684,8 @@ ElementReferenceTable.push(ElementCatalog_AND); ElementCategory_LOGIC.addElement(ElementCatalog_AND); class LogicNAND extends LogicAND { - constructor(RestoreData = null, logicengine,Inputs) { - super(RestoreData,logicengine,Inputs); + constructor(_Container, RestoreData = null, logicengine,Inputs) { + super(_Container, RestoreData,logicengine,Inputs); this.Name = "NAND"; this.Width = this.Width + 10; } @@ -1681,8 +1736,8 @@ ElementReferenceTable.push(ElementCatalog_NAND); ElementCategory_LOGIC.addElement(ElementCatalog_NAND); class LogicOR extends Element { - constructor(RestoreData = null, logicengine,Inputs) { - super(RestoreData,logicengine,Inputs); + constructor(_Container, RestoreData = null, logicengine,Inputs) { + super(_Container, RestoreData,logicengine,Inputs); this.Name = "OR"; } @@ -1728,8 +1783,8 @@ ElementReferenceTable.push(ElementCatalog_OR); ElementCategory_LOGIC.addElement(ElementCatalog_OR); class LogicNOR extends LogicOR { - constructor(RestoreData = null, logicengine,Inputs) { - super(RestoreData,logicengine,Inputs); + constructor(_Container, RestoreData = null, logicengine,Inputs) { + super(_Container, RestoreData,logicengine,Inputs); this.Name = "NOR"; this.Width = this.Width + 10; } @@ -1782,8 +1837,8 @@ ElementReferenceTable.push(ElementCatalog_NOR); ElementCategory_LOGIC.addElement(ElementCatalog_NOR); class LogicXOR extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,2); // Only 2 inputs on XOR + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,2); // Only 2 inputs on XOR this.Name = "XOR"; this.removeProperty("Inputs"); } @@ -1844,8 +1899,8 @@ ElementReferenceTable.push(ElementCatalog_XOR); ElementCategory_LOGIC.addElement(ElementCatalog_XOR); class LogicXNOR extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,2); // Only 2 inputs on XOR + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,2); // Only 2 inputs on XOR this.Name = "XNOR"; this.removeProperty("Inputs"); this.Width += 10; @@ -1918,8 +1973,8 @@ ElementReferenceTable.push(ElementCatalog_XNOR); ElementCategory_LOGIC.addElement(ElementCatalog_XNOR); class LogicNOT extends Element { - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,1); // Only 1 inputs on NOT + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,1); // Only 1 inputs on NOT this.Name = "NOT"; this.removeProperty("Inputs"); this.Width += 10; @@ -1994,6 +2049,8 @@ class LogicBuffer extends Element { setInput(Input, Value) { if (Input > 0) return; //super.setInput(Input, Value); + Value = this._Container.isHigh(this,Input); + if (Value !== false) Value = true; this.Inputs[Input] = Value; if (!this.Task.Enabled) { this.Task.LastCall = 0; @@ -2001,8 +2058,8 @@ class LogicBuffer extends Element { } } - constructor(RestoreData = null, logicengine) { - super(RestoreData,logicengine,1); + constructor(_Container, RestoreData = null, logicengine) { + super(_Container, RestoreData,logicengine,1); this.removeProperty("Inputs"); this.Output = false; this.Name = "Buffer"; diff --git a/js/globalfunctions.js b/js/globalfunctions.js index 50ff9f9..9ad59f4 100644 --- a/js/globalfunctions.js +++ b/js/globalfunctions.js @@ -1,5 +1,5 @@ function addElement(RestoreData = null,refClass,props) { - let newElement = new refClass(RestoreData,logicEngine,...props); + let newElement = new refClass(logicEngine.ActiveContainer,RestoreData,logicEngine,...props); if (!RestoreData) { let x = Math.round(logicEngine.Canvas.width / 2) - (newElement.Width/2); @@ -32,6 +32,7 @@ function addElement(RestoreData = null,refClass,props) { } logicEngine.ActiveContainer.AddElement(newElement); logicEngine.ActiveContainer.Select(newElement); + disableSelectedRCMs(false); return newElement; } @@ -173,13 +174,19 @@ function isVersionNewer(version1,version2,orEqual = true) { function disableSelectedRCMs(bool) { let rcm_Delete = document.getElementById("rcm_Delete"); let rcm_Disconnect = document.getElementById("rcm_Disconnect"); + let tfm_Delete = document.getElementById("tfm_Delete"); + let tfm_Disconnect = document.getElementById("tfm_Disconnect"); if (bool) { rcm_Delete.classList.add("disabled"); rcm_Disconnect.classList.add("disabled"); + tfm_Delete.classList.add("disabled"); + tfm_Disconnect.classList.add("disabled"); } else { rcm_Delete.classList.remove("disabled"); rcm_Disconnect.classList.remove("disabled"); + tfm_Delete.classList.remove("disabled"); + tfm_Disconnect.classList.remove("disabled"); } } @@ -234,7 +241,7 @@ function loadContainer(Elements) { } let classRef = getElementInfo(Elements[a].Name).Class; - let newElement = new classRef(Elements[a],logicEngine,getElementInfo(Elements[a].Name).Args[0]); + let newElement = new classRef(newContainer,Elements[a],logicEngine,getElementInfo(Elements[a].Name).Args[0]); newContainer.AddElement(newElement); newElement.Designator = Elements[a].Designator; diff --git a/js/logicengine.js b/js/logicengine.js index c506d22..500feee 100644 --- a/js/logicengine.js +++ b/js/logicengine.js @@ -12,7 +12,10 @@ class LogicEngineSettings { this.OutputCircleSize = 10; this.ShowGrid = true; this.SnapGrid = true; + this.TopConnections = true; + this.HideConnections = false; this.GridSize = 20; + this.ShowFPS = true; } } @@ -57,7 +60,6 @@ class LogicEngine { } Ctx.restore(); } - console.log("Resized"); } PropertyChange(property) { @@ -274,9 +276,11 @@ class LogicEngine { this.Ctx.restore(); } let ct = new CanvasTools(); - let FPSOffset = (this.Canvas.width - 150) - this.Panning.OffsetX; - ct.drawText(this.Ctx,FPSOffset,650- this.Panning.OffsetY,"FPS: " + this.FPS,"12px console", "#00ff00"); - ct.drawText(this.Ctx,FPSOffset,670- this.Panning.OffsetY,"Potential FPS: " + this.PotentialFPS,"12px console", "#00ff00"); + let FPSOffset = 5 - this.Panning.OffsetX; + if (this.Settings.ShowFPS) { + ct.drawText(this.Ctx, FPSOffset, 15 - this.Panning.OffsetY, "FPS: " + this.FPS, "12px console", "#00ff00"); + ct.drawText(this.Ctx, FPSOffset, 29 - this.Panning.OffsetY, "Potential FPS: " + Math.floor(this.PotentialFPS), "12px console", "#00ff00"); + } let timeCheck = performance.now(); this.FPSCounter++; diff --git a/js/main.js b/js/main.js index fe47f2a..2fd06f3 100644 --- a/js/main.js +++ b/js/main.js @@ -132,14 +132,30 @@ rcm_New.addEventListener('click', function(evt) { let rcm_Delete = document.getElementById("rcm_Delete"); rcm_Delete.addEventListener('click', function(evt) { logicEngine.Key_Press({ctrlKey: false, key: "Delete"}); + disableSelectedRCMs(true); }); +let tfm_Delete = document.getElementById("tfm_Delete"); +tfm_Delete.addEventListener('click', function(evt) { + logicEngine.Key_Press({ctrlKey: false, key: "Delete"}); + disableSelectedRCMs(true); + setTimeout(function(){hideMenus()},10); +}); + + let rcm_Disconect = document.getElementById("rcm_Disconnect"); rcm_Disconect.addEventListener('click', function(evt) { logicEngine.ActiveContainer.Selected.Disconnect(); logicEngine.ActiveContainer.Disconnect(logicEngine.ActiveContainer.Selected); }); +let tfm_Disconect = document.getElementById("tfm_Disconnect"); +tfm_Disconect.addEventListener('click', function(evt) { + logicEngine.ActiveContainer.Selected.Disconnect(); + logicEngine.ActiveContainer.Disconnect(logicEngine.ActiveContainer.Selected); + setTimeout(function(){hideMenus()},10); +}); + let tfm_Save = document.getElementById("tfm_Save"); tfm_Save.addEventListener('click', function(evt) { @@ -178,7 +194,7 @@ file_Load.addEventListener('change', function(evt) { return function (e) { try { let restoredata = JSON.parse(e.target.result); - console.log(restoredata); + loadresult = loadsave(restoredata); if (!loadresult) { switch(loadresult) { @@ -220,6 +236,48 @@ tfm_About.addEventListener("click", function (evt) { setTimeout(function(){hideMenus()},10); }); +let tfm_ShowConns = document.getElementById("tfm_ShowConnections"); +tfm_ShowConns.addEventListener("click", function (evt) { + if (logicEngine.Settings.HideConnections) { + let sgSpan = tfm_ShowConns.getElementsByTagName("span")[0]; + sgSpan.innerText = "✓"; + logicEngine.Settings.HideConnections = false; + } else { + let sgSpan = tfm_ShowConns.getElementsByTagName("span")[0]; + sgSpan.innerText = ""; + logicEngine.Settings.HideConnections = true; + } + setTimeout(function(){hideMenus()},10); +}); + +let tfm_ConnLayer = document.getElementById("tfm_ConnectionLayer"); +tfm_ConnLayer.addEventListener("click", function (evt) { + if (logicEngine.Settings.TopConnections) { + tfm_ConnLayer.innerText = "Connections Above"; + logicEngine.Settings.TopConnections = false; + } else { + tfm_ConnLayer.innerText = "Connections Below"; + logicEngine.Settings.TopConnections = true; + } + setTimeout(function(){hideMenus()},10); +}); + +let tfm_ShowFPS = document.getElementById("tfm_ShowFPS"); +tfm_ShowFPS.addEventListener("click", function (evt) { + if (logicEngine.Settings.ShowFPS) { + let sgSpan = tfm_ShowFPS.getElementsByTagName("span")[0]; + sgSpan.innerText = ""; + logicEngine.Settings.ShowFPS = false; + } else { + let sgSpan = tfm_ShowFPS.getElementsByTagName("span")[0]; + sgSpan.innerText = "✓"; + logicEngine.Settings.ShowFPS = true; + } + logicEngine.Resize(""); + setTimeout(function(){hideMenus()},10); +}); + + let tfm_Pan2Center = document.getElementById("tfm_Pan2Center"); tfm_Pan2Center.addEventListener("click", function (evt) { logicEngine.Ctx.setTransform(1,0,0,1,0,0); @@ -240,7 +298,7 @@ tfm_ShowGrid.addEventListener("click", function (evt) { logicEngine.Settings.ShowGrid = true; } logicEngine.Resize(""); - //setTimeout(function(){hideMenus()},10); + setTimeout(function(){hideMenus()},10); }); let tfm_SnapGrid = document.getElementById("tfm_SnapGrid"); @@ -255,7 +313,7 @@ tfm_SnapGrid.addEventListener("click", function (evt) { logicEngine.Settings.SnapGrid = true; } logicEngine.Resize(""); - //setTimeout(function(){hideMenus()},10); + setTimeout(function(){hideMenus()},10); }); let in_GridSize = document.getElementById("in_GridSize");