fix: 修复拖拽异常问题

This commit is contained in:
hewenfei 2024-05-14 15:56:55 +08:00 committed by iaom
parent 7d44c0b226
commit 208d111883
6 changed files with 571 additions and 293 deletions

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2024, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: hxf <hewenfei@kylinos.cn>
*
*/
import QtQml 2.15
import QtQuick 2.15
QtObject {
property var windowIdList: []
property var windowIcons: {}
property var windowTitles: {}
property Item currentTaskItem: null
}

View File

@ -1,232 +1,258 @@
/*
* Copyright (C) 2024, KylinSoft Co., Ltd.
*
* * Copyright (C) 2023, KylinSoft Co., Ltd.
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
* * Authors: qiqi49 <qiqi@kylinos.cn>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: qiqi49 <qiqi@kylinos.cn>
* hxf <hewenfei@kylinos.cn>
*
*/
import QtQml 2.15
import QtQuick 2.12
import QtQml.Models 2.12
import QtQuick.Layouts 1.12
import QtQuick 2.15
import QtQml.Models 2.15
import org.ukui.quick.widgets 1.0
import org.ukui.panel.taskManager 1.0 as UkuiTaskManager
import org.ukui.quick.items 1.0 as Items
import org.ukui.quick.platform 1.0 as Platform
// taskManager
ListView {
id: baseView
property bool isMergeApp: false
property int dragStartIndex: 0
property bool isBusy: false
property int itemSize: (orientation == ListView.Horizontal) ? height : width
property var screen
property int panelPosition: Widget.container.position
property alias viewModel: proxyModel
DropArea {
id: taskItemListRoot
signal itemContainsMouse(bool containsMouse, var msg)
spacing: 4
property var dragedObj: null
property alias view: taskItemView
property alias viewModel: taskItemProxyModel
property bool taskManagerActived: false
interactive: false
//
signal requestThumbnailView(bool show, TaskItemData data)
UkuiTaskManager.TaskManagerFilterModel {
id: proxyModel
id: taskItemProxyModel
sourceModel: UkuiTaskManager.TaskManager
screen: baseView.screen
screen: Widget.container.screen
}
model: DelegateModel {
id: visualModel
model: proxyModel
delegate: DropArea {
id: dropArea
property int order: DelegateModel.itemsIndex
// winId
property var singleWinId: []
width: orientation == ListView.Horizontal ? content.width : baseView.itemSize
height: orientation == ListView.Horizontal ? baseView.itemSize : content.height
Component {
id: taskIconComponent
Items.Icon {}
}
onWidthChanged: {
if(baseView.isBusy) {
baseView.forceLayout();
DelegateModel {
id: taskItemDelegateModel
property bool isMergeStatus: (Widget.globalConfig.mergeIcons === 0)
property var dragedObject: null
/**
* Item
*/
function removeTempItems() {
for (let i = tempItems.count - 1; i >= 0; --i) {
const obj = tempItems.get(i);
tempItems.remove(i);
if (obj.inItems) {
taskItemDelegateModel.items.remove(obj.itemsIndex);
}
}
}
onEntered: {
if (drag.y >= baseView.itemSize || drag.y <= 0) {
visualModel.items.move(baseView.count - 1, dropArea.order);
} else {
visualModel.items.move(drag.source.draggableOrder, dropArea.order);
}
}
onExited: {
if (drag.y >= baseView.itemSize || drag.y <= 0) {
visualModel.items.move(drag.source.draggableOrder, baseView.count - 1);
/**
* Item全部归位persistedItems组中移除
*/
function resetPersistedItems() {
let i = persistedItems.count - 1;
for (; i >= 0; --i) {
const persistedItemObj = persistedItems.get(i);
if (!persistedItemObj.inItems) {
// TODO: listviewItem
let tmpItemsIndex = persistedItemObj.itemsIndex;
persistedItems.addGroups(i, 1, [items.name]);
items.move(persistedItemObj.itemsIndex, tmpItemsIndex, 0);
}
persistedItems.remove(i, 1);
}
Item {
id: draggableItem
property int draggableOrder: dropArea.order
anchors.fill: parent
dragedObject = null;
removeTempItems();
}
Drag.supportedActions: Qt.CopyAction
Drag.dragType: Drag.Automatic
Drag.active: mouseArea.drag.active
// Items
groups: [
DelegateModelGroup { id: tempItems; name: "tempItems" }
]
function grabImage() {
var icon = mouseGrabImage.createObject(draggableItem, { width: baseView.itemSize, height: baseView.itemSize, source: model.Icon})
model: taskItemProxyModel
delegate: Item {
id: taskItemRoot
property int dragStartIndex: -1
property var icon: model.Icon
property bool isDragStatus: false
property bool useSingleItem: taskItemDelegateModel.isMergeStatus || CurrentWinIdList.length < 1
width: taskItemView.isHorizontal ? taskItemLoader.width : taskItemView.width
height: taskItemView.isHorizontal ? taskItemView.height : taskItemLoader.height
visible: DelegateModel.inItems
onIconChanged: {
generateDragImage();
}
function generateDragImage() {
let icon = taskIconComponent.createObject(this, {width: taskItemView.taskItemSize, height: taskItemView.taskItemSize, source: model.Icon});
if (icon !== null) {
icon.grabToImage(function (result) {
draggableItem.Drag.imageSource = result.url
return result;
taskItemRoot.Drag.imageSource = result.url;
icon.destroy();
});
icon.opacity = 0;
icon.visible = false
}
}
// ,
Drag.dragType: Drag.None
Drag.hotSpot: Qt.point(taskItemView.taskItemSize/2, taskItemView.taskItemSize/2)
//
Drag.onDragFinished: function (dropAction) {
//
if (DelegateModel.inPersistedItems) {
const myPObj = taskItemDelegateModel.persistedItems.get(DelegateModel.persistedItemsIndex);
taskItemDelegateModel.persistedItems.addGroups(myPObj.persistedItemsIndex, 1, [taskItemDelegateModel.items.name]);
//
const idx = (dragStartIndex < 0) ? myPObj.itemsIndex : (dragStartIndex >= taskItemDelegateModel.items.count) ? taskItemDelegateModel.items.count : dragStartIndex
if (myPObj.itemsIndex !== idx) {
taskItemDelegateModel.items.move(myPObj.itemsIndex, idx, 1);
}
}
taskItemDelegateModel.resetPersistedItems();
taskItemRoot.isDragStatus = false;
}
function startDrag() {
//
if (!DelegateModel.inItems || DelegateModel.inPersistedItems || DelegateModel.inTempItems) {
return;
}
const delegateModel = DelegateModel.model;
const itemsIndex = DelegateModel.itemsIndex;
dragStartIndex = itemsIndex;
//
delegateModel.dragedObject = delegateModel.items.get(itemsIndex);
//
delegateModel.items.addGroups(itemsIndex, 1, [delegateModel.persistedItems.name]);
taskItemRoot.isDragStatus = true;
Drag.mimeData = {
"text/plain": '{"dragStartIndex":' + dragStartIndex + "}"
};
Drag.active = true;
// Action
Drag.startDrag(Qt.MoveAction);
}
Binding {
target: taskItemListRoot
property: "taskManagerActived"
when: model.DemandsAttentionWinIdList.length !== 0
value: true
}
MouseArea {
id: mouseArea
width: orientation == ListView.Horizontal ? content.width : baseView.itemSize
height: orientation == ListView.Horizontal ? baseView.itemSize : content.height
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
// enabled: !taskItemRoot.DelegateModel.inTempItems
// *********drag*********
drag.target: draggableItem
drag.onActiveChanged: {
if (drag.active) {
baseView.isBusy = true;
if (baseView.isMergeApp) {
contentHide();
property int lastIndex: -1
property string currentWid: ""
function activeWinId(winId) {
//
taskItemListRoot.requestThumbnailView(false, null);
if (UkuiTaskManager.TaskManager.windowIsActivated(winId)) {
UkuiTaskManager.TaskManager.execSpecifiedAction(UkuiTaskManager.Action.Minimize, winId);
} else {
content.item.toDraggingFinished.connect(contentHide);
}
} else {
baseView.isBusy = false;
content.opacity = 1;
if (baseView.isMergeApp) {
dragFinished();
} else {
content.item.toNormalFinished.connect(dragFinished);
}
UkuiTaskManager.TaskManager.activateWindow(winId);
}
}
function contentHide() {
content.opacity = 0;
//
// onPressed: parent.generateDragImage();
onPressAndHold: {
taskItemRoot.startDrag();
}
function dragFinished() {
proxyModel.setOrder(visualModel.model.index(baseView.dragStartIndex, 0), dropArea.order);
}
// *********mouseEvent*********
onPressed: {
draggableItem.grabImage();
baseView.dragStartIndex = draggableItem.draggableOrder;
}
onClicked: {
onClicked: (mouse) => {
if (mouse.button === Qt.RightButton) {
proxyModel.openMenu(false, model.Actions, baseView);
taskItemProxyModel.openMenu(false, model.Actions, taskItemView);
} else {
if (CurrentWinIdList.length === 0) {
visualModel.model.launch(visualModel.model.index(model.index, 0));
return;
}
var index = -1;
if (CurrentWinIdList.length === 1) {
index = 0;
} else if (!isMergeApp) {
index = content.item.indexAt(mouseX, mouseY);
}
if (index === -1) {
taskItemDelegateModel.model.launch(taskItemDelegateModel.model.index(model.index, 0));
return;
}
var currentWinId = CurrentWinIdList[index];
if (UkuiTaskManager.TaskManager.windowIsActivated(currentWinId)) {
UkuiTaskManager.TaskManager.execSpecifiedAction(UkuiTaskManager.Action.Minimize, currentWinId);
let index = -1;
if (taskItemDelegateModel.isMergeStatus) {
//
if (currentWid !== "") {
index = CurrentWinIdList.indexOf(currentWid);
if (index < (CurrentWinIdList.length - 1)) {
++index;
} else {
UkuiTaskManager.TaskManager.activateWindow(currentWinId);
index = 0;
}
}
} else {
// taskList
index = taskItemLoader.item.indexAt(mouseX, mouseY);
}
if (index < 0) {
index = 0;
} else if (index >= CurrentWinIdList.length) {
index = CurrentWinIdList.length - 1;
}
currentWid = CurrentWinIdList[index];
activeWinId(currentWid);
}
}
onEntered: {
//
if (CurrentWinIdList.length !== 0 && !baseView.isBusy) {
if (isMergeApp) {
activeThumbnail(this, true, -1);
} else {
content.item.itemContainsMouse.connect(activeThumbnail);
if (CurrentWinIdList.length > 0) {
if (taskItemDelegateModel.isMergeStatus) {
taskItemData.windowIdList = CurrentWinIdList;
taskItemData.currentTaskItem = taskItemRoot;
taskItemListRoot.requestThumbnailView(true, taskItemData);
}
}
}
onExited: {
activeThumbnail(this, false, -1);
taskItemListRoot.requestThumbnailView(false, taskItemData);
}
QtObject {
id: message
property var currentWinIdList: isMergeApp ? model.CurrentWinIdList : singleWinId
property var windowTitles: model.WindowTitles
property var windowIcons: model.WindowIcons
}
function activeThumbnail(item, containsMouse, index) {
if (containsMouse) {
thumbnailView.visualParent = item;
if (!isMergeApp) {
var wid = model.CurrentWinIdList[index];
singleWinId = [wid];
}
itemContainsMouse(true, message);
} else {
itemContainsMouse(false, null);
}
}
Loader {
id: content
property var currentWinIdList: model.CurrentWinIdList
property var modelIcon: model.Icon
property var demandsAttentionWinIdList: model.DemandsAttentionWinIdList
property var hasActiveWindow: model.HasActiveWindow
property var index: model.index
property var windowTitles: model.WindowTitles
property var windowIcons: model.WindowIcons
sourceComponent: (isMergeApp || (currentWinIdList.length === 0)) ? appIconComponent : applistComponent
onCurrentWinIdListChanged: {
if (!currentWinIdList) {
currentWinIdList = [];
}
}
Binding {
target: baseView
property: "panelActive"
when: model.DemandsAttentionWinIdList.length !== 0
value: true
}
TaskItemData {
id: taskItemData
windowIdList: model.CurrentWinIdList
windowIcons: model.WindowIcons
windowTitles: model.WindowTitles
}
Items.Tooltip {
@ -235,7 +261,7 @@ ListView {
mainText: Name
posFollowCursor: false
// tooltip
active: model.CurrentWinIdList.length === 0
active: CurrentWinIdList.length < 1
location: {
switch(Widget.container.position) {
case Items.Types.Bottom:
@ -250,56 +276,111 @@ ListView {
}
margin: 6
}
Loader {
id: taskItemLoader
property var taskItemData: model
function loadedItemRequest(show, windId, item) {
taskItemData.windowIdList = [windId];
taskItemData.currentTaskItem = item;
taskItemListRoot.requestThumbnailView(show, taskItemData);
}
sourceComponent: {
if (taskItemRoot.DelegateModel.inTempItems) {
return tempTaskitem;
}
if (taskItemRoot.useSingleItem) {
return singleTaskItem;
}
return listTaskItem;
}
onLoaded: {
if (!taskItemRoot.useSingleItem) {
item.onRequestThumbnailView.connect(loadedItemRequest);
}
}
Component.onDestruction: {
if (!taskItemRoot.useSingleItem) {
item.onRequestThumbnailView.disconnect(loadedItemRequest);
}
}
}
Component {
id: tempTaskitem
Item {
width: taskItemView.taskItemSize
height: taskItemView.taskItemSize
}
}
// +
Component {
id: applistComponent
id: listTaskItem
UkuiTaskManager.AppList {
height: childrenRect.height
width: childrenRect.width
itemSize: baseView.itemSize
isDragged: draggableItem.Drag.active
orientation: baseView.orientation
model: CurrentWinIdList
itemSize: taskItemView.taskItemSize
isDragged: taskItemRoot.isDragStatus
orientation: taskItemView.orientation
spacing: taskItemView.spacing
model: taskItemData.CurrentWinIdList
}
}
//
Component {
id: appIconComponent
id: singleTaskItem
UkuiTaskManager.AppIcon {
height: baseView.itemSize
width: baseView.itemSize
width: taskItemView.taskItemSize
height: taskItemView.taskItemSize
appBackgroud.alpha: mouseArea.containsPress ? 0.10 : mouseArea.containsMouse ? 0.05 : 0
appIcon.source: modelIcon
appIcon.source: taskItemData.Icon
appIcon.scale: mouseArea.containsPress ? 0.9 : 1.0
}
}
}
}
}
Component {
id: mouseGrabImage
Items.ThemeIcon { }
}
ListView {
id: taskItemView
anchors.fill: parent
// contentWidth: childrenRect.width
// width: childrenRect.width
// height: parent.height
property bool isHorizontal: orientation === ListView.Horizontal
property real taskItemSize: isHorizontal ? taskItemView.height : taskItemView.width
interactive: false
spacing: 4
orientation: (Widget.orientation === Items.Types.Horizontal) ? ListView.Horizontal : ListView.Vertical
model: taskItemDelegateModel
displaced: Transition {
NumberAnimation {
properties: "x,y"
easing.type: Easing.OutQuad
duration: 250
duration: 300
}
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
}
add: Transition {
NumberAnimation {
id: addAnimation
property: (panelPosition == 2 || panelPosition == 4) ? "y" : "x"
from: (panelPosition == 1 || panelPosition == 2) ? -itemSize : itemSize
property: taskItemView.isHorizontal ? "y" : "x"
from: taskItemView.isHorizontal ? -taskItemView.taskItemSize : taskItemView.taskItemSize
to: 0
easing.overshoot: 4; easing.amplitude: 2
easing.type: Easing.OutBack; duration: 300
@ -316,3 +397,170 @@ ListView {
}
}
}
// ListViewContentItem
// listviewdropArea
function getContentPoint(localX, localY) {
return Qt.point(localX + taskItemView.contentX, localY + taskItemView.contentY);
}
/**
*
* : true
* : false
*/
function isInternalEvent() {
return taskItemDelegateModel.dragedObject !== null;
}
// Item
function getItemMidPoint(item) {
return Qt.point(item.x + item.width/2, item.y + item.height/2);
}
// point item
function beforeMidpoint(item, point) {
let midPoint = getItemMidPoint(item);
if (taskItemView.orientation === ListView.Horizontal) {
return point.x < midPoint.x;
} else {
return point.y < midPoint.y
}
}
// 1.
// Item
onEntered: (dragEvent) => {
// 1.
let enterX = dragEvent.x === width ? dragEvent.x - 1 : dragEvent.x;
let enterY = dragEvent.y === height ? dragEvent.y - 1 : dragEvent.y;
const contentPoint = getContentPoint(enterX, enterY);
// 2.Item,Item
if (tempItems.count > 0) {
taskItemDelegateModel.removeTempItems();
}
// 3.Item, null
let insertIndex = -1;
let pointItem = taskItemView.itemAt(contentPoint.x, contentPoint.y);
if (pointItem !== null) {
// 4.itemsIndex
insertIndex = pointItem.DelegateModel.itemsIndex;
// insertIndex or insertIndex+1
const maxIdx = taskItemDelegateModel.items.count - 1;
if ((insertIndex > 0) && (insertIndex < maxIdx) && beforeMidpoint(pointItem, contentPoint)) {
++insertIndex;
}
} else {
// 5.
insertIndex = taskItemDelegateModel.items.count;
}
/**
* 4.
*
* 1.listview的Item进行位置的调整
* 2.
*/
const internal = isInternalEvent();
if (internal) {
//
let draggedObj = taskItemDelegateModel.persistedItems.get(0);
// items
if (draggedObj.inItems) {
taskItemDelegateModel.items.removeGroups(draggedObj.itemsIndex, 1, ["items"]);
}
} else {
//
dragEvent.accepted = false;
return;
}
// 5.ItemtempItems
taskItemDelegateModel.items.insert(
insertIndex,
{
Name: ""
},
[taskItemDelegateModel.items.name, "tempItems"]
);
}
// 2.
onExited: {
taskItemDelegateModel.removeTempItems();
}
// 3.
onPositionChanged: (dragEvent) => {
if (tempItems.count === 1) {
//
let currentPoint = getContentPoint(dragEvent.x, dragEvent.y);
let targetItem = taskItemView.itemAt(currentPoint.x, currentPoint.y);
if (targetItem !== null && !targetItem.DelegateModel.inTempItems) {
let sourceIndex = tempItems.get(0).itemsIndex;
let targetIndex = targetItem.DelegateModel.itemsIndex;
const bmp = beforeMidpoint(targetItem, currentPoint);
if ((sourceIndex < targetIndex) && bmp) {
--targetIndex;
} else if ((sourceIndex > targetIndex) && !bmp) {
++targetIndex;
}
let moveCount = Math.abs(targetIndex - sourceIndex);
if (moveCount === 0) {
return;
}
if (sourceIndex < targetIndex) {
taskItemDelegateModel.items.move(sourceIndex + 1, sourceIndex, moveCount);
} else {
taskItemDelegateModel.items.move(targetIndex, targetIndex + 1, moveCount);
}
}
}
}
// 4.
onDropped: (dragEvent) => {
// 1.Index
let droppedIndex = -1;
if (tempItems.count > 0) {
// Item
let tempObj = tempItems.get(0);
droppedIndex = tempObj.inItems ? tempObj.itemsIndex : taskItemDelegateModel.items.count;
} else {
//
let enterX = dragEvent.x === width ? dragEvent.x - 1 : dragEvent.x;
let enterY = dragEvent.y === height ? dragEvent.y - 1 : dragEvent.y;
let contentPoint = getContentPoint(enterX, enterY);
let dropTargetItem = taskItemView.itemAt(contentPoint.x, contentPoint.y);
droppedIndex = (dropTargetItem === null) ? taskItemDelegateModel.items.count : dropTargetItem.DelegateModel.itemsIndex;
}
// 2.
taskItemDelegateModel.removeTempItems();
// 3.
if (isInternalEvent()) {
let persistedObj = taskItemDelegateModel.dragedObject;
// Itemitems
taskItemDelegateModel.persistedItems.addGroups(0, 1, ["items"])
//
taskItemDelegateModel.items.move(persistedObj.itemsIndex, droppedIndex, 1);
// Item
taskItemDelegateModel.resetPersistedItems();
const obj = JSON.parse(dragEvent.text);
if (obj !== null) {
taskItemProxyModel.setOrder(taskItemDelegateModel.model.index(obj.dragStartIndex, 0), droppedIndex);
}
} else {
//
}
}
}

View File

@ -1,21 +1,21 @@
/*
* Copyright (C) 2024, KylinSoft Co., Ltd.
*
* * Copyright (C) 2024, KylinSoft Co., Ltd.
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
* * Authors: qiqi49 <qiqi@kylinos.cn>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: qiqi49 <qiqi@kylinos.cn>
* hxf <hewenfei@kylinos.cn>
*
*/
@ -32,7 +32,7 @@ import org.ukui.quick.platform 1.0 as Platform
TaskManager {
id: taskManager
//
property bool panelActive: thumbnailView.visible
Widget.active: taskManagerActived || thumbnailView.visible
state: ""
states: [
@ -75,15 +75,14 @@ TaskManager {
}
]
Component.onCompleted: {
itemContainsMouse.connect(thumbnailToBeChanged);
}
function thumbnailToBeChanged(containsMouse, thumbnailData) {
if (containsMouse) {
onRequestThumbnailView: (show, data) => {
if (show) {
thumbnailView.visualParent = data.currentTaskItem;
state = "aboutToShowThumbnail";
viewContent.thumbnailData = thumbnailData;
if (viewContent.thumbnailData !== data) {
viewContent.thumbnailData = data;
viewContent.determineListViewSize();
}
} else {
state = "aboutToHideThumbanil";
}
@ -124,11 +123,11 @@ TaskManager {
UkuiTaskManager.ThumbnailWindow {
id: viewContent
property var thumbnailData
property var currentWinIdList: thumbnailData ? thumbnailData.currentWinIdList : []
property TaskItemData thumbnailData: null
property var currentWinIdList: thumbnailData ? thumbnailData.windowIdList : []
property var windowTitles: thumbnailData ? thumbnailData.windowTitles : []
property var windowIcons: thumbnailData ? thumbnailData.windowIcons : []
property bool isHorizontal: taskManager.orientation == ListView.Horizontal
property bool isHorizontal: taskManager.view.orientation === ListView.Horizontal
property bool hasFocus: viewContent.containsMouse || viewContent.menuVisible
onHasFocusChanged: {

View File

@ -1,21 +1,21 @@
/*
* Copyright (C) 2024, KylinSoft Co., Ltd.
*
* * Copyright (C) 2023, KylinSoft Co., Ltd.
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
* * Authors: qiqi49 <qiqi@kylinos.cn>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: qiqi49 <qiqi@kylinos.cn>
* hxf <hewenfei@kylinos.cn>
*
*/
@ -29,29 +29,14 @@ WidgetItem {
Layout.fillHeight: true
Layout.fillWidth: true
Widget.active: taskManagerView.panelActive
TaskManagerView {
id: taskManagerView
anchors.fill: parent
orientation: (Widget.orientation == Types.Horizontal) ? ListView.Horizontal : ListView.Vertical
screen: Widget.container.screen
}
function dataChangedMonitor(key) {
if (key === "mergeIcons") {
// mergeIcons value: 1(no merge)
taskManagerView.isMergeApp = (Widget.globalConfig.getValue(key) === 0);
}
}
Component.onCompleted: {
// init
if (Widget.globalConfig.getValue("mergeIcons") === undefined) {
Widget.globalConfig.setValue("mergeIcons", 0);
}
dataChangedMonitor("mergeIcons");
Widget.globalConfig.configChanged.connect(dataChangedMonitor);
if (Widget.globalConfig.mergeIcons === undefined) {
Widget.globalConfig.mergeIcons = 0;
}
}
}

View File

@ -21,7 +21,7 @@ Item {
color: "#FF9100"
z: -1
radius: 8
visible: demandsAttentionWinIdList.length > 0
visible: taskItemData.DemandsAttentionWinIdList.length > 0
NumberAnimation on opacity {
running: demandsAttention.visible
@ -43,14 +43,14 @@ Item {
}
UkuiItems.StyleBackground {
height: 4
width: Math.min(currentWinIdList.length * 8, 16)
width: Math.min(taskItemData.CurrentWinIdList.length * 8, 16)
radius: 2
anchors.verticalCenter: backgroud.bottom
anchors.horizontalCenter: parent.horizontalCenter
useStyleTransparency: false
paletteRole: hasActiveWindow? Platform.Theme.Highlight : Platform.Theme.BrightText
alpha: hasActiveWindow? 1 : 0.3
paletteRole: taskItemData.HasActiveWindow? Platform.Theme.Highlight : Platform.Theme.BrightText
alpha: taskItemData.HasActiveWindow? 1 : 0.3
Behavior on width {
NumberAnimation { duration: 200 }
}

View File

@ -28,21 +28,25 @@ import org.ukui.panel.taskManager 1.0 as UkuiTaskManager
Item {
id: root
property var orientation
property bool isDragged: false
property alias model: visualModel.model
property alias orientation: normalView.orientation
property alias spacing: normalView.spacing
property int itemSize: 48
signal toNormalFinished()
signal toDraggingFinished()
signal itemContainsMouse(var item, bool containsMouse, int index)
signal requestThumbnailView(bool show, string winId, Item item)
function indexAt(x, y) {
if (isDragged) {
return -1;
} else {
return normalView.indexAt(x, y);
let idx = normalView.normalViewItemIdx(x, y, normalView.spacing/2, true);
if (idx === -1) {
idx = normalView.normalViewItemIdx(x, y, normalView.spacing/2, false);
}
return idx;
}
DelegateModel {
id: visualModel
delegate: Package {
@ -64,7 +68,12 @@ Item {
hoverEnabled: true
onContainsMouseChanged: {
itemContainsMouse(this, containsMouse, index)
requestThumbnailView(containsMouse, modelData, this);
}
onClicked: {
console.log("==list task clicked==")
taskItemClicked(modelData);
}
}
UkuiItems.StyleBackground {
@ -133,7 +142,7 @@ Item {
anchors.fill: parent
color: "#FF9100"
radius: 8
visible: demandsAttentionWinIdList.includes(modelData)
visible: taskItemData.DemandsAttentionWinIdList.includes(modelData)
NumberAnimation on opacity {
running: demandsAttention.visible
@ -158,7 +167,7 @@ Item {
Layout.maximumWidth: height
Layout.fillHeight: true
source: windowIcons[modelData]
source: taskItemData.WindowIcons[modelData]
Behavior on scale {
NumberAnimation { duration: 200 }
}
@ -172,7 +181,7 @@ Item {
Layout.rightMargin: 8
visible: !root.isDragged && orientation === ListView.Horizontal
text: (windowTitles[modelData] === undefined) ? "" : windowTitles[modelData]
text: (taskItemData.WindowTitles[modelData] === undefined) ? "" : taskItemData.WindowTitles[modelData]
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
@ -191,6 +200,14 @@ Item {
interactive: false
spacing: 8
function normalViewItemIdx(x, y, offset, forward) {
if (normalView.orientation === ListView.Horizontal) {
return normalView.indexAt(forward ? x - offset : x + offset, y);
} else {
return normalView.indexAt(x, forward ? y - offset : y + offset);
}
}
}
Item {