Warning, /plasma/plasma-desktop/kcms/tablet/ui/main.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
0003
0004 SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006
0007 import QtQuick 2.15
0008 import QtQuick.Layouts 1.1
0009 import QtQuick.Controls 2.3 as QQC2
0010 import org.kde.kirigami 2.19 as Kirigami
0011 import org.kde.plasma.tablet.kcm 1.1
0012 import org.kde.kcmutils
0013 import org.kde.kquickcontrols 2.0
0014
0015 SimpleKCM {
0016 id: root
0017
0018 ConfigModule.buttons: ConfigModule.Default | ConfigModule.Apply
0019
0020 implicitWidth: Kirigami.Units.gridUnit * 38
0021 implicitHeight: Kirigami.Units.gridUnit * 35
0022
0023 // So it doesn't scroll while dragging
0024 flickable.interactive: Kirigami.Settings.hasTransientTouchInput
0025
0026 header: Kirigami.InlineMessage {
0027 Layout.fillWidth: true
0028
0029 type: Kirigami.MessageType.Information
0030 visible: combo.count === 0
0031 text: i18nd("kcm_tablet", "No drawing tablets found.")
0032 }
0033
0034 Kirigami.FormLayout {
0035 id: form
0036 enabled: combo.count > 0
0037 QQC2.ComboBox {
0038 id: combo
0039 Kirigami.FormData.label: i18ndc("kcm_tablet", "@label:listbox The device we are configuring", "Device:")
0040 model: kcm.toolsModel
0041
0042 onCountChanged: if (count > 0 && currentIndex < 0) {
0043 currentIndex = 0;
0044 }
0045
0046 function reloadOutputView() {
0047 const initialOutputArea = form.device.outputArea;
0048 if (initialOutputArea === Qt.rect(0, 0, 1, 1)) {
0049 outputAreaCombo.currentIndex = 0;
0050 } else if (initialOutputArea.x === 0 && initialOutputArea.y === 0 && initialOutputArea.width === 1) {
0051 outputAreaCombo.currentIndex = 1;
0052 } else {
0053 outputAreaCombo.currentIndex = 2;
0054 }
0055 keepAspectRatio.checked = tabletItem.aspectRatio === (form.device.size.width / form.device.size.height)
0056 outputAreaView.resetOutputArea(outputAreaCombo.currentIndex, initialOutputArea)
0057 }
0058
0059 onCurrentIndexChanged: {
0060 parent.device = kcm.toolsModel.deviceAt(combo.currentIndex)
0061 reloadOutputView()
0062 }
0063
0064 Connections {
0065 target: kcm
0066 function onSettingsRestored() {
0067 outputAreaView.changed = false
0068 combo.reloadOutputView()
0069 }
0070 }
0071 }
0072
0073 property QtObject device: null
0074
0075 QQC2.ComboBox {
0076 id: outputsCombo
0077 Kirigami.FormData.label: i18nd("kcm_tablet", "Target display:")
0078 model: OutputsModel {
0079 id: outputsModel
0080 }
0081 enabled: count > 2 //It's only interesting when there's more than 1 screen
0082 currentIndex: {
0083
0084 if (count === 0) {
0085 return -1
0086 }
0087
0088 outputsModel.rowForOutputName(parent.device.outputName)
0089 }
0090 textRole: "display"
0091 onActivated: {
0092 parent.device.outputName = outputsModel.outputNameAt(currentIndex)
0093 }
0094 }
0095 QQC2.ComboBox {
0096 Kirigami.FormData.label: i18nd("kcm_tablet", "Orientation:")
0097 model: OrientationsModel {
0098 id: orientationsModel
0099 }
0100 enabled: parent.device && parent.device.supportsOrientation
0101 currentIndex: orientationsModel.rowForOrientation(parent.device.orientation)
0102 textRole: "display"
0103 onActivated: {
0104 parent.device.orientation = orientationsModel.orientationAt(currentIndex)
0105 }
0106 }
0107 QQC2.CheckBox {
0108 Kirigami.FormData.label: i18nd("kcm_tablet", "Left-handed mode:")
0109 enabled: parent.device && parent.device.supportsLeftHanded
0110 checked: parent.device && parent.device.leftHanded
0111 onCheckedChanged: {
0112 parent.device.leftHanded = checked
0113 }
0114 }
0115 QQC2.ComboBox {
0116 id: outputAreaCombo
0117 Layout.fillWidth: true
0118 Kirigami.FormData.label: i18nd("kcm_tablet", "Area:")
0119 model: OutputsFittingModel {}
0120 onActivated: {
0121 outputAreaView.changed = true
0122 keepAspectRatio.checked = true
0123 outputAreaView.resetOutputArea(index, index === 0 ? Qt.rect(0,0, 1,1) : Qt.rect(0, 0, 1, outputItem.aspectRatio/tabletItem.aspectRatio))
0124 }
0125 }
0126
0127 // Display fit demo
0128 Item {
0129 id: outputAreaView
0130 function resetOutputArea(mode, outputArea) {
0131 if (mode === 0) {
0132 tabletItem.x = 0
0133 tabletItem.y = 0
0134 tabletItem.width = Qt.binding(() => outputItem.width);
0135 tabletItem.height = Qt.binding(() => outputItem.height);
0136 } else {
0137 tabletItem.x = Qt.binding(() => outputArea.x * outputItem.width)
0138 tabletItem.y = Qt.binding(() => outputArea.y * outputItem.height)
0139 tabletItem.width = Qt.binding(() => tabletSizeHandle.x);
0140 tabletItem.height = Qt.binding(() => tabletSizeHandle.y);
0141 tabletSizeHandle.x = Qt.binding(() => outputArea.width * outputItem.width)
0142 if (keepAspectRatio.checked) {
0143 tabletSizeHandle.y = Qt.binding(() => tabletSizeHandle.x / tabletItem.aspectRatio);
0144 } else {
0145 tabletSizeHandle.y = Qt.binding(() => outputArea.height * outputItem.height)
0146 }
0147
0148 }
0149 }
0150
0151 readonly property rect outputAreaSetting: Qt.rect(tabletItem.x/outputItem.width, tabletItem.y/outputItem.height,
0152 tabletItem.width/outputItem.width, tabletItem.height/outputItem.height)
0153 property bool changed: false
0154 onOutputAreaSettingChanged: {
0155 if (form.device && changed) {
0156 form.device.outputArea = outputAreaSetting
0157 }
0158 }
0159
0160 Layout.fillWidth: true
0161 Layout.preferredHeight: Math.max(outputItem.height, tabletItem.height)
0162 enabled: parent.device
0163
0164 Output {
0165 id: outputItem
0166 readonly property size outputPhysicalSize: outputsModel.data(outputsModel.index(outputsCombo.currentIndex, 0), Qt.UserRole + 1)
0167 readonly property size outputSize: outputsModel.data(outputsModel.index(outputsCombo.currentIndex, 0), Qt.UserRole + 2)
0168 readonly property real aspectRatio: outputPhysicalSize.width / outputPhysicalSize.height
0169 width: parent.width * 0.7
0170 height: width / aspectRatio
0171 }
0172
0173 Rectangle {
0174 id: tabletItem
0175 color: Kirigami.Theme.activeBackgroundColor
0176 opacity: 0.8
0177 readonly property real aspectRatio: outputAreaCombo.currentIndex === 0 ? outputItem.aspectRatio : form.device.size.width / form.device.size.height
0178 width: tabletSizeHandle.x
0179 height: tabletSizeHandle.y
0180
0181 DragHandler {
0182 cursorShape: Qt.ClosedHandCursor
0183 target: parent
0184 enabled: outputAreaCombo.currentIndex >= 2
0185 onActiveChanged: { outputAreaView.changed = true }
0186
0187 xAxis.minimum: 0
0188 xAxis.maximum: outputItem.width - tabletItem.width
0189
0190 yAxis.minimum: 0
0191 yAxis.maximum: outputItem.height - tabletItem.height
0192
0193 }
0194
0195 TapHandler {
0196 gesturePolicy: TapHandler.WithinBounds
0197 }
0198
0199 QQC2.Button {
0200 id: tabletSizeHandle
0201 x: outputItem.width
0202 y: outputItem.width / parent.aspectRatio
0203 visible: outputAreaCombo.currentIndex >= 2
0204 icon.name: "transform-move"
0205 display: QQC2.AbstractButton.IconOnly
0206 text: i18nd("kcm_tablet", "Resize the tablet area")
0207 QQC2.ToolTip {
0208 text: tabletSizeHandle.text
0209 visible: parent.hovered
0210 delay: Kirigami.Units.toolTipDelay
0211 }
0212
0213 DragHandler {
0214 cursorShape: Qt.SizeFDiagCursor
0215 target: parent
0216 onActiveChanged: { outputAreaView.changed = true }
0217
0218 xAxis.minimum: 10
0219 xAxis.maximum: outputItem.width - tabletItem.x
0220
0221 yAxis.minimum: keepAspectRatio.checked ? (tabletItem.width / tabletItem.aspectRatio) : 10
0222 yAxis.maximum: keepAspectRatio.checked ? (tabletItem.width / tabletItem.aspectRatio) : outputItem.height - tabletItem.y
0223 }
0224 }
0225 }
0226 }
0227
0228 QQC2.CheckBox {
0229 id: keepAspectRatio
0230 text: i18ndc("kcm_tablet", "@option:check", "Lock aspect ratio")
0231 visible: outputAreaCombo.currentIndex >= 2
0232 checked: true
0233 onToggled: {
0234 outputAreaView.resetOutputArea(outputAreaCombo.currentIndex, form.device.outputArea)
0235 }
0236 }
0237 QQC2.Label {
0238 text: i18ndc("kcm_tablet", "tablet area position - size", "%1,%2 - %3×%4", String(Math.floor(outputAreaView.outputAreaSetting.x * outputItem.outputSize.width))
0239 , String(Math.floor(outputAreaView.outputAreaSetting.y * outputItem.outputSize.height))
0240 , String(Math.floor(outputAreaView.outputAreaSetting.width * outputItem.outputSize.width))
0241 , String(Math.floor(outputAreaView.outputAreaSetting.height * outputItem.outputSize.height)))
0242 textFormat: Text.PlainText
0243 }
0244
0245 Repeater {
0246 model: [
0247 { value: 0x14b, text: i18nd("kcm_tablet", "Pen Button 1") },
0248 { value: 0x14c, text: i18nd("kcm_tablet", "Pen Button 2") },
0249 { value: 0x149, text: i18nd("kcm_tablet", "Pen Button 3") }
0250 ] // BTN_STYLUS, BTN_STYLUS2, BTN_STYLUS3
0251
0252 delegate: KeySequenceItem {
0253 id: seq
0254 Kirigami.FormData.label: (pressed ? "<b>" : "") + modelData.text + (pressed ? "</b>" : "")
0255 property bool pressed: false
0256
0257 Connections {
0258 target: tabletEvents
0259 function onToolButtonReceived(hardware_serial_hi, hardware_serial_lo, button, pressed) {
0260 if (button !== modelData.value) {
0261 return;
0262 }
0263 seq.pressed = pressed
0264 }
0265 }
0266
0267 keySequence: kcm.toolButtonMapping(form.device.name, modelData.value)
0268 Connections {
0269 target: kcm
0270 function onSettingsRestored() {
0271 seq.keySequence = kcm.toolButtonMapping(form.device.name, modelData.value)
0272 }
0273 }
0274
0275 showCancelButton: true
0276 modifierlessAllowed: true
0277 modifierOnlyAllowed: true
0278 multiKeyShortcutsAllowed: false
0279 checkForConflictsAgainst: ShortcutType.None
0280
0281 onCaptureFinished: {
0282 kcm.assignToolButtonMapping(form.device.name, modelData.value, keySequence)
0283 }
0284 }
0285 }
0286
0287 Kirigami.Separator {
0288 Layout.fillWidth: true
0289 }
0290
0291 property QtObject padDevice: null
0292 QQC2.ComboBox {
0293 Kirigami.FormData.label: i18ndc("kcm_tablet", "@label:listbox The pad we are configuring", "Pad:")
0294 model: kcm.padsModel
0295
0296 onCurrentIndexChanged: {
0297 parent.padDevice = kcm.padsModel.deviceAt(currentIndex)
0298 }
0299
0300 onCountChanged: if (count > 0 && currentIndex < 0) {
0301 currentIndex = 0;
0302 }
0303 enabled: count > 0
0304 displayText: enabled ? currentText : i18n("None")
0305 }
0306
0307 TabletEvents {
0308 id: tabletEvents
0309
0310 anchors.fill: parent
0311
0312 onPadButtonsChanged: {
0313 if (!path.endsWith(form.padDevice.sysName)) {
0314 return;
0315 }
0316 buttonsRepeater.model = buttonCount
0317 }
0318 }
0319
0320 Repeater {
0321 id: buttonsRepeater
0322 model: tabletEvents.padButtons
0323
0324 delegate: KeySequenceItem {
0325 id: seq
0326 Kirigami.FormData.label: (pressed ? "<b>" : "") + i18nd("kcm_tablet", "Button %1:", modelData + 1) + (pressed ? "</b>" : "")
0327 property bool pressed: false
0328
0329 Connections {
0330 target: tabletEvents
0331 function onPadButtonReceived(path, button, pressed) {
0332 if (button !== modelData || !path.endsWith(form.padDevice.sysName)) {
0333 return;
0334 }
0335 seq.pressed = pressed
0336 }
0337 }
0338
0339 keySequence: kcm.padButtonMapping(form.padDevice.name, modelData)
0340 Connections {
0341 target: kcm
0342 function onSettingsRestored() {
0343 seq.keySequence = kcm.padButtonMapping(form.padDevice.name, modelData)
0344 }
0345 }
0346
0347 showCancelButton: true
0348 modifierlessAllowed: true
0349 modifierOnlyAllowed: true
0350 multiKeyShortcutsAllowed: false
0351 checkForConflictsAgainst: ShortcutType.None
0352
0353 onCaptureFinished: {
0354 kcm.assignPadButtonMapping(form.padDevice.name, modelData, keySequence)
0355 }
0356 }
0357 }
0358 }
0359 }