diff --git a/kcms/colors/package/contents/ui/main.qml b/kcms/colors/package/contents/ui/main.qml index 6fe2633af..50ce3879e 100644 --- a/kcms/colors/package/contents/ui/main.qml +++ b/kcms/colors/package/contents/ui/main.qml @@ -1,280 +1,265 @@ /* * Copyright 2018 Kai Uwe Broulik * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . */ import QtQuick 2.6 import QtQuick.Layouts 1.1 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.0 as QtDialogs import QtQuick.Controls 2.3 as QtControls import org.kde.kirigami 2.4 as Kirigami import org.kde.kconfig 1.0 // for KAuthorized import org.kde.kcm 1.1 as KCM KCM.GridViewKCM { KCM.ConfigModule.quickHelp: i18n("This module lets you choose the color scheme.") view.model: kcm.colorsModel view.currentIndex: kcm.selectedSchemeIndex enabled: !kcm.downloadingFile Component.onCompleted: { // The thumbnails are a bit more elaborate and need more room, especially when translated view.implicitCellWidth = Kirigami.Units.gridUnit * 13; } DropArea { anchors.fill: parent onEntered: { if (!drag.hasUrls) { drag.accepted = false; } } onDropped: { infoLabel.visible = false; kcm.installSchemeFromFile(drop.urls[0]); } } // putting the InlineMessage as header item causes it to show up initially despite visible false header: ColumnLayout { Kirigami.InlineMessage { id: notInstalledWarning Layout.fillWidth: true type: Kirigami.MessageType.Warning showCloseButton: true visible: false Connections { target: kcm onShowSchemeNotInstalledWarning: { notInstalledWarning.text = i18n("The color scheme '%1' is not installed. Selecting the default theme instead.", schemeName) notInstalledWarning.visible = true; } } } } - view.remove: Transition { - ParallelAnimation { - NumberAnimation { property: "scale"; to: 0.5; duration: Kirigami.Units.longDuration } - NumberAnimation { property: "opacity"; to: 0.0; duration: Kirigami.Units.longDuration } - } - } - - view.removeDisplaced: Transition { - SequentialAnimation { - // wait for the "remove" animation to finish - PauseAnimation { duration: Kirigami.Units.longDuration } - NumberAnimation { properties: "x,y"; duration: Kirigami.Units.longDuration } - } - } - view.delegate: KCM.GridDelegate { id: delegate text: model.display thumbnailAvailable: true thumbnail: Rectangle { anchors.fill: parent opacity: model.pendingDeletion ? 0.3 : 1 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration } } color: model.palette.window Kirigami.Theme.highlightColor: model.palette.highlight Kirigami.Theme.highlightedTextColor: model.palette.highlightedText Kirigami.Theme.linkColor: model.palette.link Kirigami.Theme.textColor: model.palette.text ColumnLayout { anchors { fill: parent margins: Kirigami.Units.smallSpacing } RowLayout { Layout.fillWidth: true QtControls.Label { Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: Text.AlignVCenter text: i18n("Window text") elide: Text.ElideRight color: model.palette.windowText } QtControls.Button { Layout.alignment: Qt.AlignBottom text: i18n("Button") Kirigami.Theme.backgroundColor: model.palette.button Kirigami.Theme.textColor: model.palette.buttonText activeFocusOnTab: false } } QtControls.Frame { Layout.fillWidth: true Layout.fillHeight: true Kirigami.Theme.backgroundColor: model.palette.base // FIXME Make Frame still visible but without any inner padding padding: 1 activeFocusOnTab: false Column { id: listPreviewColumn readonly property string demoText: " %2 %4" .arg(i18nc("Hyperlink", "link")) .arg(model.palette.linkVisited) .arg(i18nc("Visited hyperlink", "visited")) width: parent.width QtControls.ItemDelegate { width: parent.width text: i18n("Normal text") + listPreviewColumn.demoText activeFocusOnTab: false } QtControls.ItemDelegate { width: parent.width highlighted: true // TODO use proper highlighted link color text: i18n("Highlighted text") + listPreviewColumn.demoText activeFocusOnTab: false } QtControls.ItemDelegate { width: parent.width enabled: false text: i18n("Disabled text") + listPreviewColumn.demoText activeFocusOnTab: false } } } } // Make the preview non-clickable but still reacting to hover MouseArea { anchors.fill: parent onClicked: delegate.clicked() onDoubleClicked: delegate.doubleClicked() } } actions: [ Kirigami.Action { iconName: "document-edit" tooltip: i18n("Edit Color Scheme") enabled: !model.pendingDeletion onTriggered: kcm.editScheme(model.index, parent) }, Kirigami.Action { iconName: "edit-delete" tooltip: i18n("Remove Color Scheme") enabled: model.removable visible: !model.pendingDeletion onTriggered: kcm.setPendingDeletion(model.index, true) }, Kirigami.Action { iconName: "edit-undo" tooltip: i18n("Restore Color Scheme") visible: model.pendingDeletion onTriggered: kcm.setPendingDeletion(model.index, false) } ] onClicked: { kcm.selectedScheme = model.schemeName; view.forceActiveFocus(); } onDoubleClicked: { kcm.save(); } } footer: ColumnLayout { Kirigami.InlineMessage { id: infoLabel Layout.fillWidth: true showCloseButton: true Connections { target: kcm onShowSuccessMessage: { infoLabel.type = Kirigami.MessageType.Positive; infoLabel.text = message; infoLabel.visible = true; // Avoid dual message widgets notInstalledWarning.visible = false; } onShowErrorMessage: { infoLabel.type = Kirigami.MessageType.Error; infoLabel.text = message; infoLabel.visible = true; notInstalledWarning.visible = false; } } } RowLayout { Layout.alignment: Qt.AlignRight QtControls.Button { text: i18n("Install from File...") icon.name: "document-import" onClicked: fileDialogLoader.active = true } QtControls.Button { text: i18n("Get New Color Schemes...") icon.name: "get-hot-new-stuff" onClicked: kcm.getNewStuff(this) visible: KAuthorized.authorize("ghns") } } } Loader { id: fileDialogLoader active: false sourceComponent: QtDialogs.FileDialog { title: i18n("Open Color Scheme") folder: shortcuts.home nameFilters: [ i18n("Color Scheme Files (*.colors)") ] Component.onCompleted: open() onAccepted: { infoLabel.visible = false; kcm.installSchemeFromFile(fileUrls[0]) fileDialogLoader.active = false } onRejected: { fileDialogLoader.active = false } } } } diff --git a/kcms/desktoptheme/package/contents/ui/main.qml b/kcms/desktoptheme/package/contents/ui/main.qml index ebe009105..c0bfdb37e 100644 --- a/kcms/desktoptheme/package/contents/ui/main.qml +++ b/kcms/desktoptheme/package/contents/ui/main.qml @@ -1,166 +1,151 @@ /* Copyright (c) 2014 Marco Martin Copyright (c) 2016 David Rosca Copyright (c) 2018 Kai Uwe Broulik This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.1 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.0 import QtQuick.Controls 2.3 as QtControls import org.kde.kirigami 2.4 as Kirigami import org.kde.kconfig 1.0 // for KAuthorized import org.kde.kcm 1.1 as KCM KCM.GridViewKCM { KCM.ConfigModule.quickHelp: i18n("This module lets you choose the Plasma theme.") view.model: kcm.desktopThemeModel view.currentIndex: kcm.selectedPluginIndex enabled: !kcm.downloadingFile DropArea { anchors.fill: parent onEntered: { if (!drag.hasUrls) { drag.accepted = false; } } onDropped: kcm.installThemeFromFile(drop.urls[0]) } - view.remove: Transition { - ParallelAnimation { - NumberAnimation { property: "scale"; to: 0.5; duration: Kirigami.Units.longDuration } - NumberAnimation { property: "opacity"; to: 0.0; duration: Kirigami.Units.longDuration } - } - } - - view.removeDisplaced: Transition { - SequentialAnimation { - // wait for the "remove" animation to finish - PauseAnimation { duration: Kirigami.Units.longDuration } - NumberAnimation { properties: "x,y"; duration: Kirigami.Units.longDuration } - } - } - view.delegate: KCM.GridDelegate { id: delegate text: model.themeName toolTip: model.description || model.themeName opacity: model.pendingDeletion ? 0.3 : 1 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration } } thumbnailAvailable: true thumbnail: ThemePreview { id: preview anchors.fill: parent themeName: model.pluginName } actions: [ Kirigami.Action { iconName: "document-edit" tooltip: i18n("Edit Theme") enabled: !model.pendingDeletion visible: kcm.canEditThemes onTriggered: kcm.editTheme(model.pluginName) }, Kirigami.Action { iconName: "edit-delete" tooltip: i18n("Remove Theme") enabled: model.isLocal visible: !model.pendingDeletion onTriggered: kcm.setPendingDeletion(model.index, true); }, Kirigami.Action { iconName: "edit-undo" tooltip: i18n("Restore Theme") visible: model.pendingDeletion onTriggered: kcm.setPendingDeletion(model.index, false); } ] onClicked: { kcm.selectedPlugin = model.pluginName; view.forceActiveFocus(); } } footer: ColumnLayout { Kirigami.InlineMessage { id: infoLabel Layout.fillWidth: true showCloseButton: true Connections { target: kcm onShowSuccessMessage: { infoLabel.type = Kirigami.MessageType.Positive; infoLabel.text = message; infoLabel.visible = true; } onShowErrorMessage: { infoLabel.type = Kirigami.MessageType.Error; infoLabel.text = message; infoLabel.visible = true; } } } RowLayout { Layout.alignment: Qt.AlignRight QtControls.Button { text: i18n("Install from File...") icon.name: "document-import" onClicked: fileDialogLoader.active = true; } QtControls.Button { text: i18n("Get New Plasma Themes...") icon.name: "get-hot-new-stuff" onClicked: kcm.getNewStuff(this) visible: KAuthorized.authorize("ghns") } } } Loader { id: fileDialogLoader active: false sourceComponent: FileDialog { title: i18n("Open Theme") folder: shortcuts.home nameFilters: [ i18n("Theme Files (*.zip *.tar.gz *.tar.bz2)") ] Component.onCompleted: open() onAccepted: { kcm.installThemeFromFile(fileUrls[0]) fileDialogLoader.active = false } onRejected: { fileDialogLoader.active = false } } } } diff --git a/kcms/icons/package/contents/ui/main.qml b/kcms/icons/package/contents/ui/main.qml index d6cd444a4..96372d338 100644 --- a/kcms/icons/package/contents/ui/main.qml +++ b/kcms/icons/package/contents/ui/main.qml @@ -1,300 +1,285 @@ /* * Copyright 2018 Kai Uwe Broulik * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . */ import QtQuick 2.7 import QtQuick.Layouts 1.1 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.0 as QtDialogs import QtQuick.Controls 2.3 as QtControls import org.kde.kirigami 2.4 as Kirigami import org.kde.kquickcontrolsaddons 2.0 as KQCAddons import org.kde.kconfig 1.0 // for KAuthorized import org.kde.kcm 1.1 as KCM import org.kde.private.kcms.icons 1.0 as Private KCM.GridViewKCM { KCM.ConfigModule.quickHelp: i18n("This module allows you to choose the icons for your desktop.") view.model: kcm.iconsModel view.currentIndex: kcm.iconsModel.selectedThemeIndex DropArea { anchors.fill: parent onEntered: { if (!drag.hasUrls) { drag.accepted = false; } } onDropped: kcm.installThemeFromFile(drop.urls[0]) } - view.remove: Transition { - ParallelAnimation { - NumberAnimation { property: "scale"; to: 0.5; duration: Kirigami.Units.longDuration } - NumberAnimation { property: "opacity"; to: 0.0; duration: Kirigami.Units.longDuration } - } - } - - view.removeDisplaced: Transition { - SequentialAnimation { - // wait for the "remove" animation to finish - PauseAnimation { duration: Kirigami.Units.longDuration } - NumberAnimation { properties: "x,y"; duration: Kirigami.Units.longDuration } - } - } - view.delegate: KCM.GridDelegate { id: delegate text: model.display toolTip: model.description thumbnailAvailable: typeof thumbFlow.previews === "undefined" || thumbFlow.previews.length > 0 thumbnail: MouseArea { id: thumbArea anchors.fill: parent acceptedButtons: Qt.NoButton hoverEnabled: true clip: thumbFlow.y < 0 opacity: model.pendingDeletion ? 0.3 : 1 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration } } Timer { interval: 1000 repeat: true running: thumbArea.containsMouse onRunningChanged: { if (!running) { thumbFlow.currentPage = 0; } } onTriggered: { if (!thumbFlow.allPreviesLoaded) { thumbFlow.loadPreviews(-1 /*no limit*/); thumbFlow.allPreviesLoaded = true; } ++thumbFlow.currentPage; if (thumbFlow.currentPage >= thumbFlow.pageCount) { stop(); } } } Flow { id: thumbFlow // undefined is "didn't load preview yet" // empty array is "no preview available" property var previews // initially we only load 6 and when the animation starts we'll load the rest property bool allPreviesLoaded: false property int currentPage readonly property int pageCount: Math.ceil(thumbRepeater.count / (thumbFlow.columns * thumbFlow.rows)) readonly property int iconWidth: Math.floor(thumbArea.width / thumbFlow.columns) readonly property int iconHeight: Math.round(thumbArea.height / thumbFlow.rows) readonly property int columns: 3 readonly property int rows: 2 function loadPreviews(limit) { previews = kcm.previewIcons(model.themeName, Math.min(thumbFlow.iconWidth, thumbFlow.iconHeight), Screen.devicePixelRatio, limit); } width: parent.width y: -currentPage * iconHeight * rows Behavior on y { NumberAnimation { duration: Kirigami.Units.longDuration } } Repeater { id: thumbRepeater model: thumbFlow.previews Item { width: thumbFlow.iconWidth height: thumbFlow.iconHeight KQCAddons.QPixmapItem { anchors.centerIn: parent width: Math.min(parent.width, nativeWidth) height: Math.min(parent.height, nativeHeight) // load on demand and avoid leaking a tiny corner of the icon pixmap: thumbFlow.y < 0 || index < (thumbFlow.columns * thumbFlow.rows) ? modelData : undefined smooth: true fillMode: KQCAddons.QPixmapItem.PreserveAspectFit } } } Component.onCompleted: { // avoid reloading it when icon sizes or dpr changes on startup Qt.callLater(function() { // We show 6 icons initially (3x2 grid), only load those thumbFlow.loadPreviews(6 /*limit*/); }); } } } actions: [ Kirigami.Action { iconName: "edit-delete" tooltip: i18n("Remove Icon Theme") enabled: model.removable visible: !model.pendingDeletion onTriggered: model.pendingDeletion = true }, Kirigami.Action { iconName: "edit-undo" tooltip: i18n("Restore Icon Theme") visible: model.pendingDeletion onTriggered: model.pendingDeletion = false } ] onClicked: { if (!model.pendingDeletion) { kcm.iconsModel.selectedTheme = model.themeName; } view.forceActiveFocus(); } } footer: ColumnLayout { Kirigami.InlineMessage { id: infoLabel Layout.fillWidth: true showCloseButton: true Connections { target: kcm onShowSuccessMessage: { infoLabel.type = Kirigami.MessageType.Positive; infoLabel.text = message; infoLabel.visible = true; } onShowErrorMessage: { infoLabel.type = Kirigami.MessageType.Error; infoLabel.text = message; infoLabel.visible = true; } } } RowLayout { id: progressRow visible: false QtControls.BusyIndicator { id: progressBusy } QtControls.Label { id: progressLabel Layout.fillWidth: true textFormat: Text.PlainText wrapMode: Text.WordWrap } Connections { target: kcm onShowProgress: { progressLabel.text = message; progressBusy.running = true; progressRow.visible = true; } onHideProgress: { progressBusy.running = false; progressRow.visible = false; } } } RowLayout { Layout.fillWidth: true QtControls.Button { id: iconSizesButton text: i18n("Configure Icon Sizes") icon.name: "transform-scale" // proper icon? checkable: true checked: iconSizePopupLoader.item && iconSizePopupLoader.item.opened onClicked: { iconSizePopupLoader.active = true; iconSizePopupLoader.item.open(); } } Item { Layout.fillWidth: true } QtControls.Button { id: installFromFileButton text: i18n("Install from File...") icon.name: "document-import" onClicked: fileDialogLoader.active = true } QtControls.Button { text: i18n("Get New Icons...") icon.name: "get-hot-new-stuff" onClicked: kcm.getNewStuff(this) visible: KAuthorized.authorize("ghns") } } } Loader { id: iconSizePopupLoader active: false sourceComponent: IconSizePopup { parent: iconSizesButton y: -height } } Loader { id: fileDialogLoader active: false sourceComponent: QtDialogs.FileDialog { title: i18n("Open Theme") folder: shortcuts.home nameFilters: [ i18n("Theme Files (*.tar.gz *.tar.bz2)") ] Component.onCompleted: open() onAccepted: { kcm.installThemeFromFile(fileUrls[0]) fileDialogLoader.active = false } onRejected: { fileDialogLoader.active = false } } } }