diff options
| author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-06-21 13:50:36 +1000 |
|---|---|---|
| committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-06-21 13:50:36 +1000 |
| commit | 088bf47172eedb19945bf1e5eba6f036a362d2dc (patch) | |
| tree | 9e698c9064c0ed3fc2c2a69747eb5c344ea4cde7 | |
| parent | 3cbe13da26023fd262bb6d9b05659629c3af28d8 (diff) | |
Add support for moving items between VisualItemModels.
| -rw-r--r-- | examples/declarative/dragtarget/launcher/IconDelegate.qml | 10 | ||||
| -rw-r--r-- | examples/declarative/dragtarget/launcher/launcher.qml | 115 | ||||
| -rw-r--r-- | src/declarative/items/qsgvisualitemmodel.cpp | 84 | ||||
| -rw-r--r-- | src/declarative/items/qsgvisualitemmodel_p.h | 11 |
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(); |
