Add quick toggles to the grab bar
Beside the gear: full keyboard, hold keys, and the numeric keypad, navigation and function key sections, each behind a drawn icon and lit while on. Section toggles hide when the layout lacks the section. The grab pill narrows when a small window leaves it less room. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import QtQuick
|
||||
|
||||
// A small on/off button in the grab bar; lit while on. The icon goes inside
|
||||
// and should draw in `foreground`.
|
||||
Item {
|
||||
id: toggle
|
||||
|
||||
required property string label
|
||||
property bool checked: false
|
||||
readonly property color foreground: checked ? Theme.accentText : (tap.pressed ? Theme.text : Theme.handle)
|
||||
default property alias icon: iconArea.data
|
||||
signal toggled(bool checked)
|
||||
|
||||
implicitWidth: 34
|
||||
implicitHeight: 22
|
||||
Accessible.role: Accessible.CheckBox
|
||||
Accessible.name: label
|
||||
Accessible.checked: checked
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 30
|
||||
height: 20
|
||||
radius: 5
|
||||
color: Theme.accent
|
||||
visible: toggle.checked
|
||||
}
|
||||
|
||||
Item {
|
||||
id: iconArea
|
||||
anchors.centerIn: parent
|
||||
width: 20
|
||||
height: 14
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
id: tap
|
||||
onTapped: toggle.toggled(!toggle.checked)
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -5,13 +5,15 @@ import QtQuick
|
||||
Item {
|
||||
id: handle
|
||||
|
||||
// Narrower when the bar's buttons leave less room in the middle.
|
||||
property real pillWidth: 120
|
||||
signal dragStarted()
|
||||
|
||||
implicitHeight: 22
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 120
|
||||
width: handle.pillWidth
|
||||
height: 5
|
||||
radius: height / 2
|
||||
color: Theme.handle
|
||||
|
||||
@@ -65,16 +65,25 @@ Window {
|
||||
DragHandle {
|
||||
id: handle
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
pillWidth: Math.min(120, width - 2 * (quickToggles.x + quickToggles.width + 12))
|
||||
onDragStarted: root.startSystemMove()
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: settingsButton
|
||||
anchors { left: parent.left; leftMargin: 8; bottom: parent.bottom }
|
||||
checked: root.settingsOpen
|
||||
alert: root.diagnostics.problems.length > 0
|
||||
onClicked: root.settingsOpen = !root.settingsOpen
|
||||
}
|
||||
|
||||
QuickToggles {
|
||||
id: quickToggles
|
||||
anchors { left: settingsButton.right; bottom: parent.bottom }
|
||||
settings: root.settings
|
||||
layoutModel: root.layoutModel
|
||||
}
|
||||
|
||||
ResizeHandle {
|
||||
anchors { right: parent.right; bottom: parent.bottom }
|
||||
onDragStarted: root.startSystemResize(Qt.RightEdge | Qt.BottomEdge)
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
import QtQuick
|
||||
import Sloposk
|
||||
|
||||
// One-tap switches for the most changed key options, beside the gear.
|
||||
// Icons are drawn from boxes so they don't depend on the fonts installed.
|
||||
Row {
|
||||
id: toggles
|
||||
|
||||
required property Settings settings
|
||||
required property LayoutModel layoutModel
|
||||
|
||||
function hasSection(id) {
|
||||
return layoutModel.sections.some(s => s.id === id);
|
||||
}
|
||||
|
||||
// Shows or hides one of the template's optional sections; absent from
|
||||
// layouts without it.
|
||||
component SectionToggle: BarToggle {
|
||||
required property string section
|
||||
|
||||
visible: toggles.hasSection(section)
|
||||
checked: toggles.settings.visibleSections.includes(section)
|
||||
onToggled: checked => toggles.settings.setSectionVisible(section, checked)
|
||||
}
|
||||
|
||||
// A grid of tiny keys, optionally in a keyboard outline.
|
||||
component KeyGrid: Item {
|
||||
id: keyGrid
|
||||
required property color color
|
||||
required property int columns
|
||||
required property int rows
|
||||
property bool framed: false
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: keyGrid.framed
|
||||
radius: 2
|
||||
color: "transparent"
|
||||
border { width: 1.5; color: keyGrid.color }
|
||||
}
|
||||
|
||||
Grid {
|
||||
readonly property real key: keyGrid.framed ? 2 : 3
|
||||
anchors.centerIn: parent
|
||||
columns: keyGrid.columns
|
||||
spacing: 1
|
||||
Repeater {
|
||||
model: keyGrid.columns * keyGrid.rows
|
||||
Rectangle {
|
||||
width: parent.key
|
||||
height: parent.key
|
||||
radius: 0.5
|
||||
color: keyGrid.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A key outline with a label on it.
|
||||
component LabelledKey: Rectangle {
|
||||
property alias label: caption.text
|
||||
property alias textColor: caption.color
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: 20
|
||||
height: 14
|
||||
radius: 3
|
||||
color: "transparent"
|
||||
border { width: 1.5; color: caption.color }
|
||||
|
||||
Text {
|
||||
id: caption
|
||||
anchors.centerIn: parent
|
||||
font { pixelSize: 9; bold: true }
|
||||
}
|
||||
}
|
||||
|
||||
BarToggle {
|
||||
id: full
|
||||
label: qsTr("Full Keyboard")
|
||||
checked: toggles.settings.fullKeyboard
|
||||
onToggled: checked => toggles.settings.fullKeyboard = checked
|
||||
KeyGrid { color: full.foreground; columns: 6; rows: 3; framed: true }
|
||||
}
|
||||
|
||||
BarToggle {
|
||||
id: hold
|
||||
label: qsTr("Hold Keys")
|
||||
checked: toggles.settings.holdKeys
|
||||
onToggled: checked => toggles.settings.holdKeys = checked
|
||||
// A fingertip resting on a key, holding it down.
|
||||
Rectangle {
|
||||
anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom }
|
||||
width: 18
|
||||
height: 8
|
||||
radius: 2
|
||||
color: "transparent"
|
||||
border { width: 1.5; color: hold.foreground }
|
||||
}
|
||||
Rectangle {
|
||||
anchors { horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 1 }
|
||||
width: 8
|
||||
height: 11
|
||||
radius: 4
|
||||
color: hold.foreground
|
||||
}
|
||||
}
|
||||
|
||||
SectionToggle {
|
||||
id: numpad
|
||||
section: "numpad"
|
||||
label: qsTr("Numeric Keypad")
|
||||
KeyGrid { color: numpad.foreground; columns: 3; rows: 3 }
|
||||
}
|
||||
|
||||
SectionToggle {
|
||||
id: navigation
|
||||
section: "navigation"
|
||||
label: qsTr("Navigation Keys")
|
||||
// The inverted T of the arrow keys.
|
||||
Repeater {
|
||||
model: [[1, 0], [0, 1], [1, 1], [2, 1]]
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
x: 1.5 + modelData[0] * 6
|
||||
y: 1.5 + modelData[1] * 6
|
||||
width: 5
|
||||
height: 5
|
||||
radius: 1
|
||||
color: navigation.foreground
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionToggle {
|
||||
id: fn
|
||||
section: "function"
|
||||
label: qsTr("Function Keys")
|
||||
LabelledKey { label: "Fn"; textColor: fn.foreground }
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ set(SLOPOSK_QML_FILES
|
||||
ResizeHandle.qml
|
||||
SectionHeader.qml
|
||||
SettingsButton.qml
|
||||
BarToggle.qml
|
||||
QuickToggles.qml
|
||||
SettingsPanel.qml
|
||||
ProblemList.qml
|
||||
ToggleRow.qml
|
||||
|
||||
Reference in New Issue
Block a user