diff --git a/css/hues-res.css b/css/hues-res.css index 0ddd48b..2dc94fb 100644 --- a/css/hues-res.css +++ b/css/hues-res.css @@ -2,7 +2,7 @@ position: relative; margin: 5px; height: 385px; - font-size: 16px; + font-size: 15px; } .res-packscontainer, .res-packcontainer { @@ -34,7 +34,7 @@ } #res-remotelist { - height: 150px; + height: 155px; } .res-list { @@ -47,6 +47,8 @@ .res-listitem { font-size: 10px; border-bottom: 1px solid black; + display: flex; + align-items: center; } .res-listitem > span { @@ -54,22 +56,50 @@ width: 100%; height: 100%; padding: 2px; + + cursor: pointer; } .res-listitem :hover { background: rgba(255,255,255,0.5); } -.res-listitem input[type="checkbox"] { +.res-listitem input[type=checkbox] { display: none; } +.res-listitem > label { + content: ""; + + width: 12px; + height: 10px; + margin: auto 2px; + + background-color: #ccc; + border: 1px solid black; + cursor: pointer; +} + +.res-listitem input[type=checkbox]:before { + border-radius: 3px; +} + +.res-listitem input[type=checkbox]:checked + label { + background-color: #222; + text-align: center; + line-height: 15px; +} + .res-buttons { display: flex; justify-content: space-between; padding: 0px 0px; } +.res-buttons.hidden { + display: none; +} + .res-button { font-size: 10px; margin: 3px 2px; @@ -88,6 +118,28 @@ user-select: none; } +.res-button.hidden { + display: none; +} + +.res-button:hover { + background: rgba(255,255,255, 0.5); +} + +.res-button.loaded { + background-color: rgb(0,127,0,0.5); + cursor: auto; +} + +#res-countscontainer { + margin-top: 3px; +} + +.res-counts { + position: absolute; + right: 3px; +} + #res-packinfo { margin-top: 5px; font-size: 9px; @@ -105,19 +157,35 @@ background: rgba(255,255,255,0.5); font-size: 9px; height: 85px; + margin: 2px; + padding: 2px; } -#res-packtabs { - display: flex; - justify-content: space-between; +#res-packtabs > label { + display: table-cell; + border: 2px solid black; + padding: 5px; + cursor: pointer; } -#res-packtabs > div { - flex-grow: 1; +#res-packtabs > input:checked + label { + background: rgba(255,255,255,0.5); + border-bottom: none; +} + +#res-packtabs > label:hover { + background: rgba(255,255,255,0.3); } -#res-packcontents { +#res-songlist, #res-imagelist { + display: none; height: 170px; + border-top: none; +} + +#res-songtab:checked ~ #res-songlist, +#res-imagetab:checked ~ #res-imagelist { + display: block; } #res-packbuttons > .res-button { diff --git a/css/style.css b/css/style.css index a0e8729..ca73a8a 100644 --- a/css/style.css +++ b/css/style.css @@ -39,6 +39,7 @@ h1, h2, h3 { #reference { display:flex; align-items:center; + justify-content: center; } .info-ref { @@ -106,6 +107,7 @@ h1, h2, h3 { #tabs { margin: -1px; + padding-top: 22px; min-height: 400px; min-width: 500px; } @@ -153,6 +155,7 @@ input.tab-input[type="radio"]:checked + label { } #settingsWindow { + position: relative; background: rgba(200,200,200, 0.7); border-color: "black"; border-width: 2px; @@ -165,6 +168,22 @@ input.tab-input[type="radio"]:checked + label { padding: 5px; } +#closeButton { + height: 20px; + width: 20px; + font-size: 20px; + color: white; + position: absolute; + right: 0px; + background-color: rgb(128,128,128); + border: 1px solid black; + cursor: pointer; +} + +#closeButton:hover { + background-color: rgb(200,200,200); +} + .settings-category { font-size: 12pt; } diff --git a/js/HuesCore.js b/js/HuesCore.js index 71bcd5a..9458539 100644 --- a/js/HuesCore.js +++ b/js/HuesCore.js @@ -6,7 +6,7 @@ HuesCore = function(defaults) { this.currentSong; this.currentImage; this.songIndex=-1; - this.colourIndex=0; + this.colourIndex=0; // TODO should be 0xF this.imageIndex=-1; this.isFullAuto = true; this.loopCount=0; @@ -30,7 +30,7 @@ HuesCore = function(defaults) { this.lastImageArray = []; this.settings = new HuesSettings(defaults); //this.autoSong = this.settings.autosong; - this.resourceManager = new Resources(); + this.resourceManager = new Resources(this); this.soundManager = new SoundManager(this); if(!this.soundManager.canUse) { this.error("Web Audio API not supported in this browser."); @@ -40,6 +40,7 @@ HuesCore = function(defaults) { this.uiArray.push(new RetroUI(), new WeedUI(), new ModernUI(), new XmasUI()); this.settings.connectCore(this); + this.setColour(this.colourIndex); if(defaults.load) { this.resourceManager.addAll(defaults.respacks, function() { @@ -50,9 +51,6 @@ HuesCore = function(defaults) { that.setImage(0); if(defaults.autoplay) { that.setSong(0); - // TODO delete me - that.previousSong(); - that.previousSong(); } }, function(progress) { var prog = document.getElementById("preMain"); @@ -132,7 +130,9 @@ HuesCore.prototype.previousSong = function() { } HuesCore.prototype.setSong = function(index) { - this.soundManager.stop(); + if(this.currentSong == this.resourceManager.enabledSongs[index]) { + return; + } this.songIndex = index; this.currentSong = this.resourceManager.enabledSongs[this.songIndex]; if (this.currentSong == undefined) { @@ -250,19 +250,16 @@ HuesCore.prototype.randomImage = function() { } } -HuesCore.prototype.getImageIndex = function() { - return this.imageIndex; -} - HuesCore.prototype.setImage = function(index) { - this.imageIndex = index; + // If there are no images, this corrects NaN to 0 + this.imageIndex = index ? index : 0; var img=this.resourceManager.enabledImages[this.imageIndex]; if (img == this.currentImage && !(img == null)) { return; } if (img) { this.currentImage = img; - } else if (!this.currentImage) { + } else { this.currentImage = {"name":"None", "fullname":"None", "align":"center", "bitmap":null, "source":null, "enabled":true}; this.imageIndex = -1; this.lastImageArray = []; diff --git a/js/HuesSettings.js b/js/HuesSettings.js index ce46787..249dd23 100644 --- a/js/HuesSettings.js +++ b/js/HuesSettings.js @@ -138,6 +138,9 @@ HuesSettings.prototype.showInfo = function() { HuesSettings.prototype.initUI = function() { var doc = this.root.ownerDocument; + var that = this; + document.getElementById("closeButton").onclick = function() {that.hide();}; + // To order things nicely for(cat in this.settingsCategories) { var catContainer = doc.createElement("div"); diff --git a/js/ResourceManager.js b/js/ResourceManager.js index 1adbb6f..69179f9 100644 --- a/js/ResourceManager.js +++ b/js/ResourceManager.js @@ -1,4 +1,9 @@ -function Resources() { +// NOTE: Any packs referenced need CORS enabled or loads fail +var packsURL = "http://cdn.0x40hu.es/getRespacks.php"; + +function Resources(core) { + this.core = core; + this.resourcePacks = []; this.allSongs = []; @@ -14,6 +19,7 @@ function Resources() { this.root = null; this.packView = { + pack: null, name: null, creator: null, size: null, @@ -22,18 +28,24 @@ function Resources() { imageCount: null, songList: null, imageList: null, + packButtons: null, totalSongs: null, totalImages: null }; this.packsView = { respackList: null, remoteList: null, + loadRemote: null, progressBar: null, progressStatus: null, progressCurrent: null, progressTop: null, progressPercent: null }; + this.remotes = null; + this.fileInput = null; + this.fileParseQueue = []; + this.currentlyParsing = false; this.initUI(); } @@ -89,16 +101,20 @@ Resources.prototype.updateProgress = function() { Resources.prototype.addPack = function(pack) { console.log("Added", pack.name, "to respacks"); - var id = "res" + this.resourcePacks.length; + var that = this; + var id = this.resourcePacks.length; this.resourcePacks.push(pack); this.addResourcesToArrays(pack); this.rebuildEnabled(); this.updateTotals(); - this.appendListItem("respacks", pack.name, id, this.packsView.respackList); - if(id == "res0") { - this.selectPack(0); - } + this.appendListItem("respacks", pack.name, "res" + id, this.packsView.respackList, + function() { + pack.enabled = this.checked; + that.rebuildEnabled(); + }, + this.selectPackCallback(id) + ); } Resources.prototype.addResourcesToArrays = function(pack) { @@ -117,9 +133,8 @@ Resources.prototype.rebuildArrays = function() { } Resources.prototype.rebuildEnabled = function() { - enabledSongs = []; - enabledImages = []; - _enabledAnimations = []; + this.enabledSongs = []; + this.enabledImages = []; for(var i = 0; i < this.resourcePacks.length; i++) { var pack = this.resourcePacks[i]; @@ -139,6 +154,7 @@ Resources.prototype.rebuildEnabled = function() { } } } + this.updateTotals(); } Resources.prototype.removePack = function(pack) { @@ -162,8 +178,39 @@ Resources.prototype.getSongNames = function() { return names; } +Resources.prototype.loadLocal = function() { + console.log("Loading local zip(s)"); + var files = this.fileInput.files; + for(var i = 0; i < files.length; i++) { + this.fileParseQueue.push(files[i]); + } + this.parseLocalQueue(); +} + +Resources.prototype.parseLocalQueue = function(recursing) { + var that = this; + // avoid race conditions + if(this.currentlyParsing && !recursing) { + return; + } + this.currentlyParsing = true; + if(this.fileParseQueue.length) { + var r = new Respack(); + r.loadBlob(this.fileParseQueue.shift(), + function() { + that.addPack(r); + that.parseLocalQueue(true); + }, + function() {that.parseLocalQueue(true);}); + } else { + console.log("Local respack parsing complete"); + this.currentlyParsing = false; + } +} + Resources.prototype.initUI = function() { this.root = document.getElementById("huesResources"); + var that = this; var packsContainer = document.createElement("div"); packsContainer.className = "res-packscontainer"; @@ -182,19 +229,30 @@ Resources.prototype.initUI = function() { var remoteList = document.createElement("div"); remoteList.className = "res-list"; remoteList.id = "res-remotelist"; + this.appendSimpleListItem("Click to load the list", remoteList, + function() {that.loadRemotes();}); this.packsView.remoteList = remoteList; var buttons = document.createElement("div"); buttons.className = "res-buttons"; var loadRemote = document.createElement("div"); - loadRemote.className = "res-button"; - loadRemote.textContent = "LOAD"; + loadRemote.className = "res-button hidden"; + loadRemote.textContent = "LOAD REMOTE"; + loadRemote.onclick = function() {that.loadCurrentRemote();}; var loadLocal = document.createElement("div"); loadLocal.className = "res-button"; loadLocal.textContent = "LOAD ZIPS"; - buttons.appendChild(loadRemote); + loadLocal.onclick = function() {that.fileInput.click();}; buttons.appendChild(loadLocal); + buttons.appendChild(loadRemote); + this.packsView.loadRemote = loadRemote; + this.fileInput = document.createElement("input"); + this.fileInput.type ="file"; + this.fileInput.accept="application/zip"; + this.fileInput.multiple = true; + this.fileInput.onchange = function() {that.loadLocal();}; + var progressContainer = document.createElement("div"); var progressBar = document.createElement("div"); var progressStatus = document.createElement("div"); @@ -223,58 +281,97 @@ Resources.prototype.initUI = function() { indivView.className = "res-packcontainer"; var packName = document.createElement("div"); + packName.textContent = "