aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-06-21 13:50:36 +1000
committerAndrew den Exter <andrew.den-exter@nokia.com>2011-06-21 13:50:36 +1000
commit088bf47172eedb19945bf1e5eba6f036a362d2dc (patch)
tree9e698c9064c0ed3fc2c2a69747eb5c344ea4cde7
parent3cbe13da26023fd262bb6d9b05659629c3af28d8 (diff)
Add support for moving items between VisualItemModels.
-rw-r--r--examples/declarative/dragtarget/launcher/IconDelegate.qml10
-rw-r--r--examples/declarative/dragtarget/launcher/launcher.qml115
-rw-r--r--src/declarative/items/qsgvisualitemmodel.cpp84
-rw-r--r--src/declarative/items/qsgvisualitemmodel_p.h11
4 files changed, 194 insertions, 26 deletions
diff --git a/examples/declarative/dragtarget/launcher/IconDelegate.qml b/examples/declarative/dragtarget/launcher/IconDelegate.qml
index bc1b61cd97..360ca8a946 100644
--- a/examples/declarative/dragtarget/launcher/IconDelegate.qml
+++ b/examples/declarative/dragtarget/launcher/IconDelegate.qml
@@ -7,6 +7,15 @@ Item {
width: 64; height: 64
+ Rectangle {
+ anchors.fill: parent
+ opacity: dragArea.drag.active ? 0.5 : 0.0
+ color: "lightgrey"
+ radius: 12
+
+ Behavior on opacity { NumberAnimation { duration: 300 } }
+ }
+
MouseArea {
id: dragArea
@@ -17,6 +26,7 @@ Item {
anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
drag.target: dragArea
+ drag.data: index
Binding {
target: dragArea
diff --git a/examples/declarative/dragtarget/launcher/launcher.qml b/examples/declarative/dragtarget/launcher/launcher.qml
index 26d8ef7d6e..f1188b85b3 100644
--- a/examples/declarative/dragtarget/launcher/launcher.qml
+++ b/examples/declarative/dragtarget/launcher/launcher.qml
@@ -18,12 +18,31 @@ Rectangle {
interactive: false
+ add: Transition {
+ NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
+ }
+ move: Transition {
+ NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
+ }
+
model: VisualItemModel {
id: applicationsVisualModel
VisualDataModel {
delegate: IconDelegate { drag.keys: [ "applications" ] }
model: ListModel {
id: applicationsModel
+
+ ListElement { icon: "images/AudioPlayer_48.png" }
+ ListElement { icon: "images/EMail_48.png" }
+ ListElement { icon: "images/Camera_48.png" }
+ ListElement { icon: "images/VideoPlayer_48.png" }
+ ListElement { icon: "images/AddressBook_48.png" }
+ ListElement { icon: "images/DateBook_48.png" }
+ ListElement { icon: "images/TodoList_48.png" }
+ ListElement { icon: "images/AudioPlayer_48.png" }
+ ListElement { icon: "images/EMail_48.png" }
+ ListElement { icon: "images/Camera_48.png" }
+ ListElement { icon: "images/VideoPlayer_48.png" }
ListElement { icon: "images/AddressBook_48.png" }
ListElement { icon: "images/DateBook_48.png" }
ListElement { icon: "images/TodoList_48.png" }
@@ -33,27 +52,54 @@ Rectangle {
}
DragTarget {
- property int initialIndex
- property int previousIndex
+ property int sourceIndex
+ property int destinationIndex
anchors.fill: applicationsView
keys: [ "applications" ]
onEntered: {
- initialIndex = applicationsView.indexAt(drag.x, drag.y)
- previousIndex = initialIndex
- if (previousIndex == -1)
+ sourceIndex = applicationsView.indexAt(drag.x, drag.y)
+ destinationIndex = sourceIndex
+ if (destinationIndex == -1)
+ drag.accepted = false
+ }
+ onPositionChanged: {
+ var index = applicationsView.indexAt(drag.x, drag.y)
+ if (index != -1) {
+ applicationsVisualModel.move(destinationIndex, index, 1)
+ destinationIndex = index
+ }
+ }
+ onDropped: applicationsModel.move(sourceIndex, destinationIndex, 1)
+ onExited: applicationsModel.move(destinationIndex, sourceIndex, 1)
+ }
+
+ DragTarget {
+ property int sourceIndex
+ property int destinationIndex
+
+ anchors.fill: applicationsView
+ keys: [ "favorites" ]
+
+ onEntered: {
+ sourceIndex = drag.data
+ destinationIndex = applicationsView.indexAt(drag.x, drag.y)
+ if (destinationIndex == -1) {
drag.accepted = false
+ } else {
+ applicationsVisualModel.insert(destinationIndex, favoritesVisualModel, sourceIndex, 1)
+ }
}
onPositionChanged: {
var index = applicationsView.indexAt(drag.x, drag.y)
if (index != -1) {
- applicationsVisualModel.move(previousIndex, index, 1)
- previousIndex = index
+ applicationsVisualModel.move(destinationIndex, index, 1)
+ destinationIndex = index
}
}
- onDropped: applicationsModel.move(initialIndex, previousIndex, 1)
- onExited: applicationsModel.move(previousIndex, initialIndex, 1)
+// onDropped: applicationsModel.move(sourceIndex, destinationIndex, 1)
+// onExited: applicationsModel.move(destinationIndex, sourceIndex, 1)
}
Rectangle {
@@ -86,6 +132,10 @@ Rectangle {
orientation: ListView.Horizontal
spacing: 32
+ add: Transition {
+ NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
+ }
+
model: VisualItemModel {
id: favoritesVisualModel
VisualDataModel {
@@ -102,27 +152,56 @@ Rectangle {
}
DragTarget {
- property int initialIndex
- property int previousIndex
+ property int sourceIndex
+ property int destinationIndex
anchors.fill: favoritesView
keys: [ "favorites" ]
onEntered: {
- initialIndex = favoritesView.indexAt(drag.x, drag.y)
- previousIndex = initialIndex
- if (previousIndex == -1)
+ sourceIndex = favoritesView.indexAt(drag.x, drag.y)
+ destinationIndex = sourceIndex
+ if (destinationIndex == -1)
+ drag.accepted = false
+ }
+ onPositionChanged: {
+ var index = favoritesView.indexAt(drag.x, drag.y)
+ if (index != -1) {
+ favoritesVisualModel.move(destinationIndex, index, 1)
+ destinationIndex = index
+ }
+ }
+ onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1)
+ onExited: favoritesVisualModel.move(destinationIndex, sourceIndex, 1)
+ }
+
+ DragTarget {
+ property int sourceIndex
+ property int destinationIndex
+
+ enabled: favoritesVisualModel.count < 4
+
+ anchors.fill: favoritesView
+ keys: [ "applications" ]
+
+ onEntered: {
+ sourceIndex = drag.data
+ destinationIndex = favoritesView.indexAt(drag.x, drag.y)
+ if (destinationIndex == -1) {
drag.accepted = false
+ } else {
+ favoritesVisualModel.insert(destinationIndex, applicationsVisualModel, sourceIndex, 1)
+ }
}
onPositionChanged: {
var index = favoritesView.indexAt(drag.x, drag.y)
if (index != -1) {
- favoritesVisualModel.move(previousIndex, index, 1)
- previousIndex = index
+ favoritesVisualModel.move(destinationIndex, index, 1)
+ destinationIndex = index
}
}
- onDropped: favoritesModel.move(initialIndex, previousIndex, 1)
- onExited: favoritesVisualModel.move(previousIndex, initialIndex, 1)
+ // onDropped: favoritesModel.move(sourceIndex, destinationIndex, 1)
+ // onExited: favoritesModel.move(destinationIndex, sourceIndex, 1)
}
}
}
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
index df9c253771..6517ef4e20 100644
--- a/src/declarative/items/qsgvisualitemmodel.cpp
+++ b/src/declarative/items/qsgvisualitemmodel.cpp
@@ -372,6 +372,35 @@ void QSGVisualItemModel::append(QSGItem *item)
}
}
+void QSGVisualItemModel::append(QSGVisualItemModel *sourceModel, int sourceIndex, int count)
+{
+ Q_D(QSGVisualItemModel);
+ int destinationIndex = d->count();
+
+ if (sourceModel == this) {
+ return;
+ }
+
+ for (int i = 0, difference = 0; i < count; i += difference) {
+ int modelIndex = 0;
+ int internalIndex = 0;
+ QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex);
+ difference = range.index + range.count - modelIndex;
+
+ if (range.internal()) {
+ for (int j = 0; j < range.count; ++j)
+ d->appendData(sourceModel->d_func()->children.at(internalIndex + j).item);
+ } else {
+ d->appendList(range.list, modelIndex, qMin(count - i, range.count), false);
+ }
+ }
+
+ emit itemsInserted(destinationIndex, count);
+
+ sourceModel->d_func()->removeAt(sourceIndex, count);
+ emit sourceModel->itemsRemoved(sourceIndex, count);
+}
+
void QSGVisualItemModel::insert(int index, QSGItem *item)
{
qDebug() << Q_FUNC_INFO << index;
@@ -387,6 +416,35 @@ void QSGVisualItemModel::insert(int index, QSGItem *item)
}
}
+void QSGVisualItemModel::insert(int destinationIndex, QSGVisualItemModel *sourceModel, int sourceIndex, int count)
+{
+ Q_D(QSGVisualItemModel);
+
+ if (sourceModel == this) {
+ move(sourceIndex, destinationIndex, count);
+ return;
+ }
+
+ for (int i = 0, difference = 0; i < count; i += difference) {
+ int modelIndex = 0;
+ int internalIndex = 0;
+ QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex);
+ difference = range.index + range.count - modelIndex;
+
+ if (range.internal()) {
+ for (int j = 0; j < range.count; ++j)
+ d->insertData(destinationIndex + i + j, sourceModel->d_func()->children.at(internalIndex + j).item);
+ } else {
+ d->insertList(destinationIndex + i, range.list, modelIndex, qMin(count - i, range.count), false);
+ }
+ }
+
+ emit itemsInserted(destinationIndex, count);
+
+ sourceModel->d_func()->removeAt(sourceIndex, count);
+ emit sourceModel->itemsRemoved(sourceIndex, count);
+}
+
void QSGVisualItemModel::remove(int index, int count)
{
Q_D(QSGVisualItemModel);
@@ -420,7 +478,7 @@ void QSGVisualItemModel::move(int from, int to, int count)
}
}
-void QSGVisualItemModel::replace(int index, QSGItem *item, QSGVisualItemModel::CachePolicy policy)
+void QSGVisualItemModel::replace(int index, QSGItem *item)
{
Q_D(QSGVisualItemModel);
const int internalIndex = d->indexOf(item);
@@ -438,12 +496,34 @@ void QSGVisualItemModel::replace(int index, QSGItem *item, QSGVisualItemModel::C
if (!d->transaction)
d->emitTransactionChanges();
}
-
} else {
d->replaceAt(index, item);
}
}
+void QSGVisualItemModel::replace(int destinationIndex, QSGVisualItemModel *sourceModel, int sourceIndex, int count)
+{
+ Q_D(QSGVisualItemModel);
+ if (sourceModel == this) {
+ return;
+ } else {
+ d->removeAt(destinationIndex, count);
+ for (int i = 0, difference = 0; i < count; i += difference) {
+ int modelIndex = 0;
+ int internalIndex = 0;
+ QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex);
+ difference = range.index + range.count - modelIndex;
+
+ if (range.internal()) {
+ for (int j = 0; j < range.count; ++j)
+ d->insertData(destinationIndex + i + j, sourceModel->d_func()->children.at(internalIndex + j).item);
+ } else {
+ d->insertList(destinationIndex + i, range.list, modelIndex, qMin(count - i, range.count), false);
+ }
+ }
+ }
+}
+
void QSGVisualItemModel::_q_itemsInserted(int index, int count)
{
Q_D(QSGVisualItemModel);
diff --git a/src/declarative/items/qsgvisualitemmodel_p.h b/src/declarative/items/qsgvisualitemmodel_p.h
index 6e9d1883b6..9b1711cdcf 100644
--- a/src/declarative/items/qsgvisualitemmodel_p.h
+++ b/src/declarative/items/qsgvisualitemmodel_p.h
@@ -114,11 +114,6 @@ class Q_DECLARATIVE_EXPORT QSGVisualItemModel : public QSGVisualModel
Q_CLASSINFO("DefaultProperty", "children")
public:
- enum CachePolicy {
- Persist,
- Reclaim
- };
-
QSGVisualItemModel(QObject *parent=0);
virtual ~QSGVisualItemModel() {}
@@ -136,10 +131,14 @@ public:
Q_INVOKABLE QScriptValue getItemInfo(int index) const;
Q_INVOKABLE void append(QSGItem *item);
+ Q_INVOKABLE void append(QSGVisualItemModel *sourceModel, int sourceIndex, int count);
Q_INVOKABLE void insert(int index, QSGItem *item);
+ Q_INVOKABLE void insert(int destinationIndex, QSGVisualItemModel *sourceModel, int sourceIndex, int count);
Q_INVOKABLE void remove(int index, int count);
Q_INVOKABLE void move(int from, int to, int count);
- Q_INVOKABLE void replace(int index, QSGItem *item, QSGVisualItemModel::CachePolicy policy = Persist);
+ Q_INVOKABLE void replace(int index, QSGItem *item);
+ Q_INVOKABLE void replace(int destinationIndex, QSGVisualItemModel *sourceModel, int sourceIndex, int count);
+
QDeclarativeListProperty<QObject> children();