mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-10 23:04:04 +09:00
another try at tui
This commit is contained in:
@@ -495,6 +495,8 @@ con.resetkeybuf = function() {
|
|||||||
con.video_reverse = function() {
|
con.video_reverse = function() {
|
||||||
print("\x1B[7m");
|
print("\x1B[7m");
|
||||||
};
|
};
|
||||||
|
con.get_color_fore = function() { return graphics.getTextFore() }
|
||||||
|
con.get_color_back = function() { return graphics.getTextBack() }
|
||||||
con.color_fore = function(n) { // 0..7; -1 for transparent
|
con.color_fore = function(n) { // 0..7; -1 for transparent
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
print("\x1B[38;5;255m");
|
print("\x1B[38;5;255m");
|
||||||
|
|||||||
@@ -841,7 +841,7 @@ if (exec_args[1] !== undefined) {
|
|||||||
goInteractive = true
|
goInteractive = true
|
||||||
}
|
}
|
||||||
else if ("/fancy" == firstSwitch) {
|
else if ("/fancy" == firstSwitch) {
|
||||||
graphics.setBackground(2,3,4)
|
graphics.setBackground(34,51,68)
|
||||||
goFancy = true
|
goFancy = true
|
||||||
goInteractive = true
|
goInteractive = true
|
||||||
}
|
}
|
||||||
|
|||||||
84
assets/disk0/tvdos/include/wintex.js
Normal file
84
assets/disk0/tvdos/include/wintex.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
class WindowObject {
|
||||||
|
|
||||||
|
constructor(x, y, w, h, inputProcessor, drawContents, title, drawFrame) {
|
||||||
|
this.isHighlighted = false
|
||||||
|
this.x = x
|
||||||
|
this.y = y
|
||||||
|
this.width = w
|
||||||
|
this.height = h
|
||||||
|
this.inputProcessorFun = inputProcessor
|
||||||
|
this.drawContentsFun = drawContents
|
||||||
|
this.title = title
|
||||||
|
this.titleLeft = undefined
|
||||||
|
this.titleRight = undefined
|
||||||
|
this.titleBack = 0 // default value
|
||||||
|
this.titleBackLeft = 245 // default value
|
||||||
|
this.titleBackRight = 245 // default value
|
||||||
|
this.drawFrameFun = drawFrame || (() => {
|
||||||
|
let oldFore = con.get_color_fore()
|
||||||
|
let oldBack = con.get_color_back()
|
||||||
|
|
||||||
|
let charset = (this.isHighlighted) ? [0xC9, 0xBB, 0xC8, 0xBC, 0xCD, 0xBA, 0xB5, 0xC6] : [0xDA, 0xBF, 0xC0, 0xD9, 0xC4, 0xB3, 0xB4, 0xC3]
|
||||||
|
let colour = (this.isHighlighted) ? 230 : 253
|
||||||
|
let colourText = (this.isHighlighted) ? 230 : 254
|
||||||
|
|
||||||
|
// set fore colour
|
||||||
|
print(`\x1B[38;5;${colour}m`)
|
||||||
|
|
||||||
|
// draw top horz
|
||||||
|
con.mvaddch(this.y, this.x, charset[0]); con.curs_right()
|
||||||
|
print(`\x84${charset[4]}u`.repeat(this.width - 2))
|
||||||
|
con.addch(charset[1])
|
||||||
|
// draw vert
|
||||||
|
for (let yp = this.y + 1; yp < this.y + this.height - 1; yp++) {
|
||||||
|
con.mvaddch(yp, this.x , charset[5])
|
||||||
|
con.mvaddch(yp, this.x + this.width - 1, charset[5])
|
||||||
|
}
|
||||||
|
// draw bottom horz
|
||||||
|
con.mvaddch(this.y + this.height - 1, this.x, charset[2]); con.curs_right()
|
||||||
|
print(`\x84${charset[4]}u`.repeat(this.width - 2))
|
||||||
|
con.addch(charset[3])
|
||||||
|
|
||||||
|
// draw title
|
||||||
|
if (this.title !== undefined) {
|
||||||
|
let tt = ''+this.title
|
||||||
|
con.move(this.y, this.x + ((this.width - 2 - tt.length) >>> 1))
|
||||||
|
if (this.titleBack !== undefined) print(`\x1B[48;5;${this.titleBack}m`)
|
||||||
|
print(`\x84${charset[6]}u`)
|
||||||
|
print(`\x1B[38;5;${colourText}m${tt}`)
|
||||||
|
print(`\x1B[38;5;${colour}m\x84${charset[7]}u`)
|
||||||
|
if (this.titleBack !== undefined) print(`\x1B[48;5;${oldBack}m`)
|
||||||
|
}
|
||||||
|
if (this.titleLeft !== undefined) {
|
||||||
|
let tt = ''+this.titleLeft
|
||||||
|
con.move(this.y, this.x)
|
||||||
|
print(`\x84${charset[0]}u`)
|
||||||
|
if (this.titleBackLeft !== undefined) print(`\x1B[48;5;${this.titleBackLeft}m`)
|
||||||
|
print(`\x1B[38;5;${colourText}m`);print(tt)
|
||||||
|
if (this.titleBackLeft !== undefined) print(`\x1B[48;5;${oldBack}m`)
|
||||||
|
print(`\x1B[38;5;${colour}m`);print(`\x84${charset[4]}u`)
|
||||||
|
}
|
||||||
|
if (this.titleRight !== undefined) {
|
||||||
|
let tt = ''+this.titleRight
|
||||||
|
con.move(this.y, this.x + this.width - tt.length - 2)
|
||||||
|
print(`\x84${charset[4]}u`)
|
||||||
|
if (this.titleBackRight !== undefined) print(`\x1B[48;5;${this.titleBackRight}m`)
|
||||||
|
print(`\x1B[38;5;${colourText}m${tt}`)
|
||||||
|
if (this.titleBackRight !== undefined) print(`\x1B[48;5;${oldBack}m`)
|
||||||
|
print(`\x1B[38;5;${colour}m\x84${charset[1]}u`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// restore fore colour
|
||||||
|
print(`\x1B[38;5;${oldFore}m`)
|
||||||
|
print(`\x1B[48;5;${oldBack}m`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
drawContents() { this.drawContentsFun(this) }
|
||||||
|
drawFrame() { this.drawFrameFun(this) }
|
||||||
|
processInput(event) { this.inputProcessor(this, event) }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
exports = { WindowObject }
|
||||||
35
assets/disk0/tvdos/tuidev/doc.md
Normal file
35
assets/disk0/tvdos/tuidev/doc.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
DATA STRUCTURE
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
[main Window Objects],
|
||||||
|
[popup Window Objects]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Window Object
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
"isFocused": false,
|
||||||
|
"inputProcessor": (this, inputEvent) => { ... },
|
||||||
|
"drawFrame": (this) => { ... },
|
||||||
|
"drawContents": (this) => { ... },
|
||||||
|
"width": 20,
|
||||||
|
"height": 12,
|
||||||
|
"x": 1,
|
||||||
|
"y": 3,
|
||||||
|
"title": undefined
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
BEHAVIOUR
|
||||||
|
|
||||||
|
1. Key event is parsed
|
||||||
|
2. If key is Tab, move focus to the next Window Object within the current window
|
||||||
|
3. If not, pass the event to the currently focused Window Object
|
||||||
|
|
||||||
|
No key combination will allow navigating between windows
|
||||||
|
e.g. Tabbing on the question popup will just loop through the Ok/Cancel buttons, until the buttons are pressed.
|
||||||
|
|
||||||
208
assets/disk0/tvdos/tuidev/zfm.js
Normal file
208
assets/disk0/tvdos/tuidev/zfm.js
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
const win = require("wintex")
|
||||||
|
const COL_TEXT = 253
|
||||||
|
const COL_BACK = 255
|
||||||
|
const COL_BACK_SEL = 81
|
||||||
|
const COL_HLTEXT = 230
|
||||||
|
const COL_HLACTION = 39
|
||||||
|
const COL_DIR = COL_TEXT
|
||||||
|
const COL_SUPERTEXT = 239
|
||||||
|
const COL_DIMTEXT = 249
|
||||||
|
const COL_LNUMBACK = 18
|
||||||
|
const COL_LNUMFORE = 253
|
||||||
|
const COL_BRAND = 161
|
||||||
|
const COL_BRAND_PAL = [241, 248]
|
||||||
|
const [WHEIGHT, WIDTH] = con.getmaxyx();const HEIGHT = WHEIGHT - 1
|
||||||
|
const SIDEBAR_WIDTH = 9
|
||||||
|
const LIST_HEIGHT = HEIGHT - 3
|
||||||
|
const FILESIZE_WIDTH = 7
|
||||||
|
const FILELIST_WIDTH = WIDTH - SIDEBAR_WIDTH - 3 - FILESIZE_WIDTH
|
||||||
|
|
||||||
|
let windowMode = 0 // 0 == left, 1 == right
|
||||||
|
let windowFocus = 0 // 0,2: files panel, 1: operation panel, -1: a wild popup message appeared
|
||||||
|
|
||||||
|
// window states
|
||||||
|
let path = [["A:"], ["A:"]]
|
||||||
|
let scroll = [0, 0]
|
||||||
|
let dirFileList = [[], []]
|
||||||
|
let cursor = [0, 0]
|
||||||
|
// end of window states
|
||||||
|
|
||||||
|
let filesPanelDraw = (wo) => {
|
||||||
|
let pathStr = path[windowMode].concat(['']).join("\\")
|
||||||
|
if (windowMode) {
|
||||||
|
wo.titleLeft = undefined
|
||||||
|
wo.titleRight = pathStr
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wo.titleLeft = pathStr
|
||||||
|
wo.titleRight = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw list header
|
||||||
|
con.color_pair(COL_HLTEXT, COL_BACK)
|
||||||
|
con.move(wo.y + 1, wo.x + 1); print(" Name")
|
||||||
|
con.mvaddch(wo.y + 1, wo.x + FILELIST_WIDTH, 0xB3)
|
||||||
|
con.curs_right(); print(" Size")
|
||||||
|
|
||||||
|
|
||||||
|
con.color_pair(COL_TEXT, COL_BACK)
|
||||||
|
// draw list
|
||||||
|
let directory = files.open(pathStr)
|
||||||
|
let fileList = directory.list()
|
||||||
|
let s = scroll[windowMode]
|
||||||
|
|
||||||
|
// sort fileList
|
||||||
|
let ds = []
|
||||||
|
let fs = []
|
||||||
|
fileList.forEach((file)=>{
|
||||||
|
if (file.isDirectory)
|
||||||
|
ds.push(file)
|
||||||
|
else
|
||||||
|
fs.push(file)
|
||||||
|
})
|
||||||
|
ds.sort((a,b) => (a.name > b.name) ? 1 : (a.name < b.name) ? -1 : 0)
|
||||||
|
fs.sort((a,b) => (a.name > b.name) ? 1 : (a.name < b.name) ? -1 : 0)
|
||||||
|
dirFileList[windowMode] = ds.concat(fs)
|
||||||
|
|
||||||
|
// print entries
|
||||||
|
for (let i = 0; i < Math.min(dirFileList[windowMode].length - s, LIST_HEIGHT); i++) {
|
||||||
|
let file = dirFileList[windowMode][i+s]
|
||||||
|
|
||||||
|
let backCol = (i == cursor[windowMode]) ? COL_BACK_SEL : COL_BACK
|
||||||
|
|
||||||
|
con.move(wo.y + 2+i, wo.x + 1)
|
||||||
|
if (file.isDirectory) {
|
||||||
|
con.color_pair(COL_DIR, backCol)
|
||||||
|
print("\\")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
con.color_pair(COL_TEXT, backCol)
|
||||||
|
print(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// print filename
|
||||||
|
con.move(wo.y + 2+i, wo.x + 2)
|
||||||
|
print(file.name)
|
||||||
|
print(' '.repeat(FILELIST_WIDTH - 2 - file.name.length))
|
||||||
|
|
||||||
|
// print filesize
|
||||||
|
con.color_pair(COL_TEXT, backCol)
|
||||||
|
con.mvaddch(wo.y + 2+i, wo.x + FILELIST_WIDTH, 0xB3)
|
||||||
|
|
||||||
|
let sizestr = ''+ (
|
||||||
|
(file.size > 9999999) ? (((file.size / 100000)|0)/100 + "M") :
|
||||||
|
(file.size > 9999) ? (((file.size / 1000)|0)/10 + "K") :
|
||||||
|
file.size
|
||||||
|
)
|
||||||
|
con.move(wo.y + 2+i, wo.x + FILELIST_WIDTH + 1)
|
||||||
|
print(' '.repeat(FILESIZE_WIDTH - sizestr.length + 1))
|
||||||
|
print(sizestr)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let opPanelDraw = (wo) => {
|
||||||
|
function hr(y) {
|
||||||
|
con.move(y, xp)
|
||||||
|
print(`\x84196u`.repeat(SIDEBAR_WIDTH - 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
con.color_pair(COL_TEXT, COL_BACK)
|
||||||
|
|
||||||
|
let xp = wo.x + 1
|
||||||
|
let yp = wo.y + 1
|
||||||
|
|
||||||
|
// go up
|
||||||
|
con.mvaddch(yp + 1, xp + 3, 0x18)
|
||||||
|
con.move(yp + 2, xp)
|
||||||
|
print(` \x1B[38;5;${COL_TEXT}mGo \x1B[38;5;${COL_HLACTION}mU\x1B[38;5;${COL_TEXT}mp`)
|
||||||
|
|
||||||
|
hr(yp+4)
|
||||||
|
|
||||||
|
// copy
|
||||||
|
con.move(yp + 6, xp + 2)
|
||||||
|
con.prnch(0xDB);con.prnch(0x1A);con.prnch(0xDB)
|
||||||
|
con.move(yp + 7, xp)
|
||||||
|
print(` \x1B[38;5;${COL_HLACTION}mC\x1B[38;5;${COL_TEXT}mopy`)
|
||||||
|
|
||||||
|
hr(yp+9)
|
||||||
|
|
||||||
|
// move
|
||||||
|
con.move(yp + 11, xp + 2)
|
||||||
|
con.prnch(0xB0);con.prnch(0x1A);con.prnch(0xDB)
|
||||||
|
con.move(yp + 12, xp)
|
||||||
|
print(` \x1B[38;5;${COL_HLACTION}mM\x1B[38;5;${COL_TEXT}move`)
|
||||||
|
|
||||||
|
hr(yp+14)
|
||||||
|
|
||||||
|
// delete
|
||||||
|
con.move(yp + 16, xp + 2)
|
||||||
|
con.prnch(0xDB);con.prnch(0x1A);con.prnch(0x58)
|
||||||
|
con.move(yp + 17, xp)
|
||||||
|
print(` \x1B[38;5;${COL_HLACTION}mD\x1B[38;5;${COL_TEXT}melete`)
|
||||||
|
|
||||||
|
hr(yp+19)
|
||||||
|
|
||||||
|
// mkdir
|
||||||
|
con.move(yp + 21, xp + 2)
|
||||||
|
con.prnch(0x2B);con.prnch(0xDE);con.prnch(0xDC)
|
||||||
|
con.move(yp + 23, xp)
|
||||||
|
print(` \x1B[38;5;${COL_TEXT}mm\x1B[38;5;${COL_HLACTION}mK\x1B[38;5;${COL_TEXT}mdir`)
|
||||||
|
|
||||||
|
hr(yp+25)
|
||||||
|
|
||||||
|
// other panel
|
||||||
|
con.move(yp + 27, xp + 3)
|
||||||
|
con.prnch((windowMode) ? 0x11 : 0x10)
|
||||||
|
con.move(yp + 28, xp)
|
||||||
|
print(` \x1B[38;5;${COL_TEXT}m[\x1B[38;5;${COL_HLACTION}mZ\x1B[38;5;${COL_TEXT}m]`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let windows = [[
|
||||||
|
new win.WindowObject(1, 2, WIDTH - SIDEBAR_WIDTH, HEIGHT, ()=>{}, filesPanelDraw), // left panel
|
||||||
|
new win.WindowObject(WIDTH - SIDEBAR_WIDTH+1, 2, SIDEBAR_WIDTH, HEIGHT, ()=>{}, opPanelDraw),
|
||||||
|
// new win.WindowObject(1, 2, SIDEBAR_WIDTH, HEIGHT, ()=>{}, opPanelDraw),
|
||||||
|
new win.WindowObject(SIDEBAR_WIDTH + 1, 2, WIDTH - SIDEBAR_WIDTH, HEIGHT, ()=>{}, filesPanelDraw), // right panel
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
// draw window title
|
||||||
|
con.color_pair(COL_BACK, COL_TEXT)
|
||||||
|
con.move(1,1)
|
||||||
|
print(' '.repeat(WIDTH))
|
||||||
|
con.move(1, WIDTH/2 - 2)
|
||||||
|
con.color_pair(COL_BRAND_PAL[0], COL_TEXT)
|
||||||
|
print("z")
|
||||||
|
con.color_pair(COL_BRAND_PAL[1], COL_TEXT)
|
||||||
|
con.prnch(0xB3)
|
||||||
|
con.color_pair(COL_BRAND, COL_TEXT)
|
||||||
|
print("fm")
|
||||||
|
|
||||||
|
|
||||||
|
// draw panels
|
||||||
|
windows[0].forEach((panel, i)=>{
|
||||||
|
panel.isHighlighted = (i == windowFocus)
|
||||||
|
})
|
||||||
|
if (windowMode) {
|
||||||
|
windows[0][2].drawContents()
|
||||||
|
windows[0][2].drawFrame()
|
||||||
|
windows[0][1].drawContents()
|
||||||
|
windows[0][1].drawFrame()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
windows[0][0].drawContents()
|
||||||
|
windows[0][0].drawFrame()
|
||||||
|
windows[0][1].drawContents()
|
||||||
|
windows[0][1].drawFrame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
con.clear()
|
||||||
|
draw()
|
||||||
|
con.move(WHEIGHT,1)
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ Background Colour Packet -
|
|||||||
uint16 0xFEFF
|
uint16 0xFEFF
|
||||||
uint8 Red (0-255)
|
uint8 Red (0-255)
|
||||||
uint8 Green (0-255)
|
uint8 Green (0-255)
|
||||||
uint8 Blue (0x255)
|
uint8 Blue (0-255)
|
||||||
uint8 0x00 (pad byte)
|
uint8 0x00 (pad byte)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
getFirstGPU()?.let { it.ttyBack = b }
|
getFirstGPU()?.let { it.ttyBack = b }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTextFore() = getFirstGPU()?.ttyFore
|
||||||
|
fun getTextBack() = getFirstGPU()?.ttyBack
|
||||||
|
|
||||||
/*fun loadBulk(fromAddr: Int, toAddr: Int, length: Int) {
|
/*fun loadBulk(fromAddr: Int, toAddr: Int, length: Int) {
|
||||||
getFirstGPU()?._loadbulk(fromAddr, toAddr, length)
|
getFirstGPU()?._loadbulk(fromAddr, toAddr, length)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user