Add CSS keyboard window

master
Manos Pitsidianakis 2020-07-09 20:18:29 +03:00
parent dd267f81ff
commit bd7e987c29
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
3 changed files with 344 additions and 23 deletions

View File

@ -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>

Binary file not shown.

View File

@ -456,6 +456,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;
/*