WIP:0.4.0 Added panning (hold ctrl while click dragging), right click menu, save dialog

This commit is contained in:
MatCat 2021-03-04 22:36:57 -08:00
parent 3729a73028
commit af617e7058
8 changed files with 255 additions and 36 deletions

View File

@ -12,6 +12,13 @@ To be decided, but at this moment this code is open source and free to use for n
## Changelog
### 0.4.0
* 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)
* Save dialog
### 0.3.10
* Added BCD and Decimal options to the 4 bit output display, as well as bit labels in inputs

View File

@ -366,7 +366,7 @@ textarea {
#WelcomeWindow label {
font-size: 0.5em;
}
#PropertiesBox, #CreateICBox {
#PropertiesBox, #CreateICBox, #SaveWindow {
display: none;
position: absolute;
right: 20px;
@ -387,16 +387,70 @@ textarea {
border: 3px solid red;
}
#PropertiesBoxTitle, #CreateICBoxTitle {
#SaveWindow {
width: 350px;
height: 120px;
}
#SaveWindowContent {
margin: auto;
width: 90%;
margin-top: 10px;
}
#PropertiesBoxTitle, #CreateICBoxTitle, #SaveWindowTitle {
text-align: center;
background-color: #222222;
font-size: 1.5em;
}
#PropertiesBoxContent, #CreateICBoxContent {
#PropertiesBoxContent, #CreateICBoxContent, #SaveWindowContent {
padding: 5px;
}
#RightClickMenu {
display: none;
position: absolute;
left: 0px;
top: 0px;
background-color: #444455;
border: 1px solid #232323;
z-index: 9999999999;
}
#RightClickMenu ul {
margin: 0px;
padding: 0px;
}
#RightClickMenu li {
cursor: default;
text-decoration: none;
list-style-type: none;
margin: 0px;
padding: 2px;
padding-left: 30px;
padding-right: 30px;
}
#RightClickMenu li:hover {
background-color: #222222;
}
#RightClickMenu .disabled {
color: #777777;
}
.rcm_seperator:hover {
background-color: transparent !important;
}
.rcm_seperator {
height: 2px;
margin-bottom: 7px;
border-bottom: 2px groove #54545d;
}
#LogicPlane {
outline: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */

View File

@ -68,6 +68,29 @@
<center><input type="button" id="btn_CreateIC_Create" value="Create IC" disabled>&nbsp;&nbsp;&nbsp;<input type="button" id="btn_CreateIC_Cancel" value="Cancel"></center>
</div>
</div>
<div id="RightClickMenu">
<ul>
<li id="rcm_New">New</li>
<li id="rcm_seperator1" class="rcm_seperator"></li>
<li id="rcm_CreateIC">Create IC</li>
<li id="rcm_seperator2" class="rcm_seperator"></li>
<li id="rcm_Delete">Delete</li>
<li id="rcm_Disconnect">Disconnect</li>
</ul>
</div>
<div id="SaveWindow">
<div id="SaveWindowTitle">
Save Design
</div>
<div id="SaveWindowContent">
<div>
<span style="padding-right: 10px;">Design Name</span><span><input type="text" id="saveName" value="My Design"></span>
</div>
<div style="margin-top: 10px;">
<center><input type="button" id="btn_SaveDesign" value="Save">&nbsp;&nbsp;&nbsp;<input type="button" id="btn_CancelSave" value="Cancel"></center>
</div>
</div>
</div>
<div id="darkout-overlay"></div>
<script src="js/globalfunctions.js"></script>

View File

@ -131,6 +131,13 @@ class elementContainer {
return false;
}
Disconnect(element) {
if (!element) return false;
for (let a = 0; a < this.Elements.length; a++) {
this.Elements[a].Disconnect(element);
}
}
DrawAll(ctx,settings) {
let ICOuts = 0;
for (let a = 0; a < this.Elements.length; a++) {

View File

@ -168,9 +168,26 @@ class Element extends CanvasTools {
// if we are active linking stop doing so
if (this.LogicEngine.ActiveLink == this) this.LogicEngine.ActiveLink = false;
// Just to clean up connections
this.Disconnect();
}
Disconnect(element = false) {
if (element) {
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);
this.OutputConnections.splice(a,1);
a--;
}
}
} else {
for (let a = 0; a < this.OutputConnections.length; a++) {
this.LogicEngine.RecursionCount = 0;
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input, false);
this.OutputConnections.splice(a,1);
a--;
}
}
}
@ -188,10 +205,11 @@ class Element extends CanvasTools {
MouseClick(mousePos) {
let ctxMousePos = this.MousePosition;
let mouseDistOutput = length2D(this.X+(this.Width-10),
this.Y+(this.Height/2),
this.MousePosition.x,
this.MousePosition.y);
ctxMousePos.x,
ctxMousePos.y);
if (this.LogicEngine.ActiveLink) {
// We need to see if an input is being clicked on to be linked to
let foundInput = false;
@ -202,8 +220,8 @@ class Element extends CanvasTools {
let mouseDist = length2D(this.X+10,
firstY+ (a*24),
this.MousePosition.x,
this.MousePosition.y);
ctxMousePos.x,
ctxMousePos.y);
if (mouseDist <= (this.inputCircleRadius)) {
this.LogicEngine.Link(a);
foundInput = true;
@ -220,8 +238,8 @@ class Element extends CanvasTools {
let mouseDist = length2D(this.X+(this.Width-10),
firstY+ (a*24),
this.MousePosition.x,
this.MousePosition.y);
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)};
@ -234,8 +252,9 @@ class Element extends CanvasTools {
}
mouseInside(mousePos) {
mousePos = this.LogicEngine.getCanvasMousePos(mousePos);
this.MouseOver = false;
if (((mousePos.x >= this.X ) && (mousePos.x <= (this.X + this.Width))) & ((mousePos.y >= this.Y ) && (mousePos.y <= (this.Y + this.Height)))) this.MouseOver = true;
if (((mousePos.x >= this.X ) && (mousePos.x <= (this.X + this.Width))) && ((mousePos.y >= this.Y ) && (mousePos.y <= (this.Y + this.Height)))) this.MouseOver = true;
this.MousePosition = mousePos;
return this.MouseOver;
}
@ -1142,7 +1161,8 @@ class output4bitDisplay extends Element {
this.Properties.push(typeProperty);
if (RestoreData) {
if (RestoreData.Properties) {
if (RestoreData.Properties.length > 0) {
console.log(RestoreData);
this.Properties[0].CurrentValue = RestoreData.Properties[0].CurrentValue;
this.Properties[0].Values = RestoreData.Properties[0].Values;
this.setType(this.Properties[0].CurrentValue);
@ -1248,6 +1268,7 @@ class InputSwitch extends inputElement {
}
MouseClick(mousePos) {
mousePos = this.LogicEngine.getCanvasMousePos(mousePos);
super.MouseClick(mousePos);
if ((mousePos.x >= (this.X + 5)) && (mousePos.x <= (this.X + 55)) && (mousePos.y >= (this.Y + 5)) && (mousePos.y <= (this.Y + 55))) {
this.Output = !this.Output;
@ -1285,6 +1306,7 @@ class InputButton extends inputElement {
}
MouseDown(mousePos) {
mousePos = this.LogicEngine.getCanvasMousePos(mousePos);
if ((mousePos.x >= (this.X + 5)) && (mousePos.x <= (this.X + 55)) && (mousePos.y >= (this.Y + 5)) && (mousePos.y <= (this.Y + 55))) {
let old_output = this.Output;
this.Output = true;

View File

@ -2,8 +2,10 @@ function addElement(RestoreData = null,refClass,props) {
let newElement = new refClass(RestoreData,logicEngine,...props);
if (!RestoreData) {
let x = Math.round(logicEngine.Canvas.width / 2);
let y = Math.round(logicEngine.Canvas.height / 2);
let x = Math.round(logicEngine.Canvas.width / 2) - (newElement.Width/2);
let y = Math.round(logicEngine.Canvas.height / 2) - (newElement.Height/2);
x -= logicEngine.Panning.OffsetX;
y -= logicEngine.Panning.OffsetY;
x = logicEngine.Settings.GridSize * Math.round(x/logicEngine.Settings.GridSize);
y = logicEngine.Settings.GridSize * Math.round(y/logicEngine.Settings.GridSize);
let width = newElement.Width;
@ -168,6 +170,19 @@ function isVersionNewer(version1,version2,orEqual = true) {
return false;
}
function disableSelectedRCMs(bool) {
let rcm_Delete = document.getElementById("rcm_Delete");
let rcm_Disconnect = document.getElementById("rcm_Disconnect");
if (bool) {
rcm_Delete.classList.add("disabled");
rcm_Disconnect.classList.add("disabled");
} else {
rcm_Delete.classList.remove("disabled");
rcm_Disconnect.classList.remove("disabled");
}
}
function createSaveState(container = false) {
let saveState = {
Name: "LogicDesign",
@ -203,7 +218,7 @@ function loadContainer(Elements) {
if (!classRef) {
// We need to add this IC to the toolbox
let newIC = createIC(JSON.stringify(Elements[a].ICBlueprint),Elements[a].Name,Elements[a].Description);
console.log("NewIC:" + newIC);
//console.log("NewIC:" + newIC);
if (!newIC) return false;
}
}
@ -241,10 +256,6 @@ function loadContainer(Elements) {
}
// Now we need to make all of the connections
for (let a = 0; a < elementConnections.length; a++) {
if (elementConnections[a].FromElement.Name == "1B_ADD") {
console.log("Making connection " + a);
console.log(elementConnections[a]);
}
let toElement = newContainer.HasElement(elementConnections[a].ToElement);
if (toElement) {
if (elementConnections[a].FromContainer) {
@ -258,12 +269,6 @@ function loadContainer(Elements) {
if (newConnection) {
//elementConnections[a].FromElement.OutputConnections.push(newConnection);
elementConnections[a].FromElement.addConnection(newContainer,toElement,elementConnections[a].Input, elementConnections[a].Output)
if (elementConnections[a].FromElement.Name == "1B_ADD") {
console.log("Making Connection");
console.log(newConnection);
console.log(elementConnections[a].FromElement);
console.log(elementConnections[a].FromElement.OutputConnections);
}
} else {
console.log("We dont have a new connection!!!");
console.log(toElement);
@ -291,6 +296,8 @@ function loadsave(savedata) {
if (!isVersionNewer(savedata.Version,"0.3.0")) return -2; // TODO: Let the person know the version is too old
let newContainer = loadContainer(savedata.Elements);
if (!newContainer) return -3;
let saveName = document.getElementById("saveName");
saveName.value = savedata.Name;
logicEngine.ActiveContainer = newContainer;
return true;
}

View File

@ -67,7 +67,19 @@ class LogicEngine {
this.MovingElementMouseStartY = mousePos.y;
element.MouseDown(mousePos);
} else {
this.MouseDown = true;
this.ActiveLink = false;
if (this.ControlPressed) {
this.Panning.StartOffsetX = this.Panning.OffsetX;
this.Panning.StartOffsetY = this.Panning.OffsetY;
this.Panning.StartX = mousePos.x;
this.Panning.StartY = mousePos.y;
}
}
if (this.ActiveContainer.Selected) {
disableSelectedRCMs(false);
} else {
disableSelectedRCMs(true);
}
}
@ -82,8 +94,14 @@ class LogicEngine {
//console.log("Mouse Up");
}
if (!this.MovingElement) this.ActiveContainer.Selected = false;
this.MovingElement = false;
this.MouseDown = false;
if (this.ActiveContainer.Selected) {
disableSelectedRCMs(false);
} else {
disableSelectedRCMs(true);
}
}
Mouse_Move(evt) {
@ -105,6 +123,18 @@ class LogicEngine {
this.MovingElement.X = actualPosX;
this.MovingElement.Y = actualPosY;
}
} else {
if (this.ControlPressed) {
let distX = mousePos.x - this.Panning.StartX;
let distY = mousePos.y - this.Panning.StartY;
this.Panning.StartX += distX;
this.Panning.StartY += distY;
this.Panning.OffsetX += distX;
this.Panning.OffsetY += distY;
this.Ctx.translate(distX, distY);
}
}
} else {
this.ActiveContainer.checkMouseBounds(mousePos);
@ -164,6 +194,7 @@ class LogicEngine {
this.RecursionError = false;
this.Canvas.setAttribute('tabindex','0');
this.ControlPressed = false;
this.Panning = {OffsetX: 0, OffsetY: 0,StartOffsetX: 0, StartOffsetY: 0, StartX: 0, StartY: 0};
}
@ -183,23 +214,31 @@ class LogicEngine {
}
getCanvasMousePos(mousePos) {
return {x: mousePos.x - this.Panning.OffsetX, y: mousePos.y - this.Panning.OffsetY};
}
DrawLoop() {
if (this.RecursionError) {
this.RecursionError = false;
alert("Recursion Error! Whatever you last did is causing an oscillating loop, please check your connections and try again!");
}
let startLoop = performance.now();
this.Ctx.clearRect(0,0,this.Canvas.width,this.Canvas.height);
this.Ctx.clearRect(0- this.Panning.OffsetX,0- this.Panning.OffsetY,this.Canvas.width,this.Canvas.height);
this.ActiveContainer.DrawAll(this.Ctx,this.Settings);
let btn_CreateIC = document.getElementById("btn_CreateIC");
let rcm_CreateIC = document.getElementById("rcm_CreateIC");
btn_CreateIC.disabled = true;
rcm_CreateIC.classList.add("disabled");
if (this.ActiveContainer.ICOutputs > 0) btn_CreateIC.disabled = false;
if (this.ActiveContainer.ICOutputs > 0) rcm_CreateIC.classList.remove("disabled");
if (this.ActiveLink) {
let startX = this.ActiveLink.LinkOutLocation().x;
let startY = this.ActiveLink.LinkOutLocation().y;
let endX = this.Mouse.x;
let endY = this.Mouse.y;
let endX = this.Mouse.x - this.Panning.OffsetX;
let endY = this.Mouse.y - this.Panning.OffsetY;
let startMidX = startX + ((endX - startX)/2);
let startMidY = startY;
let midX = startMidX;
@ -207,6 +246,7 @@ class LogicEngine {
let endMidX = startMidX;
let endMidY = endY;
this.Ctx.save();
this.Ctx.strokeStyle = this.Settings.LinkingConnectionColor;
this.Ctx.lineWidth = this.Settings.LinkingWidth;
@ -219,9 +259,9 @@ class LogicEngine {
this.Ctx.restore();
}
let ct = new CanvasTools();
let FPSOffset = this.Canvas.width - 150;
ct.drawText(this.Ctx,FPSOffset,650,"FPS: " + this.FPS,"12px console", "#00ff00");
ct.drawText(this.Ctx,FPSOffset,670,"Potential FPS: " + this.PotentialFPS,"12px console", "#00ff00");
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 timeCheck = performance.now();
this.FPSCounter++;

View File

@ -2,7 +2,7 @@
MatCat BrowserLogic Simulator
*/
let Version = "0.3.10";
let Version = "0.4.0";
let spanVersion = document.getElementById("version");
spanVersion.innerText = Version;
// get the canvas and get the engine object going
@ -25,6 +25,11 @@ window.addEventListener('keyup', function(evt) {
logicEngine.Key_Up(evt);
}, false);
window.addEventListener('mouseup', function(evt) {
let rcm = document.getElementById("RightClickMenu");
rcm.style.display = "none";
}, false);
lCanvasElement.addEventListener('mousedown', function(evt) {
logicEngine.Mouse_Down(evt);
@ -61,6 +66,14 @@ btn_CreateIC.addEventListener('click', function(evt) {
CreateICBox.style.display = "block";
});
let rcm_CreateIC = document.getElementById("rcm_CreateIC");
rcm_CreateIC.addEventListener('click', function(evt) {
if (!this.classList.contains("disabled")) {
let CreateICBox = document.getElementById("CreateICBox");
CreateICBox.style.display = "block";
}
});
let btn_CreateIC_Cancel = document.getElementById("btn_CreateIC_Cancel");
btn_CreateIC_Cancel.addEventListener('click', function(evt) {
let CreateICBox = document.getElementById("CreateICBox");
@ -94,10 +107,46 @@ btn_New.addEventListener('click', function(evt) {
logicEngine.ActiveContainer = new elementContainer();
});
let rcm_New = document.getElementById("rcm_New");
rcm_New.addEventListener('click', function(evt) {
logicEngine.ActiveContainer = new elementContainer();
});
let rcm_Delete = document.getElementById("rcm_Delete");
rcm_Delete.addEventListener('click', function(evt) {
logicEngine.Key_Press({ctrlKey: false, key: "Delete"});
});
let rcm_Disconect = document.getElementById("rcm_Disconnect");
rcm_Disconect.addEventListener('click', function(evt) {
logicEngine.ActiveContainer.Selected.Disconnect();
logicEngine.ActiveContainer.Disconnect(logicEngine.ActiveContainer.Selected);
});
let btn_Save = document.getElementById("btn_Save");
btn_Save.addEventListener('click', function(evt) {
download("mydeign.LogicParts",createSaveState(logicEngine.ActiveContainer));
//download("mydeign.LogicParts",createSaveState(logicEngine.ActiveContainer));
let saveWindow = document.getElementById("SaveWindow");
saveWindow.style.display="block";
saveWindow.style.left = Math.round((window.innerWidth / 2) - (saveWindow.clientWidth/2)) + "px";
saveWindow.style.top = Math.round((window.innerHeight / 2) - (saveWindow.clientHeight/2)) + "px";
});
let btn_SaveDesign = document.getElementById("btn_SaveDesign");
btn_SaveDesign.addEventListener('click', function(evt) {
let DesignName = document.getElementById("saveName");
let savestate = createSaveState(logicEngine.ActiveContainer);
savestate.Name = DesignName.value;
let saveWindow = document.getElementById("SaveWindow");
saveWindow.style.display = "none";
download(savestate.Name + ".LogicParts",savestate);
});
let btn_Save_Cancel = document.getElementById("btn_CancelSave");
btn_Save_Cancel.addEventListener('click', function(evt) {
let saveWindow = document.getElementById("SaveWindow");
saveWindow.style.display = "none";
});
let file_Load = document.getElementById("file_Load");
@ -127,7 +176,7 @@ file_Load.addEventListener('change', function(evt) {
}
}
} catch (ex) {
alert("Bad file!");
alert("Bad file! " + ex);
console.log(ex);
}
}
@ -135,5 +184,15 @@ file_Load.addEventListener('change', function(evt) {
fread.readAsText(evt.target.files[0]);
}, false);
document.addEventListener( "contextmenu", function(evt) {
evt.preventDefault();
let rcm = document.getElementById("RightClickMenu");
rcm.style.left = (evt.clientX-40) + "px";
rcm.style.top = (evt.clientY-25) + "px";
console.log(rcm.style);
rcm.style.display = "block";
console.log(evt);
});
CheckForWelcomeCookie();