mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +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,150 +8,42 @@ Item {
|
|||
width: applicationsView.cellWidth
|
||||
height: width
|
||||
|
||||
property int idx: index
|
||||
property int oldIdx: -1
|
||||
property var modelData: model
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
radius: units.gridUnit
|
||||
opacity: (delegateItem.drag.target != null) ? 0.4 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
opacity: root.reorderingApps && delegateRoot.GridView.view.dragData && delegateRoot.GridView.view.dragData.ApplicationStorageIdRole == modelData.ApplicationStorageIdRole ? 0.3 : 1
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
width: parent.height / 2
|
||||
height: width
|
||||
source: modelData.ApplicationIconRole
|
||||
scale: root.reorderingApps && delegateRoot.GridView.view.dragData && delegateRoot.GridView.view.dragData.ApplicationStorageIdRole != modelData.ApplicationStorageIdRole ? 0.6 : 1
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
//animate index change
|
||||
onIdxChanged: {
|
||||
if (delegateItem.drag.target != null) {
|
||||
return;
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: label
|
||||
visible: text.length > 0
|
||||
|
||||
anchors {
|
||||
top: icon.bottom
|
||||
left: icon.left
|
||||
right: icon.right
|
||||
}
|
||||
|
||||
if (oldIdx < 0) {
|
||||
oldIdx = idx;
|
||||
return;
|
||||
}
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
maximumLineCount: 2
|
||||
|
||||
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 {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
width: parent.height / 2
|
||||
height: width
|
||||
source: model.ApplicationIconRole
|
||||
scale: root.reorderingApps && !delegateItem.drag.target ? 0.6 : 1
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: label
|
||||
visible: text.length > 0
|
||||
|
||||
anchors {
|
||||
top: icon.bottom
|
||||
left: icon.left
|
||||
right: icon.right
|
||||
}
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
maximumLineCount: 2
|
||||
|
||||
text: model.ApplicationNameRole
|
||||
font.pixelSize: theme.smallestFont.pixelSize
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
}
|
||||
text: modelData.ApplicationNameRole
|
||||
font.pixelSize: theme.smallestFont.pixelSize
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import QtQuick 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
|
||||
Item {
|
||||
PlasmaCore.ColorScope {
|
||||
colorGroup: PlasmaCore.Theme.NormalColorGroup
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
z: -1
|
||||
imagePath: "widgets/background"
|
||||
|
|
@ -11,10 +13,17 @@ Item {
|
|||
topMargin: -margins.top
|
||||
bottomMargin: -margins.bottom
|
||||
}
|
||||
Rectangle {
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: parent.margins.top
|
||||
bottomMargin: parent.margins.bottom
|
||||
}
|
||||
color: PlasmaCore.ColorScope.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
opacity: 0.6
|
||||
height: Math.max(100, units.gridUnit * 2.5)
|
||||
height: applicationsView.cellWidth
|
||||
width: parent.width
|
||||
y: parent.height / 2 - height / 2
|
||||
x: 0
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ import QtQuick.Layouts 1.1
|
|||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
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 "plasmapackage:/code/LayoutManager.js" as LayoutManager
|
||||
|
||||
Item {
|
||||
MouseEventListener {
|
||||
id: root
|
||||
width: 480
|
||||
height: 640
|
||||
|
|
@ -118,10 +118,8 @@ Item {
|
|||
interval: 10
|
||||
onTriggered: {
|
||||
applicationsView.contentY += scrollDown ? 8 : -8;
|
||||
if (applicationsView.draggingItem) {
|
||||
applicationsView.draggingItem.y += scrollDown ? 8 : -8;
|
||||
|
||||
applicationsView.draggingItem.updateRow();
|
||||
if (applicationsView.dragData) {
|
||||
dragDelegate.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 {
|
||||
anchors.fill: parent
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
|
|
@ -161,6 +230,29 @@ Item {
|
|||
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 {
|
||||
id: applicationsView
|
||||
anchors {
|
||||
|
|
@ -171,6 +263,7 @@ Item {
|
|||
}
|
||||
|
||||
property Item draggingItem
|
||||
property var dragData
|
||||
|
||||
cellWidth: root.buttonHeight
|
||||
cellHeight: cellWidth
|
||||
|
|
@ -197,13 +290,30 @@ Item {
|
|||
duration: units.longDuration
|
||||
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
|
||||
delegate: HomeLauncher {}
|
||||
delegate: HomeLauncher {
|
||||
visible: index > 3
|
||||
}
|
||||
header: MouseArea {
|
||||
z: 999
|
||||
property Item layout: appletsLayout
|
||||
property Item lastSpacer: spacer
|
||||
property Item favoritesStrip: favoritesView
|
||||
width: root.width
|
||||
height: mainLayout.Layout.minimumHeight
|
||||
property int margin: stripe.height + units.gridUnit * 2
|
||||
|
|
@ -262,49 +372,30 @@ Item {
|
|||
property int viewPos: applicationsView.contentItem.height * applicationsView.visibleArea.yPosition
|
||||
|
||||
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 {
|
||||
id: stripeIcons
|
||||
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
|
||||
property int columns: 4
|
||||
property alias buttonHeight: stripe.height
|
||||
interactive: false
|
||||
flow: GridView.FlowTopToBottom
|
||||
cellWidth: root.buttonHeight
|
||||
cellHeight: cellWidth
|
||||
property Item draggingItem
|
||||
|
||||
HomeLauncherSvg {
|
||||
id: phoneIcon
|
||||
svg: stripeIcons
|
||||
elementId: "phone"
|
||||
callback: function() {
|
||||
console.log("Start phone")
|
||||
}
|
||||
}
|
||||
model: appListModel
|
||||
delegate: HomeLauncher {}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
int FavoritesModel::rowCount(const QModelIndex &parent) const
|
||||
{return QIdentityProxyModel::rowCount(parent);
|
||||
return qMin(QIdentityProxyModel::rowCount(parent), 4);
|
||||
}
|
||||
|
||||
#include "moc_favoritesmodel.cpp"
|
||||
|
|
|
|||
|
|
@ -34,11 +34,12 @@ public:
|
|||
FavoritesModel(QObject *parent = 0);
|
||||
~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
|
||||
{
|
||||
return qMin(rowCount(), 4);
|
||||
return rowCount();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in a new issue