/** Copyright 2017 Roman Gilg <subdiff@gmail.com>* Copyright 2018 Furkan Tokac <furkantokac34@gmail.com>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/import QtQuick 2.7import QtQuick.Controls 2.0 as Controlsimport QtQuick.Layouts 1.3 as Layoutsimport org.kde.kcm 1.1 as KCMimport org.kde.kirigami 2.4 as Kirigami// TODO: Change ScrollablePage as KCM.SimpleKCM// after rewrite the KCM in KConfigModule.Kirigami.ScrollablePage {id: rootspacing: Kirigami.Units.smallSpacingproperty size minimumSizeHint: Qt.size(formLayout.width/2, deviceSelector.height)property alias deviceIndex: deviceSelector.currentIndexsignal changeSignal()property QtObject touchpadproperty int touchpadCount: backend.touchpadCountproperty bool loading: falsefunction resetModel(index) {touchpadCount = backend.touchpadCountformLayout.enabled = touchpadCountdeviceSelector.enabled = touchpadCount > 1loading = trueif (touchpadCount) {touchpad = deviceModel[index]deviceSelector.model = deviceModeldeviceSelector.currentIndex = indexconsole.log("Touchpad configuration of device '" +(index + 1) + " : " + touchpad.name + "' opened")} else {deviceSelector.model = [""]console.log("No touchpad found")}loading = false}function syncValuesFromBackend() {loading = truedeviceEnabled.load()dwt.load()leftHanded.load()middleEmulation.load()accelSpeed.load()accelProfile.load()tapToClick.load()tapAndDrag.load()tapAndDragLock.load()multiTap.load()scrollMethod.load()naturalScroll.load()rightClickMethod.load()middleClickMethod.load()disableHorizontalScrolling.load()loading = false}Kirigami.FormLayout {id: formLayout// DeviceControls.ComboBox {Kirigami.FormData.label: i18nd("kcm_touchpad", "Device:")id: deviceSelectorenabled: touchpadCount > 1Layouts.Layout.fillWidth: truemodel: deviceModeltextRole: "name"onCurrentIndexChanged: {if (touchpadCount) {touchpad = deviceModel[currentIndex]if (!loading) {changeSignal()}console.log("Touchpad configuration of device '" +(currentIndex+1) + " : " + touchpad.name + "' opened")}root.syncValuesFromBackend()}}Item {Kirigami.FormData.isSection: false}// General settingsControls.CheckBox {Kirigami.FormData.label: i18nd("kcm_touchpad", "General:")id: deviceEnabledtext: i18nd("kcm_touchpad", "Device enabled")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Accept input through this device.")visible: parent.hovereddelay: 1000}function load() {if (!formLayout.enabled) {checked = falsereturn}enabled = touchpad.supportsDisableEventschecked = enabled && touchpad.enabled}onCheckedChanged: {if (enabled && !root.loading) {touchpad.enabled = checkedroot.changeSignal()}}}Controls.CheckBox {id: dwttext: i18nd("kcm_touchpad", "Disable while typing")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Disable touchpad while typing to prevent accidental inputs.")visible: parent.hovereddelay: 1000}function load() {if (!formLayout.enabled) {checked = falsereturn}enabled = touchpad.supportsDisableWhileTypingchecked = enabled && touchpad.disableWhileTyping}onCheckedChanged: {if (enabled && !root.loading) {touchpad.disableWhileTyping = checkedroot.changeSignal()}}}Controls.CheckBox {id: leftHandedtext: i18nd("kcm_touchpad", "Left handed mode")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Swap left and right buttons.")visible: parent.hovereddelay: 1000}function load() {if (!formLayout.enabled) {checked = falsereturn}enabled = touchpad.supportsLeftHandedchecked = enabled && touchpad.leftHanded}onCheckedChanged: {if (enabled && !root.loading) {touchpad.leftHanded = checkedroot.changeSignal()}}}Controls.CheckBox {id: middleEmulationtext: i18nd("kcm_touchpad", "Press left and right buttons for middle click")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Clicking left and right button simultaneously sends middle button click.")visible: parent.hovereddelay: 1000}function load() {if (!formLayout.enabled) {checked = falsereturn}enabled = touchpad.supportsMiddleEmulationchecked = enabled && touchpad.middleEmulation}onCheckedChanged: {if (enabled && !root.loading) {touchpad.middleEmulation = checkedroot.changeSignal()}loading = truemiddleClickMethod.load()loading = false}}Item {Kirigami.FormData.isSection: false}// AccelerationControls.Slider {Kirigami.FormData.label: i18nd("kcm_touchpad", "Pointer speed:")id: accelSpeedfrom: 1to: 11stepSize: 1function load() {enabled = touchpad.supportsPointerAccelerationif (!enabled) {value = 0.1return}// transform libinput's pointer acceleration range [-1, 1] to slider range [1, 11]value = 6 + touchpad.pointerAcceleration / 0.2}onValueChanged: {if (touchpad != undefined && enabled && !root.loading) {// transform slider range [1, 11] to libinput's pointer acceleration range [-1, 1]// by *10 and /10, we ignore the floating points after 1 digit. This prevents from// having a libinput value like 0.60000001touchpad.pointerAcceleration = Math.round(((value-6) * 0.2) * 10) / 10root.changeSignal()}}}Layouts.ColumnLayout {Kirigami.FormData.label: i18nd("kcm_touchpad", "Acceleration profile:")Kirigami.FormData.buddyFor: accelProfileFlatid: accelProfilespacing: Kirigami.Units.smallSpacingfunction load() {enabled = touchpad.supportsPointerAccelerationProfileAdaptiveif (!enabled) {accelProfile.visible = falseaccelProfileFlat.checked = falseaccelProfileAdaptive.checked = falsereturn}if(touchpad.pointerAccelerationProfileAdaptive) {accelProfileAdaptive.checked = true} else {accelProfileFlat.checked = true}}function syncCurrent() {if (enabled && !root.loading) {touchpad.pointerAccelerationProfileFlat = accelProfileFlat.checkedtouchpad.pointerAccelerationProfileAdaptive = accelProfileAdaptive.checkedroot.changeSignal()}}Controls.RadioButton {id: accelProfileFlattext: i18nd("kcm_touchpad", "Flat")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Cursor moves the same distance as finger.")visible: parent.hovereddelay: 1000}onCheckedChanged: accelProfile.syncCurrent()}Controls.RadioButton {id: accelProfileAdaptivetext: i18nd("kcm_touchpad", "Adaptive")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Cursor travel distance depends on movement speed of finger.")visible: parent.hovereddelay: 1000}onCheckedChanged: accelProfile.syncCurrent()}}Item {Kirigami.FormData.isSection: false}// TappingControls.CheckBox {Kirigami.FormData.label: i18nd("kcm_touchpad", "Tapping:")id: tapToClicktext: i18nd("kcm_touchpad", "Tap-to-click")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Single tap is left button click.")visible: parent.hovereddelay: 1000}function load() {enabled = touchpad.tapFingerCount > 0checked = enabled && touchpad.tapToClick}function updateDependents() {loading = truetapAndDrag.load()tapAndDragLock.load()multiTap.load()loading = false}onCheckedChanged: {if (enabled && !root.loading) {touchpad.tapToClick = checkedupdateDependents()root.changeSignal()}}}Controls.CheckBox {id: tapAndDragtext: i18nd("kcm_touchpad", "Tap-and-drag")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Sliding over touchpad directly after tap drags.")visible: parent.hovereddelay: 1000}function load() {enabled = touchpad.tapFingerCount > 0 && tapToClick.checkedchecked = enabled && touchpad.tapAndDrag}function updateDependents() {loading = truetapAndDragLock.load()loading = false}onCheckedChanged: {if (enabled && !root.loading) {touchpad.tapAndDrag = checkedupdateDependents()root.changeSignal()}}}Controls.CheckBox {id: tapAndDragLocktext: i18nd("kcm_touchpad", "Tap-and-drag lock")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Dragging continues after a short finger lift.")visible: parent.hovereddelay: 1000}function load() {enabled = touchpad.tapFingerCount > 0 && tapAndDrag.checkedchecked = enabled && touchpad.tapDragLock}onCheckedChanged: {if (enabled && !root.loading) {touchpad.tapDragLock = checkedroot.changeSignal()}}}Layouts.ColumnLayout {Kirigami.FormData.label: i18nd("kcm_touchpad", "Two-finger tap:")Kirigami.FormData.buddyFor: multiTapRightClickid: multiTapspacing: Kirigami.Units.smallSpacingfunction load() {enabled = touchpad.supportsLmrTapButtonMap && tapToClick.checkedif (touchpad.tapFingerCount > 2) {multiTapRightClick.text = i18nd("kcm_touchpad", "Right-click (three-finger tap to middle-click)")multiTapRightClickToolTip.text = i18nd("kcm_touchpad", "Tap with two fingers to right-click, tap with three fingers to middle-click.")multiTapMiddleClick.text = i18nd("kcm_touchpad", "Middle-click (three-finger tap right-click)")multiTapMiddleClickToolTip.text = i18nd("kcm_touchpad", "Tap with two fingers to middle-click, tap with three fingers to right-click.")} else {multiTapRightClick.text = i18nd("kcm_touchpad", "Right-click")multiTapRightClickToolTip.text = i18nd("kcm_touchpad", "Tap with two fingers to right-click.")multiTapMiddleClick.text = i18nd("kcm_touchpad", "Middle-click")multiTapMiddleClickToolTip.text = i18nd("kcm_touchpad", "Tap with two fingers to middle-click.")}if (!enabled) {multiTapRightClick.checked = falsemultiTapMiddleClick.checked = falsereturn}if(touchpad.lmrTapButtonMap) {multiTapMiddleClick.checked = true} else {multiTapRightClick.checked = true}}function syncCurrent() {if (enabled && !root.loading) {touchpad.lmrTapButtonMap = multiTapMiddleClick.checkedroot.changeSignal()}}Controls.RadioButton {id: multiTapRightClick// text: is handled dynamically on load.hoverEnabled: trueControls.ToolTip {id: multiTapRightClickToolTipvisible: parent.hovereddelay: 1000// text: is handled dynamically on load.}onCheckedChanged: multiTap.syncCurrent()}Controls.RadioButton {id: multiTapMiddleClick// text: is handled dynamically on load.hoverEnabled: trueControls.ToolTip {id: multiTapMiddleClickToolTipvisible: parent.hovereddelay: 1000// text: is handled dynamically on load.}onCheckedChanged: multiTap.syncCurrent()}}Item {Kirigami.FormData.isSection: false}// ScrollingLayouts.ColumnLayout {Kirigami.FormData.label: i18nd("kcm_touchpad", "Scrolling:")Kirigami.FormData.buddyFor: scrollMethodTwoFingersid: scrollMethodspacing: Kirigami.Units.smallSpacingfunction load() {scrollMethodTwoFingers.enabled = touchpad.supportsScrollTwoFingerscrollMethodTouchpadEdges.enabled = touchpad.supportsScrollEdgeif(scrollMethodTouchpadEdges.enabled && touchpad.scrollEdge) {scrollMethodTouchpadEdges.checked = formLayout.enabled} else {scrollMethodTwoFingers.checked = formLayout.enabled}}function syncCurrent() {if (enabled && !root.loading) {touchpad.scrollTwoFinger = scrollMethodTwoFingers.checkedtouchpad.scrollEdge = scrollMethodTouchpadEdges.checkedroot.changeSignal()}loading = truenaturalScroll.load()loading = false}Controls.RadioButton {id: scrollMethodTwoFingerstext: i18nd("kcm_touchpad", "Two fingers")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Slide with two fingers scrolls.")visible: parent.hovereddelay: 1000}}Controls.RadioButton {id: scrollMethodTouchpadEdgestext: i18nd("kcm_touchpad", "Touchpad edges")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Slide on the touchpad edges scrolls.")visible: parent.hovereddelay: 1000}onCheckedChanged: scrollMethod.syncCurrent()}}Controls.CheckBox {id: naturalScrolltext: i18nd("kcm_touchpad", "Invert scroll direction (Natural scrolling)")function load() {enabled = touchpad.supportsNaturalScrollchecked = enabled && touchpad.naturalScroll}onCheckedChanged: {if (enabled && !root.loading) {touchpad.naturalScroll = checkedroot.changeSignal()}}hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Touchscreen like scrolling.")visible: parent.hovereddelay: 1000}}Controls.CheckBox {id: disableHorizontalScrollingtext: i18nd("kcm_touchpad", "Disable horizontal scrolling")function load() {visible = touchpad.supportsHorizontalScrollingenabled = touchpad.supportsHorizontalScrollingchecked = enabled && !touchpad.horizontalScrolling}onCheckedChanged: {if (enabled && !root.loading) {touchpad.horizontalScrolling = !checkedroot.changeSignal()}}hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Disable horizontal scrolling")visible: parent.hovereddelay: 1000}}Item {Kirigami.FormData.isSection: false}Layouts.ColumnLayout {Kirigami.FormData.label: i18nd("kcm_touchpad", "Right-click:")Kirigami.FormData.buddyFor: rightClickMethodAreasid: rightClickMethodenabled: touchpad.supportsClickMethodAreas && touchpad.supportsClickMethodClickfingerspacing: Kirigami.Units.smallSpacingfunction load() {visible = (touchpad.supportedButtons & Qt.LeftButton)if (!visible) {rightClickMethodAreas.checked = falserightClickMethodClickfinger.checked = falsereturn;}rightClickMethodAreas.enabled = touchpad.supportsClickMethodAreasrightClickMethodClickfinger.enabled = touchpad.supportsClickMethodClickfingerif (rightClickMethodAreas.enabled && touchpad.clickMethodAreas) {rightClickMethodAreas.checked = true} else if (rightClickMethodClickfinger.enabled && touchpad.clickMethodClickfinger) {rightClickMethodClickfinger.checked = true}}function syncCurrent() {if (enabled && !root.loading) {touchpad.clickMethodAreas = rightClickMethodAreas.checkedtouchpad.clickMethodClickfinger = rightClickMethodClickfinger.checkedroot.changeSignal()}loading = truemiddleClickMethod.load()loading = false}Controls.RadioButton {id: rightClickMethodAreastext: i18nd("kcm_touchpad", "Press bottom-right corner")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Software enabled buttons will be added to bottom portion of your touchpad.")visible: parent.hovereddelay: 1000}}Controls.RadioButton {id: rightClickMethodClickfingertext: i18nd("kcm_touchpad", "Press anywhere with two fingers")hoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Tap with two finger to enable right click.")visible: parent.hovereddelay: 1000}onCheckedChanged: rightClickMethod.syncCurrent()}}Item {Kirigami.FormData.isSection: false}Layouts.ColumnLayout {Kirigami.FormData.label: i18nd("kcm_touchpad", "Middle-click: ")Kirigami.FormData.buddyFor: middleSoftwareEmulationid: middleClickMethodspacing: Kirigami.Units.smallSpacingfunction load() {visible = rightClickMethod.visibleif (!visible) {enabled = falsereturn;}enabled = touchpad.supportsMiddleEmulationif (enabled && touchpad.middleEmulation) {middleSoftwareEmulation.checked = true} else {noMiddleSoftwareEmulation.checked = true}}function syncCurrent() {if (enabled && !root.loading) {touchpad.middleEmulation = middleSoftwareEmulation.checkedroot.changeSignal()}loading = truemiddleEmulation.load()loading = false}Controls.RadioButton {id: noMiddleSoftwareEmulationtext: i18nd("kcm_touchpad", "Press bottom-middle")visible: rightClickMethodAreas.checkedhoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Software enabled middle-button will be added to bottom portion of your touchpad.")visible: parent.hovereddelay: 1000}}Controls.RadioButton {id: middleSoftwareEmulationtext: i18nd("kcm_touchpad", "Press bottom left and bottom right corners simultaneously")visible: rightClickMethodAreas.checkedhoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Clicking left and right button simultaneously sends middle button click.")visible: parent.hovereddelay: 1000}onCheckedChanged: middleClickMethod.syncCurrent()}Controls.CheckBox {id: clickfingerMiddleInfoBoxtext: i18nd("kcm_touchpad", "Press anywhere with three fingers")checked: trueenabled: falsevisible: rightClickMethodClickfinger.checkedhoverEnabled: trueControls.ToolTip {text: i18nd("kcm_touchpad", "Press anywhere with three fingers.")visible: parent.hovereddelay: 1000}}}} // END Kirigami.FormLayout} // END Kirigami.ScrollablePage