WIP: 0.5.0
This commit is contained in:
parent
ec8b26ebbd
commit
d575d46a2f
@ -20,6 +20,10 @@ LZ-String, Copyright 2013 pieroxy under MIT license https://github.com/pieroxy/l
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.5.0
|
||||
|
||||
* Local Storage
|
||||
|
||||
### 0.4.16
|
||||
|
||||
* Fixed bug where properties window didn't disappear at certain times when it should
|
||||
|
134
css/main.css
134
css/main.css
@ -283,10 +283,10 @@ textarea {
|
||||
background-color: #54545d;
|
||||
}
|
||||
|
||||
#inner-left-menu::-webkit-scrollbar, #HelpWindowContent::-webkit-scrollbar {
|
||||
#inner-left-menu::-webkit-scrollbar, #HelpWindowContent::-webkit-scrollbar, #lsbFilesContainer::-webkit-scrollbar, #lsbfoldersContainer::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
#inner-left-menu::-webkit-scrollbar-track, #HelpWindowContent::-webkit-scrollbar-track {
|
||||
#inner-left-menu::-webkit-scrollbar-track, #HelpWindowContent::-webkit-scrollbar-track, #lsbFilesContainer::-webkit-scrollbar-track, #lsbfoldersContainer::-webkit-scrollbar-track {
|
||||
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#575a60+0,292b2d+14,000000+49,292b2d+82,575a60+100 */
|
||||
background: rgb(87,90,96); /* Old browsers */
|
||||
background: -moz-linear-gradient(left, rgba(87,90,96,1) 0%, rgba(41,43,45,1) 14%, rgba(0,0,0,1) 49%, rgba(41,43,45,1) 82%, rgba(87,90,96,1) 100%); /* FF3.6-15 */
|
||||
@ -295,7 +295,7 @@ textarea {
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#575a60', endColorstr='#575a60',GradientType=1 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
#inner-left-menu::-webkit-scrollbar-thumb, #HelpWindowContent::-webkit-scrollbar-thumb {
|
||||
#inner-left-menu::-webkit-scrollbar-thumb, #HelpWindowContent::-webkit-scrollbar-thumb, #lsbFilesContainer::-webkit-scrollbar-thumb, #lsbfoldersContainer::-webkit-scrollbar-thumb {
|
||||
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#000000+0,000000+50,000000+50,8e8e8e+50,000000+100&0+0,1+50,0+100 */
|
||||
background: -moz-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(142,142,142,1) 50%, rgba(0,0,0,0) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(142,142,142,1) 50%,rgba(0,0,0,0) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
@ -382,6 +382,134 @@ textarea {
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f85032', endColorstr='#e73827',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
#LocalStorageBrowser {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
min-width: 480px;
|
||||
height: 100px;
|
||||
flex-direction: column;
|
||||
background-color: #777777;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
#lsbPath {
|
||||
width: 100%;
|
||||
height: 1.2em;
|
||||
margin: 0px;
|
||||
margin-bottom: 2px;
|
||||
background-color: #444455;
|
||||
}
|
||||
|
||||
#lsbContent {
|
||||
width: 100%;
|
||||
min-width: 480px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#lsbFolders {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
margin-right: 2px;
|
||||
min-width: 150px;
|
||||
width: 30%;
|
||||
background-color: #444455;
|
||||
border: 1px outset #333;
|
||||
}
|
||||
|
||||
#lsbfoldersContainer {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
.lsbFolderEntry {
|
||||
color: #00aaaa;
|
||||
}
|
||||
|
||||
.lsbFolderEntry:hover {
|
||||
color: #00dddd;
|
||||
}
|
||||
|
||||
#lsbFiles {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
width: 70%;
|
||||
background-color: #444455;
|
||||
border: 1px outset #333;
|
||||
}
|
||||
|
||||
#lsbFilesContainer {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
overflow-clip: all;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
.lsbFileHeader,.lsbFolderHeader {
|
||||
background-color: #555555;
|
||||
border: 1px inset #333;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
height: 1.4em;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
.lsbFileHeader .FileName,.lsbFileEntry .FileName {
|
||||
width: 50%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin-right: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.lsbFileEntry .FileModified, .lsbFileEntry .FileSize, .lsbFileEntry .FileName {
|
||||
height: 1.2em;
|
||||
}
|
||||
.lsbFileHeader .FileModified,.lsbFileEntry .FileModified {
|
||||
width: 35%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin-right: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.lsbFileHeader .FileSize,.lsbFileEntry .FileSize {
|
||||
width: 15%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.lsbFileEntry .FileModified,.lsbFileEntry .FileSize {
|
||||
font-size: 0.75em;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
|
||||
.lsbFileEntry {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#floatCanvas {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
25
index.html
25
index.html
@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html class="no-js" lang="" style="height: 100%;">
|
||||
<html class="no-js" lang="" style="height: 100%;" xmlns="http://www.w3.org/1999/html">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
@ -138,22 +138,40 @@
|
||||
<li id="rcm_Disconnect">Disconnect</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="LocalStorageBrowser">
|
||||
<div id="lsbPath">/</div>
|
||||
<div id="lsbContent">
|
||||
<div id="lsbFolders">
|
||||
<div class="lsbFolderHeader">Folders</div>
|
||||
<div id="lsbfoldersContainer">
|
||||
</div>
|
||||
</div>
|
||||
<div id="lsbFiles">
|
||||
<div class = "lsbFileHeader"><div class="FileName">Name</div><div class="FileModified">Modified</div><div class="FileSize">Size</div></div>
|
||||
<div id="lsbFilesContainer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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 id="swcLocalStorage">
|
||||
|
||||
</div>
|
||||
<div id="swcFileSystem">
|
||||
<div>
|
||||
<input type="checkbox" id="saveCompressed" checked /> Save Compressed
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<center><input type="button" id="btn_SaveDesign" value="Save"> <input type="button" id="btn_CancelSave" value="Cancel"></center>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="HelpWindow">
|
||||
<div id="HelpWindowTitle">
|
||||
MatCat Logic Engine Help
|
||||
@ -193,6 +211,7 @@
|
||||
<script src="js/rightclickmenu/rightclickmenu.js"></script>
|
||||
<script src="js/globalfunctions.js"></script>
|
||||
<script src="js/baseclasses.js"></script>
|
||||
<script src="js/localstorage.js"></script>
|
||||
<script src="js/scheduler.js"></script>
|
||||
<script src="js/elements/BaseElementClasses.js"></script>
|
||||
<script src="js/elements/InputElements.js"></script>
|
||||
|
@ -413,25 +413,26 @@ class Element extends CanvasTools {
|
||||
let firstY = (centerY - (totalHeight/2)) + 12;
|
||||
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
let mouseDist = length2D(this.X+(this.Width - 10), firstY + (this.OutputConnections[a].Output*24),this.MousePosition.x,this.MousePosition.y);
|
||||
if (this.isVisible() || this.OutputConnections[a].Element.isVisible()) {
|
||||
let mouseDist = length2D(this.X + (this.Width - 10), firstY + (this.OutputConnections[a].Output * 24), this.MousePosition.x, this.MousePosition.y);
|
||||
if (!this.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) {
|
||||
// This is a ghosted connection, lets get rid of it
|
||||
this.OutputConnections.splice(a,1);
|
||||
this.OutputConnections.splice(a, 1);
|
||||
a--;
|
||||
} else {
|
||||
let endCenterY = this.OutputConnections[a].Element.Y + Math.round(this.OutputConnections[a].Element.Height / 2);
|
||||
let endTotalHeight = this.OutputConnections[a].Element.totalInputs() * ((this.OutputConnections[a].Element.inputCircleRadius*2)+4);
|
||||
let endFirstY = (endCenterY - (endTotalHeight/2)) + 12;
|
||||
let endTotalHeight = this.OutputConnections[a].Element.totalInputs() * ((this.OutputConnections[a].Element.inputCircleRadius * 2) + 4);
|
||||
let endFirstY = (endCenterY - (endTotalHeight / 2)) + 12;
|
||||
|
||||
let startX = this.X + this.Width;
|
||||
let startY = firstY+ (this.OutputConnections[a].Output*24);
|
||||
let endX = this.OutputConnections[a].Element.X;
|
||||
let startX = this.X + (this.Width - this.outputCircleRadius);
|
||||
let startY = firstY + (this.OutputConnections[a].Output * 24);
|
||||
let endX = this.OutputConnections[a].Element.X + this.OutputConnections[a].Element.inputCircleRadius;
|
||||
//let endY = this.OutputConnections[a].Element.Y+(this.OutputConnections[a].Element.inputCircleRadius + 2)+(((this.OutputConnections[a].Input*(4+(this.OutputConnections[a].Element.inputCircleRadius*2))))-2)+(this.OutputConnections[a].Element.inputCircleRadius/2);
|
||||
let endY = endFirstY + (this.OutputConnections[a].Input*24);
|
||||
let startMidX = startX + ((endX - startX)/2);
|
||||
let endY = endFirstY + (this.OutputConnections[a].Input * 24);
|
||||
let startMidX = startX + ((endX - startX) / 2);
|
||||
let startMidY = startY;
|
||||
let midX = startMidX;
|
||||
let midY = startY + ((endY - startY)/2);
|
||||
let midY = startY + ((endY - startY) / 2);
|
||||
let endMidX = startMidX;
|
||||
let endMidY = endY;
|
||||
|
||||
@ -441,9 +442,13 @@ class Element extends CanvasTools {
|
||||
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.lineWidth = (settings.LinkWidth * 2);
|
||||
ctx.setLineDash(settings.LinkDash);
|
||||
ctx.moveTo(startX, startY);
|
||||
//ctx.lineTo(endX, endY);
|
||||
ctx.quadraticCurveTo(startMidX,startMidY,midX,midY);
|
||||
ctx.quadraticCurveTo(endMidX,endMidY,endX,endY);
|
||||
if (this instanceof LogicWireNode) {
|
||||
ctx.lineTo(endX, endY);
|
||||
} else {
|
||||
ctx.quadraticCurveTo(startMidX, startMidY, midX, midY);
|
||||
ctx.quadraticCurveTo(endMidX, endMidY, endX, endY);
|
||||
}
|
||||
|
||||
ctx.strokeStyle = settings.ActiveConnectionColor;
|
||||
if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.ActiveConnectionHoverColor;
|
||||
if (!this.getOutput(this.OutputConnections[a].Output)) {
|
||||
@ -457,6 +462,7 @@ class Element extends CanvasTools {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setConnections() {
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
|
@ -545,3 +545,145 @@ class LogicBuffer extends Element {
|
||||
let ElementCatalog_BUFFER = new ElementCatalog_Element("Buffer","The buffer is a special gate to allow the prevention of recursion loops.","|>",LogicBuffer,[]);
|
||||
ElementReferenceTable.push(ElementCatalog_BUFFER);
|
||||
ElementCategory_LOGIC.addElement(ElementCatalog_BUFFER);
|
||||
|
||||
class RAMElement extends Element {
|
||||
constructor(_Container, RestoreData = null, logicengine) {
|
||||
super(_Container, RestoreData = null, logicengine,2);
|
||||
this.Name = "RAM";
|
||||
this.removeProperty("Inputs");
|
||||
this.AddressWidth = 16;
|
||||
this.DataWidth = 8;
|
||||
this._Data = new Array((2 ** this.AddressWidth));
|
||||
|
||||
for (let a = 0; a < this._Data.length; a++) {
|
||||
this._Data[a] = (2 ** this.DataWidth)-1;
|
||||
}
|
||||
|
||||
this.Inputs = new Array(this.AddressWidth + this.DataWidth + 3);
|
||||
this.Outputs = new Array(this.DataWidth);
|
||||
|
||||
this.Height = this.Inputs.length * (this.inputCircleRadius + 14)+10;
|
||||
this.Width = (12*(this.DataWidth/4)) + 220;
|
||||
|
||||
this.InputLabels = new Array(this.Inputs.length);
|
||||
for (let a = 0; a < this.DataWidth; a++) {
|
||||
this.InputLabels[a] = "I" + a;
|
||||
this.OutputLabels[a] = "O" + a;
|
||||
}
|
||||
for (let a = 0; a < this.AddressWidth; a++) {
|
||||
this.InputLabels[this.DataWidth+a] = "A" + a;
|
||||
}
|
||||
this.InputLabels[this.DataWidth+this.AddressWidth] = "WriteEnable";
|
||||
this.InputLabels[this.DataWidth+this.AddressWidth+1] = "OutputEnable";
|
||||
this.InputLabels[this.DataWidth+this.AddressWidth+2] = "CLK";
|
||||
|
||||
this.drawElement(0,0,this.StaticCtx);
|
||||
}
|
||||
|
||||
setInput(Input, Value) {
|
||||
if (Value) {
|
||||
Value = true;
|
||||
} else {
|
||||
Value = false;
|
||||
}
|
||||
|
||||
let oldInput = this.Inputs[Input];
|
||||
if (Input < this.totalInputs()) {
|
||||
this.Inputs[Input] = Value;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
let isHigh = this._Container.isHigh(this,Input);
|
||||
if (isHigh !== false) this.Inputs[Input] = true;
|
||||
if (isHigh === false) this.Inputs[Input] = false;
|
||||
if (oldInput != this.Inputs[Input]) {
|
||||
|
||||
if (this.Inputs[this.Inputs.length-2]) {
|
||||
// Output Enable
|
||||
this.setOutput();
|
||||
} else {
|
||||
this.setOutput(true);
|
||||
}
|
||||
|
||||
if (this.Inputs[this.Inputs.length-3] && this.Inputs[this.Inputs.length-1] && (Input == this.Inputs.length-1)) {
|
||||
this._Data[this.currentAddress()] = this.currentInputValue();
|
||||
if (this.Inputs[this.Inputs.length-2]) {
|
||||
// Output Enable
|
||||
this.setOutput();
|
||||
} else {
|
||||
this.setOutput(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setConnections();
|
||||
this.drawElement(0,0,this.StaticCtx);
|
||||
|
||||
}
|
||||
currentAddress() {
|
||||
let addr = 0;
|
||||
for (let a = 0; a < this.AddressWidth; a++) {
|
||||
addr |= ((this.Inputs[this.DataWidth+a]) ? 1 : 0) << a;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
currentInputValue() {
|
||||
let val = 0;
|
||||
for (let a = 0; a < this.DataWidth; a++) {
|
||||
val |= ((this.Inputs[a]) ? 1 : 0) << a;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
currentValue() {
|
||||
return this._Data[this.currentAddress()];
|
||||
}
|
||||
|
||||
setOutput(clear = false) {
|
||||
let currentValue = this.currentValue();
|
||||
for (let a = 0; a < this.DataWidth; a++) {
|
||||
this.Outputs[a] = false;
|
||||
if (!clear && (currentValue & (0b1 << a))) this.Outputs[a] = true;
|
||||
}
|
||||
}
|
||||
|
||||
getOutput(output) {
|
||||
if (this.Outputs[output]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
drawElement(x, y, ctx) {
|
||||
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
|
||||
this.StaticCanvas.width = this.Width;
|
||||
this.StaticCanvas.height = this.Height;
|
||||
|
||||
if (!this._Data) return;
|
||||
|
||||
this.drawBorderBox(ctx,x+20,y,this.Width-40,this.Height);
|
||||
this.drawTextCentered(ctx,x+20,(y+(this.Height-16)),this.Width-40,14,this.Designator,"12px Console","#000");
|
||||
|
||||
let totalAddr = Math.floor((this.Height - 40)/14);
|
||||
let startAddr = this.currentAddress() - Math.floor(totalAddr/2);
|
||||
if (startAddr < 0) startAddr = 0;
|
||||
let endAddr = startAddr + totalAddr;
|
||||
if (endAddr > this._Data.length) startAddr = this._Data.length - totalAddr;
|
||||
if (startAddr < 0) startAddr = 0;
|
||||
|
||||
for (let a = 0; a < ((this._Data.length > totalAddr) ? totalAddr : this._Data.length) ; a++) {
|
||||
let getAddr = a+startAddr;
|
||||
if (this.currentAddress() == a + startAddr) this.drawBorderBox(ctx,x+60,(y+10+(a*14)),this.Width-100,14,0,undefined,"#ffffaa");
|
||||
this.drawTextCentered(ctx,x+57,(y+10+(a*14)),(this.Width/2)-20,14,parseInt(a+startAddr).toString(16).toUpperCase().padStart(parseInt(this._Data.length-1).toString(16).length,'0') + `: `,"12px Console","#000");
|
||||
this.drawText(ctx,x+(Math.floor(this.Width/2)+10),(y+22+Math.floor(a*14)), this._Data[(a+startAddr)].toString(16).toUpperCase().padStart(parseInt((2 ** this.DataWidth)-1).toString(16).length,'0'),"12px Console","#000");
|
||||
}
|
||||
|
||||
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
let ElementCatalog_RAM = new ElementCatalog_Element("RAM","RAM, configurable address and data width",":::",RAMElement,[]);
|
||||
ElementReferenceTable.push(ElementCatalog_RAM);
|
||||
ElementCategory_Other.addElement(ElementCatalog_RAM);
|
||||
|
@ -276,20 +276,33 @@ function SaveSettings() {
|
||||
console.log("Settings Saved");
|
||||
}
|
||||
|
||||
function createSaveState(container = false) {
|
||||
let saveState = {
|
||||
Name: "LogicDesign",
|
||||
function createSaveState(container = false,localstorage = false) {
|
||||
if (!container) return false;
|
||||
let saveState = null;
|
||||
|
||||
if (localstorage) {
|
||||
saveState = {
|
||||
V: Version,
|
||||
TS: Date.now(),
|
||||
PX: logicEngine.Panning.OffsetX,
|
||||
PY: logicEngine.Panning.OffsetY,
|
||||
Elements: new Array()
|
||||
};
|
||||
} else {
|
||||
saveState = {
|
||||
Name: "My Design",
|
||||
Version: Version,
|
||||
Timestamp: Date.now(),
|
||||
PanX: logicEngine.Panning.OffsetX,
|
||||
PanY: logicEngine.Panning.OffsetY,
|
||||
Elements: new Array()
|
||||
};
|
||||
}
|
||||
if (container.Elements.length > 0) saveState.Elements = container.Elements;
|
||||
let saveCompressed = document.getElementById("saveCompressed");
|
||||
if (saveCompressed.checked) {
|
||||
if (saveCompressed.checked || forcecompression) {
|
||||
saveState.Elements = LZString.compressToUTF16(JSON.stringify(saveState.Elements));
|
||||
saveState.Compressed = true;
|
||||
if (!localstorage) saveState.Compressed = true;
|
||||
} else {
|
||||
saveState.Compressed = false;
|
||||
}
|
||||
|
271
js/localstorage.js
Normal file
271
js/localstorage.js
Normal file
@ -0,0 +1,271 @@
|
||||
class StorageFolder {
|
||||
constructor(restoreSettings) {
|
||||
this.Name = "Folder";
|
||||
this.CreationDate = Date.now();
|
||||
this.LastModifiedDate = Date.now();
|
||||
this.Folder = undefined;
|
||||
this.Designs = new Array();
|
||||
this.Folders = new Array();
|
||||
|
||||
if (restoreSettings) {
|
||||
if (restoreSettings.Name) this.Name = restoreSettings.Name;
|
||||
if (restoreSettings.CreationDate) this.CreationDate = restoreSettings.CreationDate;
|
||||
if (restoreSettings.LastModifiedDate) this.LastModifiedDate = restoreSettings.LastModifiedDate;
|
||||
if (restoreSettings.Folders) {
|
||||
for (let a = 0; a < restoreSettings.Folders.length;a ++) {
|
||||
let sf = new StorageFolder(restoreSettings.Folders[a]);
|
||||
sf.Folder = this;
|
||||
this.Folders.push(sf);
|
||||
}
|
||||
}
|
||||
if (restoreSettings.Designs) {
|
||||
for (let a = 0; a < restoreSettings.Designs.length;a ++) {
|
||||
let sd = new StorageDesign(restoreSettings.Designs[a]);
|
||||
sd.Folder = this;
|
||||
this.Designs.push(sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(key) {
|
||||
let sfjson = {};
|
||||
sfjson.Name = this.Name;
|
||||
sfjson.CreationDate = this.CreationDate;
|
||||
sfjson.LastModifiedDate = this.LastModifiedDate;
|
||||
sfjson.Designs = this.Designs;
|
||||
sfjson.Folders = this.Folders;
|
||||
return sfjson;
|
||||
}
|
||||
|
||||
PathString(ChildrenString = "") {
|
||||
if (this.Folder) {
|
||||
let pathString = `<span>${this.Name}</span> ${(ChildrenString != "") ? "/" : ""} ${ChildrenString}`;
|
||||
pathString = this.Folder.PathString(pathString);
|
||||
return pathString;
|
||||
} else {
|
||||
if (ChildrenString == "") {
|
||||
return `<span>/</span> `;
|
||||
} else {
|
||||
return `<span>/</span> ${ChildrenString}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HasFolder(folder = undefined) {
|
||||
if (!folder) return false;
|
||||
for (let a = 0; a < this.Folders.length; a++) {
|
||||
if (folder === this.Folders[a] || folder === this.Folders[a].Name) return this.Folders[a];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AddFolder(folder) {
|
||||
if (!folder) return false;
|
||||
let nameCounter = 1;
|
||||
let ogName = folder.Name;
|
||||
folder.Folder = this;
|
||||
|
||||
while (this.HasFolder(folder.Name)) {
|
||||
// There is a name conflict!
|
||||
folder.Name = ogName + " (" + nameCounter + ")";
|
||||
nameCounter++;
|
||||
}
|
||||
|
||||
this.Folders.push(folder);
|
||||
this.LastModifiedDate = Date.now();
|
||||
return folder;
|
||||
}
|
||||
|
||||
RemoveFolder(folder,overide=false) {
|
||||
if (!folder) return false;
|
||||
for (let a = 0; a < this.Folders; a++) {
|
||||
if (folder === this.Folders[a] || folder == this.Folders[a].Name) {
|
||||
if (this.Folders[a].Designs > 0 && !overide) return -1;
|
||||
this.Folders.splice(a,1);
|
||||
this.LastModifiedDate = Date.now();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HasDesign(design) {
|
||||
if (!design) return false;
|
||||
for (let a = 0; a < this.Designs; a++) {
|
||||
if (design === this.Designs[a] || design == this.Designs[a].Name) this.Designs[a];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AddDesign(design) {
|
||||
if (!design) return false;
|
||||
let nameCounter = 1;
|
||||
let ogName = design.Name;
|
||||
design.Folder = this;
|
||||
|
||||
while (this.HasDesign(design.Name)) {
|
||||
// There is a name conflict!
|
||||
design.Name = ogName + " (" + nameCounter + ")";
|
||||
nameCounter++;
|
||||
}
|
||||
|
||||
this.Designs.push(design);
|
||||
this.LastModifiedDate = Date.now();
|
||||
return design;
|
||||
}
|
||||
|
||||
RemoveDesign(design) {
|
||||
if (!design) return false;
|
||||
for (let a = 0; a < this.Designs; a++) {
|
||||
if (design === this.Designs[a] || design == this.Designs[a].Name) {
|
||||
this.Designs.splice(a,1);
|
||||
this.LastModifiedDate = Date.now();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class StorageDesign {
|
||||
constructor(restoreSettings) {
|
||||
this.Name = "My Design";
|
||||
this.Creator = "Anonymous";
|
||||
this.CreationDate = Date.now();
|
||||
this.LastModifiedDate = Date.now();
|
||||
this.Description = "";
|
||||
this.FileIndex = 0;
|
||||
this.Folder = undefined;
|
||||
|
||||
if (restoreSettings) {
|
||||
if (restoreSettings.Name) this.Name = restoreSettings.Name;
|
||||
if (restoreSettings.Creator) this.Creator = restoreSettings.Creator;
|
||||
if (restoreSettings.CreationDate) this.CreationDate = restoreSettings.CreationDate;
|
||||
if (restoreSettings.LastModifiedDate) this.LastModifiedDate = restoreSettings.LastModifiedDate;
|
||||
if (restoreSettings.Description) this.Description = restoreSettings.Description;
|
||||
if (restoreSettings.FileIndex) this.FileIndex = restoreSettings.FileIndex;
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(key) {
|
||||
let sdjson = {};
|
||||
sdjson.Name = this.Name;
|
||||
sdjson.Creator = this.Creator;
|
||||
sdjson.CreationDate = this.CreationDate;
|
||||
sdjson.LastModifiedDate = this.LastModifiedDate;
|
||||
sdjson.Description = this.Description;
|
||||
sdjson.FileIndex = this.FileIndex;
|
||||
return sdjson;
|
||||
}
|
||||
|
||||
GetFile() {
|
||||
let file = JSON.parse(LZString.decompressFromUTF16(localStorage.getItem("LogicPartsfile" + this.FileIndex)));
|
||||
return file;
|
||||
}
|
||||
|
||||
SaveFile(container) {
|
||||
let saveState = createSaveState(container,true);
|
||||
console.log(saveState);
|
||||
}
|
||||
}
|
||||
|
||||
class LocalStorage {
|
||||
constructor() {
|
||||
this._FileIndex = 0;
|
||||
this.RootFolder = new StorageFolder({Name: "ROOT"});
|
||||
if (localStorage.getItem('LogicEngineFileTable')) {
|
||||
let LSFT = json.parse(localStorage.getItem('LogicEngineFileTable'));
|
||||
if (LSFT?.Index >= 0) {
|
||||
this._FileIndex = LSFT.Index;
|
||||
if (LSFT.RootFolder) {
|
||||
this.RootFolder = new StorageFolder(LSFT.RootFolder);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No file table yet!
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LocalBrowser {
|
||||
constructor(folder = undefined) {
|
||||
this.DOMElement = document.getElementById("LocalStorageBrowser");
|
||||
this.DOMPath = document.getElementById("lsbPath");
|
||||
this.DOMFolders = document.getElementById("lsbfoldersContainer");
|
||||
this.DOMFiles = document.getElementById("lsbFilesContainer");
|
||||
this.DOMFolders.innerHTML = "";
|
||||
this.DOMFiles.innerHTML = "Empty Folder";
|
||||
this.Folder = (folder instanceof StorageFolder) ? folder : new StorageFolder({Name: "ROOT"});
|
||||
this.DOMPath.innerHTML = this.Folder.PathString();
|
||||
|
||||
this.redrawFolders();
|
||||
this.redrawFiles();
|
||||
//this.DOMFolders.addEventListener("contextmenu",function(evt){});
|
||||
}
|
||||
redrawFolders() {
|
||||
this.DOMFolders.innerHTML="";
|
||||
for (let a = 0; a < this.Folder.Folders.length; a++) {
|
||||
this.DOMFolders.innerHTML += `<div class="lsbFolderEntry">${this.Folder.Folders[a].Name}</div>`;
|
||||
}
|
||||
if (this.Folder.Folder) this.DOMFolders.innerHTML += `<div class="lsbFolderEntry">..</div>`;
|
||||
|
||||
let folders = this.DOMFolders.getElementsByClassName('lsbFolderEntry');
|
||||
for (let a = 0; a < folders.length; a ++) {
|
||||
let lbo = this;
|
||||
folders[a].addEventListener("click",function(evt){
|
||||
lbo.FolderClick(folders[a].innerText);
|
||||
}.bind(lbo));
|
||||
}
|
||||
|
||||
let pathfolders = this.DOMPath.getElementsByTagName('span');
|
||||
for (let a = 0; a < pathfolders.length; a ++) {
|
||||
let lbo = this;
|
||||
pathfolders[a].addEventListener("click",function(evt){
|
||||
lbo.FolderClick(pathfolders[a].innerText);
|
||||
}.bind(lbo));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
redrawFiles() {
|
||||
this.DOMFiles.innerHTML="";
|
||||
for (let a = 0; a < this.Folder.Designs.length; a++) {
|
||||
this.DOMFiles.innerHTML += `<div class = "lsbFileEntry"><div class="FileName">${this.Folder.Designs[a].Name}</div><div class="FileModified">${new Date(this.Folder.Designs[a].LastModifiedDate)}</div><div class="FileSize">?.??KB</div></div>`;
|
||||
}
|
||||
|
||||
let files = this.DOMFiles.getElementsByClassName('lsbFileEntry');
|
||||
for (let a = 0; a < files.length; a ++) {
|
||||
let lbo = this;
|
||||
files[a].addEventListener("click",function(evt){
|
||||
lbo.FileClick(files[a].getElementsByClassName("FileName")[0].innerText);
|
||||
}.bind(lbo));
|
||||
}
|
||||
}
|
||||
|
||||
FileClick(file) {
|
||||
console.log(`The file ${file} was clicked from within the folder ${this.Folder.Name}`);
|
||||
}
|
||||
FolderClick(folder) {
|
||||
console.log(`Folder ${folder} was clicked.`);
|
||||
let folderobj = this.Folder.HasFolder(folder);
|
||||
if (folder === ".." || folder === "/") {
|
||||
if (this.Folder.Folder instanceof StorageFolder) this.Folder = this.Folder.Folder;
|
||||
} else {
|
||||
if (folderobj) this.Folder = folderobj;
|
||||
}
|
||||
|
||||
this.DOMPath.innerHTML = this.Folder.PathString();
|
||||
this.redrawFolders();
|
||||
this.redrawFiles();
|
||||
}
|
||||
ShowBrowser(x,y,w,h) {
|
||||
let lsb = this.DOMElement;
|
||||
lsb.style.left = x + "px";
|
||||
lsb.style.top = y + "px";
|
||||
lsb.style.width = w + "px";
|
||||
lsb.style.height = h + "px";
|
||||
lsb.style.display = "flex";
|
||||
}
|
||||
}
|
@ -550,6 +550,7 @@ class LogicEngine {
|
||||
}
|
||||
|
||||
this.Settings = new LogicEngineSettings(restoresettings);
|
||||
this.LocalStorage = new LocalStorage();
|
||||
this.FPSCounter = 0;
|
||||
this.FPS = 0;
|
||||
this.PotentialFPS = 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
MatCat BrowserLogic Simulator
|
||||
*/
|
||||
|
||||
let Version = "0.4.16";
|
||||
let Version = "0.5.0";
|
||||
|
||||
let spanVersion = document.getElementById("version");
|
||||
spanVersion.innerText = Version;
|
||||
|
Loading…
Reference in New Issue
Block a user