Add icon re-ordering support by hold and move 81/9481/1
authorTasuku Suzuki <tasuku.suzuki@qt.io>
Tue, 23 May 2017 05:24:35 +0000 (14:24 +0900)
committerTasuku Suzuki <tasuku.suzuki@qt.io>
Tue, 23 May 2017 05:51:05 +0000 (14:51 +0900)
Change-Id: Ieb6bf721932e36e4ea69cd56d59019ed8fed13ba
Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
homescreen/qml/Home.qml
homescreen/qml/IconItem.qml [new file with mode: 0644]
homescreen/qml/qml.qrc
homescreen/src/applicationmodel.cpp
homescreen/src/applicationmodel.h

index aa3a129..a312670 100644 (file)
@@ -31,6 +31,7 @@ Item {
     property int pid: -1
 
     GridView {
+        id: grid
         anchors.centerIn: parent
         width: cellHeight * 3
         height: cellHeight * 3
@@ -38,28 +39,42 @@ Item {
         cellHeight: 320
         interactive: false
 
-        model: ApplicationModel {}
-        delegate: MouseArea {
-            width: 320
-            height: 320
-            Image {
-                anchors.fill: parent
-                source: './images/HMI_AppLauncher_%1_%2-01.png'.arg(model.icon).arg(pressed ? 'Active' : 'Inactive')
-            }
-            onClicked: {
-                console.log("app is ", model.id)
-                pid = launcher.launch(model.id)
-                if (1 < pid) {
-                    layoutHandler.makeMeVisible(pid)
+        model: ApplicationModel { id: applicationModel }
+        delegate: IconItem {
+            width: grid.cellWidth
+            height: grid.cellHeight
+        }
 
-                    applicationArea.visible = true
-                    appLauncherAreaLauncher.visible = false
-                    layoutHandler.showAppLayer(pid)
-                }
-                else {
-                    console.warn("app cannot be launched!")
+        MouseArea {
+            id: loc
+            anchors.fill: parent
+            property string currentId: ''
+            property int newIndex: -1
+            property int index: grid.indexAt(loc.mouseX, loc.mouseY)
+            onPressAndHold: currentId = applicationModel.id(newIndex = index)
+            onReleased: {
+                if (currentId === '') {
+                    pid = launcher.launch(applicationModel.id(loc.index))
+                    if (1 < pid) {
+                        layoutHandler.makeMeVisible(pid)
+
+                        applicationArea.visible = true
+                        appLauncherAreaLauncher.visible = false
+                        layoutHandler.showAppLayer(pid)
+                    }
+                    else {
+                        console.warn("app cannot be launched!")
+                    }
+                } else {
+                    currentId = ''
                 }
             }
+            onPositionChanged: {
+                if (loc.currentId === '') return
+                if (index < 0) return
+                if (index === newIndex) return
+                    applicationModel.move(newIndex, newIndex = index)
+            }
         }
     }
 }
diff --git a/homescreen/qml/IconItem.qml b/homescreen/qml/IconItem.qml
new file mode 100644 (file)
index 0000000..59131c0
--- /dev/null
@@ -0,0 +1,37 @@
+import QtQuick 2.0
+
+Item {
+    id: main
+    Image {
+        id: item; parent: loc
+        x: main.x + 5; y: main.y + 5
+        width: main.width - 10; height: main.height - 10;
+        source: './images/HMI_AppLauncher_%1_%2-01.png'.arg(model.icon).arg(loc.pressed && (loc.index === model.index || loc.currentId === model.id) ? 'Active' : 'Inactive')
+        antialiasing: item.state !== ''
+        Behavior on x { enabled: item.state !== 'active'; NumberAnimation { duration: 400; easing.type: Easing.OutCubic } }
+        Behavior on y { enabled: item.state !== 'active'; NumberAnimation { duration: 400; easing.type: Easing.OutCubic } }
+        SequentialAnimation on rotation {
+            NumberAnimation { to:  5; duration: 100 }
+            NumberAnimation { to: -5; duration: 200 }
+            NumberAnimation { to:  0; duration: 100 }
+            running: loc.currentId !== '' && item.state !== 'active'
+            loops: Animation.Infinite; alwaysRunToEnd: true
+        }
+        states: [
+            State {
+                name: 'active'
+                when: loc.currentId == model.id
+                PropertyChanges { target: item; x: loc.mouseX - width/2; y: loc.mouseY - height/2; scale: 1.15; z: 10 }
+            },
+            State {
+                when: loc.currentId !== ''
+                PropertyChanges {
+                    target: item
+                    scale: 0.85
+                    opacity: 0.75
+                }
+            }
+        ]
+        transitions: Transition { NumberAnimation { properties: 'scale, opacity, x, y'; duration: 150; easing.type: Easing.OutCubic} }
+    }
+}
index 3d699e0..c25e266 100644 (file)
@@ -10,5 +10,6 @@
         <file>ShortcutIcon.qml</file>
         <file>StatusArea.qml</file>
         <file>TopArea.qml</file>
+        <file>IconItem.qml</file>
     </qresource>
 </RCC>
index c43e1bc..417bc4c 100644 (file)
@@ -114,3 +114,31 @@ QHash<int, QByteArray> ApplicationModel::roleNames() const
     roles[Qt::UserRole] = "id";
     return roles;
 }
+
+QString ApplicationModel::id(int i) const
+{
+    return data(index(i), Qt::UserRole).toString();
+}
+
+void ApplicationModel::move(int from, int to)
+{
+    QModelIndex parent;
+    if (to < 0 || to > rowCount()) return;
+    if (from < to) {
+        if (!beginMoveRows(parent, from, from, parent, to + 1)) {
+            qDebug() << from << to << false;
+            return;
+        }
+        d->data.move(from, to);
+        endMoveRows();
+    } else if (from > to) {
+        if (!beginMoveRows(parent, from, from, parent, to)) {
+            qDebug() << from << to << false;
+            return;
+        }
+        d->data.move(from, to);
+        endMoveRows();
+    } else {
+        qDebug() << from << to << false;
+    }
+}
index bffc4c9..2414b7e 100644 (file)
@@ -30,6 +30,8 @@ public:
 
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
     QHash<int, QByteArray> roleNames() const override;
+    Q_INVOKABLE QString id(int index) const;
+    Q_INVOKABLE void move(int from, int to);
 
 private:
     class Private;