mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-02 01:34:46 +00:00
shell: Update configuration dialogs based on desktop, use new UI for wallpaper selector
This commit is contained in:
parent
dee476e773
commit
436b2660d2
7 changed files with 510 additions and 600 deletions
|
|
@ -1,43 +1,116 @@
|
||||||
/*
|
// SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||||
* SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
*
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.3 as QtControls
|
import QtQuick.Controls 2.15 as QQC2
|
||||||
import QtQuick.Layouts 1.0
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.5 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
import org.kde.plasma.core 2.1 as PlasmaCore
|
|
||||||
import org.kde.plasma.configuration 2.0
|
import org.kde.plasma.configuration 2.0
|
||||||
|
import org.kde.kitemmodels 1.0 as KItemModels
|
||||||
|
|
||||||
|
|
||||||
//TODO: all of this will be done with desktop components
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
// Layout.minimumWidth: plasmoid.availableScreenRect.width
|
|
||||||
// Layout.minimumHeight: plasmoid.availableScreenRect.height
|
|
||||||
|
|
||||||
|
|
||||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||||
LayoutMirroring.childrenInherit: true
|
LayoutMirroring.childrenInherit: true
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
//BEGIN properties
|
//BEGIN properties
|
||||||
|
|
||||||
property bool isContainment: false
|
property bool isContainment: false
|
||||||
property alias internalDialog: dialogContents
|
property alias appComponent: app
|
||||||
|
|
||||||
//END properties
|
//END properties
|
||||||
|
|
||||||
//BEGIN model
|
//BEGIN model
|
||||||
property ConfigModel globalConfigModel: globalAppletConfigModel
|
|
||||||
|
property ConfigModel globalConfigModel: globalAppletConfigModel
|
||||||
|
|
||||||
ConfigModel {
|
ConfigModel {
|
||||||
id: globalAppletConfigModel
|
id: globalAppletConfigModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KItemModels.KSortFilterProxyModel {
|
||||||
|
id: configDialogFilterModel
|
||||||
|
sourceModel: configDialog.configModel
|
||||||
|
filterRowCallback: (row, parent) => {
|
||||||
|
return sourceModel.data(sourceModel.index(row, 0), ConfigModel.VisibleRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//END model
|
||||||
|
|
||||||
|
//BEGIN functions
|
||||||
|
|
||||||
|
function saveConfig() {
|
||||||
|
if (app.pageStack.currentItem.saveConfig) {
|
||||||
|
app.pageStack.currentItem.saveConfig()
|
||||||
|
}
|
||||||
|
for (var key in plasmoid.configuration) {
|
||||||
|
if (app.pageStack.currentItem["cfg_"+key] !== undefined) {
|
||||||
|
plasmoid.configuration[key] = app.pageStack.currentItem["cfg_"+key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function configurationHasChanged() {
|
||||||
|
for (var key in plasmoid.configuration) {
|
||||||
|
if (app.pageStack.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] != app.pageStack.currentItem["cfg_"+key][i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (app.pageStack.currentItem["cfg_"+key] != plasmoid.configuration[key]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function settingValueChanged() {
|
||||||
|
if (app.pageStack.currentItem.saveConfig !== undefined) {
|
||||||
|
app.pageStack.currentItem.saveConfig();
|
||||||
|
} else {
|
||||||
|
root.saveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushReplace(item, config) {
|
||||||
|
let page;
|
||||||
|
if (app.pageStack.depth === 0) {
|
||||||
|
page = app.pageStack.push(item, config);
|
||||||
|
} else {
|
||||||
|
page = app.pageStack.replace(item, config);
|
||||||
|
}
|
||||||
|
app.currentConfigPage = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(item) {
|
||||||
|
app.isAboutPage = false;
|
||||||
|
if (item.source) {
|
||||||
|
app.isAboutPage = item.source === "AboutPlugin.qml";
|
||||||
|
pushReplace(Qt.resolvedUrl("ConfigurationAppletPage.qml"), {configItem: item, title: item.name});
|
||||||
|
} else if (item.kcm) {
|
||||||
|
pushReplace(configurationKcmPageComponent, {kcm: item.kcm, internalPage: item.kcm.mainUi});
|
||||||
|
} else {
|
||||||
|
app.pageStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//END functions
|
||||||
|
|
||||||
|
|
||||||
|
//BEGIN connections
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.Window.window
|
target: root.Window.window
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
|
|
@ -47,334 +120,101 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaCore.SortFilterModel {
|
|
||||||
id: configDialogFilterModel
|
|
||||||
sourceModel: configDialog.configModel
|
|
||||||
filterRole: "visible"
|
|
||||||
filterCallback: function(source_row, value) { return value; }
|
|
||||||
}
|
|
||||||
//END model
|
|
||||||
|
|
||||||
//BEGIN functions
|
|
||||||
function saveConfig() {
|
|
||||||
if (pageStack.currentItem.saveConfig) {
|
|
||||||
pageStack.currentItem.saveConfig()
|
|
||||||
}
|
|
||||||
for (var key in plasmoid.configuration) {
|
|
||||||
if (pageStack.currentItem["cfg_"+key] !== undefined) {
|
|
||||||
plasmoid.configuration[key] = pageStack.currentItem["cfg_"+key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function configurationHasChanged() {
|
|
||||||
for (var key in plasmoid.configuration) {
|
|
||||||
if (pageStack.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] != pageStack.currentItem["cfg_"+key][i]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (pageStack.currentItem["cfg_"+key] != plasmoid.configuration[key]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function settingValueChanged() {
|
|
||||||
if (pageStack.currentItem.saveConfig !== undefined) {
|
|
||||||
pageStack.currentItem.saveConfig();
|
|
||||||
} else {
|
|
||||||
root.saveConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//END functions
|
|
||||||
|
|
||||||
|
|
||||||
//BEGIN connections
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!isContainment && configDialog.configModel && configDialog.configModel.count > 0) {
|
// if we are a containment then the first item will be ConfigurationContainmentAppearance
|
||||||
if (configDialog.configModel.get(0).source) {
|
// if the applet does not have own configs then the first item will be Shortcuts
|
||||||
pageStack.sourceFile = configDialog.configModel.get(0).source
|
if (isContainment || !configDialog.configModel || configDialog.configModel.count === 0) {
|
||||||
} else if (configDialog.configModel.get(0).kcm) {
|
open(root.globalConfigModel.get(0))
|
||||||
pageStack.sourceFile = Qt.resolvedUrl("ConfigurationKcmPage.qml");
|
|
||||||
pageStack.currentItem.kcm = configDialog.configModel.get(0).kcm;
|
|
||||||
} else {
|
|
||||||
pageStack.sourceFile = "";
|
|
||||||
}
|
|
||||||
pageStack.title = configDialog.configModel.get(0).name
|
|
||||||
} else {
|
} else {
|
||||||
pageStack.sourceFile = globalConfigModel.get(0).source
|
open(configDialog.configModel.get(0))
|
||||||
pageStack.title = globalConfigModel.get(0).name
|
|
||||||
}
|
|
||||||
// root.width = dialogRootItem.implicitWidth
|
|
||||||
// root.height = dialogRootItem.implicitHeight
|
|
||||||
}
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
dialogContents.visible = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//END connections
|
//END connections
|
||||||
|
|
||||||
//BEGIN UI components
|
//BEGIN UI components
|
||||||
|
|
||||||
Rectangle {
|
Component {
|
||||||
id: dialogContents
|
id: configurationKcmPageComponent
|
||||||
visible: true
|
ConfigurationKcmPage {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: configCategoryDelegate
|
||||||
|
Kirigami.NavigationTabButton {
|
||||||
|
icon.name: model.icon
|
||||||
|
text: model.name
|
||||||
|
// recolorIcon: false
|
||||||
|
QQC2.ButtonGroup.group: footerBar.tabGroup
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (checked) {
|
||||||
|
root.open(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checked: {
|
||||||
|
if (app.pageStack.currentItem) {
|
||||||
|
if (model.kcm && app.pageStack.currentItem.kcm) {
|
||||||
|
return model.kcm == app.pageStack.currentItem.kcm;
|
||||||
|
} else if (app.pageStack.currentItem.configItem) {
|
||||||
|
return model.source == app.pageStack.currentItem.configItem.source;
|
||||||
|
} else {
|
||||||
|
return app.pageStack.currentItem.source == Qt.resolvedUrl(model.source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.ApplicationItem {
|
||||||
|
id: app
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
|
pageStack.globalToolBar.canContainHandles: true
|
||||||
ColumnLayout {
|
pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.ToolBar
|
||||||
id: dialogRootItem
|
pageStack.globalToolBar.showNavigationButtons: Kirigami.ApplicationHeaderStyle.ShowBackButton;
|
||||||
anchors.fill: parent
|
|
||||||
|
property var currentConfigPage: null
|
||||||
spacing: 0
|
property bool isAboutPage: false
|
||||||
implicitWidth: scroll.implicitWidth
|
|
||||||
|
// pop pages when not in use
|
||||||
QtControls.ScrollView {
|
Connections {
|
||||||
id: scroll
|
target: app.pageStack
|
||||||
|
function onCurrentIndexChanged() {
|
||||||
activeFocusOnTab: false
|
// wait for animation to finish before popping pages
|
||||||
|
timer.restart();
|
||||||
Layout.fillWidth: true
|
}
|
||||||
Layout.fillHeight: true
|
}
|
||||||
|
|
||||||
implicitWidth: pageColumn.implicitWidth
|
Timer {
|
||||||
implicitHeight: pageColumn.implicitHeight
|
id: timer
|
||||||
|
interval: 300
|
||||||
property Item flickableItem: pageFlickable
|
onTriggered: {
|
||||||
// this horrible code below ensures the control with active focus stays visible in the window
|
let currentIndex = app.pageStack.currentIndex;
|
||||||
// by scrolling the view up or down as needed when tabbing through the window
|
while (app.pageStack.depth > (currentIndex + 1) && currentIndex >= 0) {
|
||||||
Window.onActiveFocusItemChanged: {
|
app.pageStack.pop();
|
||||||
var flickable = scroll.flickableItem;
|
|
||||||
|
|
||||||
var item = Window.activeFocusItem;
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when an item within ScrollView has active focus the ScrollView,
|
|
||||||
// as FocusScope, also has it, so we only scroll in this case
|
|
||||||
if (!scroll.activeFocus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var padding = PlasmaCore.Units.gridUnit * 2 // some padding to the top/bottom when we scroll
|
|
||||||
|
|
||||||
var yPos = item.mapToItem(scroll.contentItem, 0, 0).y;
|
|
||||||
if (yPos < flickable.contentY) {
|
|
||||||
flickable.contentY = Math.max(0, yPos - padding);
|
|
||||||
|
|
||||||
// The "Math.min(padding, item.height)" ensures that we only scroll the item into view
|
|
||||||
// when it's barely visible. The logic was mostly meant for keyboard navigating through
|
|
||||||
// a list of CheckBoxes, so this check keeps us from trying to scroll an inner ScrollView
|
|
||||||
// into view when it implicitly gains focus (like plasma-pa config dialog has).
|
|
||||||
} else if (yPos + Math.min(padding, item.height) > flickable.contentY + flickable.height) {
|
|
||||||
flickable.contentY = Math.min(flickable.contentHeight - flickable.height,
|
|
||||||
yPos - flickable.height + item.height + padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Flickable {
|
|
||||||
id: pageFlickable
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: PlasmaCore.Units.smallSpacing
|
|
||||||
}
|
|
||||||
contentHeight: pageColumn.height
|
|
||||||
contentWidth: width
|
|
||||||
ColumnLayout {
|
|
||||||
id: pageColumn
|
|
||||||
spacing: PlasmaCore.Units.largeSpacing / 2
|
|
||||||
width: pageFlickable.width
|
|
||||||
height: Math.max(implicitHeight, pageFlickable.height)
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
id: pageTitle
|
|
||||||
Layout.fillWidth: true
|
|
||||||
level: 1
|
|
||||||
text: pageStack.title
|
|
||||||
}
|
|
||||||
|
|
||||||
QtControls.StackView {
|
|
||||||
id: pageStack
|
|
||||||
property string title: ""
|
|
||||||
property bool invertAnimations: false
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
implicitWidth: Math.max(currentItem ? Math.max(currentItem.Layout.minimumWidth, currentItem.Layout.preferredWidth, currentItem.implicitWidth) : 0, PlasmaCore.Units.gridUnit * 15)
|
|
||||||
implicitHeight: Math.max(currentItem ? Math.max(currentItem.Layout.minimumHeight, currentItem.Layout.preferredHeight, currentItem.implicitHeight) : 0, PlasmaCore.Units.gridUnit * 15)
|
|
||||||
|
|
||||||
property string sourceFile
|
|
||||||
|
|
||||||
onSourceFileChanged: {
|
|
||||||
if (!sourceFile) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//in a StackView pages need to be initialized with stackviews size, or have none
|
|
||||||
var props = {"width": width, "height": height}
|
|
||||||
|
|
||||||
var plasmoidConfig = plasmoid.configuration
|
|
||||||
for (var key in plasmoidConfig) {
|
|
||||||
props["cfg_" + key] = plasmoid.configuration[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
var newItem = replace(Qt.resolvedUrl(sourceFile), props)
|
|
||||||
|
|
||||||
for (var key in plasmoidConfig) {
|
|
||||||
var changedSignal = newItem["cfg_" + key + "Changed"]
|
|
||||||
if (changedSignal) {
|
|
||||||
changedSignal.connect(root.settingValueChanged)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var configurationChangedSignal = newItem.configurationChanged
|
|
||||||
if (configurationChangedSignal) {
|
|
||||||
configurationChangedSignal.connect(root.settingValueChanged)
|
|
||||||
}
|
|
||||||
|
|
||||||
scroll.flickableItem.contentY = 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (var prop in currentItem) {
|
|
||||||
if (prop.indexOf("cfg_") === 0) {
|
|
||||||
currentItem[prop+"Changed"].connect(root.pageChanged)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceEnter: Transition {
|
|
||||||
ParallelAnimation {
|
|
||||||
//OpacityAnimator when starting from 0 is buggy (it shows one frame with opacity 1)
|
|
||||||
NumberAnimation {
|
|
||||||
property: "opacity"
|
|
||||||
from: 0
|
|
||||||
to: 1
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
XAnimator {
|
|
||||||
from: pageStack.invertAnimations ? -scroll.width/3: scroll.width/3
|
|
||||||
to: 0
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
replaceExit: Transition {
|
|
||||||
ParallelAnimation {
|
|
||||||
OpacityAnimator {
|
|
||||||
from: 1
|
|
||||||
to: 0
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
XAnimator {
|
|
||||||
from: 0
|
|
||||||
to: pageStack.invertAnimations ? scroll.width/3 : -scroll.width/3
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
footer: Kirigami.NavigationTabBar {
|
||||||
id: separator
|
id: footerBar
|
||||||
Layout.fillWidth: true
|
visible: count > 1
|
||||||
Layout.preferredHeight: 1
|
height: visible ? implicitHeight : 0
|
||||||
color: Kirigami.Theme.highlightColor
|
Repeater {
|
||||||
visible: categoriesScroll.visible
|
model: root.isContainment ? globalConfigModel : undefined
|
||||||
Behavior on color {
|
delegate: configCategoryDelegate
|
||||||
ColorAnimation {
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Repeater {
|
||||||
QtControls.ScrollView {
|
model: configDialogFilterModel
|
||||||
id: categoriesScroll
|
delegate: configCategoryDelegate
|
||||||
|
}
|
||||||
Layout.fillWidth: true
|
Repeater {
|
||||||
Layout.preferredHeight: categories.implicitHeight
|
model: !root.isContainment ? globalConfigModel : undefined
|
||||||
|
delegate: configCategoryDelegate
|
||||||
visible: (configDialog.configModel ? configDialog.configModel.count : 0) + globalConfigModel.count > 1
|
|
||||||
|
|
||||||
Keys.onLeftPressed: {
|
|
||||||
var buttons = categories.children
|
|
||||||
|
|
||||||
var foundPrevious = false
|
|
||||||
for (var i = buttons.length - 1; i >= 0; --i) {
|
|
||||||
var button = buttons[i];
|
|
||||||
if (!button.hasOwnProperty("current")) {
|
|
||||||
// not a ConfigCategoryDelegate
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundPrevious) {
|
|
||||||
button.openCategory()
|
|
||||||
return
|
|
||||||
} else if (button.current) {
|
|
||||||
foundPrevious = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onRightPressed: {
|
|
||||||
var buttons = categories.children
|
|
||||||
|
|
||||||
var foundNext = false
|
|
||||||
for (var i = 0, length = buttons.length; i < length; ++i) {
|
|
||||||
var button = buttons[i];
|
|
||||||
console.log(button)
|
|
||||||
if (!button.hasOwnProperty("current")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundNext) {
|
|
||||||
button.openCategory()
|
|
||||||
return
|
|
||||||
} else if (button.current) {
|
|
||||||
foundNext = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: categories
|
|
||||||
spacing: 0
|
|
||||||
width: categoriesScroll.width
|
|
||||||
height: implicitHeight
|
|
||||||
|
|
||||||
property Item currentItem: children[1]
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: root.isContainment ? globalConfigModel : undefined
|
|
||||||
delegate: ConfigCategoryDelegate {}
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
model: configDialogFilterModel
|
|
||||||
delegate: ConfigCategoryDelegate {}
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
model: !root.isContainment ? globalConfigModel : undefined
|
|
||||||
delegate: ConfigCategoryDelegate {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//END UI components
|
//END UI components
|
||||||
|
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Controls 2.3 as QtControls
|
|
||||||
import QtQuick.Window 2.2
|
|
||||||
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
import org.kde.kquickcontrolsaddons 2.0
|
|
||||||
import org.kde.kirigami 2.5 as Kirigami
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: delegate
|
|
||||||
|
|
||||||
//BEGIN properties
|
|
||||||
implicitWidth: delegateContents.implicitWidth + 4 * PlasmaCore.Units.smallSpacing
|
|
||||||
implicitHeight: delegateContents.height + PlasmaCore.Units.smallSpacing * 4
|
|
||||||
Layout.fillWidth: true
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
property bool current: (model.kcm && pageStack.currentItem.kcm && model.kcm == pageStack.currentItem.kcm) || (model.source == pageStack.sourceFile)
|
|
||||||
//END properties
|
|
||||||
|
|
||||||
//BEGIN functions
|
|
||||||
function openCategory() {
|
|
||||||
if (current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeof(categories.currentItem) !== "undefined") {
|
|
||||||
pageStack.invertAnimations = (categories.currentItem.x > delegate.x);
|
|
||||||
categories.currentItem = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model.source) {
|
|
||||||
pageStack.sourceFile = model.source;
|
|
||||||
} else if (model.kcm) {
|
|
||||||
pageStack.sourceFile = "";
|
|
||||||
pageStack.sourceFile = Qt.resolvedUrl("ConfigurationKcmPage.qml");
|
|
||||||
pageStack.currentItem.kcm = model.kcm;
|
|
||||||
} else {
|
|
||||||
pageStack.sourceFile = "";
|
|
||||||
}
|
|
||||||
pageStack.title = model.name
|
|
||||||
}
|
|
||||||
//END functions
|
|
||||||
|
|
||||||
//BEGIN connections
|
|
||||||
onPressed: {
|
|
||||||
categoriesScroll.forceActiveFocus()
|
|
||||||
|
|
||||||
if (current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
openCategory();
|
|
||||||
}
|
|
||||||
onCurrentChanged: {
|
|
||||||
if (current) {
|
|
||||||
categories.currentItem = delegate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//END connections
|
|
||||||
|
|
||||||
//BEGIN UI components
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Kirigami.Theme.highlightColor
|
|
||||||
opacity: { // try to match Breeze style hover handling
|
|
||||||
var active = categoriesScroll.activeFocus && Window.active
|
|
||||||
if (current) {
|
|
||||||
if (active) {
|
|
||||||
return 1
|
|
||||||
} else if (delegate.containsMouse) {
|
|
||||||
return 0.6
|
|
||||||
} else {
|
|
||||||
return 0.3
|
|
||||||
}
|
|
||||||
} else if (delegate.containsMouse) {
|
|
||||||
if (active) {
|
|
||||||
return 0.3
|
|
||||||
} else {
|
|
||||||
return 0.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: delegateContents
|
|
||||||
spacing: PlasmaCore.Units.smallSpacing
|
|
||||||
width: parent.width
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
QIconItem {
|
|
||||||
id: iconItem
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
width: PlasmaCore.Units.iconSizes.medium
|
|
||||||
height: width
|
|
||||||
icon: model.icon
|
|
||||||
state: current && categoriesScroll.activeFocus ? QIconItem.SelectedState : QIconItem.DefaultState
|
|
||||||
}
|
|
||||||
|
|
||||||
QtControls.Label {
|
|
||||||
id: nameLabel
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: model.name
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
color: current && categoriesScroll.activeFocus ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//END UI components
|
|
||||||
}
|
|
||||||
|
|
||||||
72
shell/contents/configuration/ConfigurationAppletPage.qml
Normal file
72
shell/contents/configuration/ConfigurationAppletPage.qml
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.10 as Kirigami
|
||||||
|
|
||||||
|
Kirigami.ScrollablePage {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: configItem.name
|
||||||
|
|
||||||
|
required property var configItem
|
||||||
|
|
||||||
|
signal settingValueChanged()
|
||||||
|
|
||||||
|
function saveConfig() {
|
||||||
|
for (let key in plasmoid.configuration) {
|
||||||
|
if (loader.item["cfg_" + key] != undefined) {
|
||||||
|
plasmoid.configuration[key] = loader.item["cfg_" + key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ConfigurationContainmentActions.qml
|
||||||
|
if (loader.item.hasOwnProperty("saveConfig")) {
|
||||||
|
loader.item.saveConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitHeight: loader.height
|
||||||
|
|
||||||
|
padding: Kirigami.Units.largeSpacing
|
||||||
|
bottomPadding: 0
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
width: parent.width
|
||||||
|
// HACK the height of the loader is based on the implicitHeight of the content.
|
||||||
|
// Unfortunately not all content items have a sensible implicitHeight.
|
||||||
|
// If it is zero fall back to the height of its children
|
||||||
|
// Also make it at least as high as the page itself. Some existing configs assume they fill the whole space
|
||||||
|
// TODO KF6 clean this up by making all configs based on SimpleKCM/ScrollViewKCM/GridViewKCM
|
||||||
|
height: Math.max(root.availableHeight, item.implicitHeight ? item.implicitHeight : item.childrenRect.height)
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
const plasmoidConfig = plasmoid.configuration
|
||||||
|
|
||||||
|
const props = {}
|
||||||
|
for (let key in plasmoidConfig) {
|
||||||
|
props["cfg_" + key] = plasmoid.configuration[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
setSource(configItem.source, props)
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
const plasmoidConfig = plasmoid.configuration;
|
||||||
|
|
||||||
|
for (let key in plasmoidConfig) {
|
||||||
|
const changedSignal = item["cfg_" + key + "Changed"]
|
||||||
|
if (changedSignal) {
|
||||||
|
changedSignal.connect(root.settingValueChanged)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const configurationChangedSignal = item.configurationChanged
|
||||||
|
if (configurationChangedSignal) {
|
||||||
|
configurationChangedSignal.connect(root.settingValueChanged)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -136,12 +136,6 @@ ColumnLayout {
|
||||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply now")
|
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply now")
|
||||||
onClicked: saveConfig()
|
onClicked: saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: categoriesScroll //from parent scope AppletConfiguration
|
|
||||||
property: "enabled"
|
|
||||||
value: !switchContainmentWarning.visible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
||||||
73
shell/contents/configuration/ConfigurationKcmPage.qml
Normal file
73
shell/contents/configuration/ConfigurationKcmPage.qml
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
// SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
|
// SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
|
||||||
|
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Controls 2.2 as QQC2
|
||||||
|
import org.kde.kirigami 2.5 as Kirigami
|
||||||
|
|
||||||
|
Kirigami.Page {
|
||||||
|
id: container
|
||||||
|
|
||||||
|
required property QtObject kcm
|
||||||
|
required property Item internalPage
|
||||||
|
|
||||||
|
signal settingValueChanged()
|
||||||
|
|
||||||
|
title: kcm.name
|
||||||
|
topPadding: 0
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
flickable: internalPage.flickable
|
||||||
|
actions.main: internalPage.actions.main
|
||||||
|
actions.contextualActions: internalPage.contextualActions
|
||||||
|
|
||||||
|
onInternalPageChanged: {
|
||||||
|
internalPage.parent = contentItem;
|
||||||
|
internalPage.anchors.fill = contentItem;
|
||||||
|
}
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
internalPage.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
kcm.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveConfig() {
|
||||||
|
kcm.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
data: [
|
||||||
|
Connections {
|
||||||
|
target: kcm
|
||||||
|
onPagePushed: {
|
||||||
|
app.pageStack.push(configurationKcmPageComponent.createObject(app.pageStack, {"kcm": kcm, "internalPage": page}));
|
||||||
|
}
|
||||||
|
onPageRemoved: app.pageStack.pop();
|
||||||
|
},
|
||||||
|
Connections {
|
||||||
|
target: app.pageStack
|
||||||
|
onPageRemoved: {
|
||||||
|
if (kcm.needsSave) {
|
||||||
|
kcm.save()
|
||||||
|
}
|
||||||
|
if (page == container) {
|
||||||
|
page.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Connections {
|
||||||
|
target: kcm
|
||||||
|
function onNeedsSaveChanged() {
|
||||||
|
if (kcm.needsSave) {
|
||||||
|
container.settingValueChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +1,23 @@
|
||||||
/*
|
// SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||||
* SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
*
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Layouts 1.0
|
import QtQuick.Layouts 1.0
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
import QtQuick.Controls 2.3 as Controls
|
import QtQuick.Controls 2.15 as Controls
|
||||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.configuration 2.0
|
import org.kde.plasma.configuration 2.0
|
||||||
|
|
||||||
//for the "simple mode"
|
|
||||||
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
|
|
||||||
import org.kde.kquickcontrolsaddons 2.0 as Addons
|
|
||||||
import org.kde.kcm 1.1 as KCM
|
|
||||||
|
|
||||||
AppletConfiguration {
|
AppletConfiguration {
|
||||||
id: root
|
id: root
|
||||||
isContainment: true
|
isContainment: true
|
||||||
|
|
||||||
internalDialog.visible: false
|
appComponent.visible: false
|
||||||
internalDialog.width: root.width < root.height ? root.width : Math.min(root.width, Math.max(internalDialog.implicitWidth, PlasmaCore.Units.gridUnit * 45))
|
appComponent.width: root.width < root.height ? root.width : Math.min(root.width, Math.max(appComponent.implicitWidth, PlasmaCore.Units.gridUnit * 45))
|
||||||
internalDialog.height: Math.min(root.height, Math.max(internalDialog.implicitHeight, PlasmaCore.Units.gridUnit * 29))
|
appComponent.height: Math.min(root.height, Math.max(appComponent.implicitHeight, PlasmaCore.Units.gridUnit * 29))
|
||||||
|
|
||||||
readonly property bool horizontal: root.width > root.height
|
readonly property bool horizontal: root.width > root.height
|
||||||
|
|
||||||
|
|
@ -40,126 +34,74 @@ AppletConfiguration {
|
||||||
}
|
}
|
||||||
//END model
|
//END model
|
||||||
|
|
||||||
Controls.Drawer {
|
Loader {
|
||||||
id: imageWallpaperDrawer
|
id: wallpaperSelectorLoader
|
||||||
edge: root.horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
asynchronous: true
|
||||||
visible: true
|
active: true
|
||||||
dragMargin: 0
|
|
||||||
|
sourceComponent: WallpaperSelector {
|
||||||
onClosed: {
|
visible: false
|
||||||
if (!root.internalDialog.visible) {
|
horizontal: root.horizontal
|
||||||
configDialog.close()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
z: -1
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: configDialog.close()
|
||||||
|
|
||||||
|
Controls.Control {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
leftPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
rightPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
topPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
bottomPadding: PlasmaCore.Units.largeSpacing
|
||||||
|
|
||||||
|
NumberAnimation on opacity {
|
||||||
|
id: opacityAnim
|
||||||
|
running: true
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
duration: PlasmaCore.Units.longDuration
|
||||||
}
|
}
|
||||||
}
|
|
||||||
onOpened: {
|
background: PlasmaCore.FrameSvgItem {
|
||||||
wallpapersView.forceActiveFocus()
|
enabledBorders: PlasmaCore.FrameSvg.AllBorders
|
||||||
}
|
imagePath: "widgets/background"
|
||||||
implicitWidth: PlasmaCore.Units.gridUnit * 10
|
|
||||||
implicitHeight: PlasmaCore.Units.gridUnit * 8
|
|
||||||
width: root.horizontal ? implicitWidth : root.width
|
|
||||||
height: root.horizontal ? root.height : implicitHeight
|
|
||||||
Wallpaper.ImageBackend {
|
|
||||||
id: imageWallpaper
|
|
||||||
}
|
|
||||||
background: null
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: wallpapersView
|
|
||||||
anchors.fill: parent
|
|
||||||
orientation: root.horizontal ? ListView.Vertical : ListView.Horizontal
|
|
||||||
keyNavigationEnabled: true
|
|
||||||
highlightFollowsCurrentItem: true
|
|
||||||
snapMode: ListView.SnapToItem
|
|
||||||
model: imageWallpaper.wallpaperModel
|
|
||||||
onCountChanged: currentIndex = Math.min(model.indexOf(configDialog.wallpaperConfiguration["Image"]), model.rowCount()-1)
|
|
||||||
footer: Controls.Control {
|
|
||||||
z: 999
|
|
||||||
width: root.horizontal ? parent.width : implicitWidth
|
|
||||||
height: root.horizontal ? implicitHeight : parent.height
|
|
||||||
leftPadding: PlasmaCore.Units.gridUnit
|
|
||||||
topPadding: PlasmaCore.Units.gridUnit
|
|
||||||
rightPadding: PlasmaCore.Units.gridUnit
|
|
||||||
bottomPadding: PlasmaCore.Units.gridUnit
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
Controls.Button {
|
|
||||||
icon.name: "configure"
|
|
||||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Customize...")
|
|
||||||
onClicked: {
|
|
||||||
print(wallpapersView.currentIndex)
|
|
||||||
internalDialog.visible = true;
|
|
||||||
imageWallpaperDrawer.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
background: Rectangle {
|
|
||||||
color: Qt.rgba (0, 0, 0, 0.3)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
headerPositioning: ListView.PullBackHeader
|
|
||||||
delegate: Controls.ItemDelegate {
|
contentItem: RowLayout {
|
||||||
width: root.horizontal ? parent.width : height * (root.Screen.width / root.Screen.height)
|
PlasmaComponents3.Button {
|
||||||
height: root.horizontal ? width / (root.Screen.width / root.Screen.height) : parent.height
|
Layout.alignment: Qt.AlignRight
|
||||||
padding: wallpapersView.currentIndex === index ? PlasmaCore.Units.gridUnit / 4 : PlasmaCore.Units.gridUnit / 2
|
Layout.preferredHeight: PlasmaCore.Units.gridUnit * 4
|
||||||
leftPadding: padding
|
Layout.preferredWidth: PlasmaCore.Units.gridUnit * 8
|
||||||
topPadding: padding
|
|
||||||
rightPadding: padding
|
display: PlasmaComponents3.ToolButton.TextUnderIcon
|
||||||
bottomPadding: padding
|
icon.name: "viewimage"
|
||||||
Behavior on padding {
|
icon.width: PlasmaCore.Units.iconSizes.medium
|
||||||
NumberAnimation {
|
icon.height: PlasmaCore.Units.iconSizes.medium
|
||||||
duration: PlasmaCore.Units.longDuration
|
text: i18n("Change Wallpaper")
|
||||||
easing.type: Easing.InOutQuad
|
onClicked: {
|
||||||
}
|
opacityAnim.from = 1;
|
||||||
}
|
opacityAnim.to = 0;
|
||||||
|
opacityAnim.restart();
|
||||||
property bool isCurrent: configDialog.wallpaperConfiguration["Image"] == model.path
|
wallpaperSelectorLoader.item.open();
|
||||||
onIsCurrentChanged: {
|
|
||||||
if (isCurrent) {
|
|
||||||
wallpapersView.currentIndex = index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
z: wallpapersView.currentIndex === index ? 2 : 0
|
PlasmaComponents3.Button {
|
||||||
contentItem: Item {
|
Layout.alignment: Qt.AlignLeft
|
||||||
Addons.QIconItem {
|
Layout.preferredHeight: PlasmaCore.Units.gridUnit * 4
|
||||||
anchors.centerIn: parent
|
Layout.preferredWidth: PlasmaCore.Units.gridUnit * 8
|
||||||
width: PlasmaCore.Units.iconSizes.large
|
|
||||||
height: width
|
display: PlasmaComponents3.ToolButton.TextUnderIcon
|
||||||
icon: "view-preview"
|
icon.name: "configure"
|
||||||
visible: !walliePreview.visible
|
icon.width: PlasmaCore.Units.iconSizes.medium
|
||||||
}
|
icon.height: PlasmaCore.Units.iconSizes.medium
|
||||||
|
text: i18n("Configure")
|
||||||
Addons.QPixmapItem {
|
onClicked: {
|
||||||
id: walliePreview
|
appComponent.visible = true;
|
||||||
anchors.fill: parent
|
wallpaperSelectorLoader.item.close()
|
||||||
visible: model.screenshot != null
|
|
||||||
smooth: true
|
|
||||||
pixmap: model.screenshot
|
|
||||||
fillMode: Image.PreserveAspectCrop
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
configDialog.currentWallpaper = "org.kde.image";
|
|
||||||
configDialog.wallpaperConfiguration["Image"] = model.path;
|
|
||||||
configDialog.applyWallpaper()
|
|
||||||
}
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
clicked();
|
|
||||||
}
|
|
||||||
background: Item {
|
|
||||||
Rectangle {
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: wallpapersView.currentIndex === index ? 0 : PlasmaCore.Units.gridUnit / 4
|
|
||||||
Behavior on margins {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: PlasmaCore.Units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
radius: PlasmaCore.Units.gridUnit / 4
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
120
shell/contents/configuration/WallpaperSelector.qml
Normal file
120
shell/contents/configuration/WallpaperSelector.qml
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
// SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||||
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Controls 2.3 as Controls
|
||||||
|
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
|
||||||
|
|
||||||
|
import org.kde.plasma.wallpapers.image 2.0 as Wallpaper
|
||||||
|
import org.kde.kquickcontrolsaddons 2.0 as Addons
|
||||||
|
import org.kde.kcm 1.1 as KCM
|
||||||
|
|
||||||
|
Controls.Drawer {
|
||||||
|
id: imageWallpaperDrawer
|
||||||
|
edge: root.horizontal ? Qt.LeftEdge : Qt.BottomEdge
|
||||||
|
dragMargin: 0
|
||||||
|
|
||||||
|
required property bool horizontal
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!root.appComponent.visible) {
|
||||||
|
configDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onOpened: {
|
||||||
|
wallpapersView.forceActiveFocus()
|
||||||
|
}
|
||||||
|
implicitWidth: PlasmaCore.Units.gridUnit * 10
|
||||||
|
implicitHeight: PlasmaCore.Units.gridUnit * 8
|
||||||
|
width: imageWallpaperDrawer.horizontal ? implicitWidth : root.width
|
||||||
|
height: imageWallpaperDrawer.horizontal ? root.height : implicitHeight
|
||||||
|
|
||||||
|
Wallpaper.ImageBackend {
|
||||||
|
id: imageWallpaper
|
||||||
|
}
|
||||||
|
|
||||||
|
background: null
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: wallpapersView
|
||||||
|
anchors.fill: parent
|
||||||
|
orientation: imageWallpaperDrawer.horizontal ? ListView.Vertical : ListView.Horizontal
|
||||||
|
keyNavigationEnabled: true
|
||||||
|
highlightFollowsCurrentItem: true
|
||||||
|
snapMode: ListView.SnapToItem
|
||||||
|
model: imageWallpaper.wallpaperModel
|
||||||
|
onCountChanged: currentIndex = Math.min(model.indexOf(configDialog.wallpaperConfiguration["Image"]), model.rowCount()-1)
|
||||||
|
headerPositioning: ListView.PullBackHeader
|
||||||
|
delegate: Controls.ItemDelegate {
|
||||||
|
width: imageWallpaperDrawer.horizontal ? parent.width : height * (root.Screen.width / root.Screen.height)
|
||||||
|
height: imageWallpaperDrawer.horizontal ? width / (root.Screen.width / root.Screen.height) : parent.height
|
||||||
|
padding: wallpapersView.currentIndex === index ? PlasmaCore.Units.gridUnit / 4 : PlasmaCore.Units.gridUnit / 2
|
||||||
|
leftPadding: padding
|
||||||
|
topPadding: padding
|
||||||
|
rightPadding: padding
|
||||||
|
bottomPadding: padding
|
||||||
|
Behavior on padding {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: PlasmaCore.Units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool isCurrent: configDialog.wallpaperConfiguration["Image"] == model.path
|
||||||
|
onIsCurrentChanged: {
|
||||||
|
if (isCurrent) {
|
||||||
|
wallpapersView.currentIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
z: wallpapersView.currentIndex === index ? 2 : 0
|
||||||
|
contentItem: Item {
|
||||||
|
Addons.QIconItem {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: PlasmaCore.Units.iconSizes.large
|
||||||
|
height: width
|
||||||
|
icon: "view-preview"
|
||||||
|
visible: !walliePreview.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
Addons.QPixmapItem {
|
||||||
|
id: walliePreview
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: model.screenshot != null
|
||||||
|
smooth: true
|
||||||
|
pixmap: model.screenshot
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
configDialog.currentWallpaper = "org.kde.image";
|
||||||
|
configDialog.wallpaperConfiguration["Image"] = model.path;
|
||||||
|
configDialog.applyWallpaper()
|
||||||
|
}
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
clicked();
|
||||||
|
}
|
||||||
|
background: Item {
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: wallpapersView.currentIndex === index ? 0 : PlasmaCore.Units.gridUnit / 4
|
||||||
|
Behavior on margins {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: PlasmaCore.Units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radius: PlasmaCore.Units.gridUnit / 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue