Add ability to record keyboard shortcuts

This commit is contained in:
Jonatan Heyman 2025-04-18 18:30:40 +02:00
parent c64033359b
commit da806d815c
4 changed files with 115 additions and 11 deletions

View File

@ -3,11 +3,13 @@
import AutoComplete from 'primevue/autocomplete' import AutoComplete from 'primevue/autocomplete'
import { HEYNOTE_COMMANDS } from '@/src/editor/commands' import { HEYNOTE_COMMANDS } from '@/src/editor/commands'
import RecordKeyInput from './RecordKeyInput.vue'
export default { export default {
name: "AddKeyBind", name: "AddKeyBind",
components: { components: {
AutoComplete, AutoComplete,
RecordKeyInput,
}, },
data() { data() {
return { return {
@ -34,6 +36,7 @@
mounted() { mounted() {
window.addEventListener("keydown", this.onKeyDown) window.addEventListener("keydown", this.onKeyDown)
this.$refs.keys.$el.focus()
}, },
beforeUnmount() { beforeUnmount() {
window.removeEventListener("keydown", this.onKeyDown) window.removeEventListener("keydown", this.onKeyDown)
@ -41,7 +44,7 @@
methods: { methods: {
onKeyDown(event) { onKeyDown(event) {
if (event.key === "Escape") { if (event.key === "Escape" && document.activeElement !== this.$refs.keys.$el) {
this.$emit("close") this.$emit("close")
} }
}, },
@ -63,11 +66,18 @@
}, },
onSave() { onSave() {
if (this.key === "" || this.command === "") {
return
}
this.$emit("save", { this.$emit("save", {
key: this.key, key: this.key,
command: this.command.name, command: this.command.name,
}) })
} },
focusCommandSelector() {
this.$refs.autocomplete.$el.querySelector("input").focus()
},
}, },
} }
</script> </script>
@ -80,11 +90,12 @@
<div class="form"> <div class="form">
<div class="field"> <div class="field">
<label>Key</label> <label>Key</label>
<input <RecordKeyInput
type="text"
v-model="key" v-model="key"
class="keys" @enter="focusCommandSelector"
> @close="$emit('close')"
ref="keys"
/>
</div> </div>
<div class="field"> <div class="field">
<label>Command</label> <label>Command</label>
@ -93,9 +104,11 @@
forceSelection forceSelection
v-model="command" v-model="command"
:suggestions="commandSuggestions" :suggestions="commandSuggestions"
:autoOptionFocus="true"
optionLabel="key" optionLabel="key"
:delay="0" :delay="0"
@complete="onCommandSearch" @complete="onCommandSearch"
ref="autocomplete"
emptySearchMessage="No commands found" emptySearchMessage="No commands found"
class="command-autocomplete" class="command-autocomplete"
> >
@ -163,6 +176,8 @@
.field .field
//width: 50% //width: 50%
margin-bottom: 20px margin-bottom: 20px
&:last-child
margin-bottom: 0
label label
display: block display: block
margin-bottom: 8px margin-bottom: 8px

View File

@ -0,0 +1,88 @@
<script>
import { keyName, base } from "w3c-keyname"
export default {
props: [
"modelValue",
],
data() {
return {
keys: this.modelValue ? this.modelValue.split(" ") : [],
}
},
computed: {
key() {
return this.keys.join(" ")
},
},
watch: {
modelValue(newValue) {
this.keys = this.modelValue ? this.modelValue.split(" ") : []
},
key(newValue) {
this.$emit("update:model-value", newValue)
},
},
methods: {
onKeyDown(event) {
event.preventDefault()
//console.log("event", event, event.code, keyName(event))
if (event.key === "Enter") {
this.$emit("enter")
} else if (event.key === "Escape") {
if (this.keys.length > 0) {
this.keys = []
} else {
// setTimeout is used to ensure that the settings dialog's keydown listener
// doesn't close the whole settings dialog
setTimeout(() => {
this.$emit("close")
}, 0)
}
} else if (["Alt", "Control", "Meta", "Shift"].includes(event.key)) {
} else {
if (this.keys.length >= 2) {
this.keys = []
}
let keyCombo = ""
if (event.altKey) {
keyCombo += "Alt-"
}
if (event.ctrlKey) {
keyCombo += "Control-"
}
if (event.metaKey) {
keyCombo += "Meta-"
}
if (event.shiftKey) {
keyCombo += "Shift-"
}
let key = base[event.keyCode]
if (key) {
if (key === " ") {
key = "Space"
}
keyCombo += key
this.keys.push(keyCombo)
}
}
},
},
}
</script>
<template>
<input
type="text"
:value="key"
@keydown.prevent="onKeyDown"
class="keys"
readonly
>
</template>

View File

@ -26,7 +26,7 @@
}, },
data() { data() {
console.log("settings:", this.initialSettings) //console.log("settings:", this.initialSettings)
return { return {
keymaps: [ keymaps: [
{ name: "Default", value: "default" }, { name: "Default", value: "default" },

View File

@ -15,13 +15,14 @@
--p-autocomplete-dropdown-border-radius: var(--p-inputtext-border-radius) --p-autocomplete-dropdown-border-radius: var(--p-inputtext-border-radius)
--p-autocomplete-dropdown-hover-border-color: var(--p-inputtext-hover-border-color) --p-autocomplete-dropdown-hover-border-color: var(--p-inputtext-hover-border-color)
--p-autocomplete-dropdown-active-border-color: var(--p-inputtext-active-border-color) --p-autocomplete-dropdown-active-border-color: var(--p-inputtext-active-border-color)
--p-autocomplete-option-focus-background: #f1f1f1 --p-autocomplete-dropdown-hover-background: #f1f1f1
--p-autocomplete-option-focus-background: var(--highlight-color)
--p-autocomplete-option-focus-color: #fff
+dark-mode +dark-mode
--p-inputtext-background: #202020 --p-inputtext-background: #202020
--p-inputtext-border-color: #444 --p-inputtext-border-color: #444
--p-autocomplete-option-focus-background: #555 --p-autocomplete-dropdown-hover-background: #2a2a2a
--p-autocomplete-option-focus-color: #fff
.p-inputtext.p-inputtext .p-inputtext.p-inputtext
font-size: 12px font-size: 12px