171 lines
6.7 KiB
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();
|
|
}
|
|
}
|
|
}
|