started menu functionality

This commit is contained in:
Rudis Muiznieks 2022-04-19 21:02:08 -05:00
parent ad7c97d1fd
commit cd5622c98e
Signed by: rudism
GPG Key ID: CABF2F86EF7884F9
11 changed files with 331 additions and 33 deletions

View File

@ -1,19 +1,31 @@
"use strict"; "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true; exports.__esModule = true;
var i2c_bus_1 = require("i2c-bus"); var menu_1 = require("./menu/menu");
var oled_i2c_bus_1 = __importDefault(require("oled-i2c-bus")); var interface_1 = require("./menu/interface");
var oled_font_5x7_1 = __importDefault(require("oled-font-5x7")); var menu = new menu_1.Menu([
var i2cbus = (0, i2c_bus_1.openSync)(1); {
var opts = { display: "df -h",
width: 128, type: interface_1.MenuType.ExecCommand,
height: 64, command: ["df", "-h"]
address: 0x3C },
}; {
var oled = new oled_i2c_bus_1["default"](i2cbus, opts); display: "Games",
oled.clearDisplay(); type: interface_1.MenuType.SubMenu,
oled.setCursor(1, 1); subMenu: [
oled.writeString(oled_font_5x7_1["default"], 1, "This is a string I am writing to the screen", 1, true); {
oled.turnOffDisplay(); display: "Chess",
type: interface_1.MenuType.ExecCommand,
command: ["df", "-h"]
},
]
},
{
display: "Reboot",
type: interface_1.MenuType.Reboot
},
{
display: "Shutdown",
type: interface_1.MenuType.Shutdown
},
], true);
menu.getSelection();

91
bin/menu/console.js Normal file
View File

@ -0,0 +1,91 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
exports.__esModule = true;
exports.ConsolePrinter = void 0;
var interface_1 = require("./interface");
var readline = __importStar(require("readline"));
var ConsolePrinter = /** @class */ (function () {
function ConsolePrinter(config) {
this._path = [];
this._selectedIndex = 0;
this._config = config;
}
ConsolePrinter.prototype.printMenu = function (curMenu) {
console.clear();
for (var i = 0; i < curMenu.length; i++) {
var line = (i === this._selectedIndex
? "> "
: " ") + curMenu[i].display;
console.log(line);
}
};
ConsolePrinter.prototype.getSelection = function () {
var _this = this;
var curMenu = this._config;
this.printMenu(curMenu);
// get user input
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on('keypress', function (_letter, key) {
if (key.ctrl && key.name === 'c') {
process.exit();
}
else if (key.name === 'up') {
_this._selectedIndex--;
if (_this._selectedIndex < 0) {
_this._selectedIndex = 0;
}
}
else if (key.name === 'down') {
_this._selectedIndex++;
if (_this._selectedIndex > curMenu.length - 1) {
_this._selectedIndex = curMenu.length - 1;
}
}
else if (key.name === 'left') {
if (_this._path.length > 0) {
_this._path.pop();
}
}
else if (key.name === 'right' || key.name === 'enter') {
if (curMenu[_this._selectedIndex].type === interface_1.MenuType.SubMenu) {
_this._path.push(_this._selectedIndex);
_this._selectedIndex = 0;
}
else {
process.exit();
}
}
curMenu = _this._config;
for (var i = 0; i < _this._path.length; i++) {
curMenu = curMenu[_this._path[i]].subMenu;
}
_this.printMenu(curMenu);
});
return this._config[this._selectedIndex];
};
return ConsolePrinter;
}());
exports.ConsolePrinter = ConsolePrinter;

10
bin/menu/interface.js Normal file
View File

@ -0,0 +1,10 @@
"use strict";
exports.__esModule = true;
exports.MenuType = void 0;
var MenuType;
(function (MenuType) {
MenuType[MenuType["ExecCommand"] = 0] = "ExecCommand";
MenuType[MenuType["Reboot"] = 1] = "Reboot";
MenuType[MenuType["Shutdown"] = 2] = "Shutdown";
MenuType[MenuType["SubMenu"] = 3] = "SubMenu";
})(MenuType = exports.MenuType || (exports.MenuType = {}));

18
bin/menu/menu.js Normal file
View File

@ -0,0 +1,18 @@
"use strict";
exports.__esModule = true;
exports.Menu = void 0;
var console_1 = require("./console");
var oled_1 = require("./oled");
var Menu = /** @class */ (function () {
function Menu(config, isConsole) {
if (isConsole === void 0) { isConsole = false; }
this._printer = isConsole
? new console_1.ConsolePrinter(config)
: new oled_1.OledPrinter(config);
}
Menu.prototype.getSelection = function () {
return this._printer.getSelection();
};
return Menu;
}());
exports.Menu = Menu;

26
bin/menu/oled.js Normal file
View File

@ -0,0 +1,26 @@
"use strict";
exports.__esModule = true;
exports.OledPrinter = void 0;
/*const i2cbus = openSync(1);
const opts = {
width: 128,
height: 64,
address: 0x3C,
};
const oled = new Oled(i2cbus, opts);
oled.clearDisplay();
oled.setCursor(1, 1);
oled.writeString(font, 1, "This is a string I am writing to the screen", 1, true);
oled.turnOffDisplay();*/
var OledPrinter = /** @class */ (function () {
function OledPrinter(config) {
this._config = config;
}
OledPrinter.prototype.getSelection = function () {
return this._config[0];
};
return OledPrinter;
}());
exports.OledPrinter = OledPrinter;

View File

@ -2,7 +2,7 @@
"scripts": { "scripts": {
"clean": "rm -rf bin/*", "clean": "rm -rf bin/*",
"build": "npm run clean && tsc --project tsconfig.json", "build": "npm run clean && tsc --project tsconfig.json",
"start": "node bin/main.js" "start": "ts-node src/main.ts"
}, },
"dependencies": { "dependencies": {
"i2c-bus": "^5.2.2", "i2c-bus": "^5.2.2",

View File

@ -1,17 +1,31 @@
import { openSync } from 'i2c-bus'; import { Menu } from './menu/menu';
import Oled from 'oled-i2c-bus'; import { MenuType } from './menu/interface';
import font from 'oled-font-5x7';
const i2cbus = openSync(1); const menu = new Menu([
const opts = { {
width: 128, display: "df -h",
height: 64, type: MenuType.ExecCommand,
address: 0x3C, command: ["df", "-h"],
}; },
{
display: "Games",
type: MenuType.SubMenu,
subMenu: [
{
display: "Chess",
type: MenuType.ExecCommand,
command: ["df", "-h"],
},
],
},
{
display: "Reboot",
type: MenuType.Reboot,
},
{
display: "Shutdown",
type: MenuType.Shutdown,
},
], true);
const oled = new Oled(i2cbus, opts); menu.getSelection();
oled.clearDisplay();
oled.setCursor(1, 1);
oled.writeString(font, 1, "This is a string I am writing to the screen", 1, true);
oled.turnOffDisplay();

63
src/menu/console.ts Normal file
View File

@ -0,0 +1,63 @@
import { MenuConfig, MenuPrinter, MenuType } from './interface';
import * as readline from 'readline';
export class ConsolePrinter implements MenuPrinter {
private _path: number[] = [];
private _selectedIndex: number = 0;
private _config: MenuConfig[];
constructor(config: MenuConfig[]) {
this._config = config;
}
private printMenu(curMenu: MenuConfig[]): void {
console.clear();
for (let i = 0; i < curMenu.length; i++) {
const line = (i === this._selectedIndex
? "> "
: " ") + curMenu[i].display;
console.log(line);
}
}
public getSelection(): MenuConfig {
let curMenu = this._config;
this.printMenu(curMenu);
// get user input
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on('keypress', (_letter, key: any) => {
if (key.ctrl && key.name === 'c') {
process.exit();
} else if (key.name === 'up') {
this._selectedIndex--;
if (this._selectedIndex < 0) {
this._selectedIndex = 0;
}
} else if (key.name ==='down') {
this._selectedIndex++
if (this._selectedIndex > curMenu.length - 1) {
this._selectedIndex = curMenu.length - 1;
}
} else if (key.name === 'left') {
if (this._path.length > 0) {
this._path.pop();
}
} else if (key.name === 'right' || key.name === 'enter') {
if (curMenu[this._selectedIndex].type === MenuType.SubMenu) {
this._path.push(this._selectedIndex);
this._selectedIndex = 0;
} else {
process.exit()
}
}
curMenu = this._config;
for (let i = 0; i < this._path.length; i++) {
curMenu = curMenu[this._path[i]].subMenu!;
}
this.printMenu(curMenu);
});
return this._config[this._selectedIndex];
}
}

17
src/menu/interface.ts Normal file
View File

@ -0,0 +1,17 @@
export enum MenuType {
ExecCommand,
Reboot,
Shutdown,
SubMenu,
}
export interface MenuConfig {
display: string,
type: MenuType,
command?: string[],
subMenu?: MenuConfig[],
}
export interface MenuPrinter {
getSelection(): MenuConfig;
}

17
src/menu/menu.ts Normal file
View File

@ -0,0 +1,17 @@
import { MenuConfig, MenuPrinter } from './interface';
import { ConsolePrinter } from './console';
import { OledPrinter } from './oled';
export class Menu {
private _printer: MenuPrinter;
constructor(config: MenuConfig[], isConsole: boolean = false) {
this._printer = isConsole
? new ConsolePrinter(config)
: new OledPrinter(config);
}
public getSelection(): MenuConfig {
return this._printer.getSelection();
}
}

30
src/menu/oled.ts Normal file
View File

@ -0,0 +1,30 @@
/*import { openSync } from 'i2c-bus';
import Oled from 'oled-i2c-bus';
import font from 'oled-font-5x7';*/
import { MenuConfig, MenuPrinter } from './interface';
/*const i2cbus = openSync(1);
const opts = {
width: 128,
height: 64,
address: 0x3C,
};
const oled = new Oled(i2cbus, opts);
oled.clearDisplay();
oled.setCursor(1, 1);
oled.writeString(font, 1, "This is a string I am writing to the screen", 1, true);
oled.turnOffDisplay();*/
export class OledPrinter implements MenuPrinter {
private _config: MenuConfig[];
constructor(config: MenuConfig[]) {
this._config = config;
}
public getSelection(): MenuConfig {
return this._config[0];
}
}