You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
12 KiB
292 lines
12 KiB
/* |
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org> |
|
SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
import QtQuick |
|
import QtQuick.Controls |
|
import QtQuick.Layouts |
|
import Qt5Compat.GraphicalEffects |
|
import org.kde.kirigami as Kirigami |
|
import org.kde.kwin as KWinComponents |
|
import org.kde.kwin.private.effects |
|
import org.kde.plasma.components as PC3 |
|
|
|
Item { |
|
id: bar |
|
|
|
readonly property real desktopHeight: Kirigami.Units.gridUnit * 5 |
|
readonly property real desktopWidth: desktopHeight * targetScreen.geometry.width / targetScreen.geometry.height |
|
readonly property real columnHeight: desktopHeight + Kirigami.Units.gridUnit |
|
readonly property real columnWidth: desktopWidth + Kirigami.Units.gridUnit |
|
readonly property int desktopCount: desktopRepeater.count |
|
|
|
property bool verticalDesktopBar |
|
property QtObject windowModel |
|
property alias desktopModel: desktopRepeater.model |
|
property QtObject selectedDesktop: null |
|
property var heap |
|
|
|
implicitHeight: columnHeight + 2 * Kirigami.Units.smallSpacing |
|
implicitWidth: columnWidth + 2 * Kirigami.Units.smallSpacing |
|
|
|
Flickable { |
|
anchors.fill: parent |
|
leftMargin: Math.max((width - contentWidth) / 2, 0) |
|
topMargin: Math.max((height - contentHeight) / 2, 0) |
|
contentWidth: contentItem.childrenRect.width |
|
contentHeight: contentItem.childrenRect.height |
|
interactive: contentWidth > width |
|
clip: true |
|
flickableDirection: Flickable.HorizontalFlick |
|
|
|
Grid { |
|
spacing: Kirigami.Units.largeSpacing |
|
columns: verticalDesktopBar ? 1 : desktopCount + 1 |
|
|
|
Repeater { |
|
id: desktopRepeater |
|
|
|
Column { |
|
id: delegate |
|
activeFocusOnTab: true |
|
width: bar.desktopWidth |
|
height: bar.columnHeight |
|
spacing: Kirigami.Units.smallSpacing |
|
|
|
required property QtObject desktop |
|
required property int index |
|
|
|
Keys.onEnterPressed: activate(); |
|
Keys.onReturnPressed: activate(); |
|
Keys.onSpacePressed: activate(); |
|
Keys.onDeletePressed: remove(); |
|
|
|
Keys.onPressed: { |
|
if (event.key === Qt.Key_F2) { |
|
event.accepted = true; |
|
label.startEditing(); |
|
} |
|
} |
|
|
|
Keys.onLeftPressed: nextItemInFocusChain(LayoutMirroring.enabled).forceActiveFocus(Qt.BacktabFocusReason); |
|
Keys.onRightPressed: nextItemInFocusChain(!LayoutMirroring.enabled).forceActiveFocus(Qt.TabFocusReason); |
|
|
|
function activate() { |
|
if (KWinComponents.Workspace.currentDesktop === delegate.desktop) { |
|
effect.deactivate() |
|
} else { |
|
KWinComponents.Workspace.currentDesktop = delegate.desktop; |
|
} |
|
} |
|
|
|
function remove() { |
|
if (desktopRepeater.count === 1) { |
|
return; |
|
} |
|
if (delegate.activeFocus) { |
|
if (delegate.index === 0) { |
|
desktopRepeater.itemAt(1).forceActiveFocus(); |
|
} else { |
|
desktopRepeater.itemAt(delegate.index - 1).forceActiveFocus(); |
|
} |
|
} |
|
bar.desktopModel.remove(delegate.index); |
|
} |
|
|
|
Item { |
|
width: bar.desktopWidth |
|
height: bar.desktopHeight |
|
|
|
scale: thumbnailHover.hovered ? 1.03 : 1 |
|
|
|
Behavior on scale { |
|
NumberAnimation { |
|
duration: Kirigami.Units.shortDuration |
|
} |
|
} |
|
|
|
HoverHandler { |
|
id: thumbnailHover |
|
} |
|
|
|
DesktopView { |
|
id: thumbnail |
|
|
|
width: targetScreen.geometry.width |
|
height: targetScreen.geometry.height |
|
windowModel: bar.windowModel |
|
desktop: delegate.desktop |
|
scale: bar.desktopHeight / targetScreen.geometry.height |
|
transformOrigin: Item.TopLeft |
|
|
|
|
|
layer.textureSize: Qt.size(bar.desktopWidth, bar.desktopHeight) |
|
layer.enabled: true |
|
layer.effect: OpacityMask { |
|
maskSource: Rectangle { |
|
anchors.centerIn: parent |
|
width: thumbnail.width |
|
height: thumbnail.height |
|
// Using 5% of width since that's constant even under scaling: |
|
radius: width / 20 |
|
} |
|
} |
|
} |
|
|
|
Rectangle { |
|
readonly property bool active: (delegate.activeFocus || dropArea.containsDrag || mouseArea.containsPress || bar.selectedDesktop === delegate.desktop) |
|
anchors.fill: parent |
|
radius: Kirigami.Units.cornerRadius |
|
color: "transparent" |
|
border.width: active ? 2 : 1 |
|
border.color: active ? Kirigami.Theme.highlightColor : Kirigami.Theme.textColor |
|
opacity: dropArea.containsDrag || !active ? 0.5 : 1.0 |
|
} |
|
|
|
MouseArea { |
|
id: mouseArea |
|
anchors.fill: parent |
|
acceptedButtons: Qt.LeftButton |
|
onClicked: mouse => { |
|
mouse.accepted = true; |
|
delegate.activate(); |
|
} |
|
} |
|
|
|
Loader { |
|
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft |
|
active: !bar.heap.dragActive && (hoverHandler.hovered || Kirigami.Settings.tabletMode || Kirigami.Settings.hasTransientTouchInput) && desktopCount > 1 |
|
anchors.right: parent.right |
|
anchors.top: parent.top |
|
sourceComponent: PC3.Button { |
|
text: i18nd("kwin", "Delete Virtual Desktop") |
|
icon.name: "delete" |
|
display: PC3.AbstractButton.IconOnly |
|
|
|
PC3.ToolTip.text: text |
|
PC3.ToolTip.visible: hovered |
|
PC3.ToolTip.delay: Kirigami.Units.toolTipDelay |
|
|
|
onClicked: delegate.remove() |
|
} |
|
} |
|
|
|
DropArea { |
|
id: dropArea |
|
anchors.fill: parent |
|
|
|
onDropped: drop => { |
|
drop.accepted = true; |
|
// dragging a KWin::Window |
|
if (drag.source.desktops.length === 0 || drag.source.desktops.indexOf(delegate.desktop) !== -1) { |
|
drop.action = Qt.IgnoreAction; |
|
return; |
|
} |
|
drag.source.desktops = [delegate.desktop]; |
|
} |
|
} |
|
} |
|
|
|
Item { |
|
id: label |
|
width: bar.desktopWidth |
|
height: Kirigami.Units.gridUnit |
|
state: "normal" |
|
|
|
PC3.Label { |
|
anchors.fill: parent |
|
elide: Text.ElideRight |
|
text: delegate.desktop.name |
|
textFormat: Text.PlainText |
|
horizontalAlignment: Text.AlignHCenter |
|
verticalAlignment: Text.AlignVCenter |
|
visible: label.state === "normal" |
|
} |
|
|
|
MouseArea { |
|
anchors.fill: parent |
|
onPressed: mouse => { |
|
mouse.accepted = true; |
|
label.startEditing(); |
|
} |
|
} |
|
|
|
Loader { |
|
active: label.state === "editing" |
|
anchors.fill: parent |
|
sourceComponent: PC3.TextField { |
|
topPadding: 0 |
|
bottomPadding: 0 |
|
horizontalAlignment: Text.AlignHCenter |
|
verticalAlignment: Text.AlignVCenter |
|
text: delegate.desktop.name |
|
onEditingFinished: { |
|
delegate.desktop.name = text; |
|
label.stopEditing(); |
|
} |
|
Keys.onEscapePressed: label.stopEditing(); |
|
Component.onCompleted: forceActiveFocus(); |
|
} |
|
} |
|
|
|
states: [ |
|
State { |
|
name: "normal" |
|
}, |
|
State { |
|
name: "editing" |
|
} |
|
] |
|
|
|
function startEditing() { |
|
state = "editing"; |
|
} |
|
function stopEditing() { |
|
state = "normal"; |
|
} |
|
} |
|
|
|
HoverHandler { |
|
id: hoverHandler |
|
} |
|
} |
|
} |
|
|
|
PC3.Button { |
|
width: bar.desktopWidth |
|
height: bar.desktopHeight |
|
|
|
text: i18nd("kwin", "Add Virtual Desktop") |
|
icon.name: "list-add" |
|
display: PC3.AbstractButton.IconOnly |
|
opacity: hovered ? 1 : 0.75 |
|
|
|
PC3.ToolTip.text: text |
|
PC3.ToolTip.visible: hovered |
|
PC3. ToolTip.delay: Kirigami.Units.toolTipDelay |
|
Accessible.name: text |
|
|
|
Keys.onReturnPressed: action.trigger() |
|
Keys.onEnterPressed: action.trigger() |
|
|
|
Keys.onLeftPressed: nextItemInFocusChain(LayoutMirroring.enabled).forceActiveFocus(Qt.BacktabFocusReason); |
|
Keys.onRightPressed: nextItemInFocusChain(!LayoutMirroring.enabled).forceActiveFocus(Qt.TabFocusReason); |
|
|
|
onClicked: desktopModel.create(desktopModel.rowCount()) |
|
|
|
DropArea { |
|
anchors.fill: parent |
|
onEntered: drag => { |
|
drag.accepted = desktopModel.rowCount() < 20 |
|
} |
|
onDropped: drag => { |
|
drag.source.desktops = [desktopModel.create(desktopModel.rowCount())]; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
}
|
|
|