Add CSS keyboard window
parent
67cd36103c
commit
88d7c1ebd6
364
pkg/index.html
364
pkg/index.html
|
@ -7,6 +7,28 @@
|
|||
<style>
|
||||
:root {
|
||||
--terminal-font: 'Terminus', 'IBM Plex Mono', 'Verdana', 'Courier', monospace;
|
||||
--colorOffWhite: white;
|
||||
--kbdbaseBorderRadius: 1px;
|
||||
--color-dark-escape-keycap: darkgray;
|
||||
--color-enter-keycap: darkgray;
|
||||
--colorOffWhite: #efefef;
|
||||
--colorLightGray: #dedede;
|
||||
--colorGray: #cccccc;
|
||||
--colorDarkGray: #919191;
|
||||
--colorBlack: #000000;
|
||||
--colorBlue: #71b0f1;
|
||||
--colorRed: #db6767;
|
||||
--baseBorderRadius: 2px;
|
||||
--gridGap: 1px;
|
||||
--keyCapHeight: 35px;
|
||||
--color-base-keycap: #d9d9d9;
|
||||
--color-dark-base-keycap: var(--colorDarkGray);
|
||||
--color-modifier-keycap: grey;
|
||||
--color-dark-modifier-keycap: var(--colorDarkGray);
|
||||
--color-enter-keycap: grey;
|
||||
--color-dark-enter-keycap: var(--colorDarkGray);
|
||||
--color-escape-keycap: grey;
|
||||
--color-dark-escape-keycap: var(--colorDarkGray);
|
||||
}
|
||||
|
||||
#terminal {
|
||||
|
@ -16,7 +38,7 @@
|
|||
padding: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #808080;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#terminal svg {
|
||||
|
@ -47,13 +69,20 @@ html,body {
|
|||
user-select: none;
|
||||
}
|
||||
.window {
|
||||
background: black;
|
||||
touch-action: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#terminal_win.window {
|
||||
width: 802px;
|
||||
height: 593px;
|
||||
transform: translate(5vw, 15vh);
|
||||
}
|
||||
#keyboard.window {
|
||||
width: calc(60* 8px + 59 * var(--gridGap) + 5px);
|
||||
position: absolute;
|
||||
transform: translate(calc(75vw - 60* 8px + 59 * var(--gridGap) + 5px), -5vh);
|
||||
}
|
||||
|
||||
.title-bar {
|
||||
background: #163339;
|
||||
font-family: "Liberation Sans", "DejaVu Sans", sans;
|
||||
|
@ -76,13 +105,150 @@ html,body {
|
|||
font-size: 1.1rem;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
/* 60 column grid. */
|
||||
/* 1u key (standard keysize) = 4 columns */
|
||||
.keyboard {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(60, 8px);
|
||||
grid-gap: var(--gridGap);
|
||||
background-color: #ccc;
|
||||
width: max-content;
|
||||
cursor: default;
|
||||
}
|
||||
/* See keycap sizing: https://deskthority.net/wiki/Keycap_size_by_keyboard */
|
||||
/* Standard 1u key */
|
||||
.keyboard__key {
|
||||
display: flex;
|
||||
grid-column: span 4;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
height: var(--keyCapHeight);
|
||||
background-color:var(--color-base-keycap);
|
||||
border-top: 2px inset white;
|
||||
border-left: 2px inset white;
|
||||
border-right: 2px outset black;
|
||||
border-bottom: 2px outset black;
|
||||
}
|
||||
.keyboard__key:active {
|
||||
border-top: 2px inset black;
|
||||
border-left: 2px inset black;
|
||||
}
|
||||
|
||||
.keyboard__key.function::before {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.keyboard__key.empty {
|
||||
display: flex;
|
||||
grid-column: span 4;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
height: var(--keyCapHeight);
|
||||
background:none;
|
||||
border:none;
|
||||
}
|
||||
/* Printed text on keycap */
|
||||
.keyboard__key::before {
|
||||
content: attr(data-key-text);
|
||||
z-index: 1;
|
||||
font-size: 12px;
|
||||
font-family: sans-serif;
|
||||
text-transform: lowercase;
|
||||
color: var(--colorBlack);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Top of key */
|
||||
.keyboard__key::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 5px;
|
||||
bottom: 4px;
|
||||
left: 5px;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: calc(var(--keyCapHeight) - 8px);
|
||||
background-color: inherit;
|
||||
filter: contrast(105%);
|
||||
border-radius: calc(var(--baseBorderRadius) + 2px);
|
||||
}
|
||||
|
||||
/* Keycap sizes */
|
||||
/* 1.25u key */
|
||||
.keyboard__key._1-25u {
|
||||
grid-column: span 5;
|
||||
}
|
||||
|
||||
/* 1.5u key */
|
||||
.keyboard__key._1-5u {
|
||||
grid-column: span 6;
|
||||
}
|
||||
|
||||
/* 1.75u key */
|
||||
.keyboard__key._1-75u {
|
||||
grid-column: span 7;
|
||||
}
|
||||
|
||||
/* 2u key */
|
||||
.keyboard__key._2u {
|
||||
grid-column: span 8;
|
||||
}
|
||||
|
||||
/* 2.25u key */
|
||||
.keyboard__key._2-25u {
|
||||
grid-column: span 9;
|
||||
}
|
||||
|
||||
/* 2.5u key */
|
||||
.keyboard__key._2-5u {
|
||||
grid-column: span 10;
|
||||
}
|
||||
|
||||
/* 2.75u key */
|
||||
.keyboard__key._2-75u {
|
||||
grid-column: span 11;
|
||||
}
|
||||
/* 5u space key */
|
||||
.keyboard__key._5u {
|
||||
grid-column: span 20;
|
||||
}
|
||||
|
||||
/* Keycap variations */
|
||||
/* Modifier keys */
|
||||
.keyboard__key.modifier {
|
||||
font-weight: bold;
|
||||
background-color: var(--color-modifier-keycap);
|
||||
background-image: linear-gradient(to bottom right, var(--color-modifier-keycap), var(--color-dark-modifier-keycap));
|
||||
}
|
||||
.keyboard__key.modifier::before {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
/* Enter key */
|
||||
.keyboard__key.enter {
|
||||
background-color: var(--color-enter-keycap);
|
||||
background-image:
|
||||
linear-gradient(to bottom right, var(--color-enter-keycap), var(--color-dark-enter-keycap));
|
||||
|
||||
}
|
||||
|
||||
/* Escape key */
|
||||
.keyboard__key.escape {
|
||||
background-color: var(--color-escape-keycap);
|
||||
background-image:
|
||||
linear-gradient(to bottom right, var(--color-escape-keycap), var(--color-dark-escape-keycap));
|
||||
}
|
||||
</style>
|
||||
<script type="module">
|
||||
import interact from 'https://cdn.interactjs.io/v1.9.20/interactjs/index.js'
|
||||
import { default as init } from './meli.js';
|
||||
|
||||
async function run() {
|
||||
interact('.window')// target elements with the "draggable" class
|
||||
interact('#terminal_win.window')// target elements with the "draggable" class
|
||||
.draggable({
|
||||
// enable inertial throwing
|
||||
inertia: true,
|
||||
|
@ -148,7 +314,7 @@ html,body {
|
|||
|
||||
inertia: true
|
||||
});
|
||||
interact('.help')// target elements with the "draggable" class
|
||||
interact('.help, #keyboard.window')// target elements with the "draggable" class
|
||||
.draggable({
|
||||
// enable inertial throwing
|
||||
inertia: true,
|
||||
|
@ -169,7 +335,7 @@ html,body {
|
|||
}
|
||||
})
|
||||
|
||||
var prev_window_position = null;
|
||||
var prev_window_position = {};
|
||||
function dragMoveListener (event) {
|
||||
var target = event.target
|
||||
// keep the dragged position in the data-x/data-y attributes
|
||||
|
@ -186,26 +352,42 @@ html,body {
|
|||
target.setAttribute('data-y', y)
|
||||
}
|
||||
|
||||
const max_button = document.querySelector('button[aria-label="Maximize"]');
|
||||
const max_buttons = document.querySelectorAll('button[aria-label="Maximize"]');
|
||||
|
||||
max_button.addEventListener('click', event => {
|
||||
const target = document.querySelector('.window');
|
||||
if (prev_window_position) {
|
||||
target.style.width = prev_window_position["width"];
|
||||
target.style.height = prev_window_position["height"];
|
||||
|
||||
target.style.webkitTransform = target.style.transform =
|
||||
prev_window_position["transform"];
|
||||
|
||||
target.setAttribute('data-x', prev_window_position["data-x"]);
|
||||
target.setAttribute('data-y', prev_window_position["data-y"]);
|
||||
prev_window_position = null;
|
||||
document.querySelector('.help').hidden = false;
|
||||
function restorePosition(element) {
|
||||
console.log("restorePosition ", element.id);
|
||||
if (prev_window_position[element.id]) {
|
||||
document.getElementById(element.id).style.width = prev_window_position[element.id]["width"];
|
||||
document.getElementById(element.id).style.height = prev_window_position[element.id]["height"];
|
||||
document.getElementById(element.id).style.webkitTransform = element.style.transform = prev_window_position[element.id]["transform"];
|
||||
document.getElementById(element.id).setAttribute('data-x', prev_window_position[element.id]["data-x"]);
|
||||
document.getElementById(element.id).setAttribute('data-y', prev_window_position[element.id]["data-y"]);
|
||||
prev_window_position[element.id] = null;
|
||||
} else {
|
||||
console.log("prev_window_position null ");
|
||||
}
|
||||
}
|
||||
function savePosition(element) {
|
||||
console.log("savePosition ", element.id);
|
||||
prev_window_position[element.id] = {"width": element.style.width, "height": element.style.height, "transform": element.style.transform, "data-x": element["data-x"], "data-y": element["data-y"]};
|
||||
}
|
||||
|
||||
function maximizeWindow(element) {
|
||||
var target = document.getElementById(element.id);
|
||||
console.log("maximize ", element.id);
|
||||
document.querySelectorAll('.window').forEach(win => {
|
||||
console.log(win.id, " (win.id != target.id) = ", (win.id != target.id));
|
||||
if (win.id != element.id) {
|
||||
document.getElementById(win.id).hidden= true;
|
||||
console.log("is hidden: ", document.getElementById(win.id).hidden);
|
||||
console.log("by id ", document.getElementById(win.id));
|
||||
}
|
||||
savePosition(document.getElementById(win.id));
|
||||
console.log(win.id, win.hidden);
|
||||
});
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
prev_window_position = {"width": target.style.width, "height": target.style.height, "transform": target.style.transform, "data-x": target["data-x"], "data-y": target["data-y"]};
|
||||
// update the element's style
|
||||
target.style.width = '100vw';
|
||||
target.style.height = '100vh';
|
||||
|
@ -215,13 +397,40 @@ html,body {
|
|||
|
||||
target.setAttribute('data-x', x);
|
||||
target.setAttribute('data-y', y);
|
||||
document.querySelector('.help').hidden = true;
|
||||
document.querySelector('.help').hidden = true;
|
||||
}
|
||||
|
||||
function unmaximizeWindow(element) {
|
||||
var target = document.getElementById(element.id);
|
||||
console.log("unmaximize ", element.id);
|
||||
restorePosition(target);
|
||||
document.querySelectorAll('.window').forEach(win => {
|
||||
console.log(win.id, " (win.id != target.id) = ", (win.id != target.id));
|
||||
if (win.id != target.id) {
|
||||
document.getElementById(win.id).hidden= false;
|
||||
console.log("is hidden: ", document.getElementById(win.id).hidden);
|
||||
console.log("by id ", document.getElementById(win.id));
|
||||
restorePosition(document.getElementById(win.id));
|
||||
}
|
||||
console.log(win.id, win.hidden);
|
||||
});
|
||||
|
||||
document.querySelector('.help').hidden = false;
|
||||
}
|
||||
|
||||
max_buttons.forEach(b => b.addEventListener('click', event => {
|
||||
var target = event.target.closest('.window');
|
||||
console.log("target is ", target.id);
|
||||
if (prev_window_position[target.id]) {
|
||||
unmaximizeWindow(target);
|
||||
} else {
|
||||
maximizeWindow(target);
|
||||
}
|
||||
var terminal_el = document.querySelector('div#terminal');
|
||||
const meli_resize_event = new CustomEvent('meli-event', { detail: "resize" });
|
||||
console.log(meli_resize_event);
|
||||
console.log(terminal_el.dispatchEvent(meli_resize_event));
|
||||
});
|
||||
}));
|
||||
|
||||
window.addEventListener('resize', event => {
|
||||
var terminal_el = document.querySelector('div#terminal');
|
||||
|
@ -247,7 +456,7 @@ html,body {
|
|||
<hr />
|
||||
<p>Click on the terminal for it to gain input focus, when it appears. Press <kbd>?</kbd> for shortcuts. Some shortcuts don't work due to the way the browser intercepts user input.</p>
|
||||
</div>
|
||||
<div class="window">
|
||||
<div class="window" id="terminal_win">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-text">
|
||||
sterm
|
||||
|
@ -270,5 +479,114 @@ html,body {
|
|||
<!-- <img src="/images/screenshots/composing.svg" style="width: 100%; height: calc(100% - 9px); object-fit: scale-down;"/>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="window" id="keyboard">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-text">skbd</div>
|
||||
|
||||
<div class="title-bar-controls">
|
||||
<button aria-label="Minimize" disabled></button>
|
||||
<button aria-label="Maximize"></button>
|
||||
<button aria-label="Close" disabled></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-body keyboard" style="user-select: none; margin: 0;">
|
||||
<!-- Start Row 0 -->
|
||||
<div class="keyboard__key modifier escape" data-key-text="esc"></div>
|
||||
<div class="keyboard__key empty" data-key-text=""></div>
|
||||
<div class="keyboard__key function" data-key-text="F1"></div>
|
||||
<div class="keyboard__key function" data-key-text="F2"></div>
|
||||
<div class="keyboard__key function" data-key-text="F3"></div>
|
||||
<div class="keyboard__key function" data-key-text="F4"></div>
|
||||
<div class="keyboard__key function" data-key-text="F5"></div>
|
||||
<div class="keyboard__key function" data-key-text="F6"></div>
|
||||
<div class="keyboard__key empty" data-key-text=""></div>
|
||||
<div class="keyboard__key function" data-key-text="F7"></div>
|
||||
<div class="keyboard__key function" data-key-text="F8"></div>
|
||||
<div class="keyboard__key function" data-key-text="F9"></div>
|
||||
<div class="keyboard__key function" data-key-text="F10"></div>
|
||||
<div class="keyboard__key function" data-key-text="F11"></div>
|
||||
<div class="keyboard__key function" data-key-text="F12"></div>
|
||||
<!-- End Row 0 -->
|
||||
|
||||
<!-- Start Row 1 -->
|
||||
<div class="keyboard__key" data-key-text="~"></div>
|
||||
<div class="keyboard__key" data-key-text="1"></div>
|
||||
<div class="keyboard__key" data-key-text="2"></div>
|
||||
<div class="keyboard__key" data-key-text="3"></div>
|
||||
<div class="keyboard__key" data-key-text="4"></div>
|
||||
<div class="keyboard__key" data-key-text="5"></div>
|
||||
<div class="keyboard__key" data-key-text="6"></div>
|
||||
<div class="keyboard__key" data-key-text="7"></div>
|
||||
<div class="keyboard__key" data-key-text="8"></div>
|
||||
<div class="keyboard__key" data-key-text="9"></div>
|
||||
<div class="keyboard__key" data-key-text="0"></div>
|
||||
<div class="keyboard__key" data-key-text="-"></div>
|
||||
<div class="keyboard__key" data-key-text="="></div>
|
||||
<div class="keyboard__key _2u modifier" data-key-text="backspace"></div>
|
||||
<!-- End Row 1 -->
|
||||
|
||||
<!-- Start Row 2 -->
|
||||
<div class="keyboard__key _1-5u modifier" data-key-text="tab"></div>
|
||||
<div class="keyboard__key" data-key-text="q"></div>
|
||||
<div class="keyboard__key" data-key-text="w"></div>
|
||||
<div class="keyboard__key" data-key-text="e"></div>
|
||||
<div class="keyboard__key" data-key-text="r"></div>
|
||||
<div class="keyboard__key" data-key-text="t"></div>
|
||||
<div class="keyboard__key" data-key-text="y"></div>
|
||||
<div class="keyboard__key" data-key-text="u"></div>
|
||||
<div class="keyboard__key" data-key-text="i"></div>
|
||||
<div class="keyboard__key" data-key-text="o"></div>
|
||||
<div class="keyboard__key" data-key-text="p"></div>
|
||||
<div class="keyboard__key" data-key-text="["></div>
|
||||
<div class="keyboard__key" data-key-text="]"></div>
|
||||
<div class="keyboard__key _1-5u modifier" data-key-text="\"></div>
|
||||
<!-- End Row 2 -->
|
||||
|
||||
<!-- Start Row 3 -->
|
||||
<div class="keyboard__key _1-75u modifier" data-key-text="caps lock"></div>
|
||||
<div class="keyboard__key" data-key-text="a"></div>
|
||||
<div class="keyboard__key" data-key-text="s"></div>
|
||||
<div class="keyboard__key" data-key-text="d"></div>
|
||||
<div class="keyboard__key" data-key-text="f"></div>
|
||||
<div class="keyboard__key" data-key-text="g"></div>
|
||||
<div class="keyboard__key" data-key-text="h"></div>
|
||||
<div class="keyboard__key" data-key-text="j"></div>
|
||||
<div class="keyboard__key" data-key-text="k"></div>
|
||||
<div class="keyboard__key" data-key-text="l"></div>
|
||||
<div class="keyboard__key" data-key-text=";"></div>
|
||||
<div class="keyboard__key" data-key-text="'"></div>
|
||||
<div class="keyboard__key _2-25u modifier enter" data-key-text="enter"></div>
|
||||
<!-- End Row 3 -->
|
||||
|
||||
<!-- Start Row 4 -->
|
||||
<div class="keyboard__key _2-25u modifier" data-key-text="shift"></div>
|
||||
<div class="keyboard__key" data-key-text="z"></div>
|
||||
<div class="keyboard__key" data-key-text="x"></div>
|
||||
<div class="keyboard__key" data-key-text="c"></div>
|
||||
<div class="keyboard__key" data-key-text="v"></div>
|
||||
<div class="keyboard__key" data-key-text="b"></div>
|
||||
<div class="keyboard__key" data-key-text="n"></div>
|
||||
<div class="keyboard__key" data-key-text="m"></div>
|
||||
<div class="keyboard__key" data-key-text=","></div>
|
||||
<div class="keyboard__key" data-key-text="."></div>
|
||||
<div class="keyboard__key" data-key-text="/"></div>
|
||||
<div class="keyboard__key _2-75u modifier" data-key-text="shift"></div>
|
||||
<!-- End Row 4 -->
|
||||
|
||||
<!-- Start Row 5 -->
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="ctrl"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="alt"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="super"></div>
|
||||
<div class="keyboard__key _5u"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="←"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="→"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="↑"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="↓"></div>
|
||||
<div class="keyboard__key _1-25u modifier" data-key-text="menu"></div>
|
||||
<!-- End Row 5 -->
|
||||
<!--<img src="http://t-sato.in.coocan.jp/xvkbd/xvkbd-small.gif"/>-->
|
||||
<!--<p>There's so much room for activities!</p>-->
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
BIN
pkg/meli_bg.wasm
BIN
pkg/meli_bg.wasm
Binary file not shown.
|
@ -518,6 +518,9 @@ impl State {
|
|||
/// On `SIGWNICH` the `State` redraws itself according to the new terminal size.
|
||||
pub fn update_size(&mut self) {
|
||||
let term_size = get_html_element_size();
|
||||
if term_size.0 == 0 || term_size.1 == 0 {
|
||||
return;
|
||||
}
|
||||
self.cols = term_size.0;
|
||||
self.rows = term_size.1;
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue