mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-09 20:51:51 +09:00
184 lines
4.6 KiB
JavaScript
184 lines
4.6 KiB
JavaScript
/*
|
|
Screen:
|
|
===================
|
|
Titlebar
|
|
===================
|
|
|
|
C A N V A S
|
|
|
|
===================
|
|
|
|
there are usually two separate canvases: main-screen and menu-screen
|
|
*/
|
|
|
|
class SimpleScreen {
|
|
|
|
constructor(title) {
|
|
this.title = title;
|
|
this.termWidth = con.getmaxyx()[1];
|
|
this.termHeight = con.getmaxyx()[0];
|
|
}
|
|
|
|
drawTitlebar() {
|
|
|
|
let titleLeftPad = (this.termWidth - this.title.length - 6) >> 1;
|
|
let titleRightPad = this.termWidth - titleLeftPad - this.title.length - 6;
|
|
|
|
con.move(1,1);
|
|
con.color_pair(253,255);
|
|
print(' ');con.addch(17);con.curs_right();
|
|
con.color_pair(0,253);
|
|
print(" ".repeat(titleLeftPad)+this.title+" ".repeat(titleRightPad));
|
|
con.color_pair(253,255);
|
|
con.addch(16);con.curs_right();print(' ');
|
|
con.move(3,1);
|
|
}
|
|
redraw() {
|
|
con.color_pair(239,255);
|
|
con.clear();
|
|
this.drawTitlebar();
|
|
if (this.canvas !== undefined) this.canvas.redraw();
|
|
}
|
|
update() {
|
|
if (this.canvas !== undefined) this.canvas.update();
|
|
}
|
|
}
|
|
|
|
class Canvas {
|
|
constructor(identifier) {
|
|
this.id = identifier;
|
|
}
|
|
redraw() {}
|
|
update() {}
|
|
}
|
|
|
|
class UIItem {
|
|
constructor(w,h,identifier) {
|
|
this.width = w;
|
|
this.height = h;
|
|
this.id = identifier;
|
|
}
|
|
redraw(y,x) {} // index starts from 0 (so that y=1 would starts from the line right after the titlebar)
|
|
update() {} // returns true when the screen must be re-drawn after the update
|
|
}
|
|
|
|
class TextList extends UIItem {
|
|
constructor(w,h,item,selection) {
|
|
super(w,h,"uiitem-textlist");
|
|
this.item = item;
|
|
this.selection = (isNaN(selection)) ? 0 : selection|0;
|
|
this.visible = true;
|
|
this.scroll = 0;
|
|
this.redrawReq = false;
|
|
}
|
|
|
|
getInternalHeight() {
|
|
return this.item.length() * 2 + 1;
|
|
}
|
|
getLongestItemLength() {
|
|
return this.item.map(it => (''+it).length).reduce((a,i) => (i>a) ? i : a);
|
|
}
|
|
|
|
redraw(y,x) {
|
|
// TODO: up/down scroll mark
|
|
let videoReversed = false
|
|
for (let i = this.scroll; i < this.item.length; i++) {
|
|
let printy = ((i - this.scroll) * 2) + 2;
|
|
if (printy < y + this.termHeight || printy < this.height) {
|
|
if (i == this.scroll + this.selection) {
|
|
con.video_reverse();
|
|
videoReversed = true;
|
|
}
|
|
con.move(y + printy, x);
|
|
print(` ${this.item[i]} `);
|
|
}
|
|
// un-reverse the video
|
|
if (videoReversed) {
|
|
con.video_reverse();
|
|
videoReversed = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
cursorUp() {
|
|
if ((this.selection + this.scroll) > 0) {
|
|
this.selection -= 1;
|
|
this.redrawReq = true;
|
|
}
|
|
}
|
|
|
|
cursorDown() {
|
|
if ((this.selection + this.scroll) < this.item.length - 1) {
|
|
this.selection += 1;
|
|
this.redrawReq = true;
|
|
}
|
|
}
|
|
|
|
getSelection() {
|
|
return {index: (this.scroll + this.selection), item: this.item[this.scroll + this.selection]};
|
|
}
|
|
|
|
update() {
|
|
let r = this.redrawReq;
|
|
this.redrawReq = false;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
class Demo extends SimpleScreen {
|
|
constructor(title) {
|
|
super(title);
|
|
let mainCanvas = new Canvas("main");
|
|
con.curs_set(0);
|
|
|
|
mainCanvas.selector = new TextList(40, 31, ["The", "Quick", "Brown", "Fox", "Jumps"]);
|
|
|
|
mainCanvas.redraw = () => {
|
|
mainCanvas.selector.redraw(1,2);
|
|
}
|
|
|
|
this.keyLatched = false;
|
|
|
|
mainCanvas.update = () => {
|
|
let keys = con.poll_keys();
|
|
let redraw = false;
|
|
|
|
// un-latch
|
|
if (this.keyLatched && keys[0] == 0) {
|
|
this.keyLatched = false;
|
|
}
|
|
|
|
// up
|
|
if (!this.keyLatched && keys[0] == 19) {
|
|
mainCanvas.selector.cursorUp();
|
|
}
|
|
// down
|
|
else if (!this.keyLatched && keys[0] == 20) {
|
|
mainCanvas.selector.cursorDown();
|
|
}
|
|
|
|
if (mainCanvas.selector.update())
|
|
mainCanvas.selector.redraw(1,2);
|
|
|
|
if (this.keyLatched && keys[0] == 66) {
|
|
con.mvaddch(20,20); print("SEL:"+mainCanvas.selector.getSelection().item);
|
|
}
|
|
|
|
// finally update key latched state
|
|
this.keyLatched = keys[0] != 0;
|
|
}
|
|
|
|
|
|
|
|
this.mainCanvas = mainCanvas
|
|
this.canvas = this.mainCanvas;
|
|
}
|
|
}
|
|
|
|
let s = new Demo("Ctrl-C to exit");
|
|
s.redraw();
|
|
while (!con.hitterminate()) {
|
|
s.update();
|
|
sys.spin();
|
|
}
|
|
con.clear(); |