refactor of the drag and drop

completely managed by a top level MouseEventListener
This commit is contained in:
Marco Martin 2015-04-10 23:59:52 +02:00
parent 5d4061efcf
commit 33547e57b0
5 changed files with 179 additions and 181 deletions

View file

@ -8,124 +8,17 @@ Item {
width: applicationsView.cellWidth width: applicationsView.cellWidth
height: width height: width
property int idx: index property var modelData: model
property int oldIdx: -1
Rectangle { opacity: root.reorderingApps && delegateRoot.GridView.view.dragData && delegateRoot.GridView.view.dragData.ApplicationStorageIdRole == modelData.ApplicationStorageIdRole ? 0.3 : 1
anchors.fill: parent
color: PlasmaCore.ColorScope.textColor
radius: units.gridUnit
opacity: (delegateItem.drag.target != null) ? 0.4 : 0
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
}
//animate index change
onIdxChanged: {
if (delegateItem.drag.target != null) {
return;
}
if (oldIdx < 0) {
oldIdx = idx;
return;
}
delegateItem.x = ((oldIdx % 4) * GridView.view.cellWidth) - ((idx % 4) * GridView.view.cellWidth);
delegateItem.y = (Math.floor(oldIdx / 4) * GridView.view.cellHeight) - (Math.floor(idx / 4) * GridView.view.cellHeight);
translAnim.running = true;
oldIdx = idx;
}
NumberAnimation {
id: translAnim
duration: units.longDuration
easing.type: Easing.InOutQuad
target: delegateItem
properties: "x,y"
to: 0
}
MouseArea {
id: delegateItem
width: applicationsView.cellWidth
height: width
states: [
State {
when: delegateItem.drag.target != null
ParentChange {
target: delegateItem
parent: delegateRoot.parent
}
PropertyChanges {
target: delegateItem
z: 9999
}
}
]
function updateRow() {
var pos = mapToItem(delegateRoot.parent, 0, 0);
var newRow = (Math.round(delegateRoot.GridView.view.width / delegateRoot.GridView.view.cellWidth) * Math.round(pos.y / delegateRoot.GridView.view.cellHeight) + Math.round(pos.x / delegateRoot.GridView.view.cellWidth));
if (model.ApplicationOriginalRowRole != newRow) {
appListModel.moveItem(model.ApplicationOriginalRowRole, newRow);
}
}
onClicked: {
console.log("Clicked: " + model.ApplicationStorageIdRole)
appListModel.runApplication(model.ApplicationStorageIdRole)
oldX = x
oldY = y
}
onPressAndHold: {
delegateRoot.GridView.view.draggingItem = delegateItem;
delegateItem.drag.target = delegateItem;
root.reorderingApps = true;
}
onReleased: {
delegateRoot.GridView.view.draggingItem = delegateItem;
delegateItem.drag.target = null;
root.reorderingApps = false;
translAnim.running = true;
autoScrollTimer.running = false;
}
onPositionChanged: {
if (!autoScrollTimer.running && delegateItem.drag.target) {
updateRow();
var screenPos = mapToItem(delegateRoot.GridView.view, 0, 0);
if (applicationsView.contentY > 0 && screenPos.y < root.height / 4) {
autoScrollTimer.scrollDown = false;
autoScrollTimer.running = true;
} else if (!applicationsView.atYEnd && screenPos.y > 3 * (root.height / 4)) {
autoScrollTimer.scrollDown = true;
autoScrollTimer.running = true;
} else {
autoScrollTimer.running = false;
}
} else {
autoScrollTimer.running = false;
}
}
PlasmaCore.IconItem { PlasmaCore.IconItem {
id: icon id: icon
anchors.centerIn: parent anchors.centerIn: parent
width: parent.height / 2 width: parent.height / 2
height: width height: width
source: model.ApplicationIconRole source: modelData.ApplicationIconRole
scale: root.reorderingApps && !delegateItem.drag.target ? 0.6 : 1 scale: root.reorderingApps && delegateRoot.GridView.view.dragData && delegateRoot.GridView.view.dragData.ApplicationStorageIdRole != modelData.ApplicationStorageIdRole ? 0.6 : 1
Behavior on scale { Behavior on scale {
NumberAnimation { NumberAnimation {
duration: units.longDuration duration: units.longDuration
@ -149,9 +42,8 @@ Item {
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
maximumLineCount: 2 maximumLineCount: 2
text: model.ApplicationNameRole text: modelData.ApplicationNameRole
font.pixelSize: theme.smallestFont.pixelSize font.pixelSize: theme.smallestFont.pixelSize
color: PlasmaCore.ColorScope.textColor color: PlasmaCore.ColorScope.textColor
} }
} }
}

View file

@ -1,7 +1,9 @@
import QtQuick 2.0 import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
Item { PlasmaCore.ColorScope {
colorGroup: PlasmaCore.Theme.NormalColorGroup
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
z: -1 z: -1
imagePath: "widgets/background" imagePath: "widgets/background"
@ -11,10 +13,17 @@ Item {
topMargin: -margins.top topMargin: -margins.top
bottomMargin: -margins.bottom bottomMargin: -margins.bottom
} }
Rectangle {
anchors {
fill: parent
topMargin: parent.margins.top
bottomMargin: parent.margins.bottom
}
color: PlasmaCore.ColorScope.backgroundColor
}
} }
opacity: 0.6 height: applicationsView.cellWidth
height: Math.max(100, units.gridUnit * 2.5)
width: parent.width width: parent.width
y: parent.height / 2 - height / 2 y: parent.height / 2 - height / 2
x: 0 x: 0

View file

@ -22,12 +22,12 @@ import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
import org.kde.satellite.components 0.1 as SatelliteComponents import org.kde.satellite.components 0.1 as SatelliteComponents
import "plasmapackage:/code/LayoutManager.js" as LayoutManager import "plasmapackage:/code/LayoutManager.js" as LayoutManager
Item { MouseEventListener {
id: root id: root
width: 480 width: 480
height: 640 height: 640
@ -118,10 +118,8 @@ Item {
interval: 10 interval: 10
onTriggered: { onTriggered: {
applicationsView.contentY += scrollDown ? 8 : -8; applicationsView.contentY += scrollDown ? 8 : -8;
if (applicationsView.draggingItem) { if (applicationsView.dragData) {
applicationsView.draggingItem.y += scrollDown ? 8 : -8; dragDelegate.updateRow();
applicationsView.draggingItem.updateRow();
} }
} }
} }
@ -151,6 +149,77 @@ Item {
} }
} }
onPressAndHold: {
var pos = mapToItem(applicationsView.headerItem.favoritesStrip, mouse.x, mouse.y);
//in favorites area?
var item;
if (applicationsView.headerItem.favoritesStrip.contains(pos)) {
item = applicationsView.headerItem.favoritesStrip.itemAt(pos.x, pos.y);
} else {
pos = mapToItem(applicationsView.contentItem, mouse.x, mouse.y);
item = applicationsView.itemAt(pos.x, pos.y)
}
if (!item) {
return;
}
applicationsView.dragData = new Object;
applicationsView.dragData.ApplicationNameRole = item.modelData.ApplicationNameRole;
applicationsView.dragData.ApplicationIconRole = item.modelData.ApplicationIconRole;
applicationsView.dragData.ApplicationStorageIdRole = item.modelData.ApplicationStorageIdRole;
applicationsView.dragData.ApplicationEntryPathRole = item.modelData.ApplicationEntryPathRole;
applicationsView.dragData.ApplicationOriginalRowRole = item.modelData.ApplicationOriginalRowRole;
dragDelegate.modelData = applicationsView.dragData;
applicationsView.interactive = false;
dragDelegate.x = mouse.x - dragDelegate.width/2;
dragDelegate.y = mouse.y - dragDelegate.height/2;
root.reorderingApps = true;
dragDelegate.visible = true;
}
onPositionChanged: {
if (!applicationsView.dragData) {
return;
}
dragDelegate.x = mouse.x - dragDelegate.width/2;
dragDelegate.y = mouse.y - dragDelegate.height/2;
dragDelegate.updateRow();
if (!autoScrollTimer.running) {
if (mouse.y < root.height / 4) {
autoScrollTimer.running = false;
} else if (applicationsView.contentY > 0 && mouse.y < root.buttonHeight + root.height / 4) {
autoScrollTimer.scrollDown = false;
autoScrollTimer.running = true;
} else if (!applicationsView.atYEnd && mouse.y > 3 * (root.height / 4)) {
autoScrollTimer.scrollDown = true;
autoScrollTimer.running = true;
} else {
autoScrollTimer.running = false;
}
} else {
autoScrollTimer.running = false;
}
}
onReleased: {
applicationsView.interactive = true;
dragDelegate.visible = false;
applicationsView.dragData = null;
root.reorderingApps = false;
applicationsView.forceLayout();
autoScrollTimer.running = false;
}
onClicked: {
var pos = mapToItem(applicationsView.contentItem, mouse.x, mouse.y);
var item = applicationsView.itemAt(pos.x, pos.y)
if (!item) {
return;
}
appListModel.runApplication(item.modelData.ApplicationStorageIdRole)
}
PlasmaCore.ColorScope { PlasmaCore.ColorScope {
anchors.fill: parent anchors.fill: parent
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
@ -161,6 +230,29 @@ Item {
anchors.fill: parent anchors.fill: parent
} }
HomeLauncher {
id: dragDelegate
z: 999
function updateRow() {
if (!applicationsView.dragData) {
return;
}
var pos = root.mapToItem(applicationsView.contentItem, x, y);
//in favorites area?
if (applicationsView.headerItem.favoritesStrip.contains(root.mapToItem(applicationsView.headerItem.favoritesStrip, x, y))) {
pos.y = 1;
}
var newRow = (Math.round(applicationsView.width / applicationsView.cellWidth) * Math.round(pos.y / applicationsView.cellHeight) + Math.round(pos.x / applicationsView.cellWidth));
if (applicationsView.dragData.ApplicationOriginalRowRole != newRow) {
appListModel.moveItem(applicationsView.dragData.ApplicationOriginalRowRole, newRow);
applicationsView.dragData.ApplicationOriginalRowRole = newRow;
}
}
}
GridView { GridView {
id: applicationsView id: applicationsView
anchors { anchors {
@ -171,6 +263,7 @@ Item {
} }
property Item draggingItem property Item draggingItem
property var dragData
cellWidth: root.buttonHeight cellWidth: root.buttonHeight
cellHeight: cellWidth cellHeight: cellWidth
@ -197,13 +290,30 @@ Item {
duration: units.longDuration duration: units.longDuration
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
} }
move: Transition {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
properties: "x,y"
}
}
moveDisplaced: Transition {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
properties: "x,y"
}
}
//clip: true //clip: true
delegate: HomeLauncher {} delegate: HomeLauncher {
visible: index > 3
}
header: MouseArea { header: MouseArea {
z: 999 z: 999
property Item layout: appletsLayout property Item layout: appletsLayout
property Item lastSpacer: spacer property Item lastSpacer: spacer
property Item favoritesStrip: favoritesView
width: root.width width: root.width
height: mainLayout.Layout.minimumHeight height: mainLayout.Layout.minimumHeight
property int margin: stripe.height + units.gridUnit * 2 property int margin: stripe.height + units.gridUnit * 2
@ -262,49 +372,30 @@ Item {
property int viewPos: applicationsView.contentItem.height * applicationsView.visibleArea.yPosition property int viewPos: applicationsView.contentItem.height * applicationsView.visibleArea.yPosition
y: Math.max(viewPos, y: Math.max(viewPos,
Math.min(parent.height, viewPos + root.height) - height + Math.max(0, -(parent.height - height + applicationsView.contentY))) Math.min(parent.height, viewPos + root.height - height) + Math.max(0, -(parent.height - height + applicationsView.contentY)))
PlasmaCore.Svg { PlasmaCore.Svg {
id: stripeIcons id: stripeIcons
imagePath: Qt.resolvedUrl("../images/homescreenicons.svg") imagePath: Qt.resolvedUrl("../images/homescreenicons.svg")
} }
Row { GridView {
id: favoritesView
//FIXME: QQuickItem has a contains, but seems to not work
function contains(point) {
return point.x > 0 && point.x < width && point.y > 0 && point.y < height;
}
anchors.fill: parent anchors.fill: parent
property int columns: 4 property int columns: 4
property alias buttonHeight: stripe.height interactive: false
flow: GridView.FlowTopToBottom
cellWidth: root.buttonHeight
cellHeight: cellWidth
property Item draggingItem
HomeLauncherSvg { model: appListModel
id: phoneIcon delegate: HomeLauncher {}
svg: stripeIcons
elementId: "phone"
callback: function() {
console.log("Start phone")
}
}
HomeLauncherSvg {
id: messagingIcon
svg: stripeIcons
elementId: "messaging"
callback: function() { console.log("Start messaging") }
}
HomeLauncherSvg {
id: emailIcon
svg: stripeIcons
elementId: "email"
callback: function() { console.log("Start email") }
}
HomeLauncherSvg {
id: webIcon
svg: stripeIcons
elementId: "web"
callback: function() { console.log("Start web") }
}
} }
} }
} }

View file

@ -35,4 +35,9 @@ QHash<int, QByteArray> FavoritesModel::roleNames() const
return sourceModel()->roleNames(); return sourceModel()->roleNames();
} }
int FavoritesModel::rowCount(const QModelIndex &parent) const
{return QIdentityProxyModel::rowCount(parent);
return qMin(QIdentityProxyModel::rowCount(parent), 4);
}
#include "moc_favoritesmodel.cpp" #include "moc_favoritesmodel.cpp"

View file

@ -34,11 +34,12 @@ public:
FavoritesModel(QObject *parent = 0); FavoritesModel(QObject *parent = 0);
~FavoritesModel(); ~FavoritesModel();
QHash<int, QByteArray> roleNames() const; QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int count() const int count() const
{ {
return qMin(rowCount(), 4); return rowCount();
} }
private: private: