kalk_web button panel

This commit is contained in:
PaddiM8 2021-01-07 23:37:26 +01:00
parent 36742abf5a
commit d2e460f229
3 changed files with 173 additions and 11 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@paddim8/kalk-component",
"version": "1.0.8",
"version": "1.0.9",
"description": "A Svelte component for kalk, a calculator that supports user-defined functions and variables.",
"svelte": "src/main.ts",
"main": "public/build/bundle.js",
@ -61,4 +61,4 @@
"browserslist": [
"defaults"
]
}
}

View File

@ -31,13 +31,35 @@
border-radius: 7px;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4) inset;
}
@media screen and (max-width: 850px) {
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
padding: 0;
}
.calculator {
width: 100vw;
height: 100vh;
box-sizing: border-box;
border-radius: 0;
box-shadow: 0;
padding: 0;
}
}
</style>
</head>
<body>
<section id="wrapper">
<div class="calculator">
<kalk-calculator hinttext="test" autofocus="true">
<kalk-calculator hinttext="test" autofocus="true" buttonpanel="true" numberrow="true">
<console-line>kalk</console-line>
<console-line>
<span class="hint">Type 'help' for instructions.</span>

View File

@ -12,14 +12,36 @@
export let linkcolor = "cornflowerblue";
export let hinttext = "";
export let autofocus = false;
export let buttonpanel = false;
export let numberrow = false;
type Kalk = typeof import("@paddim8/kalk");
let outputLines: [value: string, byUser: boolean][] = [];
let buttonRowValues = [
"+",
"-",
"*",
"/",
"^",
"=",
".",
"(",
"√",
"π",
",",
"%",
"Σ",
"⌊",
"⌈",
"ϕ",
];
let numberRowValues = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
let outputElement: HTMLElement;
let kalkContext: Context;
let selectedLineOffset: number = 0;
let calculatorElement: HTMLElement;
let inputElement: HTMLInputElement;
afterUpdate(() => {
// Scroll to bottom
@ -120,6 +142,52 @@
setCursorPos(target, cursorPos - offset);
}
function handleButtonClick(event: Event) {
const target = event.target as HTMLElement;
target.blur();
insertText(target.textContent);
}
function handleArrowClick(event: Event, left: boolean) {
const target = event.target as HTMLElement;
const cursorPos = getCursorPos(inputElement);
target.blur();
setCursorPos(inputElement, cursorPos + (left ? -1 : 1));
}
function insertText(input: string) {
let cursorPos = getCursorPos(inputElement);
const textContent = inputElement.textContent;
let movementOffset = input.length;
if (input == "(") {
input += ")";
} else if (input == "=") {
input = " = ";
movementOffset = 3;
} else if (input == "Σ") {
input += "()";
movementOffset = 2;
} else if (input == "⌊") {
input += "⌋";
} else if (input == "⌈") {
input += "⌉";
} else if (input == ",") {
input = ", ";
movementOffset = 2;
}
const newString =
textContent.slice(0, cursorPos) +
input +
textContent.slice(cursorPos);
const [highlighted, offset] = highlight(newString);
inputElement.innerHTML = highlighted;
inputElement.focus();
setCursorPos(inputElement, cursorPos - offset + movementOffset);
}
function focus(element: HTMLInputElement) {
if (autofocus) element.focus();
}
@ -210,6 +278,10 @@
newSubstring = "π";
break;
}
case "phi": {
newSubstring = "ϕ";
break;
}
case "gamma": {
newSubstring = "Γ";
break;
@ -300,6 +372,59 @@
color: gray;
background-color: transparent;
}
.button-panel {
display: grid;
grid-template-columns: repeat(4, auto);
padding-right: 1.82vw;
}
.arrow {
.left {
grid-area: left-arrow;
}
.right {
grid-area: right-arrow;
}
}
.number-row,
.button-panel {
button {
$margin: 2px;
margin-bottom: $margin;
position: relative;
border: 0;
border-right: $margin solid transparent;
$padding: 2.5vw;
$font-size: 8vw;
padding: calc(#{$padding} - #{$margin} / 2);
font-size: $font-size;
line-height: 1.2;
background-color: inherit;
font-family: inherit;
color: inherit;
cursor: pointer;
}
@media screen and (min-width: 768px) {
button {
padding: 12px;
font-size: 1.4em;
}
}
button:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
background-color: rgba(0, 0, 0, 0.2);
}
}
}
</style>
@ -331,6 +456,7 @@
autocapitalize="off"
spellcheck="false"
use:focus
bind:this={inputElement}
on:keydown={(event) => handleKeyDown(event, kalk)}
on:keyup={handleKeyUp}
on:input={handleInput}
@ -339,12 +465,26 @@
<span style="color: {errorcolor}">{error}</span>
{/await}
</section>
<section class="input-buttons">
<button>+</button>
<button>-</button>
<button>*</button>
<button>/</button>
<button>^</button>
<button>(</button>
</section>
{#if buttonpanel}
<section class="button-panel">
<button
class="arrow left"
on:click={(e) => handleArrowClick(e, true)}>←</button>
<div class="text-input-buttons">
{#each buttonRowValues as value}
<button on:click={handleButtonClick}>{value}</button>
{/each}
</div>
<button
class="arrow right"
on:click={(e) => handleArrowClick(e, false)}>→</button>
</section>
{/if}
{#if numberrow}
<section class="number-row">
{#each numberRowValues as value}
<button on:click={handleButtonClick}>{value}</button>
{/each}
</section>
{/if}
</div>