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 }