From cc47595210dfc76f65eaa5fd1380c451d56f1123 Mon Sep 17 00:00:00 2001 From: Wang Zichong Date: Fri, 16 Aug 2024 14:12:54 +0800 Subject: [PATCH 1/2] Reapply "feat: animation on item add to dock" This reverts commit a208914ea7588cf83e6604c44acfbca449bb18a8. --- panels/dock/OverflowContainer.qml | 2 ++ panels/dock/taskmanager/appitem.cpp | 4 ++-- panels/dock/taskmanager/itemmodel.cpp | 2 -- panels/dock/taskmanager/itemmodel.h | 4 ---- .../dock/taskmanager/package/TaskManager.qml | 21 ++++++++++++++++--- panels/dock/taskmanager/taskmanager.cpp | 3 --- panels/dock/taskmanager/taskmanager.h | 4 ++-- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/panels/dock/OverflowContainer.qml b/panels/dock/OverflowContainer.qml index 142af682d..30fd4ec51 100644 --- a/panels/dock/OverflowContainer.qml +++ b/panels/dock/OverflowContainer.qml @@ -12,6 +12,8 @@ Item { property alias delegate: listView.delegate property alias spacing: listView.spacing property alias count: listView.count + property alias add: listView.add + property alias remove: listView.remove property alias displaced: listView.displaced ListView { id: listView diff --git a/panels/dock/taskmanager/appitem.cpp b/panels/dock/taskmanager/appitem.cpp index 54daa78a1..f8d7ba769 100644 --- a/panels/dock/taskmanager/appitem.cpp +++ b/panels/dock/taskmanager/appitem.cpp @@ -52,8 +52,8 @@ QString AppItem::type() const QString AppItem::icon() const { - if (m_currentActiveWindow.isNull() || m_desktopfileParser->isValied().first) - return m_desktopfileParser->desktopIcon(); + if (m_currentActiveWindow.isNull() || (m_desktopfileParser && m_desktopfileParser->isValied().first)) + return m_desktopfileParser ? m_desktopfileParser->desktopIcon() : "application-default-icon"; else { return m_currentActiveWindow->icon(); } diff --git a/panels/dock/taskmanager/itemmodel.cpp b/panels/dock/taskmanager/itemmodel.cpp index 60b898502..e91b57c1e 100644 --- a/panels/dock/taskmanager/itemmodel.cpp +++ b/panels/dock/taskmanager/itemmodel.cpp @@ -138,7 +138,6 @@ void ItemModel::addItem(QPointer item) beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_items.append(item); endInsertRows(); - Q_EMIT itemAdded(); } void ItemModel::onItemDestroyed() @@ -152,7 +151,6 @@ void ItemModel::onItemDestroyed() beginRemoveRows(QModelIndex(), beginIndex, lastIndex); m_items.removeAll(item); endRemoveRows(); - Q_EMIT itemRemoved(); } void ItemModel::onItemChanged() diff --git a/panels/dock/taskmanager/itemmodel.h b/panels/dock/taskmanager/itemmodel.h index 7fb9fdb6d..f9ec6dbc0 100644 --- a/panels/dock/taskmanager/itemmodel.h +++ b/panels/dock/taskmanager/itemmodel.h @@ -41,10 +41,6 @@ class ItemModel : public QAbstractListModel void addItem(QPointer item); QJsonArray dumpDockedItems() const; -Q_SIGNALS: - void itemAdded(); - void itemRemoved(); - private Q_SLOTS: void onItemDestroyed(); void onItemChanged(); diff --git a/panels/dock/taskmanager/package/TaskManager.qml b/panels/dock/taskmanager/package/TaskManager.qml index 336a828b7..43ae6df1e 100644 --- a/panels/dock/taskmanager/package/TaskManager.qml +++ b/panels/dock/taskmanager/package/TaskManager.qml @@ -22,6 +22,24 @@ ContainmentItem { anchors.centerIn: parent useColumnLayout: taskmanager.useColumnLayout spacing: Panel.rootObject.itemSpacing + add: Transition { + NumberAnimation { + properties: "scale" + from: 0 + to: 1 + duration: 200 + easing.type: Easing.OutQuad + } + } + remove: Transition { + NumberAnimation { + properties: "scale" + from: 1 + to: 0 + duration: 200 + easing.type: Easing.InQuad + } + } displaced: Transition { NumberAnimation { properties: "x,y" @@ -86,9 +104,6 @@ ContainmentItem { onDragFinished: function() { // 就算在非法区域松开也更新 Model taskmanager.Applet.dataModel.moveTo(itemId, visualIndex) - - // 更新 visualModel 的 model 数据 - visualModel.model = taskmanager.Applet.dataModel } anchors.fill: parent // This is mandatory for draggable item center in drop area } diff --git a/panels/dock/taskmanager/taskmanager.cpp b/panels/dock/taskmanager/taskmanager.cpp index 0866f2b71..07231cde8 100644 --- a/panels/dock/taskmanager/taskmanager.cpp +++ b/panels/dock/taskmanager/taskmanager.cpp @@ -47,9 +47,6 @@ TaskManager::TaskManager(QObject* parent) qDBusRegisterMetaType(); qDBusRegisterMetaType(); - connect(ItemModel::instance(), &ItemModel::itemAdded, this, &TaskManager::itemsChanged); - connect(ItemModel::instance(), &ItemModel::itemRemoved, this, &TaskManager::itemsChanged); - connect(Settings, &TaskManagerSettings::allowedForceQuitChanged, this, &TaskManager::allowedForceQuitChanged); connect(Settings, &TaskManagerSettings::windowSplitChanged, this, &TaskManager::windowSplitChanged); } diff --git a/panels/dock/taskmanager/taskmanager.h b/panels/dock/taskmanager/taskmanager.h index 22b5ef51f..bb697d837 100644 --- a/panels/dock/taskmanager/taskmanager.h +++ b/panels/dock/taskmanager/taskmanager.h @@ -17,7 +17,7 @@ class AppItem; class TaskManager : public DS_NAMESPACE::DContainment { Q_OBJECT - Q_PROPERTY(ItemModel* dataModel READ dataModel NOTIFY itemsChanged) + Q_PROPERTY(ItemModel* dataModel READ dataModel NOTIFY dataModelChanged) Q_PROPERTY(bool windowSplit READ windowSplit NOTIFY windowSplitChanged) Q_PROPERTY(bool allowForceQuit READ allowForceQuit NOTIFY allowedForceQuitChanged) @@ -45,7 +45,7 @@ class TaskManager : public DS_NAMESPACE::DContainment Q_INVOKABLE void setAppItemWindowIconGeometry(const QString& appid, QObject* relativePositionItem, const int& x1, const int& y1, const int& x2, const int& y2); Q_SIGNALS: - void itemsChanged(); + void dataModelChanged(); void windowSplitChanged(); void allowedForceQuitChanged(); From 27b88700154104a938a9e999b56b1027823bafe3 Mon Sep 17 00:00:00 2001 From: Wang Zichong Date: Tue, 13 Aug 2024 20:11:25 +0800 Subject: [PATCH 2/2] feat: animation when drop item from launchpad MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 拖拽图标至启动器时,拖拽释放前即跟随鼠标位置进行固定,并在释放后提供 图标淡入+放大的动画。 Log: --- panels/dock/OverflowContainer.qml | 1 + panels/dock/taskmanager/itemmodel.cpp | 7 +- .../dock/taskmanager/package/TaskManager.qml | 78 ++++++++++++++----- panels/dock/taskmanager/taskmanager.cpp | 8 +- panels/dock/taskmanager/taskmanager.h | 1 + 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/panels/dock/OverflowContainer.qml b/panels/dock/OverflowContainer.qml index 30fd4ec51..74ca96677 100644 --- a/panels/dock/OverflowContainer.qml +++ b/panels/dock/OverflowContainer.qml @@ -14,6 +14,7 @@ Item { property alias count: listView.count property alias add: listView.add property alias remove: listView.remove + property alias move: listView.move property alias displaced: listView.displaced ListView { id: listView diff --git a/panels/dock/taskmanager/itemmodel.cpp b/panels/dock/taskmanager/itemmodel.cpp index e91b57c1e..7c9dbd8e8 100644 --- a/panels/dock/taskmanager/itemmodel.cpp +++ b/panels/dock/taskmanager/itemmodel.cpp @@ -82,12 +82,7 @@ void ItemModel::moveTo(const QString &id, int dIndex) if (sIndex == dIndex) { return; } - if (sIndex + 1 == dIndex) { - // Do not move from sIndex to sIndex + 1, as endMoveRows is not trivial, this operation equals do nothing. - // FIXME: maybe this is a bug of Qt? but swap these two is a compatible fix - std::swap(sIndex, dIndex); - } - beginMoveRows(QModelIndex(), sIndex, sIndex, QModelIndex(), dIndex); + beginMoveRows(QModelIndex(), sIndex, sIndex, QModelIndex(), dIndex > sIndex ? (dIndex + 1) : dIndex); m_items.move(sIndex, dIndex); endMoveRows(); diff --git a/panels/dock/taskmanager/package/TaskManager.qml b/panels/dock/taskmanager/package/TaskManager.qml index 43ae6df1e..b8dd3febd 100644 --- a/panels/dock/taskmanager/package/TaskManager.qml +++ b/panels/dock/taskmanager/package/TaskManager.qml @@ -24,20 +24,18 @@ ContainmentItem { spacing: Panel.rootObject.itemSpacing add: Transition { NumberAnimation { - properties: "scale" + properties: "scale,opacity" from: 0 to: 1 duration: 200 - easing.type: Easing.OutQuad } } remove: Transition { NumberAnimation { - properties: "scale" + properties: "scale,opacity" from: 1 to: 0 duration: 200 - easing.type: Easing.InQuad } } displaced: Transition { @@ -46,6 +44,7 @@ ContainmentItem { easing.type: Easing.OutQuad } } + move: displaced model: DelegateModel { id: visualModel model: taskmanager.Applet.dataModel @@ -58,8 +57,25 @@ ContainmentItem { required property string iconName required property string menus required property list windows - keys: ["text/x-dde-dock-dnd-appid", "text/x-dde-launcher-dnd-desktopId"] + keys: ["text/x-dde-dock-dnd-appid"] z: attention ? -1 : 0 + visible: itemId !== launcherDndDropArea.launcherDndDesktopId + + states: [ + State { + name: "item-visible" + when: delegateRoot.visible + PropertyChanges { target: delegateRoot; opacity: 1.0; scale: 1.0; } + }, + State { + name: "item-invisible" + when: !delegateRoot.visible + PropertyChanges { target: delegateRoot; opacity: 0.0; scale: 0.0; } + } + ] + + Behavior on opacity { NumberAnimation { duration: 200 } } + Behavior on scale { NumberAnimation { duration: 200 } } // TODO: 临时溢出逻辑,待后面修改 // 1:4 the distance between app : dock height; get width/height≈0.8 @@ -67,22 +83,9 @@ ContainmentItem { implicitHeight: useColumnLayout ? Panel.rootObject.dockItemMaxSize * 0.8 : Panel.rootObject.dockItemMaxSize onEntered: function(drag) { - if (drag.keys.includes("text/x-dde-launcher-dnd-desktopId")) { - // accepted but don't need to do anything here. - return; - } visualModel.items.move((drag.source as AppItem).visualIndex, app.visualIndex) } - onDropped: function(drop) { - if (drop.keys.includes("text/x-dde-launcher-dnd-desktopId")) { - let desktopId = drop.getDataAsString("text/x-dde-launcher-dnd-desktopId") - taskmanager.Applet.requestDockByDesktopId(desktopId) - drop.accepted = false - return; - } - } - property int visualIndex: DelegateModel.itemsIndex AppItem { @@ -109,6 +112,45 @@ ContainmentItem { } } } + + DropArea { + id: launcherDndDropArea + anchors.fill: parent + keys: ["text/x-dde-launcher-dnd-desktopId"] + property string launcherDndDesktopId: "" + onEntered: function(drag) { + let desktopId = drag.getDataAsString("text/x-dde-launcher-dnd-desktopId") + launcherDndDesktopId = taskmanager.Applet.desktopIdToAppId(desktopId) + if (taskmanager.Applet.requestDockByDesktopId(desktopId) === false) { + launcherDndDesktopId = "" + } + } + + onPositionChanged: function(drag) { + if (launcherDndDesktopId === "") return + let curX = taskmanager.useColumnLayout ? drag.y : drag.x + curX *= Screen.devicePixelRatio + let cellWidth = Panel.rootObject.dockItemMaxSize + let curCell = curX / cellWidth + let left = (curX % cellWidth) < (cellWidth / 2) + taskmanager.Applet.dataModel.moveTo(launcherDndDesktopId, curCell) + } + + onDropped: function(drop) { + if (launcherDndDesktopId === "") return + let curX = taskmanager.useColumnLayout ? drop.y : drop.x + curX *= Screen.devicePixelRatio + let cellWidth = Panel.rootObject.dockItemMaxSize + let curCell = curX / cellWidth + let left = (curX % cellWidth) < (cellWidth / 2) + taskmanager.Applet.dataModel.moveTo(launcherDndDesktopId, curCell) + launcherDndDesktopId = "" + } + + onExited: function() { + launcherDndDesktopId = "" + } + } } Component.onCompleted: { diff --git a/panels/dock/taskmanager/taskmanager.cpp b/panels/dock/taskmanager/taskmanager.cpp index 07231cde8..41c1cd2ce 100644 --- a/panels/dock/taskmanager/taskmanager.cpp +++ b/panels/dock/taskmanager/taskmanager.cpp @@ -179,11 +179,15 @@ bool TaskManager::allowForceQuit() return Settings->isAllowedForceQuit(); } +QString TaskManager::desktopIdToAppId(const QString& desktopId) +{ + return Q_LIKELY(desktopId.endsWith(".desktop")) ? desktopId.chopped(8) : desktopId; +} + bool TaskManager::requestDockByDesktopId(const QString& appID) { if (appID.startsWith("internal/")) return false; - QString dockAppId(Q_LIKELY(appID.endsWith(".desktop")) ? appID.chopped(8) : appID); - return RequestDock(dockAppId); + return RequestDock(desktopIdToAppId(appID)); } bool TaskManager::RequestDock(QString appID) diff --git a/panels/dock/taskmanager/taskmanager.h b/panels/dock/taskmanager/taskmanager.h index bb697d837..0d10223f9 100644 --- a/panels/dock/taskmanager/taskmanager.h +++ b/panels/dock/taskmanager/taskmanager.h @@ -33,6 +33,7 @@ class TaskManager : public DS_NAMESPACE::DContainment bool windowSplit(); bool allowForceQuit(); + Q_INVOKABLE QString desktopIdToAppId(const QString& desktopId); Q_INVOKABLE bool requestDockByDesktopId(const QString& appID); Q_INVOKABLE bool RequestDock(QString appID); Q_INVOKABLE bool IsDocked(QString appID);