Give Input keycaps, a shortcut search, and the missing pointer basics
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
// A key chord, drawn as keys.
|
||||
//
|
||||
// KeycapChord { chord: "Super + Shift + Q" }
|
||||
//
|
||||
// The chord arrives as the display string Keybinds already produces and is
|
||||
// split on "+" alone, so nothing here has to know what a keysym is. Modifiers
|
||||
// are tinted and spelled in title case, which is what makes a wall of chords
|
||||
// scannable: the eye finds the modifier pattern before it reads the key.
|
||||
//
|
||||
// Presentation only. The prettified names are never handed back -- a rebind is
|
||||
// keyed by the Lua chord the service holds, and this must not become a second,
|
||||
// lossy spelling of a binding.
|
||||
|
||||
import QtQuick
|
||||
import qs.config
|
||||
|
||||
Row {
|
||||
id: root
|
||||
|
||||
property string chord: ""
|
||||
property int capHeight: 24
|
||||
|
||||
readonly property var keys: String(root.chord)
|
||||
.split("+")
|
||||
.map(part => part.trim())
|
||||
.filter(part => part !== "")
|
||||
|
||||
// Case-insensitive: Keybinds renders "Super", an override is stored as
|
||||
// "SUPER", and both have to tint.
|
||||
readonly property var modifierNames: ({
|
||||
"super": "Super",
|
||||
"meta": "Super",
|
||||
"win": "Super",
|
||||
"shift": "Shift",
|
||||
"ctrl": "Ctrl",
|
||||
"control": "Ctrl",
|
||||
"alt": "Alt"
|
||||
})
|
||||
|
||||
function isModifier(key: string): bool {
|
||||
return root.modifierNames[String(key).toLowerCase()] !== undefined;
|
||||
}
|
||||
|
||||
function pretty(key: string): string {
|
||||
return root.modifierNames[String(key).toLowerCase()] ?? key;
|
||||
}
|
||||
|
||||
spacing: 4
|
||||
|
||||
Repeater {
|
||||
model: root.keys
|
||||
|
||||
Row {
|
||||
id: segment
|
||||
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
readonly property bool modifier: root.isModifier(String(segment.modelData))
|
||||
|
||||
spacing: 4
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: segment.index > 0
|
||||
text: "+"
|
||||
color: Theme.fgMuted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.max(26, cap.implicitWidth + 14)
|
||||
height: root.capHeight
|
||||
radius: 6
|
||||
color: Theme.alpha(Theme.fg, 0.09)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.fg, 0.16)
|
||||
|
||||
// A keycap reads as a key because it has a lip. Rectangle
|
||||
// borders are uniform, so the thicker bottom edge is its own
|
||||
// sliver rather than a border width.
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 1
|
||||
height: 1
|
||||
color: Theme.alpha(Theme.fg, 0.16)
|
||||
}
|
||||
|
||||
Text {
|
||||
id: cap
|
||||
|
||||
anchors.centerIn: parent
|
||||
text: root.pretty(String(segment.modelData))
|
||||
color: segment.modifier ? Theme.accent : Theme.fg
|
||||
font.family: Theme.fontMono
|
||||
// Digits in a chord ("Super + 1") sit in a column of other
|
||||
// chords; tabular figures keep that column from wobbling.
|
||||
font.features: Theme.tabularFigures
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user