From 2384ff36d9824e029c459eb9f42b1b524dc6ee84 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 19 Nov 2014 21:25:09 +0100 Subject: [PATCH] wallpaper config --- .../configuration/AppletConfiguration.qml | 331 ++++++++++++++++++ .../configuration/ConfigCategoryDelegate.qml | 119 +++++++ .../ConfigurationContainmentAppearance.qml | 149 ++++++++ .../ContainmentConfiguration.qml | 46 +++ 4 files changed, 645 insertions(+) create mode 100644 shell/contents/configuration/AppletConfiguration.qml create mode 100644 shell/contents/configuration/ConfigCategoryDelegate.qml create mode 100644 shell/contents/configuration/ConfigurationContainmentAppearance.qml create mode 100644 shell/contents/configuration/ContainmentConfiguration.qml diff --git a/shell/contents/configuration/AppletConfiguration.qml b/shell/contents/configuration/AppletConfiguration.qml new file mode 100644 index 00000000..75f318f0 --- /dev/null +++ b/shell/contents/configuration/AppletConfiguration.qml @@ -0,0 +1,331 @@ +/* + * Copyright 2013 Marco Martin + * + * 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 2.010-1301, USA. + */ + +import QtQuick 2.0 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.0 as QtControls +import QtQuick.Layouts 1.0 +import org.kde.plasma.configuration 2.0 + + +//TODO: all of this will be done with desktop components +Rectangle { + id: root + Layout.minimumWidth: units.gridUnit * 30 + Layout.minimumHeight: units.gridUnit * 20 + +//BEGIN properties + color: syspal.window + width: units.gridUnit * 40 + height: units.gridUnit * 30 + + property bool isContainment: false +//END properties + +//BEGIN model + property ConfigModel globalConfigModel: globalAppletConfigModel + + ConfigModel { + id: globalAppletConfigModel + ConfigCategory { + name: i18nd("plasma_shell_org.kde.plasma.desktop", "Keyboard shortcuts") + icon: "preferences-desktop-keyboard" + source: "ConfigurationShortcuts.qml" + } + } +//END model + +//BEGIN functions + function saveConfig() { + if (main.currentItem.saveConfig) { + main.currentItem.saveConfig() + } else { + for (var key in plasmoid.configuration) { + if (main.currentItem["cfg_"+key] !== undefined) { + plasmoid.configuration[key] = main.currentItem["cfg_"+key] + } + } + } + } + + function restoreConfig() { + for (var key in plasmoid.configuration) { + if (main.currentItem["cfg_"+key] !== undefined) { + main.currentItem["cfg_"+key] = plasmoid.configuration[key] + } + } + } + + function configurationHasChanged() { + for (var key in plasmoid.configuration) { + if (main.currentItem["cfg_"+key] !== undefined) { + //for objects == doesn't work + if (typeof plasmoid.configuration[key] == 'object') { + for (var i in plasmoid.configuration[key]) { + if (plasmoid.configuration[key][i] != main.currentItem["cfg_"+key][i]) { + return true; + } + } + return false; + } else if (main.currentItem["cfg_"+key] != plasmoid.configuration[key]) { + return true; + } + } + } + return false; + } + + function settingValueChanged() { + applyButton.enabled = true; + } +//END functions + + +//BEGIN connections + Component.onCompleted: { + if (!isContainment && configDialog.configModel && configDialog.configModel.count > 0) { + main.sourceFile = configDialog.configModel.get(0).source + main.title = configDialog.configModel.get(0).name + } else { + main.sourceFile = globalConfigModel.get(0).source + main.title = globalConfigModel.get(0).name + } +// root.width = mainColumn.implicitWidth +// root.height = mainColumn.implicitHeight + } +//END connections + +//BEGIN UI components + SystemPalette {id: syspal} + + MessageDialog { + id: messageDialog + icon: StandardIcon.Warning + property Item delegate + title: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply Settings") + text: i18nd("plasma_shell_org.kde.plasma.desktop", "The settings of the current module have changed. Do you want to apply the changes or discard them?") + standardButtons: StandardButton.Apply | StandardButton.Discard | StandardButton.Cancel + onApply: { + applyAction.trigger() + delegate.openCategory() + } + onDiscard: { + delegate.openCategory() + } + } + + ColumnLayout { + id: mainColumn + anchors { + fill: parent + margins: mainColumn.spacing //margins are hardcoded in QStyle we should match that here + } + property int implicitWidth: Math.max(contentRow.implicitWidth, buttonsRow.implicitWidth) + 8 + property int implicitHeight: contentRow.implicitHeight + buttonsRow.implicitHeight + 8 + + RowLayout { + id: contentRow + anchors { + left: parent.left + right: parent.right + } + spacing: units.largeSpacing + Layout.fillHeight: true + Layout.preferredHeight: parent.height - buttonsRow.height + + QtControls.ScrollView { + id: categoriesScroll + frameVisible: true + Layout.fillHeight: true + visible: (configDialog.configModel ? configDialog.configModel.count : 0) + globalConfigModel.count > 1 + width: visible ? units.gridUnit * 7 : 0 + implicitWidth: width + flickableItem.interactive: false + + Rectangle { + width: categoriesScroll.viewport.width + height: Math.max(categoriesScroll.viewport.height, categories.height) + color: syspal.base + + Column { + id: categories + width: parent.width + height: childrenRect.height + + property Item currentItem: children[1] + + Repeater { + model: root.isContainment ? globalConfigModel : undefined + delegate: ConfigCategoryDelegate {} + } + Repeater { + model: configDialog.configModel + delegate: ConfigCategoryDelegate {} + } + Repeater { + model: !root.isContainment ? globalConfigModel : undefined + delegate: ConfigCategoryDelegate {} + } + } + } + } + QtControls.ScrollView { + id: scroll + Layout.fillHeight: true + Layout.fillWidth: true + Column { + spacing: units.largeSpacing / 2 + + QtControls.Label { + id: pageTitle + width: scroll.viewport.width + font.pointSize: theme.defaultFont.pointSize*2 + font.weight: Font.Light + text: main.title + } + + QtControls.StackView { + id: main + property string title: "" + property bool invertAnimations: false + + height: Math.max((scroll.viewport.height - pageTitle.height - parent.spacing), (main.currentItem ? (main.currentItem.implicitHeight ? main.currentItem.implicitHeight : main.currentItem.childrenRect.height) : 0)) + width: scroll.viewport.width + + property string sourceFile + + onSourceFileChanged: { +// print("Source file changed in flickable" + sourceFile); + replace(Qt.resolvedUrl(sourceFile)); + root.restoreConfig() + for (var prop in currentItem) { + if (prop.indexOf("cfg_") === 0 && prop.indexOf("Changed") > 0 ) { + currentItem[prop].connect(root.settingValueChanged) + } + } + if (currentItem["configurationChanged"]) { + currentItem["configurationChanged"].connect(root.settingValueChanged) + } + applyButton.enabled = false; + /* + * This is not needed on a desktop shell that has ok/apply/cancel buttons, i'll leave it here only for future reference until we have a prototype for the active shell. + * root.pageChanged will start a timer, that in turn will call saveConfig() when triggered + + for (var prop in currentItem) { + if (prop.indexOf("cfg_") === 0) { + currentItem[prop+"Changed"].connect(root.pageChanged) + } + }*/ + } + + delegate: QtControls.StackViewDelegate { + function transitionFinished(properties) + { + properties.exitItem.opacity = 1 + } + + pushTransition: QtControls.StackViewTransition { + PropertyAnimation { + target: enterItem + property: "opacity" + from: 0 + to: 1 + duration: units.longDuration + easing.type: Easing.InOutQuad + } + PropertyAnimation { + target: enterItem + property: "x" + from: main.invertAnimations ? -target.width/3: target.width/3 + to: 0 + duration: units.longDuration + easing.type: Easing.InOutQuad + } + PropertyAnimation { + target: exitItem + property: "opacity" + from: 1 + to: 0 + duration: units.longDuration + easing.type: Easing.InOutQuad + } + PropertyAnimation { + target: exitItem + property: "x" + from: 0 + to: main.invertAnimations ? target.width/3 : -target.width/3 + duration: units.longDuration + easing.type: Easing.InOutQuad + } + } + } + } + } + } + } + + QtControls.Action { + id: acceptAction + onTriggered: { + applyAction.trigger(); + configDialog.close(); + } + shortcut: "Return" + } + + QtControls.Action { + id: applyAction + onTriggered: { + if (main.currentItem.saveConfig !== undefined) { + main.currentItem.saveConfig(); + } else { + root.saveConfig(); + } + } + } + + QtControls.Action { + id: cancelAction + onTriggered: configDialog.close(); + shortcut: "Escape" + } + + RowLayout { + id: buttonsRow + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + QtControls.Button { + iconName: "dialog-ok" + text: i18nd("plasma_shell_org.kde.plasma.desktop", "OK") + onClicked: acceptAction.trigger() + } + QtControls.Button { + id: applyButton + enabled: false + iconName: "dialog-ok-apply" + text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply") + onClicked: applyAction.trigger() + } + QtControls.Button { + iconName: "dialog-cancel" + text: i18nd("plasma_shell_org.kde.plasma.desktop", "Cancel") + onClicked: cancelAction.trigger() + } + } + } +//END UI components +} diff --git a/shell/contents/configuration/ConfigCategoryDelegate.qml b/shell/contents/configuration/ConfigCategoryDelegate.qml new file mode 100644 index 00000000..68301adb --- /dev/null +++ b/shell/contents/configuration/ConfigCategoryDelegate.qml @@ -0,0 +1,119 @@ +/* + * Copyright 2013 Marco Martin + * + * 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 2.010-1301, USA. + */ + +import QtQuick 2.0 +import QtQuick.Controls 1.0 as QtControls +import org.kde.plasma.core 2.0 as PlasmaCore + +MouseArea { + id: delegate + +//BEGIN properties + y: units.smallSpacing *2 + width: parent.width + height: delegateContents.height + units.smallSpacing * 4 + hoverEnabled: true + property bool current: model.source == main.sourceFile + property string name: model.name +//END properties + +//BEGIN functions + function openCategory() { + if (typeof(categories.currentItem) !== "undefined") { + main.invertAnimations = (categories.currentItem.y > delegate.y); + categories.currentItem = delegate; + } + main.sourceFile = model.source + main.title = model.name + } +//END functions + +//BEGIN connections + onClicked: { + print("model source: " + model.source + " " + main.sourceFile); + if (root.configurationHasChanged()) { + messageDialog.delegate = delegate + messageDialog.open(); + return; + } + if (delegate.current) { + return; + } else { + openCategory(); + } + } + onCurrentChanged: { + if (current) { + categories.currentItem = delegate; + } + } +//END connections + +//BEGIN UI components + Rectangle { + anchors.fill: parent + color: syspal.highlight + opacity: { + if (categories.currentItem == delegate) { + return 1 + } else if (delegate.containsMouse) { + return 0.3 // there's no "hover" color in SystemPalette + } else { + return 0 + } + } + Behavior on opacity { + NumberAnimation { + duration: units.longDuration + } + } + } + + Column { + id: delegateContents + spacing: units.smallSpacing + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + right: parent.right + } + PlasmaCore.IconItem { + anchors.horizontalCenter: parent.horizontalCenter + width: theme.IconSizeHuge + height: width + source: model.icon + } + QtControls.Label { + anchors { + left: parent.left + right: parent.right + } + text: model.name + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + color: current ? syspal.highlightedText : syspal.text + Behavior on color { + ColorAnimation { + duration: units.longDuration + easing.type: "InOutQuad" + } + } + } + } +//END UI components +} diff --git a/shell/contents/configuration/ConfigurationContainmentAppearance.qml b/shell/contents/configuration/ConfigurationContainmentAppearance.qml new file mode 100644 index 00000000..705f7b84 --- /dev/null +++ b/shell/contents/configuration/ConfigurationContainmentAppearance.qml @@ -0,0 +1,149 @@ +/* + * Copyright 2013 Marco Martin + * + * 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 2.010-1301, USA. + */ + +import QtQuick 2.0 +import org.kde.plasma.configuration 2.0 +import QtQuick.Controls 1.0 as QtControls +import QtQuick.Layouts 1.1 + +ColumnLayout { + id: root + + property int formAlignment: wallpaperComboBox.x + (units.largeSpacing/2) + property string currentWallpaper: "" + property string containmentPlugin: "" + signal configurationChanged + +//BEGIN functions + function saveConfig() { + for (var key in configDialog.wallpaperConfiguration) { + if (main.currentItem["cfg_"+key] !== undefined) { + configDialog.wallpaperConfiguration[key] = main.currentItem["cfg_"+key] + } + } + configDialog.currentWallpaper = root.currentWallpaper; + configDialog.applyWallpaper() + configDialog.containmentPlugin = root.containmentPlugin + } + + function restoreConfig() { + for (var key in configDialog.wallpaperConfiguration) { + if (main.currentItem["cfg_"+key] !== undefined) { + main.currentItem["cfg_"+key] = configDialog.wallpaperConfiguration[key] + } + + if (main.currentItem["cfg_"+key+"Changed"]) { + main.currentItem["cfg_"+key+"Changed"].connect(root.configurationChanged) + } + } + } +//END functions + + Component.onCompleted: { + for (var i = 0; i < configDialog.containmentPluginsConfigModel.count; ++i) { + var data = configDialog.containmentPluginsConfigModel.get(i); + for(var j in data) print(j) + if (configDialog.containmentPlugin == data.pluginName) { + pluginComboBox.currentIndex = i + break; + } + } + + for (var i = 0; i < configDialog.wallpaperConfigModel.count; ++i) { + var data = configDialog.wallpaperConfigModel.get(i); + for(var j in data) print(j) + if (configDialog.currentWallpaper == data.pluginName) { + wallpaperComboBox.currentIndex = i + break; + } + } + } + + Row { + spacing: units.largeSpacing / 2 + anchors.right: wallpaperRow.right + Item { + width: units.largeSpacing + height: parent.height + } + QtControls.Label { + anchors.verticalCenter: pluginComboBox.verticalCenter + text: i18nd("plasma_shell_org.kde.plasma.desktop", "Layout:") + } + QtControls.ComboBox { + id: pluginComboBox + enabled: !plasmoid.immutable + model: configDialog.containmentPluginsConfigModel + width: theme.mSize(theme.defaultFont).width * 24 + textRole: "name" + onCurrentIndexChanged: { + var model = configDialog.containmentPluginsConfigModel.get(currentIndex) + root.containmentPlugin = model.pluginName + root.configurationChanged() + } + } + } + + Row { + id: wallpaperRow + spacing: units.largeSpacing / 2 + Item { + width: units.largeSpacing + height: parent.height + } + QtControls.Label { + anchors.verticalCenter: wallpaperComboBox.verticalCenter + text: i18nd("plasma_shell_org.kde.plasma.desktop", "Wallpaper Type:") + } + QtControls.ComboBox { + id: wallpaperComboBox + model: configDialog.wallpaperConfigModel + width: theme.mSize(theme.defaultFont).width * 24 + textRole: "name" + onCurrentIndexChanged: { + var model = configDialog.wallpaperConfigModel.get(currentIndex) + root.currentWallpaper = model.pluginName + main.sourceFile = model.source + configDialog.currentWallpaper = model.pluginName + root.restoreConfig() + root.configurationChanged() + } + } + } + + Item { + id: emptyConfig + } + + QtControls.StackView { + id: main + Layout.fillHeight: true; + anchors { + left: parent.left; + right: parent.right; + } + property string sourceFile + onSourceFileChanged: { + if (sourceFile != "") { + replace(Qt.resolvedUrl(sourceFile)) + } else { + replace(emptyConfig); + } + } + } +} diff --git a/shell/contents/configuration/ContainmentConfiguration.qml b/shell/contents/configuration/ContainmentConfiguration.qml new file mode 100644 index 00000000..cf83801a --- /dev/null +++ b/shell/contents/configuration/ContainmentConfiguration.qml @@ -0,0 +1,46 @@ +/* + * Copyright 2013 Marco Martin + * + * 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 2.010-1301, USA. + */ + +import QtQuick 2.0 +import QtQuick.Layouts 1.0 +import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.configuration 2.0 + + +AppletConfiguration { + id: root + isContainment: true + Layout.minimumWidth: Math.min(plasmoid.availableScreenRect.width, units.gridUnit * 32) + Layout.minimumHeight: Math.min(plasmoid.availableScreenRect.height, units.gridUnit * 36) + +//BEGIN model + globalConfigModel: globalContainmentConfigModel + + ConfigModel { + id: globalContainmentConfigModel + ConfigCategory { + name: i18nd("plasma_shell_org.kde.plasma.desktop", "Wallpaper") + icon: "preferences-desktop-wallpaper" + source: "ConfigurationContainmentAppearance.qml" + } + } +//END model + +}