From 5c2911c05364199aba533f2c0ded39a4071cb6f3 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Tue, 29 Jun 2021 16:50:54 +0200 Subject: [PATCH] First steps toward tag selection --- ts/editor/Tag.svelte | 23 +++++++++++++++++++++-- ts/lib/keys.ts | 0 ts/lib/shortcuts.ts | 44 +++++++++++++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 ts/lib/keys.ts diff --git a/ts/editor/Tag.svelte b/ts/editor/Tag.svelte index d50f7f4b1..1ed890526 100644 --- a/ts/editor/Tag.svelte +++ b/ts/editor/Tag.svelte @@ -23,6 +23,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html setTimeout(() => (flashing = false), 300); } + let showDelete = true; + + function hideDeleteOnCtrlShfit(event: MouseEvent) { + showDelete = !event.ctrlKey && !event.shiftKey; + } + + function showDeleteOnLeave() { + showDelete = true; + } + + function toggleDelete() { + // TODO + } + const nightMode = getContext(nightModeKey); @@ -32,11 +46,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html class:btn-day={!nightMode} class:btn-night={nightMode} tabindex="-1" + on:mousemove={hideDeleteOnCtrlShfit} + on:mouseleave={showDeleteOnLeave} + on:keydown={toggleDelete} + on:keyup={toggleDelete} on:click > {name} - {@html deleteIcon}{@html deleteIcon} diff --git a/ts/lib/keys.ts b/ts/lib/keys.ts new file mode 100644 index 000000000..e69de29bb diff --git a/ts/lib/shortcuts.ts b/ts/lib/shortcuts.ts index 0c62ebda1..02603da28 100644 --- a/ts/lib/shortcuts.ts +++ b/ts/lib/shortcuts.ts @@ -12,6 +12,14 @@ const platformModifiers = isApplePlatform() ? ["Meta", "Alt", "Shift", "Control"] : ["Control", "Alt", "Shift", "OS"]; +export function isControl(key: string): boolean { + return key === platformModifiers[0]; +} + +export function isShift(key: string): boolean { + return key === platformModifiers[2]; +} + function modifiersToPlatformString(modifiers: string[]): string { const displayModifiers = isApplePlatform() ? ["^", "⌥", "⇧", "⌘"] @@ -84,6 +92,23 @@ function checkKey(event: KeyboardEvent, key: number): boolean { const allModifiers: Modifier[] = ["Control", "Alt", "Shift", "Meta"]; +const checkModifiers = + (required: Modifier[], optional: Modifier[] = []) => + (event: KeyboardEvent): boolean => { + return allModifiers.reduce( + ( + matches: boolean, + currentModifier: Modifier, + currentIndex: number + ): boolean => + matches && + (optional.includes(currentModifier as Modifier) || + event.getModifierState(platformModifiers[currentIndex]) === + required.includes(currentModifier)), + true + ); + }; + function partition(predicate: (t: T) => boolean, items: T[]): [T[], T[]] { const trueItems: T[] = []; const falseItems: T[] = []; @@ -100,28 +125,25 @@ function removeTrailing(modifier: string): string { return modifier.substring(0, modifier.length - 1); } -function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean { +// function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean { +function separateRequiredOptionalModifiers( + modifiers: string[] +): [Modifier[], Modifier[]] { const [requiredModifiers, otherModifiers] = partition( isRequiredModifier, modifiers ); const optionalModifiers = otherModifiers.map(removeTrailing); - - return allModifiers.reduce( - (matches: boolean, currentModifier: string, currentIndex: number): boolean => - matches && - (optionalModifiers.includes(currentModifier as Modifier) || - event.getModifierState(platformModifiers[currentIndex]) === - requiredModifiers.includes(currentModifier)), - true - ); + return [requiredModifiers as Modifier[], optionalModifiers as Modifier[]]; } const check = (keyCode: number, modifiers: string[]) => (event: KeyboardEvent): boolean => { - return checkKey(event, keyCode) && checkModifiers(event, modifiers); + const [required, optional] = separateRequiredOptionalModifiers(modifiers); + + return checkKey(event, keyCode) && checkModifiers(required, optional)(event); }; function keyToCode(key: string): number {