mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
another try at tui
This commit is contained in:
@@ -495,6 +495,8 @@ con.resetkeybuf = function() {
|
||||
con.video_reverse = function() {
|
||||
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
|
||||
if (n < 0)
|
||||
print("\x1B[38;5;255m");
|
||||
|
||||
@@ -841,7 +841,7 @@ if (exec_args[1] !== undefined) {
|
||||
goInteractive = true
|
||||
}
|
||||
else if ("/fancy" == firstSwitch) {
|
||||
graphics.setBackground(2,3,4)
|
||||
graphics.setBackground(34,51,68)
|
||||
goFancy = 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
|
||||
uint8 Red (0-255)
|
||||
uint8 Green (0-255)
|
||||
uint8 Blue (0x255)
|
||||
uint8 Blue (0-255)
|
||||
uint8 0x00 (pad byte)
|
||||
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
||||
getFirstGPU()?.let { it.ttyBack = b }
|
||||
}
|
||||
|
||||
fun getTextFore() = getFirstGPU()?.ttyFore
|
||||
fun getTextBack() = getFirstGPU()?.ttyBack
|
||||
|
||||
/*fun loadBulk(fromAddr: Int, toAddr: Int, length: Int) {
|
||||
getFirstGPU()?._loadbulk(fromAddr, toAddr, length)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user