mirror of
https://gitgud.io/wackyideas/aerothemeplasma.git
synced 2024-08-15 00:43:43 +00:00
Very early KDE 6 release.
This commit is contained in:
parent
7cc4ccabbc
commit
686046d4f7
6272 changed files with 140920 additions and 529657 deletions
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
|
||||
SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.kcmutils as KCM
|
||||
|
||||
/**
|
||||
* A copy of Kirigami.AboutPage adapted to KPluginMetadata instead of KAboutData
|
||||
*/
|
||||
KCM.SimpleKCM {
|
||||
id: page
|
||||
title: i18n("About")
|
||||
|
||||
property var metaData: Plasmoid.metaData
|
||||
|
||||
Component {
|
||||
id: personDelegate
|
||||
|
||||
RowLayout {
|
||||
height: implicitHeight + (Kirigami.Units.smallSpacing * 2)
|
||||
|
||||
spacing: Kirigami.Units.smallSpacing * 2
|
||||
Kirigami.Icon {
|
||||
width: Kirigami.Units.iconSizes.smallMedium
|
||||
height: width
|
||||
source: "user"
|
||||
}
|
||||
QQC2.Label {
|
||||
text: modelData.name
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
Row {
|
||||
// Group action buttons together
|
||||
spacing: 0
|
||||
QQC2.ToolButton {
|
||||
visible: modelData.emailAddress
|
||||
width: height
|
||||
icon.name: "mail-sent"
|
||||
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Send an email to %1", modelData.emailAddress)
|
||||
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.text: text
|
||||
|
||||
onClicked: Qt.openUrlExternally("mailto:%1".arg(modelData.emailAddress))
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
visible: modelData.webAddress
|
||||
width: height
|
||||
icon.name: "globe"
|
||||
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
text: i18ndc("plasma_shell_org.kde.plasma.desktop", "@info:tooltip %1 url", "Open website %1", modelData.webAddress)
|
||||
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: hovered
|
||||
QQC2.ToolTip.text: modelData.webAddress
|
||||
|
||||
onClicked: Qt.openUrlExternally(modelData.webAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: licenseComponent
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
property alias text: licenseLabel.text
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
Kirigami.SelectableLabel {
|
||||
id: licenseLabel
|
||||
implicitWidth: Math.max(Kirigami.Units.gridUnit * 25, Math.round(page.width / 2), contentWidth)
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Component.onCompleted: open();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: childrenRect.height
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.rowSpan: 2
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
||||
Layout.preferredWidth: height
|
||||
Layout.maximumWidth: page.width / 3;
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
source: page.metaData.iconName || page.metaData.pluginId
|
||||
fallback: "application-x-plasma"
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
text: page.metaData.name + " " + page.metaData.version
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 15
|
||||
level: 2
|
||||
wrapMode: Text.WordWrap
|
||||
text: page.metaData.description
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Copyright")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.Label {
|
||||
text: page.metaData.copyrightText
|
||||
textFormat: Text.PlainText
|
||||
visible: text.length > 0
|
||||
}
|
||||
Kirigami.UrlButton {
|
||||
url: page.metaData.website
|
||||
visible: url.length > 0
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
QQC2.Label {
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "License:")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
Kirigami.LinkButton {
|
||||
text: page.metaData.license
|
||||
Accessible.description: i18ndc("plasma_shell_org.kde.plasma.desktop", "@info:whatsthis", "View license text")
|
||||
onClicked: {
|
||||
licenseComponent.incubateObject(page.Window.window.contentItem, {
|
||||
"text": page.metaData.licenseText,
|
||||
"title": page.metaData.license,
|
||||
}, Qt.Asynchronous);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Authors")
|
||||
textFormat: Text.PlainText
|
||||
visible: page.metaData.authors.length > 0
|
||||
}
|
||||
Repeater {
|
||||
model: page.metaData.authors
|
||||
delegate: personDelegate
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
height: visible ? implicitHeight : 0
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Credits")
|
||||
textFormat: Text.PlainText
|
||||
visible: repCredits.count > 0
|
||||
}
|
||||
Repeater {
|
||||
id: repCredits
|
||||
model: page.metaData.otherContributors
|
||||
delegate: personDelegate
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
height: visible ? implicitHeight : 0
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Translators")
|
||||
textFormat: Text.PlainText
|
||||
visible: repTranslators.count > 0
|
||||
}
|
||||
Repeater {
|
||||
id: repTranslators
|
||||
model: page.metaData.translators
|
||||
delegate: personDelegate
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
icon.name: "tools-report-bug"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Report a Bug…")
|
||||
|
||||
visible: page.metaData.bugReportUrl.length > 0
|
||||
|
||||
onClicked: Qt.openUrlExternally(page.metaData.bugReportUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,514 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
|
||||
SPDX-FileCopyrightText: 2022-2023 ivan tkachenko <me@ratijas.tk>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kitemmodels 1.0 as KItemModels
|
||||
import org.kde.plasma.configuration 2.0
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
implicitWidth: Kirigami.Units.gridUnit * 40
|
||||
implicitHeight: Kirigami.Units.gridUnit * 30
|
||||
|
||||
Layout.minimumWidth: Kirigami.Units.gridUnit * 30
|
||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 21
|
||||
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
|
||||
property bool isContainment: false
|
||||
|
||||
property ConfigModel globalConfigModel: globalAppletConfigModel
|
||||
|
||||
property url currentSource
|
||||
|
||||
function closing() {
|
||||
if (applyButton.enabled) {
|
||||
messageDialog.item = null;
|
||||
messageDialog.open();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function saveConfig() {
|
||||
const config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
config.keys().forEach(key => {
|
||||
const cfgKey = "cfg_" + key;
|
||||
if (cfgKey in app.pageStack.currentItem) {
|
||||
config[key] = app.pageStack.currentItem[cfgKey];
|
||||
}
|
||||
})
|
||||
|
||||
plasmoid.configuration.writeConfig();
|
||||
|
||||
// For ConfigurationContainmentActions.qml
|
||||
if (app.pageStack.currentItem.hasOwnProperty("saveConfig")) {
|
||||
app.pageStack.currentItem.saveConfig()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: configDialog
|
||||
function onClosing(event) {
|
||||
event.accepted = closing();
|
||||
}
|
||||
}
|
||||
|
||||
ConfigModel {
|
||||
id: globalAppletConfigModel
|
||||
ConfigCategory {
|
||||
name: i18nd("plasma_shell_org.kde.plasma.desktop", "Keyboard Shortcuts")
|
||||
icon: "preferences-desktop-keyboard"
|
||||
source: Qt.resolvedUrl("ConfigurationShortcuts.qml")
|
||||
}
|
||||
}
|
||||
|
||||
KItemModels.KSortFilterProxyModel {
|
||||
id: configDialogFilterModel
|
||||
sourceModel: configDialog.configModel
|
||||
filterRowCallback: (row, parent) => {
|
||||
return sourceModel.data(sourceModel.index(row, 0), ConfigModel.VisibleRole);
|
||||
}
|
||||
}
|
||||
|
||||
function settingValueChanged() {
|
||||
applyButton.enabled = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Component {
|
||||
id: configurationKcmPageComponent
|
||||
ConfigurationKcmPage {
|
||||
}
|
||||
}
|
||||
|
||||
function open(item) {
|
||||
app.isAboutPage = false;
|
||||
root.currentSource = item.source
|
||||
|
||||
if (item.source) {
|
||||
app.isAboutPage = item.source === Qt.resolvedUrl("AboutPlugin.qml");
|
||||
|
||||
if (isContainment) {
|
||||
pushReplace(Qt.resolvedUrl("ConfigurationAppletPage.qml"), {configItem: item});
|
||||
} else {
|
||||
|
||||
const config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
const props = {
|
||||
"title": item.name
|
||||
};
|
||||
|
||||
config.keys().forEach(key => {
|
||||
props["cfg_" + key] = config[key];
|
||||
});
|
||||
|
||||
pushReplace(item.source, props);
|
||||
}
|
||||
|
||||
} else if (item.kcm) {
|
||||
pushReplace(configurationKcmPageComponent, {kcm: item.kcm, internalPage: item.kcm.mainUi});
|
||||
} else {
|
||||
app.pageStack.pop();
|
||||
}
|
||||
|
||||
applyButton.enabled = false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: app.currentConfigPage
|
||||
|
||||
function onSettingValueChanged() {
|
||||
applyButton.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: app.pageStack
|
||||
|
||||
function onCurrentItemChanged() {
|
||||
if (app.pageStack.currentItem !== null && !isContainment) {
|
||||
const config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
config.keys().forEach(key => {
|
||||
const changedSignal = app.pageStack.currentItem["cfg_" + key + "Changed"];
|
||||
if (changedSignal) {
|
||||
changedSignal.connect(() => root.settingValueChanged());
|
||||
}
|
||||
});
|
||||
|
||||
const configurationChangedSignal = app.pageStack.currentItem.configurationChanged;
|
||||
if (configurationChangedSignal) {
|
||||
configurationChangedSignal.connect(() => root.settingValueChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// if we are a containment then the first item will be ConfigurationContainmentAppearance
|
||||
// if the applet does not have own configs then the first item will be Shortcuts
|
||||
if (isContainment || !configDialog.configModel || configDialog.configModel.count === 0) {
|
||||
open(root.globalConfigModel.get(0))
|
||||
} else {
|
||||
open(configDialog.configModel.get(0))
|
||||
}
|
||||
}
|
||||
|
||||
function applicationWindow() {
|
||||
return app;
|
||||
}
|
||||
|
||||
|
||||
QQC2.ScrollView {
|
||||
id: categoriesScroll
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: Kirigami.Units.gridUnit * 10
|
||||
contentWidth: availableWidth
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Kirigami.Theme.inherit: false
|
||||
activeFocusOnTab: true
|
||||
focus: true
|
||||
Accessible.role: Accessible.MenuBar
|
||||
background: Rectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "rsrc/bg.png"
|
||||
anchors.fill: parent
|
||||
smooth: true
|
||||
}
|
||||
Keys.onUpPressed: event => {
|
||||
const buttons = categories.children
|
||||
|
||||
let foundPrevious = false
|
||||
for (let i = buttons.length - 1; i >= 0; --i) {
|
||||
const button = buttons[i];
|
||||
if (!button.hasOwnProperty("highlighted")) {
|
||||
// not a ConfigCategoryDelegate
|
||||
continue;
|
||||
}
|
||||
|
||||
if (foundPrevious) {
|
||||
categories.openCategory(button.item)
|
||||
categoriesScroll.forceActiveFocus(Qt.TabFocusReason)
|
||||
return
|
||||
} else if (button.highlighted) {
|
||||
foundPrevious = true
|
||||
}
|
||||
}
|
||||
|
||||
event.accepted = false
|
||||
}
|
||||
|
||||
Keys.onDownPressed: event => {
|
||||
const buttons = categories.children
|
||||
|
||||
let foundNext = false
|
||||
for (let i = 0, length = buttons.length; i < length; ++i) {
|
||||
const button = buttons[i];
|
||||
if (!button.hasOwnProperty("highlighted")) {
|
||||
continue;
|
||||
}
|
||||
if (foundNext) {
|
||||
categories.openCategory(button.item)
|
||||
categoriesScroll.forceActiveFocus(Qt.TabFocusReason)
|
||||
return
|
||||
} else if (button.highlighted) {
|
||||
foundNext = true
|
||||
}
|
||||
}
|
||||
|
||||
event.accepted = false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: categories
|
||||
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
width: categoriesScroll.contentWidth
|
||||
focus: true
|
||||
|
||||
function openCategory(item) {
|
||||
if (applyButton.enabled) {
|
||||
messageDialog.item = item;
|
||||
messageDialog.open();
|
||||
return;
|
||||
}
|
||||
open(item)
|
||||
}
|
||||
|
||||
Item {
|
||||
id: paddingItem
|
||||
Layout.preferredHeight: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
Component {
|
||||
id: categoryDelegate
|
||||
|
||||
RowLayout {
|
||||
id: delegate
|
||||
|
||||
required property var model
|
||||
property var item: model
|
||||
|
||||
Accessible.role: Accessible.MenuItem
|
||||
Accessible.name: model.name
|
||||
Accessible.description: i18nd("plasma_shell_org.kde.plasma.desktop", "Open configuration page")
|
||||
Accessible.onPressAction: ma.clicked(null)
|
||||
|
||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
property bool highlighted: {
|
||||
if (app.pageStack.currentItem) {
|
||||
if (model.kcm && app.pageStack.currentItem.kcm) {
|
||||
return model.kcm == app.pageStack.currentItem.kcm
|
||||
} else {
|
||||
return root.currentSource == model.source
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
implicitWidth: Kirigami.Units.iconSizes.small
|
||||
implicitHeight: Kirigami.Units.iconSizes.small
|
||||
source: delegate.model.icon
|
||||
}
|
||||
Text {
|
||||
color: ma.containsMouse ? "#074ae5" : "#151c55"
|
||||
font.underline: ma.containsMouse
|
||||
font.bold: parent.highlighted || delegate.focus
|
||||
text: parent.model.name
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
MouseArea {
|
||||
id: ma
|
||||
anchors.fill: parent
|
||||
enabled: !highlighted
|
||||
hoverEnabled: true
|
||||
onClicked: categories.openCategory(model);
|
||||
cursorShape: delegate.highlighted ? Qt.ArrowCursor : Qt.PointingHandCursor
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ConfigCategoryDelegate {
|
||||
id: delegate
|
||||
onActivated: categories.openCategory(model);
|
||||
highlighted: {
|
||||
if (app.pageStack.currentItem) {
|
||||
if (model.kcm && app.pageStack.currentItem.kcm) {
|
||||
return model.kcm == app.pageStack.currentItem.kcm
|
||||
} else {
|
||||
return root.currentSource == model.source
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
item: model
|
||||
}*/
|
||||
}
|
||||
|
||||
Repeater {
|
||||
Layout.fillWidth: true
|
||||
model: root.isContainment ? globalConfigModel : undefined
|
||||
delegate: categoryDelegate
|
||||
}
|
||||
Repeater {
|
||||
Layout.fillWidth: true
|
||||
model: configDialogFilterModel
|
||||
delegate: categoryDelegate
|
||||
}
|
||||
Repeater {
|
||||
Layout.fillWidth: true
|
||||
model: !root.isContainment ? globalConfigModel : undefined
|
||||
delegate: categoryDelegate
|
||||
}
|
||||
Repeater {
|
||||
Layout.fillWidth: true
|
||||
model: ConfigModel {
|
||||
ConfigCategory{
|
||||
name: i18nd("plasma_shell_org.kde.plasma.desktop", "About")
|
||||
icon: "help-about"
|
||||
source: Qt.resolvedUrl("AboutPlugin.qml")
|
||||
}
|
||||
}
|
||||
delegate: categoryDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
z: 1
|
||||
}
|
||||
Kirigami.Separator {
|
||||
id: verticalSeparator
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: categoriesScroll.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
z: 1
|
||||
}
|
||||
|
||||
Kirigami.ApplicationItem {
|
||||
id: app
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: verticalSeparator.right
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.Breadcrumb
|
||||
wideScreen: true
|
||||
pageStack.globalToolBar.separatorVisible: bottomSeparator.visible
|
||||
pageStack.globalToolBar.colorSet: Kirigami.Theme.View
|
||||
property var currentConfigPage: null
|
||||
onCurrentConfigPageChanged: {
|
||||
if(currentConfigPage) {
|
||||
currentConfigPage.Kirigami.Theme.colorSet = Kirigami.Theme.View
|
||||
}
|
||||
}
|
||||
property bool isAboutPage: false
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: messageDialog
|
||||
property var item
|
||||
title: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply Settings")
|
||||
subtitle: 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: Kirigami.Dialog.Apply | Kirigami.Dialog.Discard | Kirigami.Dialog.Cancel
|
||||
onApplied: {
|
||||
applyAction.trigger()
|
||||
discarded();
|
||||
}
|
||||
onDiscarded: {
|
||||
if (item) {
|
||||
root.open(item);
|
||||
messageDialog.close();
|
||||
} else {
|
||||
applyButton.enabled = false;
|
||||
configDialog.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: QQC2.Pane {
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: RowLayout {
|
||||
id: buttonsRow
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
icon.name: "dialog-ok"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "OK")
|
||||
onClicked: acceptAction.trigger()
|
||||
KeyNavigation.tab: categories
|
||||
}
|
||||
QQC2.Button {
|
||||
id: applyButton
|
||||
enabled: false
|
||||
icon.name: "dialog-ok-apply"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply")
|
||||
visible: !app.isAboutPage && app.pageStack.currentItem && (!app.pageStack.currentItem.kcm || app.pageStack.currentItem.kcm.buttons & 4) // 4 = Apply button
|
||||
onClicked: applyAction.trigger()
|
||||
}
|
||||
QQC2.Button {
|
||||
icon.name: "dialog-cancel"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Cancel")
|
||||
onClicked: cancelAction.trigger()
|
||||
visible: !app.isAboutPage
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
Kirigami.Separator {
|
||||
id: bottomSeparator
|
||||
visible: app.pageStack.currentItem
|
||||
&& app.pageStack.currentItem.flickable
|
||||
&& !(app.pageStack.currentItem.flickable.atYBeginning
|
||||
&& app.pageStack.currentItem.flickable.atYEnd)
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Action {
|
||||
id: acceptAction
|
||||
onTriggered: {
|
||||
applyAction.trigger();
|
||||
configDialog.close();
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Action {
|
||||
id: applyAction
|
||||
onTriggered: {
|
||||
if (isContainment) {
|
||||
app.pageStack.get(0).saveConfig()
|
||||
} else {
|
||||
root.saveConfig()
|
||||
}
|
||||
|
||||
applyButton.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Action {
|
||||
id: cancelAction
|
||||
onTriggered: {
|
||||
if (root.closing()) {
|
||||
configDialog.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: acceptAction.trigger();
|
||||
Keys.onEscapePressed: cancelAction.trigger();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@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 QQC2
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import org.kde.kquickcontrolsaddons 2.0
|
||||
import org.kde.kirigami 2.5 as Kirigami
|
||||
|
||||
QQC2.ItemDelegate {
|
||||
id: delegate
|
||||
|
||||
signal activated()
|
||||
|
||||
//BEGIN properties
|
||||
Layout.fillWidth: true
|
||||
hoverEnabled: true
|
||||
|
||||
Accessible.role: Accessible.MenuItem
|
||||
Accessible.name: model.name
|
||||
Accessible.description: i18nd("plasma_shell_org.kde.plasma.desktop", "Open configuration page")
|
||||
Accessible.onPressAction: delegate.clicked()
|
||||
|
||||
property var item
|
||||
//END properties
|
||||
|
||||
//BEGIN connections
|
||||
onClicked: {
|
||||
if (highlighted) {
|
||||
return;
|
||||
}
|
||||
|
||||
activated()
|
||||
}
|
||||
//END connections
|
||||
|
||||
//BEGIN UI components
|
||||
contentItem: ColumnLayout {
|
||||
id: delegateContents
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: Kirigami.Units.iconSizes.medium
|
||||
implicitHeight: Kirigami.Units.iconSizes.medium
|
||||
source: model.icon
|
||||
selected: Window.active && (delegate.highlighted || delegate.pressed)
|
||||
}
|
||||
|
||||
QQC2.Label {
|
||||
id: nameLabel
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
text: model.name
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Window.active && (delegate.highlighted || delegate.pressed) ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
|
||||
font.bold: delegate.highlighted && delegate.parent.activeFocus
|
||||
Accessible.ignored: true
|
||||
}
|
||||
}
|
||||
//END UI components
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import org.kde.plasma.plasmoid 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() {
|
||||
const config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
config.keys().forEach(key => {
|
||||
const cfgKey = "cfg_" + key;
|
||||
if (cfgKey in loader.item) {
|
||||
config[key] = loader.item[cfgKey];
|
||||
}
|
||||
})
|
||||
|
||||
Plasmoid.configuration.writeConfig();
|
||||
|
||||
// For ConfigurationContainmentActions.qml
|
||||
if (loader.item.hasOwnProperty("saveConfig")) {
|
||||
loader.item.saveConfig()
|
||||
}
|
||||
}
|
||||
|
||||
implicitHeight: loader.height
|
||||
|
||||
padding: configItem.includeMargins ? Kirigami.Units.largeSpacing : 0
|
||||
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 config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
const props = {};
|
||||
|
||||
config.keys().forEach(key => {
|
||||
props["cfg_" + key] = config[key];
|
||||
});
|
||||
|
||||
setSource(configItem.source, props);
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
const config = Plasmoid.configuration; // type: KConfigPropertyMap
|
||||
|
||||
config.keys().forEach(key => {
|
||||
const changedSignal = item["cfg_" + key + "Changed"];
|
||||
if (changedSignal) {
|
||||
changedSignal.connect(() => root.settingValueChanged());
|
||||
}
|
||||
});
|
||||
|
||||
const configurationChangedSignal = item.configurationChanged;
|
||||
if (configurationChangedSignal) {
|
||||
configurationChangedSignal.connect(() => root.settingValueChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls 2.3 as QQC2
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal configurationChanged
|
||||
implicitWidth: mainColumn.implicitWidth
|
||||
implicitHeight: mainColumn.implicitHeight
|
||||
|
||||
property var prettyStrings: {
|
||||
"LeftButton": i18nd("plasma_shell_org.kde.plasma.desktop", "Left-Button"),
|
||||
"RightButton": i18nd("plasma_shell_org.kde.plasma.desktop", "Right-Button"),
|
||||
"MiddleButton": i18nd("plasma_shell_org.kde.plasma.desktop", "Middle-Button"),
|
||||
"BackButton": i18nd("plasma_shell_org.kde.plasma.desktop", "Back-Button"),
|
||||
"ForwardButton": i18nd("plasma_shell_org.kde.plasma.desktop", "Forward-Button"),
|
||||
|
||||
"wheel:Vertical": i18nd("plasma_shell_org.kde.plasma.desktop", "Vertical-Scroll"),
|
||||
"wheel:Horizontal": i18nd("plasma_shell_org.kde.plasma.desktop", "Horizontal-Scroll"),
|
||||
|
||||
"ShiftModifier": i18nd("plasma_shell_org.kde.plasma.desktop", "Shift"),
|
||||
"ControlModifier": i18nd("plasma_shell_org.kde.plasma.desktop", "Ctrl"),
|
||||
"AltModifier": i18nd("plasma_shell_org.kde.plasma.desktop", "Alt"),
|
||||
"MetaModifier": i18nd("plasma_shell_org.kde.plasma.desktop", "Meta")
|
||||
}
|
||||
|
||||
function saveConfig() {
|
||||
configDialog.currentContainmentActionsModel.save();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: configDialog.currentContainmentActionsModel
|
||||
function onConfigurationChanged() {
|
||||
root.configurationChanged()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: aboutComponent
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: internalAboutDialog
|
||||
|
||||
property alias metaData: aboutPluginPage.metaData
|
||||
|
||||
width: Math.round(root.width * 0.8)
|
||||
onClosed: destroy()
|
||||
|
||||
AboutPlugin {
|
||||
id: aboutPluginPage
|
||||
metaData: internalAboutDialog.metaData
|
||||
}
|
||||
|
||||
Component.onCompleted: open();
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: mainColumn
|
||||
flow: GridLayout.TopToBottom
|
||||
y: 25
|
||||
width: parent.width
|
||||
|
||||
Repeater {
|
||||
id: actionsRepeater
|
||||
model: configDialog.currentContainmentActionsModel
|
||||
|
||||
MouseEventInputButton {
|
||||
Layout.column: 0
|
||||
Layout.row: index
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: implicitWidth
|
||||
defaultText: {
|
||||
var splitAction = model.action.split(';');
|
||||
|
||||
var button = splitAction[0];
|
||||
var modifiers = (splitAction[1] || "").split('|').filter(function (item) {
|
||||
return item !== "NoModifier";
|
||||
});
|
||||
|
||||
var parts = modifiers;
|
||||
modifiers.push(button);
|
||||
|
||||
return parts.map(function (item) {
|
||||
return prettyStrings[item] || item;
|
||||
}).join(i18ndc("plasma_shell_org.kde.plasma.desktop", "Concatenation sign for shortcuts, e.g. Ctrl+Shift", "+"));
|
||||
}
|
||||
eventString: model.action
|
||||
onEventStringChanged: {
|
||||
configDialog.currentContainmentActionsModel.update(index, eventString, model.pluginName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: configDialog.currentContainmentActionsModel
|
||||
|
||||
QQC2.ComboBox {
|
||||
id: pluginsCombo
|
||||
// "index" argument of onActivated shadows the model index
|
||||
readonly property int pluginIndex: index
|
||||
Layout.fillWidth: true
|
||||
Layout.column: 1
|
||||
Layout.row: index
|
||||
// both MouseEventInputButton and this ComboBox have fillWidth for a uniform layout
|
||||
// however, their implicit sizes is taken into account and they compete against
|
||||
// each other for available space. By setting an insane preferredWidth we give
|
||||
// ComboBox a greater share of the available space
|
||||
Layout.preferredWidth: 9000
|
||||
model: configDialog.containmentActionConfigModel
|
||||
textRole: "name"
|
||||
property bool initialized: false
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < configDialog.containmentActionConfigModel.count; ++i) {
|
||||
if (configDialog.containmentActionConfigModel.get(i).pluginName === pluginName) {
|
||||
pluginsCombo.currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pluginsCombo.initialized = true;
|
||||
}
|
||||
onActivated: {
|
||||
if (initialized) {
|
||||
var newPluginName = configDialog.containmentActionConfigModel.get(index).pluginName;
|
||||
if (newPluginName !== pluginName) {
|
||||
configDialog.currentContainmentActionsModel.update(pluginIndex, action, newPluginName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: configDialog.currentContainmentActionsModel
|
||||
|
||||
RowLayout {
|
||||
Layout.column: 2
|
||||
Layout.row: index
|
||||
|
||||
QQC2.Button {
|
||||
icon.name: "configure"
|
||||
width: height
|
||||
enabled: model.hasConfigurationInterface
|
||||
onClicked: {
|
||||
configDialog.currentContainmentActionsModel.showConfiguration(index, this);
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
icon.name: "dialog-information"
|
||||
width: height
|
||||
onClicked: {
|
||||
const metaData = configDialog.currentContainmentActionsModel.aboutMetaData(index);
|
||||
if (!metaData) {
|
||||
return;
|
||||
}
|
||||
aboutComponent.incubateObject(root.Window.window.contentItem, {
|
||||
"metaData": metaData,
|
||||
"title": i18ndc("plasma_shell_org.kde.plasma.desktop", "@title", "About"),
|
||||
}, Qt.Asynchronous);
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
icon.name: "list-remove"
|
||||
width: height
|
||||
onClicked: {
|
||||
configDialog.currentContainmentActionsModel.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseEventInputButton {
|
||||
defaultText: i18nd("plasma_shell_org.kde.plasma.desktop", "Add Action");
|
||||
icon.name: checked ? "input-mouse-symbolic" : "list-add"
|
||||
onEventStringChanged: {
|
||||
configDialog.currentContainmentActionsModel.append(eventString, "org.kde.contextmenu");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import org.kde.plasma.configuration 2.0
|
||||
import QtQuick.Controls 2.3 as QQC2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQml 2.15
|
||||
|
||||
import org.kde.newstuff 1.62 as NewStuff
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.kcmutils
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.configuration 2.0
|
||||
|
||||
Item {
|
||||
id: appearanceRoot
|
||||
signal configurationChanged
|
||||
|
||||
property int formAlignment: wallpaperComboBox.Kirigami.ScenePosition.x - appearanceRoot.Kirigami.ScenePosition.x + Kirigami.Units.smallSpacing
|
||||
property string currentWallpaper: ""
|
||||
property string containmentPlugin: ""
|
||||
property alias parentLayout: parentLayout
|
||||
|
||||
function saveConfig() {
|
||||
if (main.currentItem.saveConfig) {
|
||||
main.currentItem.saveConfig()
|
||||
}
|
||||
configDialog.currentWallpaper = appearanceRoot.currentWallpaper;
|
||||
for (var key in configDialog.wallpaperConfiguration) {
|
||||
if (main.currentItem["cfg_"+key] !== undefined) {
|
||||
configDialog.wallpaperConfiguration[key] = main.currentItem["cfg_"+key]
|
||||
}
|
||||
}
|
||||
configDialog.applyWallpaper()
|
||||
configDialog.containmentPlugin = appearanceRoot.containmentPlugin
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
width: root.availableWidth
|
||||
height: Math.max(implicitHeight, root.availableHeight)
|
||||
spacing: 0 // unless it's 0 there will be an additional gap between two FormLayouts
|
||||
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < configDialog.containmentPluginsConfigModel.count; ++i) {
|
||||
var pluginName = configDialog.containmentPluginsConfigModel.data(configDialog.containmentPluginsConfigModel.index(i, 0), ConfigModel.PluginNameRole);
|
||||
if (configDialog.containmentPlugin === pluginName) {
|
||||
pluginComboBox.currentIndex = i
|
||||
pluginComboBox.activated(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < configDialog.wallpaperConfigModel.count; ++i) {
|
||||
var pluginName = configDialog.wallpaperConfigModel.data(configDialog.wallpaperConfigModel.index(i, 0), ConfigModel.PluginNameRole);
|
||||
if (configDialog.currentWallpaper === pluginName) {
|
||||
wallpaperComboBox.currentIndex = i
|
||||
wallpaperComboBox.activated(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.InlineMessage {
|
||||
visible: Plasmoid.immutable || animating
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Layout changes have been restricted by the system administrator")
|
||||
showCloseButton: true
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing * 2 // we need this because ColumnLayout's spacing is 0
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: parentLayout // needed for twinFormLayouts to work in wallpaper plugins
|
||||
twinFormLayouts: main.currentItem.formLayout || []
|
||||
Layout.fillWidth: true
|
||||
QQC2.ComboBox {
|
||||
id: pluginComboBox
|
||||
Layout.preferredWidth: Math.max(implicitWidth, wallpaperComboBox.implicitWidth)
|
||||
Kirigami.FormData.label: i18nd("plasma_shell_org.kde.plasma.desktop", "Layout:")
|
||||
enabled: !Plasmoid.immutable
|
||||
model: configDialog.containmentPluginsConfigModel
|
||||
textRole: "name"
|
||||
onActivated: {
|
||||
var model = configDialog.containmentPluginsConfigModel.get(currentIndex)
|
||||
appearanceRoot.containmentPlugin = model.pluginName
|
||||
appearanceRoot.configurationChanged()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
enabled: main.currentItem.objectName !== "switchContainmentWarningItem"
|
||||
Kirigami.FormData.label: i18nd("plasma_shell_org.kde.plasma.desktop", "Wallpaper type:")
|
||||
|
||||
QQC2.ComboBox {
|
||||
id: wallpaperComboBox
|
||||
Layout.preferredWidth: Math.max(implicitWidth, pluginComboBox.implicitWidth)
|
||||
model: configDialog.wallpaperConfigModel
|
||||
textRole: "name"
|
||||
onActivated: {
|
||||
var idx = configDialog.wallpaperConfigModel.index(currentIndex, 0)
|
||||
var pluginName = configDialog.wallpaperConfigModel.data(idx, ConfigModel.PluginNameRole)
|
||||
if (appearanceRoot.currentWallpaper === pluginName) {
|
||||
return;
|
||||
}
|
||||
appearanceRoot.currentWallpaper = pluginName
|
||||
configDialog.currentWallpaper = pluginName
|
||||
main.sourceFile = configDialog.wallpaperConfigModel.data(idx, ConfigModel.SourceRole)
|
||||
appearanceRoot.configurationChanged()
|
||||
}
|
||||
}
|
||||
NewStuff.Button {
|
||||
configFile: "wallpaperplugin.knsrc"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Get New Plugins…")
|
||||
visibleWhenDisabled: true // don't hide on disabled
|
||||
Layout.preferredHeight: wallpaperComboBox.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: emptyConfig
|
||||
}
|
||||
|
||||
QQC2.StackView {
|
||||
id: main
|
||||
|
||||
implicitHeight: main.empty ? 0 : currentItem.implicitHeight
|
||||
|
||||
Layout.fillHeight: true;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
// Bug 360862: if wallpaper has no config, sourceFile will be ""
|
||||
// so we wouldn't load emptyConfig and break all over the place
|
||||
// hence set it to some random value initially
|
||||
property string sourceFile: "tbd"
|
||||
|
||||
onSourceFileChanged: loadSourceFile()
|
||||
|
||||
function loadSourceFile() {
|
||||
const wallpaperConfig = configDialog.wallpaperConfiguration
|
||||
// BUG 407619: wallpaperConfig can be null before calling `ContainmentItem::loadWallpaper()`
|
||||
if (wallpaperConfig && sourceFile) {
|
||||
var props = {
|
||||
"configDialog": configDialog
|
||||
}
|
||||
|
||||
for (var key in wallpaperConfig) {
|
||||
props["cfg_" + key] = wallpaperConfig[key]
|
||||
}
|
||||
|
||||
var newItem = replace(Qt.resolvedUrl(sourceFile), props)
|
||||
|
||||
for (var key in wallpaperConfig) {
|
||||
var changedSignal = newItem["cfg_" + key + "Changed"]
|
||||
if (changedSignal) {
|
||||
changedSignal.connect(appearanceRoot.configurationChanged)
|
||||
}
|
||||
}
|
||||
|
||||
const configurationChangedSignal = newItem.configurationChanged
|
||||
if (configurationChangedSignal) {
|
||||
configurationChangedSignal.connect(appearanceRoot.configurationChanged)
|
||||
}
|
||||
} else {
|
||||
replace(emptyConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: switchContainmentWarning
|
||||
|
||||
Item {
|
||||
objectName: "switchContainmentWarningItem"
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
id: message
|
||||
width: parent.width - Kirigami.Units.largeSpacing * 8
|
||||
anchors.centerIn: parent
|
||||
|
||||
icon.name: "documentinfo"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Layout changes must be applied before other changes can be made")
|
||||
|
||||
helpfulAction: QQC2.Action {
|
||||
icon.name: "dialog-ok-apply"
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply Now")
|
||||
onTriggered: saveConfig()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onContainmentPluginChanged: {
|
||||
if (configDialog.containmentPlugin !== appearanceRoot.containmentPlugin) {
|
||||
main.push(switchContainmentWarning);
|
||||
categoriesScroll.enabled = false;
|
||||
} else if (main.currentItem.objectName === "switchContainmentWarningItem") {
|
||||
main.pop();
|
||||
categoriesScroll.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
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 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: internalPage.actions
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3 as QQC2
|
||||
import QtQuick.Layouts 1.0
|
||||
import org.kde.kquickcontrols 2.0
|
||||
import org.kde.kirigami 2.14 as Kirigami
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.kcmutils as KCM
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
|
||||
title: i18n("Shortcuts")
|
||||
|
||||
signal configurationChanged
|
||||
function saveConfig() {
|
||||
Plasmoid.globalShortcut = button.keySequence
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "This shortcut will activate the applet as though it had been clicked.")
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
KeySequenceItem {
|
||||
id: button
|
||||
keySequence: Plasmoid.globalShortcut
|
||||
modifierOnlyAllowed: true
|
||||
onCaptureFinished: {
|
||||
if (keySequence !== Plasmoid.globalShortcut) {
|
||||
root.configurationChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.plasma.configuration 2.0
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
|
||||
AppletConfiguration {
|
||||
id: root
|
||||
isContainment: true
|
||||
Layout.minimumWidth: Kirigami.Units.gridUnit * 35
|
||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 30
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 32
|
||||
Layout.preferredHeight: Kirigami.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"
|
||||
includeMargins: false
|
||||
}
|
||||
ConfigCategory {
|
||||
name: i18nd("plasma_shell_org.kde.plasma.desktop", "Mouse Actions")
|
||||
icon: "preferences-desktop-mouse"
|
||||
source: "ConfigurationContainmentActions.qml"
|
||||
}
|
||||
}
|
||||
//END model
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3 as QQC2
|
||||
|
||||
|
||||
QQC2.Button {
|
||||
id: mouseInputButton
|
||||
property string defaultText: i18nd("plasma_shell_org.kde.plasma.desktop", "Add Action")
|
||||
text: defaultText
|
||||
checkable: true
|
||||
property string eventString
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
text = i18nd("plasma_shell_org.kde.plasma.desktop", "Input Here");
|
||||
mouseInputArea.enabled = true;
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseInputArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.AllButtons
|
||||
enabled: false
|
||||
|
||||
onClicked: {
|
||||
var newEventString = configDialog.currentContainmentActionsModel.mouseEventString(mouse.button, mouse.modifiers);
|
||||
|
||||
if (eventString === newEventString || !configDialog.currentContainmentActionsModel.isTriggerUsed(newEventString)) {
|
||||
eventString = newEventString;
|
||||
mouseInputButton.text = defaultText;
|
||||
mouseInputButton.checked = false;
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
onWheel: {
|
||||
var newEventString = configDialog.currentContainmentActionsModel.wheelEventString(wheel);
|
||||
|
||||
if (eventString === newEventString || !configDialog.currentContainmentActionsModel.isTriggerUsed(newEventString)) {
|
||||
eventString = newEventString;
|
||||
mouseInputButton.text = defaultText;
|
||||
mouseInputButton.checked = false;
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,632 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2023 Niccolò Venerandi <niccolo.venerandi@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.plasma.shell.panel 0.1 as Panel
|
||||
import org.kde.kquickcontrols 2.0
|
||||
import "panelconfiguration"
|
||||
|
||||
ColumnLayout {
|
||||
id: dialogRoot
|
||||
spacing: Kirigami.Units.largeSpacing * 2
|
||||
|
||||
signal closeContextMenu
|
||||
|
||||
required property QtObject panelConfiguration
|
||||
|
||||
property bool vertical: (panel.location === PlasmaCore.Types.LeftEdge || panel.location === PlasmaCore.Types.RightEdge)
|
||||
|
||||
readonly property int headingLevel: 2
|
||||
|
||||
property Item panelRuler: Ruler {
|
||||
id: ruler
|
||||
|
||||
prefix: {
|
||||
switch (panel.location) {
|
||||
case PlasmaCore.Types.TopEdge:
|
||||
return "north"
|
||||
case PlasmaCore.Types.LeftEdge:
|
||||
return "west"
|
||||
case PlasmaCore.Types.RightEdge:
|
||||
return "east"
|
||||
case PlasmaCore.Types.BottomEdge:
|
||||
default:
|
||||
return "south"
|
||||
}
|
||||
}
|
||||
Item {
|
||||
activeFocusOnTab: true
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus && dialogRoot.Window.window && dialogRoot.Window.window.visible) {
|
||||
dialogRoot.Window.window.requestActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
// This item is used to "pass" focus to the main window when we're at the last of the control of the ruler
|
||||
Item {
|
||||
parent: dialogRoot.parent // Used to not take space in the ColumnLayout
|
||||
activeFocusOnTab: true
|
||||
onActiveFocusChanged: {
|
||||
let window = dialogRoot.Window.window
|
||||
if (activeFocus && window && window.visible) {
|
||||
window.requestActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: panel
|
||||
function onOffsetChanged() {
|
||||
ruler.offset = panel.offset
|
||||
}
|
||||
function onMinimumLengthChanged() {
|
||||
ruler.minimumLength = panel.minimumLength
|
||||
}
|
||||
function onMaximumLengthChanged() {
|
||||
ruler.maximumLength = panel.maximumLength
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (panel.lengthMode === Panel.Global.Custom) {
|
||||
Qt.callLater(()=> {
|
||||
panelConfiguration.panelRulerView.visible = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlasmaExtras.PlasmoidHeading {
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Panel Settings")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
PC3.ToolButton {
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Add Spacer")
|
||||
icon.name: "distribute-horizontal-x"
|
||||
|
||||
PC3.ToolTip.text: i18nd("plasma_shell_org.kde.plasma.desktop", "Add spacer widget to the panel")
|
||||
PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
PC3.ToolTip.visible: hovered
|
||||
onClicked: configDialog.addPanelSpacer()
|
||||
}
|
||||
|
||||
PC3.ToolButton {
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Add Widgets…")
|
||||
icon.name: "list-add"
|
||||
|
||||
PC3.ToolTip.text: i18nd("plasma_shell_org.kde.plasma.desktop", "Open the widget selector to drag and drop widgets to the panel")
|
||||
PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
PC3.ToolTip.visible: hovered
|
||||
onClicked: {
|
||||
configDialog.close()
|
||||
configDialog.showAddWidgetDialog()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.leftMargin: columnSpacing
|
||||
Layout.rightMargin: columnSpacing
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: (positionRepresentation.implicitWidth + columnSpacing) * columns + columnSpacing
|
||||
rowSpacing: dialogRoot.spacing
|
||||
columnSpacing: Kirigami.Units.smallSpacing
|
||||
rows: 2
|
||||
columns: 3
|
||||
uniformCellWidths: true
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Heading {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
level: dialogRoot.headingLevel
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Position")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
id: positionRepresentation
|
||||
text: (panel.location === PlasmaCore.Types.TopEdge ? i18nd("plasma_shell_org.kde.plasma.desktop", "Top") :
|
||||
panel.location === PlasmaCore.Types.RightEdge ? i18nd("plasma_shell_org.kde.plasma.desktop", "Right") :
|
||||
panel.location === PlasmaCore.Types.LeftEdge ? i18nd("plasma_shell_org.kde.plasma.desktop", "Left") :
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Bottom"))
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
alignment: (panel.location === PlasmaCore.Types.TopEdge ? Qt.AlignHCenter | Qt.AlignTop :
|
||||
panel.location === PlasmaCore.Types.RightEdge ? Qt.AlignVCenter | Qt.AlignRight :
|
||||
panel.location === PlasmaCore.Types.LeftEdge ? Qt.AlignVCenter | Qt.AlignLeft :
|
||||
Qt.AlignHCenter | Qt.AlignBottom)
|
||||
isVertical: dialogRoot.vertical
|
||||
mainIconSource: (panel.location === PlasmaCore.Types.TopEdge ? "arrow-up" :
|
||||
panel.location === PlasmaCore.Types.RightEdge ? "arrow-right" :
|
||||
panel.location === PlasmaCore.Types.LeftEdge ? "arrow-left": "arrow-down")
|
||||
onClicked: {
|
||||
setPositionButton.checked = !setPositionButton.checked
|
||||
setPositionButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
PC3.Button {
|
||||
id: setPositionButton
|
||||
Layout.minimumHeight: transparencyBox.height
|
||||
Layout.minimumWidth: positionRepresentation.width
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Set Position…")
|
||||
checkable: true
|
||||
|
||||
function moveTo(newLocation: int, associatedWindow = null) {
|
||||
if (!setPositionButton.checked) {
|
||||
return;
|
||||
}
|
||||
panel.location = newLocation;
|
||||
if (associatedWindow !== null) {
|
||||
panel.screenToFollow = dialogRoot.panelConfiguration.screenFromWindow(associatedWindow);
|
||||
}
|
||||
setPositionButton.checked = false;
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: moveTo(PlasmaCore.Types.LeftEdge)
|
||||
Keys.onRightPressed: moveTo(PlasmaCore.Types.RightEdge)
|
||||
Keys.onUpPressed: moveTo(PlasmaCore.Types.TopEdge)
|
||||
Keys.onDownPressed: moveTo(PlasmaCore.Types.BottomEdge)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Heading {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
level: dialogRoot.headingLevel
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Alignment")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
id: alignmentRepresentation
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
mainIconSource: {
|
||||
if (dialogRoot.vertical) {
|
||||
if (alignmentBox.previewIndex === 0) {
|
||||
return "align-vertical-top"
|
||||
} else if (alignmentBox.previewIndex === 1) {
|
||||
return "align-vertical-center"
|
||||
} else {
|
||||
return "align-vertical-bottom"
|
||||
}
|
||||
} else {
|
||||
if (alignmentBox.previewIndex === 0) {
|
||||
return "align-horizontal-left"
|
||||
} else if (alignmentBox.previewIndex === 1) {
|
||||
return "align-horizontal-center"
|
||||
} else {
|
||||
return "align-horizontal-right"
|
||||
}
|
||||
}
|
||||
}
|
||||
alignment: {
|
||||
let first, second;
|
||||
if (dialogRoot.vertical) {
|
||||
if (alignmentBox.previewIndex === 0) {
|
||||
first = Qt.AlignTop
|
||||
} else if (alignmentBox.previewIndex === 1) {
|
||||
first = Qt.AlignVCenter
|
||||
} else {
|
||||
first = Qt.AlignBottom
|
||||
}
|
||||
if (panel.location === PlasmaCore.Types.LeftEdge) {
|
||||
second = Qt.AlignLeft
|
||||
} else {
|
||||
second = Qt.AlignRight
|
||||
}
|
||||
} else {
|
||||
if (alignmentBox.previewIndex === 0) {
|
||||
first = Qt.AlignLeft
|
||||
} else if (alignmentBox.previewIndex === 1) {
|
||||
first = Qt.AlignHCenter
|
||||
} else {
|
||||
first = Qt.AlignRight
|
||||
}
|
||||
if (panel.location === PlasmaCore.Types.TopEdge) {
|
||||
second = Qt.AlignTop
|
||||
} else {
|
||||
second = Qt.AlignBottom
|
||||
}
|
||||
}
|
||||
return first | second;
|
||||
}
|
||||
onClicked: alignmentBox.popup.visible = true
|
||||
isVertical: dialogRoot.vertical
|
||||
}
|
||||
PC3.ComboBox {
|
||||
id: alignmentBox
|
||||
property int previewIndex: highlightedIndex > -1 ? highlightedIndex : currentIndex
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: alignmentRepresentation.width
|
||||
model: [
|
||||
dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Top") : i18nd("plasma_shell_org.kde.plasma.desktop", "Left"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Center"),
|
||||
dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Bottom") : i18nd("plasma_shell_org.kde.plasma.desktop", "Right")
|
||||
]
|
||||
currentIndex: (panel.alignment === Qt.AlignLeft ? 0 :
|
||||
panel.alignment === Qt.AlignCenter ? 1 : 2)
|
||||
onActivated: (index) => {
|
||||
if (index === 0) {
|
||||
panel.alignment = Qt.AlignLeft
|
||||
} else if (index === 1) {
|
||||
panel.alignment = Qt.AlignCenter
|
||||
} else {
|
||||
panel.alignment = Qt.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Heading {
|
||||
level: dialogRoot.headingLevel
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Height")
|
||||
: i18nd("plasma_shell_org.kde.plasma.desktop", "Width")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
id: lengthRepresentation
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
mainIconSource: (widthBox.previewIndex === 1 ? "gnumeric-ungroup" :
|
||||
widthBox.previewIndex === 0 ? (dialogRoot.vertical ? "panel-fit-height" : "panel-fit-width") : "kdenlive-custom-effect")
|
||||
isVertical: dialogRoot.vertical
|
||||
alignment: positionRepresentation.alignment
|
||||
fillAvailable: widthBox.previewIndex === 0
|
||||
onClicked: widthBox.popup.visible = true
|
||||
}
|
||||
PC3.ComboBox {
|
||||
id: widthBox
|
||||
property int previewIndex: highlightedIndex > -1 ? highlightedIndex : currentIndex
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: lengthRepresentation.width
|
||||
model: [
|
||||
dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Fill height") : i18nd("plasma_shell_org.kde.plasma.desktop", "Fill width"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Fit content"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Custom")
|
||||
]
|
||||
currentIndex: (panel.lengthMode === Panel.Global.FillAvailable ? 0 :
|
||||
panel.lengthMode === Panel.Global.FitContent ? 1 : 2)
|
||||
onActivated: (index) => {
|
||||
if (index === 0) {
|
||||
panel.lengthMode = Panel.Global.FillAvailable
|
||||
panelConfiguration.panelRulerView.visible = false
|
||||
} else if (index === 1) {
|
||||
panel.lengthMode = Panel.Global.FitContent
|
||||
panelConfiguration.panelRulerView.visible = false
|
||||
} else {
|
||||
panel.lengthMode = Panel.Global.Custom
|
||||
panelConfiguration.panelRulerView.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Heading {
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
level: dialogRoot.headingLevel
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Visibility")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
id: visibilityRepresentation
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
sunkenPanel: autoHideBox.previewIndex !== 0
|
||||
onClicked: autoHideBox.popup.visible = true
|
||||
}
|
||||
PC3.ComboBox {
|
||||
id: autoHideBox
|
||||
property int previewIndex: popup.visible ? highlightedIndex : currentIndex
|
||||
model: [
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Always visible"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Auto hide"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Dodge windows"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Windows Go Below"),
|
||||
]
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: visibilityRepresentation.width
|
||||
currentIndex: {
|
||||
switch (panel.visibilityMode) {
|
||||
case Panel.Global.AutoHide:
|
||||
return 1;
|
||||
case Panel.Global.DodgeWindows:
|
||||
return 2;
|
||||
case Panel.Global.WindowsGoBelow:
|
||||
return 3;
|
||||
case Panel.Global.NormalPanel:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onActivated: (index) => {
|
||||
switch (index) {
|
||||
case 1:
|
||||
panel.visibilityMode = Panel.Global.AutoHide;
|
||||
break;
|
||||
case 2:
|
||||
panel.visibilityMode = Panel.Global.DodgeWindows;
|
||||
break;
|
||||
case 3:
|
||||
panel.visibilityMode = Panel.Global.WindowsGoBelow;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
panel.visibilityMode = Panel.Global.NormalPanel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Heading {
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
level: dialogRoot.headingLevel
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Opacity")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
id: opacityRepresentation
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
adaptivePanel: transparencyBox.previewIndex === 0
|
||||
translucentPanel: transparencyBox.previewIndex === 2
|
||||
onClicked: transparencyBox.popup.visible = true
|
||||
}
|
||||
PC3.ComboBox {
|
||||
id: transparencyBox
|
||||
readonly property int previewIndex: popup.visible ? highlightedIndex : currentIndex
|
||||
model: [
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Adaptive"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Opaque"),
|
||||
i18nd("plasma_shell_org.kde.plasma.desktop", "Translucent")
|
||||
]
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: opacityRepresentation.width
|
||||
currentIndex: (panel.opacityMode === Panel.Global.Adaptive ? 0 :
|
||||
panel.opacityMode === Panel.Global.Opaque ? 1 : 2)
|
||||
onActivated: (index) => {
|
||||
if (index === 0) {
|
||||
panel.opacityMode = Panel.Global.Adaptive
|
||||
} else if (index === 1) {
|
||||
panel.opacityMode = Panel.Global.Opaque
|
||||
} else {
|
||||
panel.opacityMode = Panel.Global.Translucent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Kirigami.Action {
|
||||
id: floatingAction
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Floating")
|
||||
checkable: true
|
||||
checked: panel.floating
|
||||
onToggled: source => {
|
||||
panel.floating = checked;
|
||||
}
|
||||
}
|
||||
Kirigami.Heading {
|
||||
level: dialogRoot.headingLevel
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Style")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PanelRepresentation {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
floatingGap: Kirigami.Units.smallSpacing * floatingSwitch.checked
|
||||
onClicked: floatingAction.toggle(this)
|
||||
}
|
||||
PC3.Switch {
|
||||
id: floatingSwitch
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumHeight: transparencyBox.height
|
||||
action: floatingAction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
active: setPositionButton.checked
|
||||
asynchronous: true
|
||||
model: Application.screens
|
||||
Item {
|
||||
width: 0
|
||||
height: 0
|
||||
required property var modelData
|
||||
|
||||
component Indicator : PlasmaCore.Dialog {
|
||||
id: root
|
||||
property string iconSource
|
||||
property var onClickedLocation
|
||||
flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint
|
||||
location: PlasmaCore.Types.Floating
|
||||
visible: setPositionButton.checked && (panel.location !== onClickedLocation || modelData.name !== panel.screenToFollow.name)
|
||||
|
||||
x: modelData.virtualX + Kirigami.Units.largeSpacing
|
||||
y: modelData.virtualY + modelData.height / 2 - mainItem.height / 2 - margins.top
|
||||
|
||||
mainItem: PC3.ToolButton {
|
||||
width: Kirigami.Units.iconSizes.enormous
|
||||
height: Kirigami.Units.iconSizes.enormous
|
||||
icon.name: root.iconSource
|
||||
|
||||
onClicked: setPositionButton.moveTo(root.onClickedLocation, Window.window)
|
||||
}
|
||||
}
|
||||
|
||||
Indicator {
|
||||
x: modelData.virtualX + Kirigami.Units.largeSpacing
|
||||
y: modelData.virtualY + modelData.height / 2 - mainItem.height / 2 - margins.top
|
||||
iconSource: "arrow-left"
|
||||
onClickedLocation: PlasmaCore.Types.LeftEdge
|
||||
}
|
||||
Indicator {
|
||||
x: modelData.virtualX + modelData.width - Kirigami.Units.largeSpacing - margins.left - margins.right - mainItem.width
|
||||
y: modelData.virtualY + modelData.height / 2 - mainItem.height / 2 - margins.top
|
||||
iconSource: "arrow-right"
|
||||
onClickedLocation: PlasmaCore.Types.RightEdge
|
||||
}
|
||||
Indicator {
|
||||
x: modelData.virtualX + modelData.width / 2 - mainItem.width / 2 - margins.left
|
||||
y: modelData.virtualY + Kirigami.Units.largeSpacing
|
||||
iconSource: "arrow-up"
|
||||
onClickedLocation: PlasmaCore.Types.TopEdge
|
||||
}
|
||||
Indicator {
|
||||
x: modelData.virtualX + modelData.width / 2 - mainItem.width / 2 - margins.left
|
||||
y: modelData.virtualY + modelData.height - mainItem.height - margins.top - margins.bottom - Kirigami.Units.largeSpacing
|
||||
iconSource: "arrow-down"
|
||||
onClickedLocation: PlasmaCore.Types.BottomEdge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
rowSpacing: Kirigami.Units.largeSpacing
|
||||
columnSpacing: Kirigami.Units.largeSpacing
|
||||
rows: 2
|
||||
columns: 2
|
||||
|
||||
PC3.Label {
|
||||
id: spinBoxLabel
|
||||
Layout.alignment: Qt.AlignRight
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
text: panel.location === PlasmaCore.Types.LeftEdge || panel.location === PlasmaCore.Types.RightEdge
|
||||
? i18nd("plasma_shell_org.kde.plasma.desktop", "Panel Width:")
|
||||
: i18nd("plasma_shell_org.kde.plasma.desktop", "Panel Height:")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
PC3.SpinBox {
|
||||
id: spinBox
|
||||
|
||||
editable: true
|
||||
focus: !Kirigami.InputMethod.willShowOnActive
|
||||
from: Math.max(20, panel.minThickness) // below this size, the panel is mostly unusable
|
||||
to: panel.location === PlasmaCore.Types.LeftEdge || panel.location === PlasmaCore.Types.RightEdge
|
||||
? panel.screenToFollow.geometry.width / 2
|
||||
: panel.screenToFollow.geometry.height / 2
|
||||
|
||||
stepSize: 2
|
||||
|
||||
value: panel.thickness
|
||||
onValueModified: {
|
||||
panel.thickness = value
|
||||
}
|
||||
}
|
||||
|
||||
PC3.Label {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Focus shortcut:")
|
||||
textFormat: Text.PlainText
|
||||
visible: panel.adaptiveOpacityEnabled
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
PC3.ToolTip {
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Press this keyboard shortcut to move focus to the Panel")
|
||||
visible: mouseArea.containsMouse
|
||||
}
|
||||
}
|
||||
KeySequenceItem {
|
||||
id: button
|
||||
keySequence: plasmoid.globalShortcut
|
||||
onCaptureFinished: {
|
||||
plasmoid.globalShortcut = button.keySequence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.PlasmoidHeading {
|
||||
position: PlasmaExtras.PlasmoidHeading.Footer
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
topPadding: Kirigami.Units.smallSpacing * 2
|
||||
leftPadding: Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
bottomPadding: Kirigami.Units.smallSpacing
|
||||
|
||||
Layout.fillWidth: true
|
||||
RowLayout {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
PC3.ToolButton {
|
||||
text: i18ndc("plasma_shell_org.kde.plasma.desktop", "@action:button Delete the panel", "Delete Panel")
|
||||
icon.name: "delete"
|
||||
|
||||
PC3.ToolTip.text: i18nd("plasma_shell_org.kde.plasma.desktop", "Remove this panel; this action is undo-able")
|
||||
PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
PC3.ToolTip.visible: hovered
|
||||
|
||||
onClicked: plasmoid.internalAction("remove").trigger()
|
||||
}
|
||||
|
||||
|
||||
Item {Layout.fillWidth: true}
|
||||
|
||||
PC3.ToolButton {
|
||||
text: i18ndc("plasma_shell_org.kde.plasma.desktop", "@action:button Done configuring the panel", "Done")
|
||||
icon.name: "dialog-ok-symbolic"
|
||||
|
||||
PC3.ToolTip.text: i18nd("plasma_shell_org.kde.plasma.desktop", "Close Panel Settings window and exit Edit Mode")
|
||||
PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
PC3.ToolTip.visible: hovered
|
||||
|
||||
onClicked: plasmoid.containment.corona.editMode = false
|
||||
}
|
||||
}
|
||||
}
|
||||
// This item is used to "pass" focus to the ruler with tab when we're at the last of the control of this window
|
||||
Item {
|
||||
parent: dialogRoot.parent // Used to not take space in the ColumnLayout
|
||||
activeFocusOnTab: true
|
||||
onActiveFocusChanged: {
|
||||
let window = ruler.Window.window
|
||||
if (activeFocus && window && window.visible) {
|
||||
window.requestActivate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Cyril Rossi <cyril.rossi@enioka.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.15
|
||||
|
||||
import org.kde.kirigami 2.13 as Kirigami
|
||||
|
||||
import "shellcontainmentconfiguration"
|
||||
|
||||
Kirigami.AbstractApplicationWindow {
|
||||
id: root
|
||||
|
||||
title: i18nd("plasma_shell_org.kde.plasma.desktop", "Panel and Desktop Management")
|
||||
|
||||
width: Kirigami.Units.gridUnit * 40
|
||||
height: Kirigami.Units.gridUnit * 32
|
||||
|
||||
minimumWidth: Kirigami.Units.gridUnit * 30
|
||||
minimumHeight: Kirigami.Units.gridUnit * 25
|
||||
|
||||
header: QQC2.ToolBar {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
contentItem: QQC2.Label {
|
||||
Layout.fillWidth: parent
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "You can drag Panels and Desktops around to move them to different screens.")
|
||||
textFormat: Text.PlainText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
footer: QQC2.Control {
|
||||
contentItem: QQC2.DialogButtonBox {
|
||||
QQC2.Button {
|
||||
text: i18nd("plasma_shell_org.kde.plasma.desktop", "Close")
|
||||
onClicked: Window.window.close()
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
// FIXME: automate that somehow?
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
visible: mainPage.flickable.contentHeight > mainPage.flickable.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: mainPage
|
||||
anchors.fill: parent
|
||||
|
||||
leftPadding: 0
|
||||
topPadding: 0
|
||||
rightPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
Flow {
|
||||
id: mainGrid
|
||||
width: mainPage.flickable.width
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: ShellContainmentModel
|
||||
|
||||
delegate: Delegate {
|
||||
viewPort: mainPage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.plasma.components as PC3
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
import org.kde.ksvg as KSvg
|
||||
import org.kde.plasma.shell.panel as Panel
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string text
|
||||
property /*Qt::Alignment*/int alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
property string tooltip
|
||||
|
||||
property bool isVertical: false
|
||||
property bool checked: false
|
||||
property bool windowVisible: false
|
||||
property bool panelVisible: true
|
||||
property bool translucentPanel: false
|
||||
property bool sunkenPanel: false
|
||||
property bool adaptivePanel: false
|
||||
property bool fillAvailable: false
|
||||
property int floatingGap: 0
|
||||
property int windowZ: 0
|
||||
property var mainIconSource: null
|
||||
property int screenHeight: Math.round(screenRect.height / 2)
|
||||
|
||||
readonly property bool iconAndLabelsShouldlookSelected: checked || mouseArea.pressed
|
||||
|
||||
signal clicked()
|
||||
|
||||
implicitHeight: mainItem.height
|
||||
implicitWidth: mainItem.width
|
||||
|
||||
PC3.ToolTip {
|
||||
text: root.tooltip
|
||||
visible: mouseArea.containsMouse && text.length > 0
|
||||
}
|
||||
|
||||
PlasmaExtras.Highlight {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -Kirigami.Units.smallSpacing
|
||||
hovered: mouseArea.containsMouse
|
||||
pressed: root.iconAndLabelsShouldlookSelected
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Rectangle {
|
||||
id: screenRect
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: Math.round(Math.min(Kirigami.Units.gridUnit * 6, Screen.width * 0.1))
|
||||
implicitHeight: Math.round(Math.min(Kirigami.Units.gridUnit * 4, Screen.width * 0.1))
|
||||
color: Qt.tint(Kirigami.Theme.backgroundColor, Qt.rgba(1, 1, 1, 0.3))
|
||||
border.color: Kirigami.Theme.highlightColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
clip: root.sunkenPanel
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Rectangle {
|
||||
id: panelImage
|
||||
|
||||
implicitWidth: root.isVertical ? Math.round(parent.width / 6) : Math.round(parent.width * (root.fillAvailable ? 1 : 0.8))
|
||||
implicitHeight: root.isVertical ? Math.round(parent.height * (root.fillAvailable ? 1 : 0.8)) : Math.round(parent.height / 4)
|
||||
Layout.alignment: root.alignment
|
||||
Layout.bottomMargin: root.sunkenPanel * -Math.round(height / 2) + root.floatingGap
|
||||
color: root.translucentPanel ? screenRect.color : Kirigami.Theme.backgroundColor
|
||||
opacity: root.translucentPanel ? 0.8 : 1.0
|
||||
border.color: "transparent"
|
||||
visible: root.panelVisible
|
||||
clip: root.adaptivePanel
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
|
||||
z: 1
|
||||
|
||||
Loader {
|
||||
id: horizontalAdaptivePanelLoader
|
||||
active: root.adaptivePanel && !root.isVertical
|
||||
sourceComponent: Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Math.round(panelImage.width / 3)
|
||||
color: Qt.lighter(screenRect.color)
|
||||
border.color: Kirigami.Theme.highlightColor
|
||||
width: panelImage.width
|
||||
height: Math.round(panelImage.height * 4)
|
||||
radius: Math.round(height / 2)
|
||||
rotation: 45
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: verticalAdaptivePanelLoader
|
||||
active: root.adaptivePanel && root.isVertical
|
||||
sourceComponent: Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Math.round(panelImage.height / 4)
|
||||
color: Qt.lighter(screenRect.color)
|
||||
border.color: Kirigami.Theme.highlightColor
|
||||
width: Math.round(panelImage.width * 2)
|
||||
height: panelImage.height
|
||||
radius: Math.round(height / 2)
|
||||
rotation: 45
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: panelBorder
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: Kirigami.Theme.highlightColor
|
||||
radius: panelImage.radius
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: window
|
||||
width: Math.round(parent.width / 2)
|
||||
height: Math.round(parent.height / 2)
|
||||
visible: root.windowVisible
|
||||
radius: 5
|
||||
color: Kirigami.Theme.highlightColor
|
||||
border.color: "transparent"
|
||||
|
||||
x: root.isVertical ? Math.round(panelImage.x + panelImage.width / 2) : Math.round(screenRect.width / 2 - width / 2) + Kirigami.Units.gridUnit
|
||||
y: root.isVertical ? Math.round(screenRect.height / 2 - height / 2) : Math.round(panelImage.y - height + panelImage.height / 2)
|
||||
z: root.windowZ
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Kirigami.Units.smallSpacing
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Repeater {
|
||||
model: 3
|
||||
delegate: Rectangle {
|
||||
width: Math.round(Kirigami.Units.gridUnit / 6)
|
||||
height: width
|
||||
radius: Math.round(height / 2)
|
||||
color: Kirigami.Theme.textColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: mainIcon
|
||||
visible: valid
|
||||
anchors.centerIn: parent
|
||||
transform: Translate {
|
||||
y: root.isVertical ? 0 : Math.round((mainIcon.y - panelImage.y) / 4)
|
||||
x: root.isVertical ? Math.round((mainIcon.x - panelImage.x) / 4) : 0
|
||||
}
|
||||
height: parent.height / 2
|
||||
source: root.mainIconSource
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.plasma.shell.panel 0.1 as Panel
|
||||
import org.kde.kquickcontrols 2.0
|
||||
|
||||
KSvg.FrameSvgItem {
|
||||
id: root
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
//Those properties get updated by PanelConfiguration.qml whenever a value in the panel changes
|
||||
property alias offset: offsetHandle.value
|
||||
property alias minimumLength: rightMinimumLengthHandle.value
|
||||
property alias maximumLength: rightMaximumLengthHandle.value
|
||||
property bool isHorizontal: root.prefix[0] === 'north' || root.prefix[0] === 'south'
|
||||
|
||||
property string maximumText: (dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Drag to change maximum height.") : i18nd("plasma_shell_org.kde.plasma.desktop", "Drag to change maximum width.")) + "\n" + i18nd("plasma_shell_org.kde.plasma.desktop", "Double click to reset.")
|
||||
property string minimumText: (dialogRoot.vertical ? i18nd("plasma_shell_org.kde.plasma.desktop", "Drag to change minimum height.") : i18nd("plasma_shell_org.kde.plasma.desktop", "Drag to change minimum width.")) + "\n" + i18nd("plasma_shell_org.kde.plasma.desktop", "Double click to reset.")
|
||||
|
||||
imagePath: "widgets/containment-controls"
|
||||
implicitWidth: Math.max(offsetHandle.width, rightMinimumLengthHandle.width + rightMaximumLengthHandle.width)
|
||||
implicitHeight: Math.max(offsetHandle.height, rightMinimumLengthHandle.height + rightMaximumLengthHandle.height)
|
||||
|
||||
onMinimumLengthChanged: rightMinimumLengthHandle.value = leftMinimumLengthHandle.value = minimumLength
|
||||
onMaximumLengthChanged: rightMaximumLengthHandle.value = leftMaximumLengthHandle.value = maximumLength
|
||||
|
||||
/* As offset and length have a different meaning in all alignments, the panel shifts on alignment change.
|
||||
* This could result in wrong panel positions (e.g. panel shifted over monitor border).
|
||||
* The fancy version would be a recalculation of all values, so that the panel stays at it's current position,
|
||||
* but this would be error prone and complicated. As the panel alignment is rarely changed, it's not worth it.
|
||||
* The more easy approach is just setting the panel offset to zero. This makes sure the panel has a valid position and size.
|
||||
*/
|
||||
Connections {
|
||||
target: panel
|
||||
function onAlignmentChanged() {
|
||||
offset = 0
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
offsetHandle.value = panel.offset
|
||||
rightMinimumLengthHandle.value = panel.minimumLength
|
||||
rightMaximumLengthHandle.value = panel.maximumLength
|
||||
leftMinimumLengthHandle.value = panel.minimumLength
|
||||
leftMaximumLengthHandle.value = panel.maximumLength
|
||||
}
|
||||
|
||||
KSvg.SvgItem {
|
||||
id: centerMark
|
||||
imagePath: "widgets/containment-controls"
|
||||
elementId: dialogRoot.vertical ? "vertical-centerindicator" : "horizontal-centerindicator"
|
||||
visible: panel.alignment === Qt.AlignCenter
|
||||
width: dialogRoot.vertical ? parent.width : naturalSize.width
|
||||
height: dialogRoot.vertical ? naturalSize.height : parent.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
SliderHandle {
|
||||
id: offsetHandle
|
||||
anchors {
|
||||
right: !root.isHorizontal ? root.right : undefined
|
||||
bottom: root.isHorizontal ? root.bottom : undefined
|
||||
}
|
||||
graphicElementName: "offsetslider"
|
||||
description: i18nd("plasma_shell_org.kde.plasma.desktop", "Drag to change position on this screen edge.\nDouble click to reset.")
|
||||
offset: panel.alignment === Qt.AlignCenter ? 0 : (dialogRoot.vertical ? panel.height : panel.width) / 2
|
||||
property int position: (dialogRoot.vertical) ? y + height / 2 : x + width / 2
|
||||
onPositionChanged: {
|
||||
if (!offsetHandle.hasEverBeenMoved) return;
|
||||
let panelLength = dialogRoot.vertical ? panel.height : panel.width
|
||||
let rootLength = dialogRoot.vertical ? root.height : root.width
|
||||
// Snap at the center
|
||||
if (Math.abs(position - rootLength / 2) < 5) {
|
||||
if (panel.alignment !== Qt.AlignCenter) {
|
||||
panel.alignment = Qt.AlignCenter
|
||||
// Coordinate change: since we switch from measuring the min/max
|
||||
// length from the side of the panel to the center of the panel,
|
||||
// we need to double the distance between the min/max indicators
|
||||
// and the panel side.
|
||||
panel.minimumLength += panel.minimumLength - panelLength
|
||||
panel.maximumLength += panel.maximumLength - panelLength
|
||||
}
|
||||
panel.offset = 0
|
||||
} else if (position > rootLength / 2) {
|
||||
if (panel.alignment === Qt.AlignCenter) {
|
||||
// This is the opposite of the previous comment, as we are
|
||||
// cutting in half the distance between the min/max indicators
|
||||
// and the side of the panel.
|
||||
panel.minimumLength -= (panel.minimumLength - panelLength) / 2
|
||||
panel.maximumLength -= (panel.maximumLength - panelLength) / 2
|
||||
}
|
||||
panel.alignment = Qt.AlignRight
|
||||
panel.offset = Math.round(rootLength - position - offset)
|
||||
} else if (position <= rootLength / 2) {
|
||||
if (panel.alignment === Qt.AlignCenter) {
|
||||
panel.minimumLength -= (panel.minimumLength - panelLength) / 2
|
||||
panel.maximumLength -= (panel.maximumLength - panelLength) / 2
|
||||
}
|
||||
panel.alignment = Qt.AlignLeft
|
||||
panel.offset = Math.round(position - offset)
|
||||
}
|
||||
}
|
||||
/* The maximum/minimumPosition values are needed to prevent the user from moving a panel with
|
||||
* center alignment to the left and then drag the position handle to the left.
|
||||
* This would make the panel to go off the monitor:
|
||||
* |<- V -> |
|
||||
* | -> | <- |
|
||||
* ^move this slider to the left
|
||||
*/
|
||||
minimumPosition: {
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
switch(panel.alignment){
|
||||
case Qt.AlignLeft:
|
||||
return -size / 2 + offset
|
||||
case Qt.AlignRight:
|
||||
return leftMaximumLengthHandle.value - size / 2 - offset
|
||||
default:
|
||||
return panel.maximumLength / 2 - size / 2
|
||||
}
|
||||
}
|
||||
//Needed for the same reason as above
|
||||
maximumPosition: {
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
var rootSize = dialogRoot.vertical ? root.height : root.width
|
||||
switch(panel.alignment){
|
||||
case Qt.AlignLeft:
|
||||
return rootSize - rightMaximumLengthHandle.value - size / 2 + offset
|
||||
case Qt.AlignRight:
|
||||
return rootSize - size / 2 - offset
|
||||
default:
|
||||
return rootSize - panel.maximumLength / 2 - size / 2
|
||||
}
|
||||
}
|
||||
function defaultPosition(): int /*override*/ {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The maximumPosition value for the right handles and the minimumPosition value for the left handles are
|
||||
* needed to prevent the user from moving a panel with center alignment to the left (right) and then pull one of the
|
||||
* right (left) sliders to the right (left).
|
||||
* Because the left and right sliders are coupled, this would make the left (right) sliders to go off the monitor.
|
||||
*
|
||||
* |<- V -> |
|
||||
* | -> | <- |
|
||||
* ^move this slider to the right
|
||||
*
|
||||
* The other max/min Position values just set a minimum panel size
|
||||
*/
|
||||
|
||||
SliderHandle {
|
||||
id: rightMinimumLengthHandle
|
||||
anchors {
|
||||
left: !root.isHorizontal ? root.left : undefined
|
||||
top: root.isHorizontal ? root.top : undefined
|
||||
}
|
||||
description: root.minimumText
|
||||
alignment: panel.alignment | Qt.AlignLeft
|
||||
visible: panel.alignment !== Qt.AlignRight
|
||||
offset: panel.offset
|
||||
graphicElementName: "minslider"
|
||||
onValueChanged: panel.minimumLength = value
|
||||
minimumPosition: offsetHandle.position + Kirigami.Units.gridUnit * 3
|
||||
maximumPosition: {
|
||||
var rootSize = dialogRoot.vertical ? root.height : root.width
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
panel.alignment === Qt.AlignCenter ? Math.min(rootSize - size/2, rootSize + offset * 2 - size/2) : rootSize - size/2
|
||||
}
|
||||
}
|
||||
|
||||
SliderHandle {
|
||||
id: rightMaximumLengthHandle
|
||||
anchors {
|
||||
right: !root.isHorizontal ? root.right : undefined
|
||||
bottom: root.isHorizontal ? root.bottom : undefined
|
||||
}
|
||||
description: root.maximumText
|
||||
alignment: panel.alignment | Qt.AlignLeft
|
||||
visible: panel.alignment !== Qt.AlignRight
|
||||
offset: panel.offset
|
||||
graphicElementName: "maxslider"
|
||||
onValueChanged: panel.maximumLength = value
|
||||
minimumPosition: offsetHandle.position + Kirigami.Units.gridUnit * 3
|
||||
maximumPosition: {
|
||||
var rootSize = dialogRoot.vertical ? root.height : root.width
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
panel.alignment === Qt.AlignCenter ? Math.min(rootSize - size/2, rootSize + offset * 2 - size/2) : rootSize - size/2
|
||||
}
|
||||
}
|
||||
|
||||
SliderHandle {
|
||||
id: leftMinimumLengthHandle
|
||||
anchors {
|
||||
left: !root.isHorizontal ? root.left : undefined
|
||||
top: root.isHorizontal ? root.top : undefined
|
||||
}
|
||||
description: root.minimumText
|
||||
alignment: panel.alignment | Qt.AlignRight
|
||||
visible: panel.alignment !== Qt.AlignLeft
|
||||
offset: panel.offset
|
||||
graphicElementName: "maxslider"
|
||||
onValueChanged: panel.minimumLength = value
|
||||
maximumPosition: offsetHandle.position - Kirigami.Units.gridUnit * 3
|
||||
minimumPosition: {
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
panel.alignment === Qt.AlignCenter ? Math.max(-size/2, offset*2 - size/2) : -size/2
|
||||
}
|
||||
}
|
||||
|
||||
SliderHandle {
|
||||
id: leftMaximumLengthHandle
|
||||
anchors {
|
||||
right: !root.isHorizontal ? root.right : undefined
|
||||
bottom: root.isHorizontal ? root.bottom : undefined
|
||||
}
|
||||
description: root.maximumText
|
||||
alignment: panel.alignment | Qt.AlignRight
|
||||
visible: panel.alignment !== Qt.AlignLeft
|
||||
offset: panel.offset
|
||||
graphicElementName: "minslider"
|
||||
onValueChanged: panel.maximumLength = value
|
||||
maximumPosition: offsetHandle.position - Kirigami.Units.gridUnit * 3
|
||||
minimumPosition: {
|
||||
var size = dialogRoot.vertical ? height : width
|
||||
panel.alignment === Qt.AlignCenter ? Math.max(-size/2, offset*2 - size/2) : -size/2
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.kirigami 2.20 as Kirigami
|
||||
import org.kde.ksvg 1.0 as KSvg
|
||||
import org.kde.plasma.components 3.0 as PC3
|
||||
import org.kde.plasma.shell.panel 0.1 as Panel
|
||||
import org.kde.kquickcontrols 2.0
|
||||
|
||||
KSvg.SvgItem {
|
||||
id: root
|
||||
|
||||
//Those properties get updated by PanelConfiguration.qml whenever a value changes
|
||||
imagePath: "widgets/containment-controls"
|
||||
elementId: parent.prefix + '-' + graphicElementName
|
||||
width: naturalSize.width
|
||||
height: naturalSize.height
|
||||
|
||||
//value expressed by this slider, this is the distance to offset
|
||||
property int value
|
||||
|
||||
//name of the graphics to load
|
||||
property string graphicElementName
|
||||
|
||||
//where the point "0" is
|
||||
property int offset: 0
|
||||
|
||||
/*handle type: behave in different ways based on the alignment:
|
||||
* alignment === Qt.AlignRight: Panel aligned to right and handle value relative to the right
|
||||
* alignment === Qt.AlignLeft: Panel aligned to left and handle relative to the left
|
||||
* (alignment !== Qt.AlignRight) && (alignment & Qt.AlignRight): Panel aligned to the center and handle right of offset and value doubled
|
||||
* (alignment !== Qt.AlignLeft) && (alignment & Qt.AlignLeft): Panel aligned to the center and handle left of offset and value doubled
|
||||
* else: Panel aligned to center and handle relative to the center
|
||||
* Note that right/left and top/bottom are interchangeable
|
||||
*/
|
||||
property int alignment: panel.alignment
|
||||
|
||||
//The maximum/minimum Position (X/Y) the silder can be moved to
|
||||
property int minimumPosition
|
||||
property int maximumPosition
|
||||
//Provide default position for "reset" action.
|
||||
function defaultPosition(): int {
|
||||
var dialogSize, panelSize;
|
||||
if (dialogRoot.vertical) {
|
||||
dialogSize = dialogRoot.height;
|
||||
panelSize = panel.height;
|
||||
} else {
|
||||
dialogSize = dialogRoot.width;
|
||||
panelSize = panel.width;
|
||||
}
|
||||
return (value === panelSize) ? dialogSize : panelSize;
|
||||
}
|
||||
|
||||
// Handle name displayed as a tooltip.
|
||||
property string description
|
||||
|
||||
property bool hasEverBeenMoved: false
|
||||
|
||||
function syncPos() {
|
||||
if (dialogRoot.vertical) {
|
||||
if (alignment === Qt.AlignRight) {
|
||||
y = root.parent.height - (value + offset + root.height/2)
|
||||
} else if (alignment === Qt.AlignLeft) {
|
||||
y = value + offset - root.height/2
|
||||
} else {
|
||||
if (root.alignment & Qt.AlignRight) {
|
||||
y = root.parent.height/2 - value/2 + offset - root.height/2
|
||||
} else if (root.alignment & Qt.AlignLeft) {
|
||||
y = root.parent.height/2 + value/2 + offset - root.height/2
|
||||
} else {
|
||||
y = root.parent.height/2 + value + offset -root.height/2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (alignment === Qt.AlignRight) {
|
||||
x = root.parent.width - (value + offset + root.width/2)
|
||||
} else if (alignment === Qt.AlignLeft) {
|
||||
x = value + offset - root.width/2
|
||||
} else {
|
||||
if (root.alignment & Qt.AlignRight) {
|
||||
x = root.parent.width/2 - value/2 + offset - root.width/2
|
||||
} else if (root.alignment & Qt.AlignLeft) {
|
||||
x = root.parent.width/2 + value/2 + offset -root.width/2
|
||||
} else {
|
||||
x = root.parent.width/2 + value + offset -root.width/2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onValueChanged: syncPos()
|
||||
onOffsetChanged: syncPos()
|
||||
onAlignmentChanged: syncPos()
|
||||
Connections {
|
||||
target: root.parent
|
||||
function onWidthChanged() {
|
||||
syncPos()
|
||||
}
|
||||
function onHeightChanged() {
|
||||
syncPos()
|
||||
}
|
||||
}
|
||||
|
||||
PC3.ToolTip {
|
||||
text: root.description
|
||||
visible: root.description !== "" && ((area.containsMouse && !area.containsPress) || area.activeFocus)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: area
|
||||
drag {
|
||||
target: parent
|
||||
axis: (dialogRoot.vertical) ? Drag.YAxis : Drag.XAxis
|
||||
minimumX: root.minimumPosition
|
||||
minimumY: root.minimumPosition
|
||||
maximumX: root.maximumPosition
|
||||
maximumY: root.maximumPosition
|
||||
}
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: (dialogRoot.vertical) ? 0 : -Kirigami.Units.gridUnit
|
||||
rightMargin: (dialogRoot.vertical) ? 0 : -Kirigami.Units.gridUnit
|
||||
topMargin: (dialogRoot.vertical) ? -Kirigami.Units.gridUnit : 0
|
||||
bottomMargin: (dialogRoot.vertical) ? -Kirigami.Units.gridUnit : 0
|
||||
}
|
||||
|
||||
readonly property int keyboardMoveStepSize: Math.ceil((root.maximumPosition - root.minimumPosition) / 20)
|
||||
|
||||
activeFocusOnTab: true
|
||||
hoverEnabled: true
|
||||
cursorShape: dialogRoot.vertical ? Qt.SizeVerCursor : Qt.SizeHorCursor
|
||||
|
||||
Accessible.description: root.description
|
||||
|
||||
Keys.onEnterPressed: doubleClicked(null);
|
||||
Keys.onReturnPressed: doubleClicked(null);
|
||||
Keys.onSpacePressed: doubleClicked(null);
|
||||
|
||||
// BEGIN Arrow keys
|
||||
Keys.onUpPressed: if (dialogRoot.vertical) {
|
||||
root.y = Math.max(root.minimumPosition, root.y - ((event.modifiers & Qt.ShiftModifier) ? 1 : keyboardMoveStepSize));
|
||||
changePosition();
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
Keys.onDownPressed: if (dialogRoot.vertical) {
|
||||
root.y = Math.min(root.maximumPosition, root.y + ((event.modifiers & Qt.ShiftModifier) ? 1 : keyboardMoveStepSize));
|
||||
changePosition();
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
Keys.onLeftPressed: if (!dialogRoot.vertical) {
|
||||
root.x = Math.max(root.minimumPosition, root.x - ((event.modifiers & Qt.ShiftModifier) ? 1 : keyboardMoveStepSize));
|
||||
changePosition();
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
Keys.onRightPressed: if (!dialogRoot.vertical) {
|
||||
root.x = Math.min(root.maximumPosition, root.x + ((event.modifiers & Qt.ShiftModifier) ? 1 : keyboardMoveStepSize));
|
||||
changePosition();
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
// END Arrow keys
|
||||
|
||||
onPositionChanged: {
|
||||
if (!drag.active) {
|
||||
return;
|
||||
}
|
||||
changePosition();
|
||||
}
|
||||
onDoubleClicked: {
|
||||
root.value = root.defaultPosition();
|
||||
}
|
||||
|
||||
function changePosition() {
|
||||
root.hasEverBeenMoved = true
|
||||
if (dialogRoot.vertical) {
|
||||
if (root.alignment === Qt.AlignRight) {
|
||||
root.value = root.parent.height - (root.y + offset + root.height/2)
|
||||
} else if (alignment === Qt.AlignLeft) {
|
||||
root.value = root.y - offset + root.height/2
|
||||
//Center
|
||||
} else {
|
||||
if (root.alignment & Qt.AlignRight) {
|
||||
root.value = (root.parent.height/2 - root.y + offset)*2 - root.height
|
||||
} else if (root.alignment & Qt.AlignLeft) {
|
||||
root.value = (root.y - offset - root.parent.height/2)*2 + root.height
|
||||
} else {
|
||||
var value = root.y - root.parent.height/2 - offset + root.height/2
|
||||
//Snap
|
||||
if (Math.abs(value) < 5) {
|
||||
root.value = 0
|
||||
} else {
|
||||
root.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (root.alignment === Qt.AlignRight) {
|
||||
root.value = root.parent.width - (root.x + offset + root.width/2)
|
||||
} else if (alignment === Qt.AlignLeft) {
|
||||
root.value = root.x - offset + root.width/2
|
||||
//Center
|
||||
} else {
|
||||
if (root.alignment & Qt.AlignRight) {
|
||||
root.value = (root.parent.width/2 - root.x + offset)*2 - root.width
|
||||
} else if (root.alignment & Qt.AlignLeft) {
|
||||
root.value = (root.x - offset - root.parent.width/2)*2 + root.width
|
||||
} else {
|
||||
var value = root.x - root.parent.width/2 - offset + root.width/2
|
||||
//Snap
|
||||
if (Math.abs(value) < 5) {
|
||||
root.value = 0
|
||||
} else {
|
||||
root.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaExtras.Highlight {
|
||||
anchors.fill: parent
|
||||
visible: parent.activeFocus
|
||||
hovered: true
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Cyril Rossi <cyril.rossi@enioka.com>
|
||||
SPDX-FileCopyrightText: 2022 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.4 as QQC2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.15
|
||||
|
||||
import org.kde.kirigami 2.13 as Kirigami
|
||||
|
||||
QQC2.Control {
|
||||
id: delegate
|
||||
property Item viewPort
|
||||
readonly property string screenName: model.screenName
|
||||
readonly property int screenId: model.screenId
|
||||
property bool containsDrag
|
||||
property alias contentsLayout: contentsLayout
|
||||
|
||||
width: Math.min(Kirigami.Units.gridUnit * 25, Math.floor(viewPort.width / Math.min(repeater.count, Math.floor(viewPort.width / (Kirigami.Units.gridUnit * 12)))))
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
id: contentsLayout
|
||||
width: Math.min(parent.width, Kirigami.Units.gridUnit * 15)
|
||||
|
||||
Rectangle {
|
||||
id: screenRect
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: width / 1.6
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
border.color: Kirigami.Theme.textColor
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: 9
|
||||
color: "black"
|
||||
opacity: delegate.containsDrag ? 0.3 : 0
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: containmentRepeater
|
||||
model: containments
|
||||
|
||||
Rectangle {
|
||||
id: contRect
|
||||
property real homeX
|
||||
property real homeY
|
||||
property string oldState
|
||||
readonly property int edgeDistance: {
|
||||
return (state === "left" || state === "right" ? width : height) * model.edgePosition;
|
||||
}
|
||||
|
||||
width: moveButton.width
|
||||
height: moveButton.height
|
||||
border.color: Kirigami.Theme.textColor
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
state: model.edge
|
||||
z: state === "floating" ? 0 : 1
|
||||
visible: !model.isDestroyed
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.OpenHandCursor
|
||||
}
|
||||
DragHandler {
|
||||
id: dragHandler
|
||||
property QQC2.Control targetDelegate
|
||||
|
||||
cursorShape: Qt.ClosedHandCursor
|
||||
onActiveChanged: {
|
||||
if (active) {
|
||||
delegate.z = 1;
|
||||
} else {
|
||||
if (targetDelegate) {
|
||||
resetAnim.restart();
|
||||
containmentRepeater.model.moveContainementToScreen(model.containmentId, targetDelegate.screenId)
|
||||
targetDelegate.containsDrag = false;
|
||||
targetDelegate = null;
|
||||
} else {
|
||||
resetAnim.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
onTranslationChanged: {
|
||||
if (!active) {
|
||||
if (targetDelegate) {
|
||||
targetDelegate.containsDrag = false;
|
||||
targetDelegate = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
let pos = contRect.mapToItem(delegate.parent, dragHandler.centroid.position.x, dragHandler.centroid.position.y);
|
||||
let otherDelegate = delegate.parent.childAt(pos.x, pos.y);
|
||||
if (targetDelegate && targetDelegate !== otherDelegate) {
|
||||
targetDelegate.containsDrag = false;
|
||||
}
|
||||
if (!otherDelegate || otherDelegate === delegate) {
|
||||
targetDelegate = null;
|
||||
} else if (otherDelegate && otherDelegate !== delegate
|
||||
&& otherDelegate.hasOwnProperty("screenId")
|
||||
&& otherDelegate.hasOwnProperty("containsDrag")) {
|
||||
targetDelegate = otherDelegate;
|
||||
targetDelegate.containsDrag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
SequentialAnimation {
|
||||
id: resetAnim
|
||||
property var targetDelegatePos: dragHandler.targetDelegate
|
||||
? dragHandler.targetDelegate.contentsLayout.mapToItem(delegate.contentsLayout, 0, 0)
|
||||
: Qt.point(0, 0)
|
||||
ParallelAnimation {
|
||||
XAnimator {
|
||||
target: contRect
|
||||
from: contRect.x
|
||||
to: contRect.homeX + resetAnim.targetDelegatePos.x
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
YAnimator {
|
||||
target: contRect
|
||||
from: contRect.y
|
||||
to: contRect.homeY + resetAnim.targetDelegatePos.y
|
||||
duration: Kirigami.Units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
PropertyAction {
|
||||
target: delegate
|
||||
property: "z"
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: containmentImage
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 1
|
||||
}
|
||||
// It needs to reload the image from disk when the file changes
|
||||
cache: false
|
||||
source: model.imageSource
|
||||
fillMode: model.edge == "floating" ? Image.PreserveAspectCrop : Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
id: moveButton
|
||||
icon.name: "open-menu-symbolic"
|
||||
checked: contextMenu.visible
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: model.edge == "floating"
|
||||
? model.panelCountAtTop * moveButton.height + Kirigami.Units.largeSpacing
|
||||
: 0
|
||||
rightMargin: model.edge == "floating"
|
||||
? (moveButton.LayoutMirroring.enabled ? model.panelCountAtLeft : model.panelCountAtRight) * moveButton.height + Kirigami.Units.largeSpacing
|
||||
: 0
|
||||
}
|
||||
onClicked: {
|
||||
contextMenu.open()
|
||||
}
|
||||
|
||||
QQC2.Menu {
|
||||
id: contextMenu
|
||||
y: moveButton.height
|
||||
Repeater {
|
||||
model: ShellContainmentModel
|
||||
QQC2.MenuItem {
|
||||
text: edge == "floating"
|
||||
? i18nd("plasma_shell_org.kde.plasma.desktop", "Swap with Desktop on Screen %1", model.screenName)
|
||||
: i18nd("plasma_shell_org.kde.plasma.desktop", "Move to Screen %1", model.screenName)
|
||||
visible: model.screenName !== delegate.screenName
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: {
|
||||
containmentRepeater.model.moveContainementToScreen(containmentId, screenId)
|
||||
}
|
||||
}
|
||||
}
|
||||
QQC2.MenuSeparator {
|
||||
visible: removeItem.visible
|
||||
}
|
||||
QQC2.MenuItem {
|
||||
id: removeItem
|
||||
text: contRect.state === "floating"
|
||||
? i18nd("plasma_shell_org.kde.plasma.desktop", "Remove Desktop")
|
||||
: i18nd("plasma_shell_org.kde.plasma.desktop", "Remove Panel")
|
||||
icon.name: "edit-delete"
|
||||
onTriggered: {
|
||||
if (contRect.state === "floating") {
|
||||
ShellContainmentModel.remove(screenId);
|
||||
} else {
|
||||
containments.remove(containmentId);
|
||||
}
|
||||
}
|
||||
visible: contRect.state !== "floating" || !model.active
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "floating"
|
||||
PropertyChanges {
|
||||
target: contRect;
|
||||
width: screenRect.width
|
||||
height: screenRect.height
|
||||
color: "transparent"
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "top"
|
||||
PropertyChanges {
|
||||
target: contRect;
|
||||
width: screenRect.width
|
||||
y: homeY
|
||||
homeX: 0
|
||||
homeY: contRect.edgeDistance
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "right"
|
||||
PropertyChanges {
|
||||
target: contRect;
|
||||
x: homeX
|
||||
homeX: screenRect.width - contRect.width - contRect.edgeDistance;
|
||||
height: screenRect.height
|
||||
homeY: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "bottom"
|
||||
PropertyChanges {
|
||||
target: contRect;
|
||||
y: homeY
|
||||
homeX: 0
|
||||
homeY: screenRect.height - contRect.height - contRect.edgeDistance;
|
||||
width: screenRect.width
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "left"
|
||||
PropertyChanges {
|
||||
target: contRect;
|
||||
height: screenRect.height
|
||||
x: homeX
|
||||
homeX: contRect.edgeDistance
|
||||
homeY: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
text: model.isPrimary
|
||||
? i18nd("plasma_shell_org.kde.plasma.desktop", "%1 (primary)", model.screenName)
|
||||
: model.screenName
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue