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})
icon.grabToImage(function(result) {
draggableItem.Drag.imageSource = result.url
return result;
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) {
taskItemRoot.Drag.imageSource = result.url;
icon.destroy();
});
icon.opacity = 0;
icon.visible = false
}
}
MouseArea {
id: mouseArea
width: orientation == ListView.Horizontal ? content.width : baseView.itemSize
height: orientation == ListView.Horizontal ? baseView.itemSize : content.height
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
// *********drag*********
drag.target: draggableItem
drag.onActiveChanged: {
if (drag.active) {
baseView.isBusy = true;
if (baseView.isMergeApp) {
contentHide();
} else {
content.item.toDraggingFinished.connect(contentHide);
}
} else {
baseView.isBusy = false;
content.opacity = 1;
if (baseView.isMergeApp) {
dragFinished();
} else {
content.item.toNormalFinished.connect(dragFinished);
}
// ,
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);
}
}
function contentHide() {
content.opacity = 0;
taskItemDelegateModel.resetPersistedItems();
taskItemRoot.isDragStatus = false;
}
function startDrag() {
//
if (!DelegateModel.inItems || DelegateModel.inPersistedItems || DelegateModel.inTempItems) {
return;
}
function dragFinished() {
proxyModel.setOrder(visualModel.model.index(baseView.dragStartIndex, 0), dropArea.order);
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
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
// enabled: !taskItemRoot.DelegateModel.inTempItems
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 {
UkuiTaskManager.TaskManager.activateWindow(winId);
}
}
// *********mouseEvent*********
onPressed: {
draggableItem.grabImage();
baseView.dragStartIndex = draggableItem.draggableOrder;
//
// onPressed: parent.generateDragImage();
onPressAndHold: {
taskItemRoot.startDrag();
}
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 {
index = 0;
}
}
} else {
UkuiTaskManager.TaskManager.activateWindow(currentWinId);
// 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,69 +276,291 @@ ListView {
}
margin: 6
}
}
// +
Component {
id: applistComponent
UkuiTaskManager.AppList {
height: childrenRect.height
width: childrenRect.width
Loader {
id: taskItemLoader
property var taskItemData: model
itemSize: baseView.itemSize
isDragged: draggableItem.Drag.active
orientation: baseView.orientation
model: CurrentWinIdList
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: listTaskItem
UkuiTaskManager.AppList {
height: childrenRect.height
width: childrenRect.width
itemSize: taskItemView.taskItemSize
isDragged: taskItemRoot.isDragStatus
orientation: taskItemView.orientation
spacing: taskItemView.spacing
model: taskItemData.CurrentWinIdList
}
}
Component {
id: singleTaskItem
UkuiTaskManager.AppIcon {
width: taskItemView.taskItemSize
height: taskItemView.taskItemSize
appBackgroud.alpha: mouseArea.containsPress ? 0.10 : mouseArea.containsMouse ? 0.05 : 0
appIcon.source: taskItemData.Icon
appIcon.scale: mouseArea.containsPress ? 0.9 : 1.0
}
}
}
}
}
//
Component {
id: appIconComponent
UkuiTaskManager.AppIcon {
height: baseView.itemSize
width: baseView.itemSize
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
appBackgroud.alpha: mouseArea.containsPress ? 0.10 : mouseArea.containsMouse ? 0.05 : 0
appIcon.source: modelIcon
appIcon.scale: mouseArea.containsPress ? 0.9 : 1.0
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: 300
}
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 300 }
}
add: Transition {
NumberAnimation {
id: addAnimation
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
}
}
remove: Transition {
NumberAnimation {
id: removeAnimation
property: addAnimation.property
easing.type: Easing.OutCubic
from: 0; to: addAnimation.from
duration: 300
}
}
}
// 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);
}
}
}
}
Component {
id: mouseGrabImage
Items.ThemeIcon { }
}
// 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);
displaced: Transition {
NumberAnimation {
properties: "x,y"
easing.type: Easing.OutQuad
duration: 250
let dropTargetItem = taskItemView.itemAt(contentPoint.x, contentPoint.y);
droppedIndex = (dropTargetItem === null) ? taskItemDelegateModel.items.count : dropTargetItem.DelegateModel.itemsIndex;
}
}
add: Transition {
NumberAnimation {
id: addAnimation
property: (panelPosition == 2 || panelPosition == 4) ? "y" : "x"
from: (panelPosition == 1 || panelPosition == 2) ? -itemSize : itemSize
to: 0
easing.overshoot: 4; easing.amplitude: 2
easing.type: Easing.OutBack; duration: 300
}
}
// 2.
taskItemDelegateModel.removeTempItems();
remove: Transition {
NumberAnimation {
id: removeAnimation
property: addAnimation.property
easing.type: Easing.OutCubic
from: 0; to: addAnimation.from
duration: 300
// 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;
viewContent.determineListViewSize();
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);
if (Widget.globalConfig.mergeIcons === undefined) {
Widget.globalConfig.mergeIcons = 0;
}
dataChangedMonitor("mergeIcons");
Widget.globalConfig.configChanged.connect(dataChangedMonitor);
}
}

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 {