Warning, /plasma/plasma-bigscreen/shell/contents/configuration/AppletConfiguration.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.6 0008 import QtQuick.Controls 2.3 as QtControls 0009 import QtQuick.Layouts 1.0 0010 import QtQuick.Window 2.2 0011 0012 import org.kde.kirigami 2.5 as Kirigami 0013 import org.kde.plasma.core 2.1 as PlasmaCore 0014 import org.kde.plasma.configuration 2.0 0015 0016 0017 //TODO: all of this will be done with desktop components 0018 Rectangle { 0019 id: root 0020 Layout.minimumWidth: plasmoid.availableScreenRect.width 0021 Layout.minimumHeight: plasmoid.availableScreenRect.height 0022 0023 0024 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft 0025 LayoutMirroring.childrenInherit: true 0026 0027 color: Qt.rgba(0, 0, 0, 0.6 * dialog.position) 0028 0029 //BEGIN properties 0030 property bool isContainment: false 0031 property alias internalDialog: dialog 0032 //END properties 0033 0034 //BEGIN model 0035 property ConfigModel globalConfigModel: globalAppletConfigModel 0036 0037 ConfigModel { 0038 id: globalAppletConfigModel 0039 } 0040 0041 PlasmaCore.SortFilterModel { 0042 id: configDialogFilterModel 0043 sourceModel: configDialog.configModel 0044 filterRole: "visible" 0045 filterCallback: function(source_row, value) { return value; } 0046 } 0047 //END model 0048 0049 //BEGIN functions 0050 function saveConfig() { 0051 if (pageStack.currentItem.saveConfig) { 0052 pageStack.currentItem.saveConfig() 0053 } 0054 for (var key in plasmoid.configuration) { 0055 if (pageStack.currentItem["cfg_"+key] !== undefined) { 0056 plasmoid.configuration[key] = pageStack.currentItem["cfg_"+key] 0057 } 0058 } 0059 } 0060 0061 function configurationHasChanged() { 0062 for (var key in plasmoid.configuration) { 0063 if (pageStack.currentItem["cfg_"+key] !== undefined) { 0064 //for objects == doesn't work 0065 if (typeof plasmoid.configuration[key] == 'object') { 0066 for (var i in plasmoid.configuration[key]) { 0067 if (plasmoid.configuration[key][i] != pageStack.currentItem["cfg_"+key][i]) { 0068 return true; 0069 } 0070 } 0071 return false; 0072 } else if (pageStack.currentItem["cfg_"+key] != plasmoid.configuration[key]) { 0073 return true; 0074 } 0075 } 0076 } 0077 return false; 0078 } 0079 0080 0081 function settingValueChanged() { 0082 if (pageStack.currentItem.saveConfig !== undefined) { 0083 pageStack.currentItem.saveConfig(); 0084 } else { 0085 root.saveConfig(); 0086 } 0087 } 0088 //END functions 0089 0090 0091 //BEGIN connections 0092 Component.onCompleted: { 0093 if (!isContainment && configDialog.configModel && configDialog.configModel.count > 0) { 0094 if (configDialog.configModel.get(0).source) { 0095 pageStack.sourceFile = configDialog.configModel.get(0).source 0096 } else if (configDialog.configModel.get(0).kcm) { 0097 pageStack.sourceFile = Qt.resolvedUrl("ConfigurationKcmPage.qml"); 0098 pageStack.currentItem.kcm = configDialog.configModel.get(0).kcm; 0099 } else { 0100 pageStack.sourceFile = ""; 0101 } 0102 pageStack.title = configDialog.configModel.get(0).name 0103 } else { 0104 pageStack.sourceFile = globalConfigModel.get(0).source 0105 pageStack.title = globalConfigModel.get(0).name 0106 } 0107 // root.width = dialogRootItem.implicitWidth 0108 // root.height = dialogRootItem.implicitHeight 0109 } 0110 //END connections 0111 0112 //BEGIN UI components 0113 0114 QtControls.Drawer { 0115 id: dialog 0116 visible: true 0117 edge: Qt.BottomEdge 0118 onClosed: configDialog.close() 0119 x: parent.width/2 - width/2 0120 0121 opacity: position 0122 width: Math.min(Math.max(units.gridUnit * 35, dialogRootItem.implicitWidth + leftPadding + rightPadding), root.width) 0123 height: Math.min(root.height - units.gridUnit * 2, dialogRootItem.implicitHeight + topPadding + bottomPadding + units.gridUnit, root.height) 0124 0125 leftPadding: background.margins.left 0126 topPadding: background.margins.top 0127 rightPadding: background.margins.right 0128 bottomPadding: 0 0129 background: PlasmaCore.FrameSvgItem { 0130 imagePath: "widgets/background" 0131 enabledBorders: PlasmaCore.FrameSvgItem.LeftBorder | PlasmaCore.FrameSvgItem.TopBorder | PlasmaCore.FrameSvgItem.RightBorder 0132 } 0133 contentItem: ColumnLayout { 0134 id: dialogRootItem 0135 0136 spacing: 0 0137 implicitWidth: scroll.implicitWidth 0138 0139 QtControls.ScrollView { 0140 id: scroll 0141 0142 activeFocusOnTab: false 0143 0144 Layout.fillWidth: true 0145 Layout.fillHeight: true 0146 0147 implicitWidth: pageColumn.implicitWidth 0148 implicitHeight: pageColumn.implicitHeight 0149 0150 property Item flickableItem: pageFlickable 0151 // this horrible code below ensures the control with active focus stays visible in the window 0152 // by scrolling the view up or down as needed when tabbing through the window 0153 Window.onActiveFocusItemChanged: { 0154 var flickable = scroll.flickableItem; 0155 0156 var item = Window.activeFocusItem; 0157 if (!item) { 0158 return; 0159 } 0160 0161 // when an item within ScrollView has active focus the ScrollView, 0162 // as FocusScope, also has it, so we only scroll in this case 0163 if (!scroll.activeFocus) { 0164 return; 0165 } 0166 0167 var padding = units.gridUnit * 2 // some padding to the top/bottom when we scroll 0168 0169 var yPos = item.mapToItem(scroll.contentItem, 0, 0).y; 0170 if (yPos < flickable.contentY) { 0171 flickable.contentY = Math.max(0, yPos - padding); 0172 0173 // The "Math.min(padding, item.height)" ensures that we only scroll the item into view 0174 // when it's barely visible. The logic was mostly meant for keyboard navigating through 0175 // a list of CheckBoxes, so this check keeps us from trying to scroll an inner ScrollView 0176 // into view when it implicitly gains focus (like plasma-pa config dialog has). 0177 } else if (yPos + Math.min(padding, item.height) > flickable.contentY + flickable.height) { 0178 flickable.contentY = Math.min(flickable.contentHeight - flickable.height, 0179 yPos - flickable.height + item.height + padding); 0180 } 0181 } 0182 Flickable { 0183 id: pageFlickable 0184 anchors { 0185 fill: parent 0186 margins: units.smallSpacing 0187 } 0188 contentHeight: pageColumn.height 0189 contentWidth: width 0190 ColumnLayout { 0191 id: pageColumn 0192 spacing: units.largeSpacing / 2 0193 width: pageFlickable.width 0194 height: Math.max(implicitHeight, pageFlickable.height) 0195 0196 Kirigami.Heading { 0197 id: pageTitle 0198 Layout.fillWidth: true 0199 level: 1 0200 text: pageStack.title 0201 } 0202 0203 QtControls.StackView { 0204 id: pageStack 0205 property string title: "" 0206 property bool invertAnimations: false 0207 0208 Layout.fillWidth: true 0209 Layout.fillHeight: true 0210 implicitWidth: Math.max(currentItem ? Math.max(currentItem.Layout.minimumWidth, currentItem.Layout.preferredWidth, currentItem.implicitWidth) : 0, units.gridUnit * 15) 0211 implicitHeight: Math.max(currentItem ? Math.max(currentItem.Layout.minimumHeight, currentItem.Layout.preferredHeight, currentItem.implicitHeight) : 0, units.gridUnit * 15) 0212 0213 property string sourceFile 0214 0215 onSourceFileChanged: { 0216 if (!sourceFile) { 0217 return; 0218 } 0219 0220 //in a StackView pages need to be initialized with stackviews size, or have none 0221 var props = {"width": width, "height": height} 0222 0223 var plasmoidConfig = plasmoid.configuration 0224 for (var key in plasmoidConfig) { 0225 props["cfg_" + key] = plasmoid.configuration[key] 0226 } 0227 0228 var newItem = replace(Qt.resolvedUrl(sourceFile), props) 0229 0230 for (var key in plasmoidConfig) { 0231 var changedSignal = newItem["cfg_" + key + "Changed"] 0232 if (changedSignal) { 0233 changedSignal.connect(root.settingValueChanged) 0234 } 0235 } 0236 0237 var configurationChangedSignal = newItem.configurationChanged 0238 if (configurationChangedSignal) { 0239 configurationChangedSignal.connect(root.settingValueChanged) 0240 } 0241 0242 scroll.flickableItem.contentY = 0 0243 0244 /* 0245 for (var prop in currentItem) { 0246 if (prop.indexOf("cfg_") === 0) { 0247 currentItem[prop+"Changed"].connect(root.pageChanged) 0248 } 0249 }*/ 0250 } 0251 0252 replaceEnter: Transition { 0253 ParallelAnimation { 0254 //OpacityAnimator when starting from 0 is buggy (it shows one frame with opacity 1) 0255 NumberAnimation { 0256 property: "opacity" 0257 from: 0 0258 to: 1 0259 duration: units.longDuration 0260 easing.type: Easing.InOutQuad 0261 } 0262 XAnimator { 0263 from: pageStack.invertAnimations ? -scroll.width/3: scroll.width/3 0264 to: 0 0265 duration: units.longDuration 0266 easing.type: Easing.InOutQuad 0267 } 0268 } 0269 } 0270 replaceExit: Transition { 0271 ParallelAnimation { 0272 OpacityAnimator { 0273 from: 1 0274 to: 0 0275 duration: units.longDuration 0276 easing.type: Easing.InOutQuad 0277 } 0278 XAnimator { 0279 from: 0 0280 to: pageStack.invertAnimations ? scroll.width/3 : -scroll.width/3 0281 duration: units.longDuration 0282 easing.type: Easing.InOutQuad 0283 } 0284 } 0285 } 0286 } 0287 } 0288 } 0289 } 0290 0291 Rectangle { 0292 id: separator 0293 Layout.fillWidth: true 0294 Layout.preferredHeight: 1 0295 color: Kirigami.Theme.highlightColor 0296 visible: categoriesScroll.visible 0297 Behavior on color { 0298 ColorAnimation { 0299 duration: units.longDuration 0300 easing.type: Easing.InOutQuad 0301 } 0302 } 0303 } 0304 0305 QtControls.ScrollView { 0306 id: categoriesScroll 0307 0308 Layout.fillWidth: true 0309 Layout.preferredHeight: categories.implicitHeight 0310 0311 visible: (configDialog.configModel ? configDialog.configModel.count : 0) + globalConfigModel.count > 1 0312 0313 Keys.onLeftPressed: { 0314 var buttons = categories.children 0315 0316 var foundPrevious = false 0317 for (var i = buttons.length - 1; i >= 0; --i) { 0318 var button = buttons[i]; 0319 if (!button.hasOwnProperty("current")) { 0320 // not a ConfigCategoryDelegate 0321 continue; 0322 } 0323 0324 if (foundPrevious) { 0325 button.openCategory() 0326 return 0327 } else if (button.current) { 0328 foundPrevious = true 0329 } 0330 } 0331 } 0332 0333 Keys.onRightPressed: { 0334 var buttons = categories.children 0335 0336 var foundNext = false 0337 for (var i = 0, length = buttons.length; i < length; ++i) { 0338 var button = buttons[i]; 0339 console.log(button) 0340 if (!button.hasOwnProperty("current")) { 0341 continue; 0342 } 0343 0344 if (foundNext) { 0345 button.openCategory() 0346 return 0347 } else if (button.current) { 0348 foundNext = true 0349 } 0350 } 0351 } 0352 0353 RowLayout { 0354 id: categories 0355 spacing: 0 0356 width: categoriesScroll.width 0357 height: implicitHeight 0358 0359 property Item currentItem: children[1] 0360 0361 Repeater { 0362 model: root.isContainment ? globalConfigModel : undefined 0363 delegate: ConfigCategoryDelegate {} 0364 } 0365 Repeater { 0366 model: configDialogFilterModel 0367 delegate: ConfigCategoryDelegate {} 0368 } 0369 Repeater { 0370 model: !root.isContainment ? globalConfigModel : undefined 0371 delegate: ConfigCategoryDelegate {} 0372 } 0373 } 0374 } 0375 0376 } 0377 } 0378 //END UI components 0379 }