diff --git a/assets/JS_INIT.js b/assets/JS_INIT.js index ec62954..0ae04c9 100644 --- a/assets/JS_INIT.js +++ b/assets/JS_INIT.js @@ -423,6 +423,9 @@ con.resetkeybuf = function() { sys.poke(-41, 0); sys.poke(-42, 0); sys.poke(-43, 0); sys.poke(-44, 0); sys.poke(-45, 0); sys.poke(-46, 0); sys.poke(-47, 0); sys.poke(-48, 0); }; +con.video_reverse = function() { + print(String.fromCharCode(27,91)+"7m"); +}; con.color_fore = function(n) { // 0..7; -1 for transparent if (n < 0) print(String.fromCharCode(27,91)+"38;5;255m"); @@ -449,6 +452,11 @@ con.curs_set = function(arg) { con.reset_graphics = function() { print(String.fromCharCode(27,91,109)); }; +// returns current key-down status +con.poll_keys = function() { + sys.poke(-40, 1); + return [-41,-42,-43,-44,-45,-46,-47,-48].map(it => sys.peek(it)); +}; Object.freeze(con); // system management function var system = {}; diff --git a/assets/disk0/tvdos/tuidev/demo.js b/assets/disk0/tvdos/tuidev/demo.js index dff4c57..4b12115 100644 --- a/assets/disk0/tvdos/tuidev/demo.js +++ b/assets/disk0/tvdos/tuidev/demo.js @@ -52,14 +52,90 @@ class Canvas { 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.keyLatched = 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; + } + } + } + + 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 && (this.selection + this.scroll) > 0) { + this.selection -= 1; + redraw = true; + } + // down + else if (!this.keyLatched && keys[0] == 20 && (this.selection + this.scroll) < this.item.length - 1) { + this.selection += 1; + redraw = true; + } + + // finally update key latched state + this.keyLatched = keys[0] != 0; + return redraw; + } +} + class Demo extends SimpleScreen { constructor(title) { super(title); let mainCanvas = new Canvas("main"); con.curs_set(0); - mainCanvas.redraw = () => { + mainCanvas.selector = new TextList(40, 31, ["The", "Quick", "Brown", "Fox", "Jumps"]); + mainCanvas.redraw = () => { + mainCanvas.selector.redraw(1,1); } this.ballX = 1 + ((Math.random() * this.termWidth)|0); @@ -70,7 +146,7 @@ class Demo extends SimpleScreen { mainCanvas.update = () => { // erase a track - con.mvaddch(this.ballY, this.ballX, 0); + /*con.mvaddch(this.ballY, this.ballX, 0); // collide if (this.ballX <= 1) this.ballMomentumX = 1; @@ -90,10 +166,19 @@ class Demo extends SimpleScreen { this.ballY += this.ballMomentumY; // draw - con.mvaddch(this.ballY, this.ballX, 2); - sys.spin();sys.spin();sys.spin();sys.spin(); + con.mvaddch(this.ballY, this.ballX, 2);*/ + //sys.spin();sys.spin();sys.spin();sys.spin(); + + + if (mainCanvas.selector.update()) { + mainCanvas.selector.redraw(1,1); + } + con.mvaddch(20,20); print("TEXT"); + } + + this.mainCanvas = mainCanvas this.canvas = this.mainCanvas; } @@ -103,5 +188,6 @@ let s = new Demo("Ctrl-C to exit"); s.redraw(); while (!con.hitterminate()) { s.update(); + sys.spin(); } con.clear(); \ No newline at end of file diff --git a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt index 5421cee..2542238 100644 --- a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt +++ b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt @@ -423,6 +423,11 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super else if (arg in 40..47) { ttyBack = sgrDefault8ColPal[arg - 40] } + else if (arg == 7) { + val t = ttyFore + ttyFore = ttyBack + ttyBack = t + } else if (arg == 0) { ttyFore = TTY_FORE_DEFAULT ttyBack = TTY_BACK_DEFAULT