Skip to content

Commit

Permalink
feat: dnd multi selected item
Browse files Browse the repository at this point in the history
drag image
  • Loading branch information
kegechen committed Aug 5, 2024
1 parent 6f702a2 commit d2df084
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 15 deletions.
54 changes: 50 additions & 4 deletions qt6/src/qml/ItemDelegate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later

import QtQuick 2.11
import QtQuick
import QtQuick.Templates as T
import QtQuick.Layouts 1.11
import org.deepin.dtk 1.0 as D
Expand All @@ -18,6 +18,7 @@ T.ItemDelegate {
property Component content
property D.Palette checkedTextColor: DS.Style.checkedButton.text
property int corners: D.RoundRectangle.TopLeftCorner | D.RoundRectangle.TopRightCorner | D.RoundRectangle.BottomLeftCorner | D.RoundRectangle.BottomRightCorner
property bool dragActive: false
function getCornersForBackground(index, count) {
if (count <= 1)
return D.RoundRectangle.TopLeftCorner | D.RoundRectangle.TopRightCorner | D.RoundRectangle.BottomLeftCorner | D.RoundRectangle.BottomRightCorner
Expand All @@ -36,7 +37,7 @@ T.ItemDelegate {
spacing: DS.Style.control.spacing
checkable: true
autoExclusive: true
palette.windowText: checked && !control.cascadeSelected && control.backgroundVisible ? D.ColorSelector.checkedTextColor : undefined
palette.windowText: checked && !control.cascadeSelected && control.backgroundVisible && !dragActive? D.ColorSelector.checkedTextColor : undefined

D.DciIcon.mode: D.ColorSelector.controlState
D.DciIcon.theme: D.ColorSelector.controlTheme
Expand Down Expand Up @@ -90,7 +91,7 @@ T.ItemDelegate {

Loader {
anchors.fill: parent
active: checked && !control.cascadeSelected
active: checked && !control.cascadeSelected && !dragActive
sourceComponent: HighlightPanel {}
}

Expand All @@ -103,13 +104,58 @@ T.ItemDelegate {
corners: control.corners
}
}

Loader {
anchors.fill: parent
active: !control.ListView.view && !checked && control.backgroundVisible
sourceComponent: D.RoundRectangle {
color: DS.Style.itemDelegate.normalColor
radius: DS.Style.control.radius
corners: control.corners
}
}

Loader {
anchors.fill: parent
active: dragActive
sourceComponent: Rectangle {
border.color: Qt.rgba(0, 0, 0, 0.09)
radius: DS.Style.control.radius
}
}
}

DragHandler {
id: draghandler
enabled: checked
onActiveChanged: {
if (control.ListView.view.dragItem)
control.ListView.view.dragItem.dragging = active

if (active) {
control.Drag.mimeData = { "text/plain": control.text }
control.Drag.dragType = Drag.Automatic

control.ListView.view.dragItem.grabToImage(function(result) {
control.Drag.imageSource = result.url;
let item = control.ListView.view.dragItem
control.Drag.hotSpot = Qt.point(item.width / 2, item.height / 2)
control.Drag.active = true
})
}
}
}

onHoveredChanged: {
if (checked || control.cascadeSelected || !backgroundVisible)
if (checked || control.cascadeSelected || !backgroundVisible || dragActive)
return

if (ListView.view)
ListView.view.setHoverItem(control.hovered ? control : null)
}

onCheckedChanged: {
if (ListView.view)
ListView.view.updateCheckedItems()
}
}
81 changes: 70 additions & 11 deletions qt6/src/qml/ListView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later

import QtQuick 2.11
import QtQuick 2.15
import QtQuick.Templates as T
import org.deepin.dtk 1.0 as D
import org.deepin.dtk.style 1.0 as DS
import org.deepin.dtk.private 1.0 as P

Expand All @@ -12,16 +13,8 @@ ListView {
property int duration: 100
property bool bgVisible: false
property Item hoveredItem

onContentXChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.x = hoveredItem.x - contentX
}

onContentYChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.y = hoveredItem.y - contentY
}
property list<Item> checkedItems
property alias dragItem: dragItem

function setHoverItem(item) {
if (item) {
Expand All @@ -39,6 +32,72 @@ ListView {
}
}

function updateCheckedItems() {
var items = [];
for (var i = 0; i < count; ++i) {
let item = itemAtIndex(i)
if (item && item.checked) {
items.push(item)
}
}
// console.log("checked items", items)
checkedItems = items
}

Item {
id: dragItem
width: DS.Style.itemDelegate.width + 30
height: DS.Style.itemDelegate.height * 2 + 32
visible: Drag.active
property bool dragging : false

Repeater {
model: checkedItems.length
delegate: Image {
id: img
anchors.centerIn: parent
antialiasing: true
rotation: index ? (index % 2 === 0 ? 10 : -10) : 0
opacity: (1 - index * 0.2)
z: -index
Component.onCompleted: {
let item = checkedItems[index]
if (!item)
return

let dragActive = item.dragActive;
item.dragActive = true
item.grabToImage(function(result) {
img.source = result.url
item.dragActive = dragActive;
})
}
}
}

RoundButton {
id: number
checked: true
anchors.right: dragItem.right
anchors.top: dragItem.top
anchors.margins: 8
implicitWidth: 24
implicitHeight: 24
text: checkedItems.length > 1 ? checkedItems.length : ""
opacity: checkedItems.length > 1 ? 1 : 0
}
}

onContentXChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.x = hoveredItem.x - contentX
}

onContentYChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.y = hoveredItem.y - contentY
}

// ItemDelegate hover item0 ==> item1, add timer ignore [item0.unhovered]
// item0.hovered, item0.unhovered, item1.hovered
Timer {
Expand Down

0 comments on commit d2df084

Please sign in to comment.