Routing support added to QML ui
authorJanne Kiiski <janne.kiiski@ixonos.com>
Fri, 12 Nov 2010 12:53:17 +0000 (14:53 +0200)
committerJanne Kiiski <janne.kiiski@ixonos.com>
Fri, 12 Nov 2010 12:53:17 +0000 (14:53 +0200)
src/engine/engine.cpp
src/engine/engine.h
src/qmlui/Main.qml
src/qmlui/Map.qml
src/qmlui/RoutingDelegate.qml [new file with mode: 0644]
src/qmlui/RoutingPanel.qml [new file with mode: 0644]
src/qmlui/res.qrc
src/routing/route.cpp
src/src.pro

index 8f76494..b40a77f 100644 (file)
@@ -49,8 +49,8 @@
 #include <QApplication>
 #include <QDesktopWidget>
 #include <QDeclarativeEngine>
-
 #include "engine.h"
+#include "routing/routemodel.h"
 
 const QString SETTINGS_GPS_ENABLED = "GPS_ENABLED"; ///< GPS setting
 const QString SETTINGS_AUTO_CENTERING_ENABLED = "AUTO_CENTERING_ENABLED";///< Auto centering setting
@@ -59,8 +59,15 @@ const qreal USER_MOVEMENT_MINIMUM_LONGITUDE_DIFFERENCE = 0.003;///< Min value fo
 const qreal USER_MOVEMENT_MINIMUM_LATITUDE_DIFFERENCE = 0.001;///< Min value for user move longitude
 const int MIN_UPDATE_INTERVAL_MSECS = 5*60*1000;
 
+class SituareEnginePrivate
+{
+public:
+    RouteModel routeModel;
+};
+
 SituareEngine::SituareEngine()
-    : m_autoCenteringEnabled(false),
+    : d_ptr(new SituareEnginePrivate),
+      m_autoCenteringEnabled(false),
       m_automaticUpdateFirstStart(true),
       m_automaticUpdateRequest(false),
       m_userMoved(false),
@@ -141,9 +148,20 @@ SituareEngine::SituareEngine()
 #ifdef Q_WS_MAEMO_5
 //    view.setAttribute(Qt::WA_Maemo5AutoOrientation, true);
 #endif
+    Q_D(SituareEngine);
     Rotation *rotation = new Rotation();
     view->rootContext()->setContextProperty("deviceRotation", static_cast<QObject *>(rotation));
     view->rootContext()->setContextProperty("facebookAuthenticator", m_facebookAuthenticator);
+
+    // test segments
+    for( int i = 0; i < 4; ++i) {
+        RouteSegment segment;
+        segment.setInstruction(i != 3 ? "Turn left" : "You're back at starting point");
+        d->routeModel.addSegment(segment);
+    }
+    view->rootContext()->setContextProperty("routingModel", &d->routeModel);
+    view->rootContext()->setContextProperty("engine", this);
+
     view->setSource(QUrl("qrc:/Main.qml"));
     view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
     view->show();
@@ -485,7 +503,9 @@ void SituareEngine::routeParsed(Route &route)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    Q_UNUSED(route);
+    Q_D(SituareEngine);
+
+    d->routeModel.setSegments(route.segments());
 
     m_ui->toggleProgressIndicator(false);
 }
@@ -816,3 +836,12 @@ void SituareEngine::userDataChanged(User *user, QList<User *> &friendsList)
     emit userLocationReady(user);
     emit friendsLocationsReady(friendsList);
 }
+
+void SituareEngine::routeFromTo(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_ui->toggleProgressIndicator(true);
+
+    m_routingService->requestRoute(GeoCoordinate(fromLatitude, fromLongitude), GeoCoordinate(toLatitude, toLongitude));
+}
index 4e1930a..fc04dae 100644 (file)
@@ -49,6 +49,8 @@ class RoutingService;
 class SituareService;
 class User;
 
+class SituareEnginePrivate;
+
 /**
 * @brief Engine class for Situare Application
 *
@@ -142,6 +144,15 @@ public slots:
     */
     void userDataChanged(User *user, QList<User *> &friendsList);
 
+    /**
+      * @brief Routes from given coordinates to given coordinates
+      * @param fromLatitude start point latitude
+      * @param fromLongitude start point longitude
+      * @param toLatitude end point latitude
+      * @param toLongitude end point longitude
+      */
+    void routeFromTo(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude);
+
 private:
     /**
     * @brief Read settings and determine whether to use GPS and autocentering.
@@ -363,6 +374,9 @@ signals:
  * DATA MEMBERS
  ******************************************************************************/
 private:
+    Q_DECLARE_PRIVATE(SituareEngine);
+    QScopedPointer<SituareEnginePrivate> d_ptr;
+
     bool m_autoCenteringEnabled;        ///< Auto centering flag
     bool m_automaticUpdateFirstStart;   ///< Automatic location update first start flag
     bool m_automaticUpdateRequest;      ///< Flag for automatic update request
index daf060a..7d90171 100644 (file)
@@ -8,7 +8,7 @@ Rectangle {
     color: "black"
     id: root
 
-    Map { x: 0; y: 0; width: friendPanel.x; height: parent.height }
+    Map { id: map; x: 0; y: 0; width: friendPanel.x; height: parent.height }
 
     PanelContents {
         id: friendPanel
@@ -16,6 +16,12 @@ Rectangle {
         y: parent.y
         width: (parent.width - me.width ) / 2
     }
+    RoutingPanel {
+        id: routingPanel
+        x: me.x
+        y: parent.y
+        width: (parent.width - me.width) / 2
+    }
 
     Button {
         id: me
@@ -40,6 +46,7 @@ Rectangle {
         anchors.top: friends.bottom
         image: "qrc:/res/routing.png"
         text: "Routing"
+        onButtonClicked: routingPanel.state == "opened" ? routingPanel.state = "" : routingPanel.state = "opened"
     }
 
     Button {
index 2aec253..85db118 100644 (file)
@@ -6,6 +6,11 @@ Item {
     state: deviceRotation.orientation
     clip: true
 
+    property alias centerLatitude: map.centerLatitude
+    property alias centerLongitude: map.centerLongitude
+    property alias gpsLocationLatitude: map.gpsLocationLatitude
+    property alias gpsLocationLongitude: map.gpsLocationLongitude
+
     Rectangle {
         id: mapContents
         color: palette.window
diff --git a/src/qmlui/RoutingDelegate.qml b/src/qmlui/RoutingDelegate.qml
new file mode 100644 (file)
index 0000000..277b4cd
--- /dev/null
@@ -0,0 +1,154 @@
+import Qt 4.7
+
+Item {
+    id: delegate
+
+    width: delegate.ListView.view.width
+    height: childrenRect.height
+
+    Rectangle {
+        id: background
+        anchors {
+            left: parent.left
+            right: parent.right
+            top: parent.top
+            bottom: lengthText.bottom
+            topMargin: 5
+            bottomMargin: -5
+        }
+        gradient: Gradient {
+            GradientStop {
+                position: 0
+                color: "#777777"
+            }
+
+            GradientStop {
+                position: 1
+                color: "#222222"
+            }
+        }
+        border { width: 1; color: "#777777" }
+        radius: 5
+    }
+
+    Image {
+        id: turnImage
+        x: 10
+        y: 4
+        source: {
+            switch(turnType) {
+            case "C": "qrc:/res/images/arrow_turn_continue.png"; break;
+            case "TL": "qrc:/res/images/arrow_turn_left.png"; break;
+            case "TSLL": "qrc:/res/images/arrow_turn_slight_left.png"; break;
+            case "TSHL": "qrc:/res/images/arrow_turn_sharp_left.png"; break;
+            case "TR": "qrc:/res/images/arrow_turn_right.png"; break;
+            case "TSLR": "qrc:/res/images/arrow_turn_slight_right.png"; break;
+            case "TSLL": "qrc:/res/images/arrow_turn_sharp_right.png"; break;
+            case "TU": "qrc:/res/images/arrow_turn_u_turn.png"; break;
+            default: "qrc:/res/images/arrow_turn_start.png"; break;
+            }
+        }
+    }
+    BorderImage {
+        id: borderImage
+        anchors.fill: turnImage
+        anchors.margins: -8
+        source: "qrc:/res/images/profile_pic_border.png"
+        border.left: 24; border.top: 24
+        border.right: 24; border.bottom: 24
+        horizontalTileMode: BorderImage.Stretch
+        verticalTileMode: BorderImage.Stretch
+    }
+
+    Text {
+        id: instructionText
+        anchors { left: turnImage.right; right: background.right; top: background.top; margins: 5; leftMargin: 10 }
+        text: streetName
+        clip: true;
+        elide: Text.ElideRight
+    }
+
+    Image {
+        id: timeImage
+        source: "qrc:/res/images/clock.png"
+        anchors { left: instructionText.left; top: instructionText.bottom }
+    }
+    Text {
+        id: timeText
+        font.pixelSize: timeImage.height * 0.8
+        anchors { margins: 5; left: timeImage.right; right: parent.right; verticalCenter: timeImage.verticalCenter }
+        text: time
+    }
+
+    Image {
+        id: lengthImage
+        anchors { left: instructionText.left; top: timeImage.bottom }
+        source: "qrc:/res/images/ruler.png"
+    }
+    Text {
+        id: lengthText
+        font.pixelSize: lengthImage.height * 0.8
+        anchors { margins: 5; left: lengthImage.right; right: parent.right; verticalCenter: lengthImage.verticalCenter }
+        text: lengthCaption
+    }
+
+
+//    Rectangle {
+//        id: listItem
+//        width: parent.width
+//        height: col.height + 8
+//        color: "lightsteelblue"
+//        radius: 10
+//        border { color: "black"; width: 2 }
+//        clip: true
+
+//        MouseArea {
+//            anchors.fill: parent
+//            onClicked: listItem.state == 'expanded' ? listItem.state = '' : listItem.state = 'expanded'
+//        }
+
+//        Image {
+//            id: image
+//            source: picture
+//            anchors.top: parent.top
+//            anchors.topMargin: 5
+//            anchors.left: parent.left
+//            anchors.leftMargin: 7
+//        }
+
+//        Column {
+//            id: col
+//            x: image.x + image.width + 7
+//            width: parent.width - x - 7
+//            y: 3
+//            Text { text: '<b>' + instruction + '</b> ' }
+//            Text {
+//                id: msg;
+//                text: message;
+//                font.pixelSize: 16;
+//                clip: true;
+//                elide: Text.ElideRight
+//                anchors.left: parent.left;
+//                anchors.right: parent.right}
+//            }
+
+//        states: [
+//            State {
+//                name: "expanded"
+//                PropertyChanges {
+//                    target: msg
+//                    wrapMode: Text.Wrap
+//                    elide: Text.ElideNone
+//                }
+//            }
+//        ]
+
+//        transitions: [
+//            Transition {
+//                from: ""
+//                to: "expanded"
+//                NumberAnimation { properties: "height"; duration: 100 }
+//                reversible: true
+//            }
+//        ]
+    }
diff --git a/src/qmlui/RoutingPanel.qml b/src/qmlui/RoutingPanel.qml
new file mode 100644 (file)
index 0000000..7068e5e
--- /dev/null
@@ -0,0 +1,85 @@
+import Qt 4.7
+
+Item {
+    id: panel
+    height: parent.height
+    Rectangle {
+        anchors.fill: parent
+        color: "black"
+        opacity: 0.3
+    }
+    clip: true
+
+    Item {
+        id: contentsArea
+        state: deviceRotation.orientation
+        anchors.centerIn: parent
+        x: 0
+        y: 0
+        height: panel.height
+        width: panel.width
+
+        Button {
+            id: routeTo
+            text: "route to cursor"
+            width: parent.width
+            height: 30
+            onButtonClicked: {
+                console.log("clicked: Route to cursor")
+                engine.routeFromTo(map.gpsLocationLatitude, map.gpsLocationLongitude, map.centerLatitude, map.centerLongitude);
+            }
+        }
+
+        ListView {
+            anchors { left: parent.left; right: parent.right; top: routeTo.bottom; bottom: parent.bottom }
+
+            anchors.margins: 5
+            spacing: 5
+
+            model: routingModel
+            delegate: RoutingDelegate {}
+            focus: true
+            clip: true
+        }
+
+        states: [
+            State {
+                name: "potrait"
+                PropertyChanges {
+                    target: contentsArea
+                    rotation: -90
+                    height: panel.width
+                    width: panel.height
+                }
+            }
+        ]
+
+        transitions: [
+            Transition {
+                from: ""
+                to: "potrait"
+                NumberAnimation { properties: "rotation,heigth,width"; duration: 200 }
+                reversible: true
+            }
+        ]
+    }
+
+    states: [
+        State {
+            name: "opened"
+            PropertyChanges {
+                target: panel
+                x: width
+            }
+        }
+    ]
+
+    transitions: [
+        Transition {
+            from: ""
+            to: "opened"
+            NumberAnimation { properties: "x"; duration: 200 }
+            reversible: true
+        }
+    ]
+}
index 6662d9c..01e11bc 100644 (file)
@@ -23,5 +23,7 @@
         <file>res/ixonos_logo.png</file>
         <file>Dialog.qml</file>
         <file>LoginWidget.qml</file>
+        <file>RoutingPanel.qml</file>
+        <file>RoutingDelegate.qml</file>
     </qresource>
 </RCC>
index 3e4ae8d..dd06be1 100644 (file)
@@ -115,3 +115,4 @@ int Route::totalTime() const
 
     return m_totalTime;
 }
+
index 0a8b49f..928ab7b 100644 (file)
@@ -91,6 +91,7 @@ SOURCES += main.cpp \
     qmlui/geomap.cpp \
     qmlui/loginlogic.cpp \
     qmlui/rotation.cpp \
+    routing/routemodel.cpp
 
 HEADERS += application.h \
     common.h \
@@ -180,6 +181,7 @@ HEADERS += application.h \
     qmlui/geomap.h \
     qmlui/loginlogic.h \
     qmlui/rotation.h \
+    routing/routemodel.h
 
 OTHER_FILES += qmlui/Main.qml \
     qmlui/Dialog.qml \
@@ -189,6 +191,8 @@ OTHER_FILES += qmlui/Main.qml \
     qmlui/Map.qml \
     qmlui/PanelContents.qml \
     qmlui/List.qml \
+    qmlui/RoutingPanel.qml \
+    qmlui/RoutingDelegate.qml
 
 QT += network \
     webkit  \