Warning, /plasma/kwin/src/plugins/overview/qml/DesktopBar.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003     SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 import QtQuick
0009 import QtQuick.Controls
0010 import QtQuick.Layouts
0011 import Qt5Compat.GraphicalEffects
0012 import org.kde.kirigami as Kirigami
0013 import org.kde.kwin as KWinComponents
0014 import org.kde.kwin.private.effects
0015 import org.kde.plasma.components as PC3
0016 
0017 Item {
0018     id: bar
0019 
0020     readonly property real desktopHeight: Kirigami.Units.gridUnit * 5
0021     readonly property real desktopWidth: desktopHeight * targetScreen.geometry.width / targetScreen.geometry.height
0022     readonly property real columnHeight: desktopHeight + Kirigami.Units.gridUnit
0023     readonly property real columnWidth: desktopWidth + Kirigami.Units.gridUnit
0024     readonly property int desktopCount: desktopRepeater.count
0025 
0026     property bool verticalDesktopBar
0027     property QtObject windowModel
0028     property alias desktopModel: desktopRepeater.model
0029     property QtObject selectedDesktop: null
0030     property var heap
0031 
0032     implicitHeight: columnHeight + 2 * Kirigami.Units.smallSpacing
0033     implicitWidth: columnWidth + 2 * Kirigami.Units.smallSpacing
0034 
0035     Flickable {
0036         anchors.fill: parent
0037         leftMargin: Math.max((width - contentWidth) / 2, 0)
0038         topMargin: Math.max((height - contentHeight) / 2, 0)
0039         contentWidth: contentItem.childrenRect.width
0040         contentHeight: contentItem.childrenRect.height
0041         interactive: contentWidth > width
0042         clip: true
0043         flickableDirection: Flickable.HorizontalFlick
0044 
0045         Grid {
0046             spacing: Kirigami.Units.largeSpacing
0047             columns: verticalDesktopBar ? 1 : desktopCount + 1
0048 
0049             Repeater {
0050                 id: desktopRepeater
0051 
0052                 Column {
0053                     id: delegate
0054                     activeFocusOnTab: true
0055                     width: bar.desktopWidth
0056                     height: bar.columnHeight
0057                     spacing: Kirigami.Units.smallSpacing
0058 
0059                     required property QtObject desktop
0060                     required property int index
0061 
0062                     Keys.onEnterPressed: activate();
0063                     Keys.onReturnPressed: activate();
0064                     Keys.onSpacePressed: activate();
0065                     Keys.onDeletePressed: remove();
0066 
0067                     Keys.onPressed: {
0068                         if (event.key === Qt.Key_F2) {
0069                             event.accepted = true;
0070                             label.startEditing();
0071                         }
0072                     }
0073 
0074                     Keys.onLeftPressed: nextItemInFocusChain(LayoutMirroring.enabled).forceActiveFocus(Qt.BacktabFocusReason);
0075                     Keys.onRightPressed: nextItemInFocusChain(!LayoutMirroring.enabled).forceActiveFocus(Qt.TabFocusReason);
0076 
0077                     function activate() {
0078                         if (KWinComponents.Workspace.currentDesktop === delegate.desktop) {
0079                             effect.deactivate()
0080                         } else {
0081                             KWinComponents.Workspace.currentDesktop = delegate.desktop;
0082                         }
0083                     }
0084 
0085                     function remove() {
0086                         if (desktopRepeater.count === 1) {
0087                             return;
0088                         }
0089                         if (delegate.activeFocus) {
0090                             if (delegate.index === 0) {
0091                                 desktopRepeater.itemAt(1).forceActiveFocus();
0092                             } else {
0093                                 desktopRepeater.itemAt(delegate.index - 1).forceActiveFocus();
0094                             }
0095                         }
0096                         bar.desktopModel.remove(delegate.index);
0097                     }
0098 
0099                     Item {
0100                         width: bar.desktopWidth
0101                         height: bar.desktopHeight
0102 
0103                         scale: thumbnailHover.hovered ? 1.03 : 1
0104 
0105                         Behavior on scale {
0106                             NumberAnimation {
0107                                 duration: Kirigami.Units.shortDuration
0108                             }
0109                         }
0110 
0111                         HoverHandler {
0112                             id: thumbnailHover
0113                         }
0114 
0115                         DesktopView {
0116                             id: thumbnail
0117 
0118                             width: targetScreen.geometry.width
0119                             height: targetScreen.geometry.height
0120                             windowModel: bar.windowModel
0121                             desktop: delegate.desktop
0122                             scale: bar.desktopHeight / targetScreen.geometry.height
0123                             transformOrigin: Item.TopLeft
0124 
0125 
0126                             layer.textureSize: Qt.size(bar.desktopWidth, bar.desktopHeight)
0127                             layer.enabled: true
0128                             layer.effect: OpacityMask {
0129                                 maskSource: Rectangle {
0130                                     anchors.centerIn: parent
0131                                     width: thumbnail.width
0132                                     height: thumbnail.height
0133                                     // Using 5% of width since that's constant even under scaling:
0134                                     radius: width / 20
0135                                 }
0136                             }
0137                         }
0138 
0139                         Rectangle {
0140                             readonly property bool active: (delegate.activeFocus || dropArea.containsDrag || mouseArea.containsPress || bar.selectedDesktop === delegate.desktop)
0141                             anchors.fill: parent
0142                             radius: width / 20
0143                             color: "transparent"
0144                             border.width: active ? 2 : 1
0145                             border.color: active ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor
0146                             opacity: dropArea.containsDrag || !active ? 0.5 : 1.0
0147                         }
0148 
0149                         MouseArea {
0150                             id: mouseArea
0151                             anchors.fill: parent
0152                             acceptedButtons: Qt.LeftButton | Qt.MiddleButton
0153                             onClicked: mouse => {
0154                                 mouse.accepted = true;
0155                                 switch (mouse.button) {
0156                                 case Qt.LeftButton:
0157                                     delegate.activate();
0158                                     break;
0159                                 case Qt.MiddleButton:
0160                                     delegate.remove();
0161                                     break;
0162                                 }
0163                             }
0164                         }
0165 
0166                         Loader {
0167                             LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0168                             active: !bar.heap.dragActive && (hoverHandler.hovered || Kirigami.Settings.tabletMode || Kirigami.Settings.hasTransientTouchInput) && desktopCount > 1
0169                             anchors.right: parent.right
0170                             anchors.top: parent.top
0171                             sourceComponent: PC3.Button {
0172                                 text: i18nd("kwin", "Delete Virtual Desktop")
0173                                 icon.name: "delete"
0174                                 display: PC3.AbstractButton.IconOnly
0175 
0176                                 PC3.ToolTip.text: text
0177                                 PC3.ToolTip.visible: hovered
0178                                 PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0179 
0180                                 onClicked: delegate.remove()
0181                             }
0182                         }
0183 
0184                         DropArea {
0185                             id: dropArea
0186                             anchors.fill: parent
0187 
0188                             onDropped: drop => {
0189                                 drop.accepted = true;
0190                                 // dragging a KWin::Window
0191                                 if (drag.source.desktops.length === 0 || drag.source.desktops.indexOf(delegate.desktop) !== -1) {
0192                                     drop.action = Qt.IgnoreAction;
0193                                     return;
0194                                 }
0195                                 drag.source.desktops = [delegate.desktop];
0196                             }
0197                         }
0198                     }
0199 
0200                     Item {
0201                         id: label
0202                         width: bar.desktopWidth
0203                         height: Kirigami.Units.gridUnit
0204                         state: "normal"
0205 
0206                         PC3.Label {
0207                             anchors.fill: parent
0208                             elide: Text.ElideRight
0209                             text: delegate.desktop.name
0210                             textFormat: Text.PlainText
0211                             horizontalAlignment: Text.AlignHCenter
0212                             verticalAlignment: Text.AlignVCenter
0213                             visible: label.state === "normal"
0214                         }
0215 
0216                         MouseArea {
0217                             anchors.fill: parent
0218                             onPressed: mouse => {
0219                                 mouse.accepted = true;
0220                                 label.startEditing();
0221                             }
0222                         }
0223 
0224                         Loader {
0225                             active: label.state === "editing"
0226                             anchors.fill: parent
0227                             sourceComponent: PC3.TextField {
0228                                 topPadding: 0
0229                                 bottomPadding: 0
0230                                 horizontalAlignment: Text.AlignHCenter
0231                                 verticalAlignment: Text.AlignVCenter
0232                                 text: delegate.desktop.name
0233                                 onEditingFinished: {
0234                                     delegate.desktop.name = text;
0235                                     label.stopEditing();
0236                                 }
0237                                 Keys.onEscapePressed: label.stopEditing();
0238                                 Component.onCompleted: forceActiveFocus();
0239                             }
0240                         }
0241 
0242                         states: [
0243                             State {
0244                                 name: "normal"
0245                             },
0246                             State {
0247                                 name: "editing"
0248                             }
0249                         ]
0250 
0251                         function startEditing() {
0252                             state = "editing";
0253                         }
0254                         function stopEditing() {
0255                             state = "normal";
0256                         }
0257                     }
0258 
0259                     HoverHandler {
0260                         id: hoverHandler
0261                     }
0262                 }
0263             }
0264 
0265             PC3.Button {
0266                 width: bar.desktopWidth
0267                 height: bar.desktopHeight
0268 
0269                 text: i18nd("kwin", "Add Virtual Desktop")
0270                 icon.name: "list-add"
0271                 display: PC3.AbstractButton.IconOnly
0272                 opacity: hovered ? 1 : 0.75
0273 
0274                 PC3.ToolTip.text: text
0275                 PC3.ToolTip.visible: hovered
0276                 PC3. ToolTip.delay: Kirigami.Units.toolTipDelay
0277                 Accessible.name: text
0278 
0279                 Keys.onReturnPressed: action.trigger()
0280                 Keys.onEnterPressed: action.trigger()
0281 
0282                 Keys.onLeftPressed: nextItemInFocusChain(LayoutMirroring.enabled).forceActiveFocus(Qt.BacktabFocusReason);
0283                 Keys.onRightPressed: nextItemInFocusChain(!LayoutMirroring.enabled).forceActiveFocus(Qt.TabFocusReason);
0284 
0285                 onClicked: desktopModel.create(desktopModel.rowCount())
0286 
0287                 DropArea {
0288                     anchors.fill: parent
0289                     onEntered: drag => {
0290                         drag.accepted = desktopModel.rowCount() < 20
0291                     }
0292                     onDropped: drag => {
0293                         drag.source.desktops = [desktopModel.create(desktopModel.rowCount())];
0294                     }
0295                 }
0296             }
0297         }
0298     }
0299 }