132 lines
4.4 KiB
QML
132 lines
4.4 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
|
|
Rectangle {
|
|
id: control
|
|
implicitWidth: 140
|
|
implicitHeight: 32
|
|
color: "#1a1a20"
|
|
radius: 6
|
|
activeFocusOnTab: true
|
|
Accessible.role: Accessible.Button
|
|
Accessible.name: control.currentSequence ? "Hotkey: " + control.currentSequence + ". Click to change" : "No hotkey set. Click to record"
|
|
border.width: (activeFocus || recording) ? SettingsStyle.focusRingWidth : 1
|
|
border.color: activeFocus || recording ? SettingsStyle.accent : SettingsStyle.borderSubtle
|
|
|
|
property string currentSequence: ""
|
|
signal sequenceChanged(string seq)
|
|
|
|
property bool recording: false
|
|
|
|
onRecordingChanged: {
|
|
if (recording) {
|
|
ui.hotkeysEnabled = false
|
|
} else {
|
|
ui.hotkeysEnabled = true
|
|
}
|
|
}
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: control.recording ? "Listening..." : (formatSequence(control.currentSequence) || "None")
|
|
color: control.recording ? SettingsStyle.accent : (control.currentSequence ? "#ffffff" : "#ABABAB")
|
|
font.family: "JetBrains Mono"
|
|
font.pixelSize: 13
|
|
font.bold: true
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
control.forceActiveFocus()
|
|
control.recording = true
|
|
}
|
|
}
|
|
|
|
Keys.onPressed: (event) => {
|
|
if (!control.recording) return
|
|
|
|
// Ignore specific standalone modifiers to allow combos
|
|
if (event.key === Qt.Key_Control || event.key === Qt.Key_Shift || event.key === Qt.Key_Alt || event.key === Qt.Key_Meta) {
|
|
return
|
|
}
|
|
|
|
// Build Modifier String
|
|
var seq = ""
|
|
if (event.modifiers & Qt.ControlModifier) seq += "ctrl+"
|
|
if (event.modifiers & Qt.ShiftModifier) seq += "shift+"
|
|
if (event.modifiers & Qt.AltModifier) seq += "alt+"
|
|
if (event.modifiers & Qt.MetaModifier) seq += "win+"
|
|
|
|
// Get Key Name
|
|
var keyName = getKeyName(event.key, event.text)
|
|
seq += keyName
|
|
|
|
// Update
|
|
control.currentSequence = seq
|
|
control.sequenceChanged(seq)
|
|
control.recording = false
|
|
event.accepted = true
|
|
}
|
|
|
|
onActiveFocusChanged: {
|
|
if (!activeFocus) control.recording = false
|
|
}
|
|
|
|
function formatSequence(seq) {
|
|
if (!seq) return ""
|
|
var parts = seq.split("+")
|
|
for (var i = 0; i < parts.length; i++) {
|
|
var p = parts[i]
|
|
// Standardize modifiers
|
|
if (p === "ctrl") parts[i] = "Ctrl"
|
|
else if (p === "alt") parts[i] = "Alt"
|
|
else if (p === "shift") parts[i] = "Shift"
|
|
else if (p === "win") parts[i] = "Win"
|
|
else if (p === "esc") parts[i] = "Esc"
|
|
// Capitalize F-keys and others (e.g. f8 -> F8, space -> Space)
|
|
else parts[i] = p.charAt(0).toUpperCase() + p.slice(1)
|
|
}
|
|
return parts.join(" + ")
|
|
}
|
|
|
|
function getKeyName(key, text) {
|
|
// F-Keys
|
|
if (key >= Qt.Key_F1 && key <= Qt.Key_F35) return "f" + (key - Qt.Key_F1 + 1)
|
|
|
|
// Common Keys
|
|
switch (key) {
|
|
case Qt.Key_Space: return "space"
|
|
case Qt.Key_Backspace: return "backspace"
|
|
case Qt.Key_Tab: return "tab"
|
|
case Qt.Key_Return: return "enter"
|
|
case Qt.Key_Enter: return "enter"
|
|
case Qt.Key_Escape: return "esc"
|
|
case Qt.Key_Delete: return "delete"
|
|
case Qt.Key_Insert: return "insert"
|
|
case Qt.Key_Home: return "home"
|
|
case Qt.Key_End: return "end"
|
|
case Qt.Key_PageUp: return "pageup"
|
|
case Qt.Key_PageDown: return "pagedown"
|
|
case Qt.Key_Up: return "up"
|
|
case Qt.Key_Down: return "down"
|
|
case Qt.Key_Left: return "left"
|
|
case Qt.Key_Right: return "right"
|
|
case Qt.Key_CapsLock: return "capslock"
|
|
case Qt.Key_NumLock: return "numlock"
|
|
case Qt.Key_ScrollLock: return "scrolllock"
|
|
case Qt.Key_Print: return "printscreen"
|
|
case Qt.Key_Pause: return "pause"
|
|
}
|
|
|
|
// Letters and Numbers (Use text if available, fallback to manual)
|
|
if (text && text.length > 0 && text.charCodeAt(0) >= 32) {
|
|
return text.toLowerCase()
|
|
}
|
|
|
|
return "key" + key
|
|
}
|
|
}
|