diff --git a/qml/AppUI/AppList.qml b/qml/AppUI/AppList.qml index 0e02a78..662bfad 100644 --- a/qml/AppUI/AppList.qml +++ b/qml/AppUI/AppList.qml @@ -21,6 +21,7 @@ import QtQml 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.12 import AppControls2 1.0 as AppControls2 +import org.ukui.quick.items 1.0 as UkuiItems import org.ukui.menu.core 1.0 AppListView { @@ -59,9 +60,7 @@ AppListView { width: appListView.view ? appListView.view.width : 0 height: appListView.itemHeight acceptedButtons: Qt.LeftButton | Qt.RightButton - // Drag.active: drag.active - // Drag.hotSpot.x: width / 2 - // Drag.hotSpot.y: height / 2 + drag.target: appItemBase onClicked: { if (mouse.button === Qt.RightButton) { appListView.model.openMenu(index, MenuInfo.AppList); @@ -72,24 +71,28 @@ AppListView { return; } } - // onPressAndHold: { - // if (mouse.button === Qt.LeftButton) { - // x = appItem.mapToItem(appListView,0,0).x; - // y = appItem.mapToItem(appListView,0,0).y; - // drag.target = appItem; - // appItem.parent = appListView; - // appItem.isSelect = true; - // } - // } - // onReleased: { - // Drag.drop(); - // drag.target = null; - // appItem.parent = appItemBase; - // x = 0; - // y = 0; - // appItem.isSelect = false; - // } + onPressed: parent.grabImage(); } + + function grabImage() { + var icon = mouseGrabImage.createObject(appItemBase, { width: 48, height: 48, source: model.icon}) + icon.grabToImage(function(result) { + appItemBase.Drag.imageSource = result.url + return result; + }); + icon.opacity = 0; + } + + Component { + id: mouseGrabImage + UkuiItems.Icon { } + } + + Drag.supportedActions: Qt.CopyAction + Drag.dragType: Drag.Automatic + Drag.active: appItem.drag.active + Drag.mimeData: {"id": id, "favorite": favorite} + Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { appManager.launchApp(id); diff --git a/qml/AppUI/FullScreenAppList.qml b/qml/AppUI/FullScreenAppList.qml index 705005f..acc4f45 100644 --- a/qml/AppUI/FullScreenAppList.qml +++ b/qml/AppUI/FullScreenAppList.qml @@ -80,6 +80,7 @@ ListView { height: GridView.view.cellHeight FullScreenAppItem { + id: appItem anchors.fill: parent anchors.margins: 12 @@ -96,7 +97,18 @@ ListView { menuManager.showMenu(model.id, MenuInfo.FullScreen); } } + + drag.target: parent + onPressed: parent.grabToImage(function(result) { + parent.Drag.imageSource = result.url + }) } + Drag.supportedActions: Qt.CopyAction + Drag.dragType: Drag.Automatic + Drag.active: appItem.drag.active + Drag.hotSpot.x: width / 2 + Drag.hotSpot.y: height / 2 + Drag.mimeData: {"id": model.id, "favorite": model.favorite > 0} } } } @@ -137,20 +149,6 @@ ListView { ] } - // 拖动到文件到空白区域 添加到收藏 - DropArea { - width: parent.width - height: favoriteView.contentHeight - onEntered: { - if (drag.source.isFavorite) { - favoriteView.dragTypeIsMerge = false; - } else { - var id = drag.source.id; - extensionData.favoriteAppsModel.addAppToFavorites(id); - } - } - } - Column { width: parent.width height: childrenRect.height + spacing @@ -162,58 +160,132 @@ ListView { displayName: qsTr("Favorite") } - GridView { - id: favoriteView + Item { width: parent.width - height: contentHeight - property string mergeToAppId: "" - property bool isMergeToFolder: false - property bool dragTypeIsMerge: false - property int exchangedStartIndex: 0 - property alias viewModel: visualModel + height: favoriteView.height - cellWidth: width / root.column - cellHeight: cellWidth - model: DelegateModel { - id: visualModel - model: favoriteModel - delegate: Item { - id: container - width: favoriteView.cellWidth - height: favoriteView.cellHeight - Extension.FavoriteDelegate { - anchors.fill: parent - anchors.margins: 12 + DropArea { + anchors.fill: parent + property int addedIndex: -1 + property string addedId: "" - visualIndex: container.DelegateModel.itemsIndex - delegateLayout.anchors.topMargin: 16 - delegateLayout.anchors.bottomMargin: 16 - delegateLayout.spacing: 8 - mergePrompt.anchors.topMargin: 10 - mergePrompt.width: width*0.675 -// mergePrompt.width: 108 - mergePrompt.radius: 32 - - Component.onCompleted: contentShowFinished.connect(resetOpacity) - Component.onDestruction: contentShowFinished.disconnect(resetOpacity) + function reset() { + addedId = ""; + var nullIndex = favoriteView.indexAtNullItem(); + if (nullIndex > -1 && nullIndex < favoriteView.count) { + favoriteView.viewModel.items.remove(nullIndex); } + } - //编辑模式标志 - Extension.EditModeFlag { - id: tag - anchors.top: parent.top - anchors.topMargin: 10 - anchors.right: parent.right - anchors.rightMargin: 28 - onClicked: { - visualModel.model.removeAppFromFavorites(id); + onEntered: { + if (drag.getDataAsString("favorite") === "true") { + drag.accepted = false; + + } else if (drag.getDataAsString("favorite") === "false") { + // 从左侧列表添加到收藏 + // 已经触发从左侧拖动到收藏区域的事件,不需要再次添加空白item + if (addedId === drag.getDataAsString("id")) { + return; + } + + addedId = drag.getDataAsString("id") + addedIndex = favoriteView.count; + visualModel.items.insert(addedIndex, {"id":"", "icon":"", "name": ""}); + + } else { + // 收藏插件内拖拽 + favoriteView.dragTypeIsMerge = false; + } + } + + onPositionChanged: { + if (drag.getDataAsString("favorite") === "false" && addedIndex > -1) { + var dragIndex = favoriteView.indexAt(drag.x, drag.y); + + if (dragIndex < 0) { + return; + } + + visualModel.items.move(addedIndex, dragIndex); + addedIndex = dragIndex; + } + } + + onDropped: { + if (drop.getDataAsString("favorite") === "false") { + reset(); + favoriteModel.addAppToFavorites(drop.getDataAsString("id"), addedIndex); + } + } + onExited: reset() + } + + GridView { + id: favoriteView + width: parent.width + height: contentHeight + property string mergeToAppId: "" + property bool isMergeToFolder: false + property bool dragTypeIsMerge: false + property int exchangedStartIndex: 0 + property alias viewModel: visualModel + + cellWidth: width / root.column + cellHeight: cellWidth + + function indexAtNullItem() { + var nullItemIndex; + for (var i = 0; i < favoriteView.count; i ++) { + if (favoriteView.itemAtIndex(i).id === "") { + nullItemIndex = i; + return nullItemIndex; + } + } + return -1; + } + + model: DelegateModel { + id: visualModel + model: favoriteModel + delegate: Item { + id: container + width: favoriteView.cellWidth + height: favoriteView.cellHeight + property var id: model.id + Extension.FavoriteDelegate { + anchors.fill: parent + anchors.margins: 12 + + visualIndex: container.DelegateModel.itemsIndex + delegateLayout.anchors.topMargin: 16 + delegateLayout.anchors.bottomMargin: 16 + delegateLayout.spacing: 8 + mergePrompt.anchors.topMargin: 10 + mergePrompt.width: width*0.675 + // mergePrompt.width: 108 + mergePrompt.radius: 32 + + Component.onCompleted: contentShowFinished.connect(resetOpacity) + Component.onDestruction: contentShowFinished.disconnect(resetOpacity) + } + + //编辑模式标志 + Extension.EditModeFlag { + id: tag + anchors.top: parent.top + anchors.topMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 28 + onClicked: { + visualModel.model.removeAppFromFavorites(id); + } } } } - } - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 } + displaced: Transition { + NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 } + } } } } diff --git a/qml/extensions/FavoriteDelegate.qml b/qml/extensions/FavoriteDelegate.qml index c80a77e..53e58d0 100644 --- a/qml/extensions/FavoriteDelegate.qml +++ b/qml/extensions/FavoriteDelegate.qml @@ -41,7 +41,9 @@ UkuiItems.StyleBackground { // drag.source [itemLoader] onEntered: { - if (drag.source.isFolder) { + // 拖拽对象为folder 或 左侧列表应用时 + if (drag.source.isFolder || !drag.source.sourceId) { + drag.accepted = false; return; } @@ -49,6 +51,10 @@ UkuiItems.StyleBackground { delegateDropTimer.running = true; } onExited: { + if (!drag.source.sourceId) { + return; + } + if (delegateDropTimer.timeOutCount < 1) { favoriteView.dragTypeIsMerge = false; favoriteView.viewModel.items.move(drag.source.visualIndex, iconItem.visualIndex); @@ -210,8 +216,9 @@ UkuiItems.StyleBackground { if (mouseButton === Qt.RightButton) { favoriteModel.openMenu(index) } else { - var data = {"id": model.id}; - send(data); +// var data = {"id": model.id}; +// send(data); + appManager.launchApp(id); } } } diff --git a/qml/extensions/FavoriteExtension.qml b/qml/extensions/FavoriteExtension.qml index 1544fbb..e04dd8b 100644 --- a/qml/extensions/FavoriteExtension.qml +++ b/qml/extensions/FavoriteExtension.qml @@ -88,14 +88,59 @@ UkuiMenuExtension { // 拖动到文件到空白区域 添加到收藏 DropArea { anchors.fill: parent - onEntered: { - if (drag.source.isFavorite) { - favoriteView.dragTypeIsMerge = false; - } else { - var id = drag.source.id; - extensionData.favoriteAppsModel.addAppToFavorites(id); + property int addedIndex: -1 + property string addedId: "" + + function reset() { + addedId = ""; + var nullIndex = favoriteView.indexAtNullItem(); + if (nullIndex > -1 && nullIndex < favoriteView.count) { + favoriteView.viewModel.items.remove(nullIndex); } } + + onEntered: { + if (drag.getDataAsString("favorite") === "true") { + drag.accepted = false; + + } else if (drag.getDataAsString("favorite") === "false") { + // 从左侧列表添加到收藏 + // 已经触发从左侧拖动到收藏区域的事件,不需要再次添加空白item + if (addedId === drag.getDataAsString("id")) { + return; + } + + addedId = drag.getDataAsString("id") + addedIndex = favoriteView.count; + favoriteView.viewModel.items.insert(addedIndex, {"id":"", "icon":"", "name": ""}); + + } else { + // 收藏插件内拖拽 + favoriteView.dragTypeIsMerge = false; + } + } + + onPositionChanged: { + if (drag.getDataAsString("favorite") === "false" && addedIndex > -1) { + var dragIndex = favoriteView.indexAt(drag.x, drag.y); + + if (dragIndex < 0) { + return; + } + + favoriteView.viewModel.items.move(addedIndex, dragIndex); + addedIndex = dragIndex; + } + } + + onDropped: { + if (drop.getDataAsString("favorite") === "false") { + reset(); + extensionData.favoriteAppsModel.addAppToFavorites(drop.getDataAsString("id"), addedIndex); + } + } + + onExited: reset() } FavoriteGridView { diff --git a/qml/extensions/FavoriteGridView.qml b/qml/extensions/FavoriteGridView.qml index 7cb7227..8584edf 100644 --- a/qml/extensions/FavoriteGridView.qml +++ b/qml/extensions/FavoriteGridView.qml @@ -106,6 +106,17 @@ GridView { NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 } } + function indexAtNullItem() { + var nullItemIndex; + for (var i = 0; i < favoriteView.count; i ++) { + if (favoriteView.itemAtIndex(i).id === "") { + nullItemIndex = i; + return nullItemIndex; + } + } + return -1; + } + model: DelegateModel { id: visualModel delegate: Item { @@ -113,6 +124,7 @@ GridView { focus: true width: favoriteView.cellWidth height: favoriteView.cellHeight + property var id: model.id states: State { when: activeFocus