diff --git a/README.md b/README.md index 3da2622..d8094a3 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/css/main.css b/css/main.css index f0b070f..ac30f7d 100644 --- a/css/main.css +++ b/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; diff --git a/index.html b/index.html index 072cecf..83d7957 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -138,20 +138,38 @@
  • Disconnect
  • +
    +
    /
    +
    +
    +
    Folders
    +
    +
    +
    +
    +
    Name
    Modified
    Size
    +
    +
    +
    +
    +
    Save Design
    -
    Design Name
    -
    - Save Compressed +
    + +
    +
    +
    + Save Compressed +
       
    -
    @@ -193,6 +211,7 @@ + diff --git a/js/elements/BaseElementClasses.js b/js/elements/BaseElementClasses.js index 0c8496c..e11bceb 100644 --- a/js/elements/BaseElementClasses.js +++ b/js/elements/BaseElementClasses.js @@ -413,47 +413,53 @@ 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.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) { - // This is a ghosted connection, lets get rid of it - 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; + 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); + 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 startX = this.X + this.Width; - let startY = firstY+ (this.OutputConnections[a].Output*24); - let endX = this.OutputConnections[a].Element.X; - //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 startMidY = startY; - let midX = startMidX; - let midY = startY + ((endY - startY)/2); - let endMidX = startMidX; - let endMidY = endY; + 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 startMidY = startY; + let midX = startMidX; + let midY = startY + ((endY - startY) / 2); + let endMidX = startMidX; + let endMidY = endY; + + ctx.save(); + ctx.beginPath(); + ctx.lineWidth = settings.LinkWidth; + if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.lineWidth = (settings.LinkWidth * 2); + ctx.setLineDash(settings.LinkDash); + ctx.moveTo(startX, startY); + 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)) { + ctx.strokeStyle = settings.InactiveConnectionColor; + if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.InactiveConnectionHoverColor; + } + + ctx.stroke(); + ctx.restore(); - ctx.save(); - ctx.beginPath(); - ctx.lineWidth = settings.LinkWidth; - 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); - ctx.strokeStyle = settings.ActiveConnectionColor; - if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.ActiveConnectionHoverColor; - if (!this.getOutput(this.OutputConnections[a].Output)) { - ctx.strokeStyle = settings.InactiveConnectionColor; - if ((mouseDist <= (this.outputCircleRadius)) && !this.LogicEngine.ActiveLink) ctx.strokeStyle = settings.InactiveConnectionHoverColor; } - - ctx.stroke(); - ctx.restore(); - } } } diff --git a/js/elements/BasicElements.js b/js/elements/BasicElements.js index 52de653..adb76ff 100644 --- a/js/elements/BasicElements.js +++ b/js/elements/BasicElements.js @@ -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); diff --git a/js/globalfunctions.js b/js/globalfunctions.js index 2a1f8ef..d3de7f9 100644 --- a/js/globalfunctions.js +++ b/js/globalfunctions.js @@ -276,20 +276,33 @@ function SaveSettings() { console.log("Settings Saved"); } -function createSaveState(container = false) { - let saveState = { - Name: "LogicDesign", - Version: Version, - Timestamp: Date.now(), - PanX: logicEngine.Panning.OffsetX, - PanY: logicEngine.Panning.OffsetY, - Elements: new Array() - }; +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; } diff --git a/js/localstorage.js b/js/localstorage.js new file mode 100644 index 0000000..7114949 --- /dev/null +++ b/js/localstorage.js @@ -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 = `${this.Name} ${(ChildrenString != "") ? "/" : ""} ${ChildrenString}`; + pathString = this.Folder.PathString(pathString); + return pathString; + } else { + if (ChildrenString == "") { + return `/ `; + } else { + return `/ ${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 += `
    ${this.Folder.Folders[a].Name}
    `; + } + if (this.Folder.Folder) this.DOMFolders.innerHTML += `
    ..
    `; + + 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 += `
    ${this.Folder.Designs[a].Name}
    ${new Date(this.Folder.Designs[a].LastModifiedDate)}
    ?.??KB
    `; + } + + 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"; + } +} diff --git a/js/logicengine.js b/js/logicengine.js index 3d7e615..1bbc291 100644 --- a/js/logicengine.js +++ b/js/logicengine.js @@ -550,6 +550,7 @@ class LogicEngine { } this.Settings = new LogicEngineSettings(restoresettings); + this.LocalStorage = new LocalStorage(); this.FPSCounter = 0; this.FPS = 0; this.PotentialFPS = 0; diff --git a/js/main.js b/js/main.js index c0d02c2..84419a1 100644 --- a/js/main.js +++ b/js/main.js @@ -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;