plasma-taskmanager-zoom/contents/ui/GroupDialog.qml

171 lines
6.7 KiB
QML

/*
SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org>
SPDX-FileCopyrightText: 2021 Fushan Wen <qydwhotmail@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick
import QtQml.Models
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents3
import org.kde.kirigami as Kirigami
import org.kde.plasma.plasmoid
import "code/layoutmetrics.js" as LayoutMetrics
PlasmaCore.Dialog {
id: groupDialog
visible: true
type: PlasmaCore.Dialog.PopupMenu
flags: Qt.WindowStaysOnTopHint
hideOnWindowDeactivate: true
location: Plasmoid.location
readonly property real preferredWidth: Screen.width / 3
readonly property real preferredHeight: Screen.height / 2
readonly property real contentWidth: mainItem.width // No padding here to avoid text elide.
property /*PlasmaCore.ItemStatus*/int _oldAppletStatus: PlasmaCore.Types.UnknownStatus
function findActiveTaskIndex(): void {
if (!tasksModel.activeTask) {
return;
}
for (let i = 0; i < groupListView.count; i++) {
if (tasksModel.makeModelIndex(visualParent.index, i) === tasksModel.activeTask) {
groupListView.positionViewAtIndex(i, ListView.Contain); // Prevent visual glitches
groupListView.currentIndex = i;
return;
}
}
}
mainItem: MouseHandler {
id: mouseHandler
width: Math.min(groupDialog.preferredWidth, Math.max(groupListView.maxWidth, groupDialog.visualParent.width))
height: Math.min(groupDialog.preferredHeight, groupListView.maxHeight)
target: groupListView
handleWheelEvents: !scrollView.overflowing
isGroupDialog: true
Keys.onEscapePressed: event => {
groupDialog.visible = false;
}
function moveRow(event: KeyEvent, insertAt: int): void {
if (!(event.modifiers & Qt.ControlModifier) || !(event.modifiers & Qt.ShiftModifier)) {
event.accepted = false;
return;
} else if (insertAt < 0 || insertAt >= groupListView.count) {
return;
}
const parentModelIndex = tasksModel.makeModelIndex(groupDialog.visualParent.index);
const status = tasksModel.move(groupListView.currentIndex, insertAt, parentModelIndex);
if (!status) {
return;
}
groupListView.currentIndex = insertAt;
}
PlasmaComponents3.ScrollView {
id: scrollView
// To achieve a bottom-to-top layout on vertical panels, the task manager
// is rotated by 180 degrees(see main.qml). This makes the group dialog's
// items rotated, so un-rotate them here to fix that.
rotation: Plasmoid.configuration.reverseMode && Plasmoid.formFactor === PlasmaCore.Types.Vertical ? 180 : 0
anchors.fill: parent
readonly property bool overflowing: leftPadding > 0 || rightPadding > 0 // Scrollbar is visible
ListView {
id: groupListView
readonly property real maxWidth: groupFilter.maxTextWidth
+ LayoutMetrics.horizontalMargins()
+ Kirigami.Units.iconSizes.medium
+ 2 * (LayoutMetrics.labelMargin + LayoutMetrics.iconMargin)
+ scrollView.leftPadding + scrollView.rightPadding
// Use groupFilter.count because sometimes count is not updated in time (BUG 446105)
readonly property real maxHeight: groupFilter.count * (LayoutMetrics.verticalMargins() + Math.max(Kirigami.Units.iconSizes.sizeForLabels, Kirigami.Units.iconSizes.medium))
model: DelegateModel {
id: groupFilter
readonly property TextMetrics textMetrics: TextMetrics {}
property real maxTextWidth: 0
model: tasksModel
rootIndex: tasksModel.makeModelIndex(groupDialog.visualParent.index)
delegate: Task {
width: groupListView.width
visible: true
inPopup: true
tasksRoot: tasks
ListView.onRemove: Qt.callLater(groupFilter.updateMaxTextWidth)
Connections {
enabled: index < 20 // 20 is based on performance considerations.
function onLabelTextChanged(): void { // ListView.onAdd included
if (groupFilter.maxTextWidth === 0) {
// Update immediately to avoid shrinking
groupFilter.updateMaxTextWidth();
} else {
Qt.callLater(groupFilter.updateMaxTextWidth);
}
}
}
}
function updateMaxTextWidth(): void {
let tempMaxTextWidth = 0;
// 20 is based on performance considerations.
for (let i = 0; i < Math.min(count, 20); i++) {
textMetrics.text = items.get(i).model.display;
if (textMetrics.boundingRect.width > tempMaxTextWidth) {
tempMaxTextWidth = textMetrics.boundingRect.width;
}
}
maxTextWidth = tempMaxTextWidth;
}
}
reuseItems: false
Keys.onUpPressed: event => mouseHandler.moveRow(event, groupListView.currentIndex - 1)
Keys.onDownPressed: event => mouseHandler.moveRow(event, groupListView.currentIndex + 1)
onCountChanged: {
if (count > 0) {
backend.cancelHighlightWindows()
} else {
groupDialog.visible = false;
}
}
}
}
}
onVisibleChanged: {
if (visible) {
_oldAppletStatus = Plasmoid.status;
Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
groupDialog.requestActivate();
groupListView.forceActiveFocus(); // Active focus on ListView so keyboard navigation can work.
Qt.callLater(findActiveTaskIndex);
} else {
Plasmoid.status = _oldAppletStatus;
tasks.groupDialog = null;
destroy();
}
}
}