From 81e26a625a9b2f5dd82654073a1d91c02893024a Mon Sep 17 00:00:00 2001 From: bluesaxman Date: Fri, 16 Sep 2022 08:42:55 -0600 Subject: [PATCH] initial addition of bluepixle_ui.js --- libs/bluepixle_ui.js | 128 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 libs/bluepixle_ui.js diff --git a/libs/bluepixle_ui.js b/libs/bluepixle_ui.js new file mode 100644 index 0000000..a3fbbbd --- /dev/null +++ b/libs/bluepixle_ui.js @@ -0,0 +1,128 @@ +const UP_KEY = "KeyW"; +const DOWN_KEY = "KeyS"; +const LEFT_KEY = "KeyA"; +const RIGHT_KEY = "KeyD"; +const ACT_KEY = "KeyE"; +const MENU_KEY = "KeyQ"; + +class menu { + constructor (frameBufferRef, dimentions, closeable, options, callbackArray) { + this.parentBuffer = frameBufferRef; + this.closeable = "boolean" == typeof closeable ? closeable : true; + this.options = Array.isArray(options) ? options : ["Empty Menu"]; + this.callbackArray = Array.isArray(callbackArray) ? callbackArray : options.map(o=>{ return function () { print(o); } }); + this.callbackArray = this.callbackArray.map(cb=>{ if ("function" == typeof cb) { return cb; } else { return ()=> { print("Not Implimented") }; } }); + this.dimentions = dimentions instanceof vector ? dimentions : new vector([500,500]); + this.renderLayer = new container( new vector([0,0]), this.dimentions); + this.active = false; + this.selectedOption = 0; + this.renderLayer.addShape(new shape("rect", new vector([0,0]), this.dimentions, null, "#ffffff", "#000000", 2)); + this.selectorShape = new shape("rect", new vector([5,2]), new vector([this.dimentions.d[0] - 10, 16]), null, "#aaaaaa", "#000000", 2); + this.renderLayer.addShape(this.selectorShape); + // add case for menu with more options than screen allows + this.optionShapes = []; + for (var i = 0; i < this.options.length; i++) { + var thisOption = this.options[i]; + this.optionShapes[i] = new shape("text", new vector([10,20+20*i]), new vector([this.dimentions.d[0] - 20,20]), null, "#000000", null, null, {text:thisOption}); + this.renderLayer.addShape(this.optionShapes[i]); + } + + } + + activate () { + this.previousMenu = window.activeMenu; + window.activeMenu = this; + this.active = true; + this.selectedOption = 0; + this.selectorShape.coordinates.d[1] = 8 + 20 * this.selectedOption; + this.parentBuffer.addContainer(this.renderLayer); + } + + deactivate () { + window.activeMenu = this.previousMenu; + var layerID = this.parentBuffer.containerArray.indexOf(this.renderLayer); + this.parentBuffer.containerArray.splice(layerID,1); + } + + selectItem () { + this.deactivate(); + this.callbackArray[this.selectedOption](); + } + + move (n) { + this.selectedOption = (this.selectedOption + n + this.options.length) % this.options.length; + this.selectorShape.coordinates.d[1] = 8 + 20 * this.selectedOption; + } + + controls (e) { + var input = e.code; + if ((input == MENU_KEY) && this.closeable ) { this.deactivate(); } + if (input == ACT_KEY) { this.selectItem(); } + if (input == UP_KEY) { this.move(-1); } + if (input == DOWN_KEY) { this.move(1); } + } +} + +class dialogBox { + constructor (parentBufferRef) { + this.parentBufferRef = parentBufferRef; + this.messageLayer = new container(new vector([0, parentBufferRef.height - 100]), new vector([parentBufferRef.width, 100])); + this.messageLayer.addShape( new shape("rect", new vector([0,0]), this.messageLayer.size, null, "#ffffff", "#000000", 1)); + this.line = [ + new shape("text", new vector([30,30]), new vector([this.messageLayer.size.d[0]-20,30]),null, "#000000"), + new shape("text", new vector([30,60]), new vector([this.messageLayer.size.d[0]-20,30]),null, "#000000") + ]; + this.textQueue = []; + this.messageLayer.addShape( this.line[0] ); + this.messageLayer.addShape( this.line[1] ); + } + + progressMessage () { + if (this.textQueue.length <= 1) { + if (undefined != this.choice) { + this.choice.activate(); + this.choice = undefined; + return; + } else { + this.deactivate(); + } + } + this.textQueue.shift(); + this.line[0].text = "string" == typeof this.textQueue[0] ? this.textQueue[0] : ""; + this.line[1].text = "string" == typeof this.textQueue[1] ? this.textQueue[1] : ""; + } + + activate (message="No message", interactive, choice) { + message = "string" == typeof message ? message : "No valid text"; + interactive = "boolean" == typeof interactive ? interactive : false; + this.choice = choice instanceof menu ? choice : undefined; + this.textQueue.push(...message.match(/.{1,50}( |$)/g)); + if (!this.parentBufferRef.containerArray.includes(this.messageLayer)) { + this.parentBufferRef.addContainer(this.messageLayer); + } + this.line[0].text = "string" == typeof this.textQueue[0] ? this.textQueue[0] : ""; + this.line[1].text = "string" == typeof this.textQueue[1] ? this.textQueue[1] : ""; + if (interactive) { + if (undefined != window.activeDialog) { this.previousDialog = window.activeDialog; } + window.activeDialog = this; + } else { + var me = this; + setTimeout(function () { me.progressMessage(); }, 5000); // Not cleaned up properly yet + } + } + + deactivate () { + var layerID = this.parentBufferRef.containerArray.indexOf(this.messageLayer); + this.parentBufferRef.containerArray.splice(layerID,1); + if (undefined != this.previousDialog) { + window.activeDialog = this.previousDialog; + this.previousDialog = undefined; + } else { + window.activeDialog = undefined; + } + } + + controls (e) { + this.progressMessage(); + } +}