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 }