diff --git a/qml/BarToggle.qml b/qml/BarToggle.qml new file mode 100644 index 0000000..d2a2a60 --- /dev/null +++ b/qml/BarToggle.qml @@ -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) + } +} diff --git a/qml/DragHandle.qml b/qml/DragHandle.qml index 99c6871..b1409e9 100644 --- a/qml/DragHandle.qml +++ b/qml/DragHandle.qml @@ -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 diff --git a/qml/Main.qml b/qml/Main.qml index c271548..7f3eda3 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -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) diff --git a/qml/QuickToggles.qml b/qml/QuickToggles.qml new file mode 100644 index 0000000..6843831 --- /dev/null +++ b/qml/QuickToggles.qml @@ -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 } + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6dcea70..a6e8f95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,8 @@ set(SLOPOSK_QML_FILES ResizeHandle.qml SectionHeader.qml SettingsButton.qml + BarToggle.qml + QuickToggles.qml SettingsPanel.qml ProblemList.qml ToggleRow.qml