Add preliminary station chooser UI for realtime
authorThomas Perl <m@thp.io>
Fri, 14 Oct 2011 13:06:18 +0000 (15:06 +0200)
committerThomas Perl <m@thp.io>
Fri, 14 Oct 2011 13:06:18 +0000 (15:06 +0200)
gotovienna-qml
qml/MainPage.qml
qml/StationListItem.qml [new file with mode: 0644]

index 3dab53a..d0ba500 100755 (executable)
@@ -17,6 +17,7 @@ from gotovienna.realtime import *
 import urllib2
 import os
 import sys
+import threading
 
 class GotoViennaListModel(QAbstractListModel):
     def __init__(self, objects=None):
@@ -55,6 +56,37 @@ class Gui(QObject):
         for _, lines in categorize_lines(self.itip.lines):
             self.lines.extend(lines)
 
+        self.current_line = ''
+        self.current_stations = []
+
+    @Slot(int, result=str)
+    def get_direction(self, idx):
+        return self.current_stations[idx][0]
+
+    @Slot(str, str, result='QStringList')
+    def get_stations(self, line, direction):
+        print 'line:', line, 'current line:', self.current_line
+        for dx, stations in self.current_stations:
+            print 'dx:', dx, 'direction:', direction
+            if dx == direction:
+                return [stationname for stationname, url in stations]
+
+        return ['no stations found']
+
+    directionsLoaded = Signal()
+
+    @Slot(str)
+    def load_directions(self, line):
+        def load_async():
+            stations = sorted(self.itip.get_stations(line).items())
+
+            self.current_line = line
+            self.current_stations = stations
+
+            self.directionsLoaded.emit()
+
+        threading.Thread(target=load_async).start()
+
     @Slot(result='QStringList')
     def get_lines(self):
         return self.lines
index a4b3a98..d1ccffc 100644 (file)
@@ -101,20 +101,201 @@ Page {
         anchors {
             top: gline.bottom
             left: parent.left
-            right: parent.right
+            right: stationPickerButton.left
             topMargin: 10
             leftMargin: 10
+            rightMargin: 10*stationPickerButton.opacity
+        }
+        onTextChanged: {
+            directionLabel.currentDirection = ''
+        }
+    }
+
+    Sheet {
+        id: stationSheet
+        property string currentLine: ''
+        property string currentDirection: ''
+        property string currentStation: ''
+
+        acceptButtonText: 'Select'
+        rejectButtonText: 'Cancel'
+
+        function loadData(lineName) {
+            stationSheet.currentLine = lineName
+
+            directionChooser.direction1 = ''
+            directionChooser.direction2 = ''
+
+            directionChooserBusyIndicator.running = true
+            itip.load_directions(stationSheet.currentLine)
+
+            firstDirection.clicked()
+            directionChooser.checkedButton = firstDirection
+        }
+
+        Connections {
+            target: itip
+
+            onDirectionsLoaded: {
+                directionChooserBusyIndicator.running = false
+
+                directionChooser.direction1 = itip.get_direction(0)
+                directionChooser.direction2 = itip.get_direction(1)
+
+                firstDirection.clicked()
+                directionChooser.checkedButton = firstDirection
+            }
+        }
+
+        content: Item {
+            anchors.fill: parent
+
+            ButtonColumn {
+                id: directionChooser
+                property string direction1
+                property string direction2
+
+                visible: !directionChooserBusyIndicator.running
+
+                function chosen(idx) {
+                    console.log('direction chosen: '+ idx)
+
+                    stationSelectorListView.selectedIndex = -1
+
+                    if (idx == 1) {
+                        stationSheet.currentDirection = directionChooser.direction1
+                    } else {
+                        stationSheet.currentDirection = directionChooser.direction2
+                    }
+
+                    directionChooserModel.clear()
+                    var stations = itip.get_stations(stationSheet.currentLine, stationSheet.currentDirection)
+
+                    for (var s in stations) {
+                        directionChooserModel.append({'station': stations[s]})
+                    }
+                }
+
+                anchors {
+                    margins: 10
+                    top: parent.top
+                    left: parent.left
+                    right: parent.right
+                }
+
+                Button {
+                    id: firstDirection
+                    text: 'Richtung ' + directionChooser.direction1
+                    onClicked: directionChooser.chosen(1)
+                }
+
+                Button {
+                    id: secondDirection
+                    text: 'Richtung ' + directionChooser.direction2
+                    onClicked: directionChooser.chosen(2)
+                }
+            }
+
+            ListView {
+                id: stationSelectorListView
+                visible: !directionChooserBusyIndicator.running
+
+                property int selectedIndex: -1
+                onSelectedIndexChanged: {
+                    console.log('current index: ' + selectedIndex)
+                }
+
+                anchors {
+                    margins: 10
+                    top: directionChooser.bottom
+                    left: parent.left
+                    right: parent.right
+                    bottom: parent.bottom
+                }
+
+                clip: true
+
+                model: ListModel {
+                    id: directionChooserModel
+                }
+
+                delegate: StationListItem { selector: stationSelectorListView }
+            }
+
+            ScrollDecorator {
+                flickableItem: stationSelectorListView
+            }
+
+            BusyIndicator {
+                id: directionChooserBusyIndicator
+                anchors.centerIn: parent
+                visible: running
+                platformStyle: BusyIndicatorStyle { size: 'large' }
+            }
+        }
+
+        onAccepted: {
+            if (stationSelectorListView.selectedIndex == -1) {
+                gstation.text = ''
+            } else {
+                gstation.text = directionChooserModel.get(stationSelectorListView.selectedIndex).station
+            }
+
+            directionLabel.currentDirection = stationSheet.currentDirection
+        }
+    }
+
+    Button {
+        id: stationPickerButton
+
+        anchors {
+            top: gstation.top
+            bottom: gstation.bottom
+            right: parent.right
             rightMargin: 10
         }
+
+        Behavior on opacity { PropertyAnimation { } }
+
+        opacity: gline.text != '' // XXX: Check if the line is valid
+
+        width: lineSearchButton.width * opacity
+        //iconSource: 'image://theme/icon-m-common-location-picker'
+        iconSource: 'image://theme/icon-m-toolbar-list'
+
+        onClicked: {
+            stationSheet.open()
+            stationSheet.loadData(gline.text)
+        }
     }
 
     ResultRealtime { id: resu }
 
+    Label {
+        id: directionLabel
+        property string currentDirection: ''
+        text: 'Richtung ' + currentDirection
+
+        anchors {
+            left: parent.left
+            right: parent.right
+            top: gstation.bottom
+            margins: 20*directionLabel.opacity
+        }
+
+        font.pixelSize: UIConstants.FONT_SMALL
+
+        opacity: currentDirection != ''
+        scale: opacity
+
+        Behavior on opacity { PropertyAnimation { } }
+    }
+
     Button {
         id: btnSearch
         text: 'Search'
         anchors {
-            top: gstation.bottom
+            top: directionLabel.bottom
             topMargin: 10
             horizontalCenter: parent.horizontalCenter
         }
diff --git a/qml/StationListItem.qml b/qml/StationListItem.qml
new file mode 100644 (file)
index 0000000..c09c3e9
--- /dev/null
@@ -0,0 +1,61 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.0
+
+import "UIConstants.js" as UIConstants
+import "ExtrasConstants.js" as ExtrasConstants
+
+Item {
+    property Item selector
+
+    width: parent.width
+    height: 60
+
+    BorderImage {
+        anchors.fill: parent
+        visible: mouseArea.pressed
+        source: theme.inverted ? 'image://theme/meegotouch-list-inverted-background-pressed-vertical-center': 'image://theme/meegotouch-list-background-pressed-vertical-center'
+    }
+
+    BorderImage {
+        anchors.fill: parent
+        visible: selector.selectedIndex == index
+        source: theme.inverted ? 'image://theme/meegotouch-list-inverted-background-selected-vertical-center': 'image://theme/meegotouch-list-background-selected-vertical-center'
+    }
+
+    Item {
+        anchors.fill: parent
+        anchors.margins: UIConstants.DEFAULT_MARGIN
+
+        Text {
+            anchors {
+                verticalCenter: parent.center
+                left: parent.left
+                leftMargin: 10
+                right: parent.right
+            }
+
+            elide: Text.ElideRight
+
+            text: station
+            font.pixelSize: UIConstants.FONT_DEFAULT
+            font.family: ExtrasConstants.FONT_FAMILY
+
+            color: {
+                if (theme.inverted) {
+                    (selector.selectedIndex == index) ? UIConstants.COLOR_FOREGROUND : UIConstants.COLOR_INVERTED_FOREGROUND
+                } else {
+                    (selector.selectedIndex != index) ? UIConstants.COLOR_FOREGROUND : UIConstants.COLOR_INVERTED_FOREGROUND
+                }
+            }
+        }
+    }
+
+    MouseArea {
+        id: mouseArea
+        anchors.fill: parent
+        onClicked: selector.selectedIndex = index
+    }
+}
+