1/* 2 SPDX-FileCopyrightText: 2020 Ismael Asensio <isma.af@gmail.com> 3 4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5*/ 6 7import QtQuick 2.14 8import QtQuick.Layouts 1.14 9import QtQuick.Controls 2.14 as QQC2 10 11import org.kde.kirigami 2.10 as Kirigami 12import org.kde.kquickcontrols 2.0 as KQC 13import org.kde.kcms.kwinrules 1.0 14 15 16Loader { 17 id: valueEditor 18 focus: true 19 20 property var ruleValue 21 property var ruleOptions 22 property int controlType 23 24 signal valueEdited(var value) 25 26 sourceComponent: { 27 switch (controlType) { 28 case RuleItem.Boolean: return booleanEditor 29 case RuleItem.String: return stringEditor 30 case RuleItem.Integer: return integerEditor 31 case RuleItem.Option: return optionEditor 32 case RuleItem.NetTypes: return netTypesEditor 33 case RuleItem.Percentage: return percentageEditor 34 case RuleItem.Point: return coordinateEditor 35 case RuleItem.Size: return coordinateEditor 36 case RuleItem.Shortcut: return shortcutEditor 37 case RuleItem.OptionList: return optionListEditor 38 default: return emptyEditor 39 } 40 } 41 42 Component { 43 id: emptyEditor 44 Item {} 45 } 46 47 Component { 48 id: booleanEditor 49 RowLayout { 50 Item { 51 Layout.fillWidth: true 52 } 53 QQC2.RadioButton { 54 text: i18n("Yes") 55 checked: ruleValue 56 Layout.margins: Kirigami.Units.smallSpacing 57 onToggled: valueEditor.valueEdited(checked) 58 } 59 QQC2.RadioButton { 60 text: i18n("No") 61 checked: !ruleValue 62 Layout.margins: Kirigami.Units.smallSpacing 63 onToggled: valueEditor.valueEdited(!checked) 64 } 65 } 66 } 67 68 Component { 69 id: stringEditor 70 QQC2.TextField { 71 id: stringTextField 72 property bool isTextEdited: false 73 horizontalAlignment: Text.AlignLeft 74 onTextEdited: { valueEditor.valueEdited(text); } 75 Connections { 76 target: valueEditor 77 function onRuleValueChanged() { 78 if (!stringTextField.activeFocus) { // Protects from self-updating when editing 79 stringTextField.text = valueEditor.ruleValue 80 } 81 } 82 } 83 Component.onCompleted: { this.text = valueEditor.ruleValue } 84 } 85 } 86 87 Component { 88 id: integerEditor 89 QQC2.SpinBox { 90 editable: true 91 value: ruleValue 92 onValueModified: valueEditor.valueEdited(value) 93 } 94 } 95 96 Component { 97 id: optionEditor 98 OptionsComboBox { 99 flat: true 100 model: ruleOptions 101 onActivated: (index) => { 102 valueEditor.valueEdited(currentValue); 103 } 104 } 105 } 106 107 Component { 108 id: netTypesEditor 109 OptionsComboBox { 110 flat: true 111 model: ruleOptions 112 multipleChoice: true 113 useFlagsValue: true 114 // Filter the provided value with the options mask 115 selectionMask: ruleValue & optionsMask 116 onActivated: { 117 valueEditor.valueEdited(selectionMask); 118 } 119 } 120 } 121 122 Component { 123 id: optionListEditor 124 OptionsComboBox { 125 id: optionListCombo 126 flat: true 127 model: ruleOptions 128 multipleChoice: true 129 130 onActivated: { 131 let selectionList = [] 132 for (let i = 0; i < count; i++) { 133 if (selectionMask & (1 << i)) { 134 selectionList.push(model.data(model.index(i,0), Qt.UserRole)) 135 } 136 } 137 valueEditor.valueEdited(selectionList); 138 } 139 140 function updateSelectionMask() { 141 selectionMask = 0 142 for (let i = 0; i < count; i++) { 143 if (ruleValue.includes(model.data(model.index(i,0), Qt.UserRole))) { 144 selectionMask += 1 << i 145 } 146 } 147 } 148 149 onModelChanged: updateSelectionMask() 150 Component.onCompleted: updateSelectionMask() 151 Connections { 152 target: valueEditor 153 function onRuleValueChanged() { 154 optionListCombo.updateSelectionMask() 155 } 156 } 157 } 158 } 159 160 Component { 161 id: percentageEditor 162 RowLayout { 163 QQC2.Slider { 164 id: slider 165 Layout.fillWidth: true 166 from: 0 167 to: 100 168 value: ruleValue 169 onMoved: valueEditor.valueEdited(Math.round(slider.value)) 170 } 171 QQC2.Label { 172 text: i18n("%1 %", Math.round(slider.value)) 173 horizontalAlignment: Qt.AlignRight 174 Layout.minimumWidth: maxPercentage.width + Kirigami.Units.smallSpacing 175 Layout.margins: Kirigami.Units.smallSpacing 176 } 177 TextMetrics { 178 id: maxPercentage 179 text: i18n("%1 %", 100) 180 } 181 } 182 } 183 184 Component { 185 id: coordinateEditor 186 RowLayout { 187 id: coordItem 188 spacing: Kirigami.Units.smallSpacing 189 190 readonly property bool isSize: controlType == RuleItem.Size 191 readonly property var coord: (isSize) ? Qt.size(coordX.value, coordY.value) 192 : Qt.point(coordX.value, coordY.value) 193 194 QQC2.SpinBox { 195 id: coordX 196 editable: true 197 Layout.preferredWidth: 50 // 50% 198 Layout.fillWidth: true 199 from: (isSize) ? 0 : -32767 200 to: 32767 201 value: (isSize) ? ruleValue.width : ruleValue.x 202 onValueModified: valueEditor.valueEdited(coord) 203 } 204 QQC2.Label { 205 id: coordSeparator 206 Layout.preferredWidth: implicitWidth 207 text: i18nc("(x, y) coordinates separator in size/position","x") 208 horizontalAlignment: Text.AlignHCenter 209 } 210 QQC2.SpinBox { 211 id: coordY 212 editable: true 213 from: coordX.from 214 to: coordX.to 215 Layout.preferredWidth: 50 // 50% 216 Layout.fillWidth: true 217 value: (isSize) ? ruleValue.height : ruleValue.y 218 onValueModified: valueEditor.valueEdited(coord) 219 } 220 } 221 } 222 223 Component { 224 id: shortcutEditor 225 RowLayout { 226 Item { 227 Layout.fillWidth: true 228 } 229 KQC.KeySequenceItem { 230 keySequence: ruleValue 231 onCaptureFinished: valueEditor.valueEdited(keySequence) 232 } 233 } 234 } 235} 236