mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2025-12-11 05:16:16 +00:00
fix: autospace cursor wonkyness
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
import { get } from "svelte/store";
|
import { get } from "svelte/store";
|
||||||
import { action } from "$lib/title";
|
import { action } from "$lib/title";
|
||||||
import semverGte from "semver/functions/gte";
|
import semverGte from "semver/functions/gte";
|
||||||
|
import Action from "$lib/components/Action.svelte";
|
||||||
|
|
||||||
let { chord }: { chord: ChordInfo } = $props();
|
let { chord }: { chord: ChordInfo } = $props();
|
||||||
|
|
||||||
@@ -27,14 +28,14 @@
|
|||||||
if (!event.shiftKey && event.key === "ArrowUp") {
|
if (!event.shiftKey && event.key === "ArrowUp") {
|
||||||
addSpecial(event);
|
addSpecial(event);
|
||||||
} else if (!event.shiftKey && event.key === "ArrowLeft") {
|
} else if (!event.shiftKey && event.key === "ArrowLeft") {
|
||||||
moveCursor(cursorPosition - 1);
|
moveCursor(cursorPosition - 1, true);
|
||||||
} else if (!event.shiftKey && event.key === "ArrowRight") {
|
} else if (!event.shiftKey && event.key === "ArrowRight") {
|
||||||
moveCursor(cursorPosition + 1);
|
moveCursor(cursorPosition + 1, true);
|
||||||
} else if (event.key === "Backspace") {
|
} else if (event.key === "Backspace") {
|
||||||
deleteAction(cursorPosition - 1);
|
deleteAction(cursorPosition - 1, 1, true);
|
||||||
moveCursor(cursorPosition - 1);
|
moveCursor(cursorPosition - 1, true);
|
||||||
} else if (event.key === "Delete") {
|
} else if (event.key === "Delete") {
|
||||||
deleteAction(cursorPosition);
|
deleteAction(cursorPosition, 1, true);
|
||||||
} else {
|
} else {
|
||||||
if (event.key === "Shift") return;
|
if (event.key === "Shift") return;
|
||||||
const action = inputToAction(event, get(serialPort)?.device === "X");
|
const action = inputToAction(event, get(serialPort)?.device === "X");
|
||||||
@@ -45,14 +46,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveCursor(to: number) {
|
function moveCursor(to: number, user = false) {
|
||||||
if (!box) return;
|
if (!box) return;
|
||||||
cursorPosition = Math.max(0, Math.min(to, chord.phrase.length));
|
cursorPosition = Math.max(
|
||||||
|
user ? chord.phrase.findIndex((it, i, arr) => !isHidden(it, i, arr)) : 0,
|
||||||
|
Math.min(
|
||||||
|
to,
|
||||||
|
user
|
||||||
|
? chord.phrase.findLastIndex((it, i, arr) => !isHidden(it, i, arr)) +
|
||||||
|
1 || chord.phrase.length
|
||||||
|
: chord.phrase.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
const item = box.children.item(cursorPosition) as HTMLElement;
|
const item = box.children.item(cursorPosition) as HTMLElement;
|
||||||
cursorOffset = item.offsetLeft + item.offsetWidth;
|
cursorOffset = item.offsetLeft + item.offsetWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteAction(at: number, count = 1) {
|
function deleteAction(at: number, count = 1, user = false) {
|
||||||
|
if (user && isHidden(chord.phrase[at]!, at, chord.phrase)) return;
|
||||||
if (!(at in chord.phrase)) return;
|
if (!(at in chord.phrase)) return;
|
||||||
changes.update((changes) => {
|
changes.update((changes) => {
|
||||||
changes.push([
|
changes.push([
|
||||||
@@ -89,12 +100,12 @@
|
|||||||
for (const child of box.children) {
|
for (const child of box.children) {
|
||||||
const { offsetLeft, offsetWidth } = child as HTMLElement;
|
const { offsetLeft, offsetWidth } = child as HTMLElement;
|
||||||
if (distance < offsetLeft + offsetWidth / 2) {
|
if (distance < offsetLeft + offsetWidth / 2) {
|
||||||
moveCursor(i - 1);
|
moveCursor(i - 1, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
moveCursor(i - 1);
|
moveCursor(i - 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSpecial(event: MouseEvent | KeyboardEvent) {
|
function addSpecial(event: MouseEvent | KeyboardEvent) {
|
||||||
@@ -118,6 +129,7 @@
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
deleteAction(chord.phrase.length - 1);
|
deleteAction(chord.phrase.length - 1);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -126,13 +138,16 @@
|
|||||||
return;
|
return;
|
||||||
} else if (chord.phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
} else if (chord.phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
||||||
deleteAction(chord.phrase.length - 1);
|
deleteAction(chord.phrase.length - 1);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
} else {
|
} else {
|
||||||
insertAction(chord.phrase.length, JOIN_ACTION);
|
insertAction(chord.phrase.length, JOIN_ACTION);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chord.phrase.at(-1) === JOIN_ACTION) {
|
if (chord.phrase.at(-1) === JOIN_ACTION) {
|
||||||
deleteAction(chord.phrase.length - 1);
|
deleteAction(chord.phrase.length - 1);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
} else {
|
} else {
|
||||||
if (chord.phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
if (chord.phrase.at(-1) === NO_CONCATENATOR_ACTION) {
|
||||||
if (
|
if (
|
||||||
@@ -144,9 +159,11 @@
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
deleteAction(chord.phrase.length - 1);
|
deleteAction(chord.phrase.length - 1);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
insertAction(chord.phrase.length, NO_CONCATENATOR_ACTION);
|
insertAction(chord.phrase.length, NO_CONCATENATOR_ACTION);
|
||||||
|
moveCursor(cursorPosition, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,16 +188,13 @@
|
|||||||
isPrintable || chord.phrase.at(-1) === JOIN_ACTION,
|
isPrintable || chord.phrase.at(-1) === JOIN_ACTION,
|
||||||
);
|
);
|
||||||
|
|
||||||
let displayPhrase = $derived(
|
function isHidden(action: number, index: number, array: number[]) {
|
||||||
chord.phrase.filter(
|
return (
|
||||||
(it, i, arr) =>
|
(index === 0 && action === JOIN_ACTION) ||
|
||||||
!(
|
(index === array.length - 1 &&
|
||||||
(i === 0 && it === JOIN_ACTION) ||
|
(action === JOIN_ACTION || action === NO_CONCATENATOR_ACTION))
|
||||||
(i === arr.length - 1 &&
|
);
|
||||||
(it === JOIN_ACTION || it === NO_CONCATENATOR_ACTION))
|
}
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -196,18 +210,22 @@
|
|||||||
use:action={{ title: "Remove previous concatenator" }}
|
use:action={{ title: "Remove previous concatenator" }}
|
||||||
><span class="icon">join_inner</span><input
|
><span class="icon">join_inner</span><input
|
||||||
checked={chord.phrase[0] === JOIN_ACTION}
|
checked={chord.phrase[0] === JOIN_ACTION}
|
||||||
onchange={(event) => {
|
onchange={async (event) => {
|
||||||
const autospace = hasAutospace;
|
const autospace = hasAutospace;
|
||||||
if ((event.target as HTMLInputElement).checked) {
|
if ((event.target as HTMLInputElement).checked) {
|
||||||
if (chord.phrase[0] !== JOIN_ACTION) {
|
if (chord.phrase[0] !== JOIN_ACTION) {
|
||||||
insertAction(0, JOIN_ACTION);
|
insertAction(0, JOIN_ACTION);
|
||||||
|
moveCursor(cursorPosition + 1, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chord.phrase[0] === JOIN_ACTION) {
|
if (chord.phrase[0] === JOIN_ACTION) {
|
||||||
deleteAction(0, 1);
|
deleteAction(0, 1);
|
||||||
|
await tick();
|
||||||
|
moveCursor(cursorPosition - 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tick().then(() => resolveAutospace(autospace));
|
await tick();
|
||||||
|
resolveAutospace(autospace);
|
||||||
}}
|
}}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/></label
|
/></label
|
||||||
@@ -233,7 +251,13 @@
|
|||||||
<div></div>
|
<div></div>
|
||||||
<!-- placeholder for cursor placement -->
|
<!-- placeholder for cursor placement -->
|
||||||
{/if}
|
{/if}
|
||||||
<ActionString actions={displayPhrase} />
|
{#each chord.phrase as action, i}
|
||||||
|
{#if isHidden(action, i, chord.phrase)}
|
||||||
|
<span style:display="none"></span>
|
||||||
|
{:else}
|
||||||
|
<Action display="inline-keys" {action} />
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{#if supportsAutospace}
|
{#if supportsAutospace}
|
||||||
<label class="auto-space-edit" use:action={{ title: "Add concatenator" }}
|
<label class="auto-space-edit" use:action={{ title: "Add concatenator" }}
|
||||||
|
|||||||
Reference in New Issue
Block a user