mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-02 17:54:45 +00:00
refactor of the drag and drop
completely managed by a top level MouseEventListener
This commit is contained in:
parent
5d4061efcf
commit
33547e57b0
5 changed files with 179 additions and 181 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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") }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue