diff --git a/app/mxwm/startz.js b/app/mxwm/startz.js index 3b32552..590a530 100644 --- a/app/mxwm/startz.js +++ b/app/mxwm/startz.js @@ -1,47 +1,126 @@ eval(readFile("/app/zcom.js")) +const headerHeight = 32; + +async function drawScreen(ctx) { + ctx.fillStyle = "darkcyan" + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height) + + for (const win of window.mxwm_windows) { + drawWindowDecorations(ctx, win.x, win.y, win.width, win.height, win.title) + ctx.drawImage(win.canvas, win.x, win.y); + } +} + +async function drawWindowDecorations(ctx, x, y, width, height, title) { + const borderRadius = 8; + const borderWidth = 1; + const buttonRadius = 6; + const buttonSpacing = 8; + + const outerX = x - borderWidth; + const outerY = y - headerHeight - borderWidth; + const outerWidth = width + borderWidth * 2; + const outerHeight = height + headerHeight + borderWidth * 2; + + ctx.fillStyle = "#f4f4f4"; + ctx.fillRect(outerX, outerY, outerWidth, outerHeight) + + ctx.fillStyle = "#222"; + ctx.font = "bold 14px sans-serif"; + ctx.textBaseline = "middle"; + ctx.textAlign = "left"; + ctx.fillText(title, outerX + 12, outerY + headerHeight / 2); +} + +async function onStart(screen_ctx) { + let wid, ctx = createWindow({ + "title": "zterm", + "width": 500, + "height": 500, + "x": 50, + "y": 50 + }) + + ctx.fillStyle = "cyan" + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height) +} + +async function onKeyDown(ctx, key) { + if (key == "Escape") { + disableGraphics() + } +} + +async function onKeyUp(ctx, key) { +} + +let dragging_window = null + +function isMouseOnHeader(window) { + return window.x < mouse_position[0] && mouse_position[0] < window.x + window.width && + window.y - headerHeight < mouse_position[1] && mouse_position[1] < window.y +} + +async function onMouseDown(ctx, button) { + for (let window of listWindows()) { + if (isMouseOnHeader(window)) { + dragging_window = window["wid"] + } + } +} + +async function onMouseUp(ctx, button) { + let window = getWindow(dragging_window) + + if (isMouseOnHeader(window)) { + dragging_window = null + } +} + +let mouse_position = [0, 0] + +async function onMouseMove(ctx, x, y) { + if (dragging_window != null) { + let window = getWindow(dragging_window) + if (isMouseOnHeader(window)) { + window.x += x - mouse_position[0] + window.y += y - mouse_position[1] + } + } + + mouse_position = [x, y] +} + async function main(args) { - enableGraphics() + let ctx = null + + enableGraphics({ + "onmousemove": (x, y) => onMouseMove(ctx, x, y), + "onmousedown": (btn) => onMouseDown(ctx, btn), + "onmouseup": (btn) => onMouseUp(ctx, btn), + "onkeydown": (key) => onKeyDown(ctx, key), + "onkeyup": (key) => onKeyUp(ctx, key) + }) window.mxwm_windows = [] - let ctx = getGraphics() + ctx = getGraphics() - let run = true + await onStart() - setTimeout(async () => { - setStdinFlag(SILENT_STDIN) - setStdinFlag(ENABLE_STDIN) - - while (true) { - let event = await pollStdinEvent() - - console.log(event) - - if (event.type == "key") { - if (event.key == "Escape") { - run = false - break - } - } + let drawLoop = () => { + if (graphics_canvas != null) { + drawScreen(ctx) + requestAnimationFrame(drawLoop) } - - setStdinFlag(RENDER_STDIN) - setStdinFlag(DISABLE_STDIN) - }) - - while (run) { - ctx.fillStyle = "black" - ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height) - - for (const win of window.mxwm_windows) { - ctx.drawImage(win.canvas, win.x, win.y); - } - - await new Promise(resolve => setTimeout(resolve, 1000 / 60)) } - disableGraphics() + drawLoop() + while (graphics_canvas != null) { + await new Promise(res => setTimeout(res, 1000)) + } + return 0 -} \ No newline at end of file +} diff --git a/app/mxwm/zcom.js b/app/mxwm/zcom.js index 880dfa7..3f55bc3 100644 --- a/app/mxwm/zcom.js +++ b/app/mxwm/zcom.js @@ -6,14 +6,21 @@ function hasGraphicsImplementation() { function createWindow(options) { let canvas = document.createElement("canvas") + let wid = Date.now().toString() + Math.round(Math.random() * 100).toString() + let win = { "title": options["title"], "x": options["x"] || 0, "y": options["y"] || 0, "width": options["width"] || options["w"] || 200, "height": options["height"] || options["h"] || 200, - "wid": Date.now().toString() + Math.round(Math.random() * 100).toString(), - "on_signal": options["on_signal"] || options["callback"] || (o => {}) + "wid": wid, + "onsignal": options["onsignal"] || (o => {}), + "onkeydown": options["onkeydown"] || (o => {}), + "onkeyup": options["onkeyup"] || (o => {}), + "onmousedown": options["onmousedown"] || (o => {}), + "onmouseup": options["onmouseup"] || (o => {}), + "onmousemove": options["onmousemove"] || ((x,y) => {}), } canvas.width = win["width"].toString() @@ -29,6 +36,8 @@ function createWindow(options) { } else { window.mxwm_windows = [ win ] } + + return (wid, context) } function moveWindow(wid, x, y, w, h) { @@ -53,7 +62,7 @@ function signalWindow(wid, signal) { for (const win of window.mxwm_windows) { if (win["wid"] == wid) { - win.on_signal(signal) + win.onsignal(signal) } } } @@ -85,4 +94,4 @@ function listWindows() { } return window.mxwm_windows -} \ No newline at end of file +} diff --git a/sys/graphics.js b/sys/graphics.js index 3bfe1d2..53a30ca 100644 --- a/sys/graphics.js +++ b/sys/graphics.js @@ -7,6 +7,7 @@ function enableGraphics(options={}) { graphics_canvas.id = "graphics" graphics_canvas.width = window.innerWidth.toString() graphics_canvas.height = window.innerHeight.toString() + graphics_canvas.setAttribute("tabindex", "0") if ("onmousemove" in options) { graphics_canvas.onmousemove = e => { @@ -48,6 +49,8 @@ function enableGraphics(options={}) { }) document.body.appendChild(graphics_canvas) + + graphics_canvas.focus() } function getGraphics() { diff --git a/sys/terminal.js b/sys/terminal.js index 370c2ef..af247f6 100644 --- a/sys/terminal.js +++ b/sys/terminal.js @@ -152,6 +152,8 @@ function stripHtml(html) { return tmp.innerHTML; } +var clipboard_collect = document.getElementById("clipboard-collect") + document.onkeydown = (e) => { let key = e.key; if (!disable_stdin) { @@ -174,10 +176,10 @@ document.onkeydown = (e) => { } } -var clipboard_collect = document.getElementById("clipboard-collect") - setInterval(() => { - clipboard_collect.focus() + if (graphics_canvas == null) { + clipboard_collect.focus() + } }); clipboard_collect.onpaste = (e) => { @@ -187,4 +189,4 @@ clipboard_collect.onpaste = (e) => { stdin += paste.replace("\r", "") writeTerminal(paste) } -} \ No newline at end of file +}