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 }