[gnome-maps/wip/mlundblad/transit-routing: 4/5] sidebar: WIP, Hook up a new transit mode button
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps/wip/mlundblad/transit-routing: 4/5] sidebar: WIP, Hook up a new transit mode button
- Date: Thu, 26 May 2016 21:31:24 +0000 (UTC)
commit a42276669bec375078fe65218d5e90e8160806b2
Author: Marcus Lundblad <ml update uu se>
Date: Thu Mar 17 21:34:11 2016 +0100
sidebar: WIP, Hook up a new transit mode button
Performs transit routing, work in progress...
data/gnome-maps.css | 4 +
data/ui/sidebar.ui | 276 ++++++++++++++++++++++++++++++++++++++++++++++-----
src/sidebar.js | 142 ++++++++++++++++++++-------
3 files changed, 363 insertions(+), 59 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index 0f7c8ce..ecc0aeb 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -81,3 +81,7 @@
.maps-check-in GtkTextView {
font-size: large;
}
+
+.shaded {
+ background-color: alpha(black, 0.1);
+}
diff --git a/data/ui/sidebar.ui b/data/ui/sidebar.ui
index 77347ed..a141d2e 100644
--- a/data/ui/sidebar.ui
+++ b/data/ui/sidebar.ui
@@ -94,6 +94,28 @@
</style>
</object>
</child>
+ <child>
+ <object class="GtkRadioButton" id="modeTransitToggle">
+ <property name="name">mode-transit-toggle</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="draw_indicator">False</property>
+ <property name="group">modeBikeToggle</property>
+ <property name="height-request">32</property>
+ <property name="width-request">42</property>
+ <child>
+ <object class="GtkImage" id="mode-transit-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">route-transit-symbolic</property>
+ </object>
+ </child>
+ <style>
+ <class name="transportation-mode-button"/>
+ </style>
+ </object>
+ </child>
<style>
<class name="linked"/>
</style>
@@ -140,55 +162,259 @@
</object>
</child>
<child>
- <object class="GtkStack" id="instructionStack">
+ <object class="GtkGrid">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="valign">fill</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand_set">True</property>
+ <style>
+ <class name="frame"/>
+ </style>
<child>
- <object class="GtkScrolledWindow" id="instructionWindow">
- <property name="name">instruction-window</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="valign">fill</property>
- <property name="vexpand">True</property>
- <property name="margin">1</property>
- <property name="hscrollbar_policy">never</property>
+ <object class="GtkStack" id="transitHeader">
+ <property name="no_show_all">True</property>
+ <property name="visible">False</property>
<child>
- <object class="GtkListBox" id="instructionList">
- <property name="name">instruction-list</property>
+ <object class="GtkGrid" id="transitOptionsGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="valign">fill</property>
<style>
- <class name="frame"/>
+ <class name="shaded"/>
</style>
+ <child>
+ <object class="GtkComboBoxText"
+ id="transitTimeOptionsComboBox">
+ <property name="visible">True</property>
+ <property name="active_id">leaveNow</property>
+ <property name="margin_start">6</property>
+ <property name="margin_end">6</property>
+ <property name="margin_top">4</property>
+ <property name="margin_bottom">4</property>
+ <items>
+ <item translatable="yes" id="leaveNow">Leave Now</item>
+ <item translatable="yes" id="leaveBy">Leave By</item>
+ <item translatable="yes" id="arriveBy">Arrive By</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="transitTimeEntry">
+ <property name="visible">False</property>
+ <property name="width_chars">5</property>
+ <property name="margin_start">3</property>
+ <property name="margin_end">3</property>
+ <property name="margin_top">4</property>
+ <property name="margin_bottom">4</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="transitDateButton">
+ <property name="visible">False</property>
+ <property name="popover">transitDatePopover</property>
+ <property name="margin_start">3</property>
+ <property name="margin_end">3</property>
+ <property name="margin_top">4</property>
+ <property name="margin_bottom">4</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="transitParametersMenuButton">
+ <property name="visible">True</property>
+ <property name="popover">transitParametersPopover</property>
+ <property name="halign">GTK_ALIGN_END</property>
+ <property name="margin_start">3</property>
+ <property name="margin_end">6</property>
+ <property name="margin_top">4</property>
+ <property name="margin_bottom">4</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">GTK_ALIGN_CENTER</property>
+ <property name="hexpand">True</property>
+ <property name="icon-name">open-menu-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="name">options</property>
+ </packing>
</child>
</object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
</child>
+
<child>
- <object class="GtkSpinner" id="instructionSpinner">
+ <object class="GtkStack" id="instructionStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="active">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="instructionWindow">
+ <property name="name">instruction-window</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">fill</property>
+ <property name="vexpand">True</property>
+ <property name="margin">1</property>
+ <property name="hscrollbar_policy">never</property>
+ <child>
+ <object class="GtkListBox" id="instructionList">
+ <property name="name">instruction-list</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">fill</property>
+ <property name="hexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="instructionSpinner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">True</property>
+ </object>
+ </child>
</object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
</child>
</object>
</child>
<child>
- <object class="GtkLinkButton" id="linkbutton1">
- <property name="label" translatable="yes">Route search by GraphHopper</property>
+ <object class="GtkStack" id="linkButtonStack">
+ <child>
+ <object class="GtkLinkButton" id="graphHopperLinkButton">
+ <property name="label" translatable="yes">Route search by GraphHopper</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="relief">none</property>
+ <property name="uri">https://graphhopper.com</property>
+ <style>
+ <class name="small-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="name">graphHopper</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="openTripPlannerLinkButton">
+ <property name="label" translatable="yes">Route search by OpenTripPlanner</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="relief">none</property>
+ <!-- opentripplanner.org uses an SSL cert only valid for github
+ domains... -->
+ <property name="uri">http://www.opentripplanner.org</property>
+ <style>
+ <class name="small-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="name">openTripPlanner</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkPopover" id="transitDatePopover">
+ <property name="visible">False</property>
+ <child>
+ <object class="GtkCalendar" id="transitDateCalendar">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkPopover" id="transitParametersPopover">
+ <property name="visible">False</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="margin">6</property>
+ <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+ <child>
+ <object class="GtkLabel">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="relief">none</property>
- <property name="uri">https://graphhopper.com</property>
+ <property name="halign">GTK_ALIGN_START</property>
+ <property name="label" translatable="yes">Show</property>
+ <property name="margin_start">6</property>
<style>
- <class name="small-label"/>
+ <class name="dim-label"/>
</style>
</object>
</child>
+ <child>
+ <object class="GtkCheckButton" id="busCheckButton">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="label" translatable="yes">Buses</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="tramCheckButton">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="label" translatable="yes">Trams</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="trainCheckButton">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="label" translatable="yes">Trains</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="subwayCheckButton">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="label" translatable="yes">Subway</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ferryCheckButton">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="label" translatable="yes">Ferries</property>
+ </object>
+ </child>
</object>
</child>
- </template>
+ </object>
</interface>
diff --git a/src/sidebar.js b/src/sidebar.js
index 64ec5e6..cbc1109 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -48,40 +48,64 @@ const Sidebar = new Lang.Class({
'modeBikeToggle',
'modeCarToggle',
'modePedestrianToggle',
- 'timeInfo' ],
+ 'modeTransitToggle',
+ 'timeInfo',
+ 'linkButtonStack',
+ 'transitHeader',
+ 'transitTimeOptionsComboBox',
+ 'transitTimeEntry',
+ 'transitDateButton',
+ 'transitDateCalendar',
+ 'transitParametersMenuButton' ],
_init: function(mapView) {
this.parent({ transition_type: Gtk.RevealerTransitionType.SLIDE_LEFT });
this._mapView = mapView;
+ this._query = Application.routeQuery;
this._initInstructionList();
-
+ this._initTransitOptions();
this._initTransportationToggles(this._modePedestrianToggle,
this._modeBikeToggle,
- this._modeCarToggle);
- this._initQuerySignals();
-
- let query = Application.routeService.query;
+ this._modeCarToggle,
+ this._modeTransitToggle);
- query.addPoint(0);
- query.addPoint(1);
+ this._initQuerySignals();
+ this._query.addPoint(0);
+ this._query.addPoint(1);
+ this._switchRoutingMode(RouteQuery.Transportation.CAR);
},
- _initTransportationToggles: function(pedestrian, bike, car) {
- let query = Application.routeService.query;
+ _initTransportationToggles: function(pedestrian, bike, car, transit) {
let transport = RouteQuery.Transportation;
let onToggle = function(mode, button) {
- if (button.active && query.transportation !== mode)
- query.transportation = mode;
+ Utils.debug('onToggle: ' + mode + ', query.mode: ' + this._query.transportation);
+
+ let previousMode = this._query.transportation;
+
+ /* if the transportation mode changes to/from transit
+ change the routing engine */
+ if (button.active &&
+ ((mode !== transport.TRANSIT
+ && previousMode === transport.TRANSIT)
+ || (mode === transport.TRANSIT
+ && previousMode !== transport.TRANSIT))) {
+ Utils.debug('switching routing mode');
+ this._switchRoutingMode(mode);
+ }
+
+ if (button.active && previousMode !== mode)
+ this._query.transportation = mode;
};
pedestrian.connect('toggled', onToggle.bind(this, transport.PEDESTRIAN));
car.connect('toggled', onToggle.bind(this, transport.CAR));
bike.connect('toggled', onToggle.bind(this, transport.BIKE));
+ transit.connect('toggled', onToggle.bind(this, transport.TRANSIT))
let setToggles = function() {
- switch(query.transportation) {
+ switch(Application.routeQuery.transportation) {
case transport.PEDESTRIAN:
pedestrian.active = true;
break;
@@ -91,21 +115,42 @@ const Sidebar = new Lang.Class({
case transport.BIKE:
bike.active = true;
break;
+ case transport.TRANSIT:
+ transit.active = true;
+ break;
}
};
setToggles();
- query.connect('notify::transportation', setToggles);
+ this._query.connect('notify::transportation', setToggles);
},
- _initQuerySignals: function() {
- let query = Application.routeService.query;
+ _switchRoutingMode: function(mode) {
+ let graphHopper = Application.routeService;
+ let openTripPlanner = Application.openTripPlanner;
+
+ if (mode === RouteQuery.Transportation.TRANSIT) {
+ Utils.debug('switching to transit');
+ graphHopper.disconnect();
+ openTripPlanner.connect();
+ this._linkButtonStack.visible_child_name = 'openTripPlanner';
+ this._transitHeader.show();
+ this._clearInstructions();
+ } else {
+ Utils.debug('switch from transit');
+ openTripPlanner.disconnect();
+ graphHopper.connect();
+ this._linkButtonStack.visible_child_name = 'graphHopper';
+ this._transitHeader.hide();
+ }
+ },
- query.connect('point-added', (function(obj, point, index) {
+ _initQuerySignals: function() {
+ this._query.connect('point-added', (function(obj, point, index) {
this._createRouteEntry(index, point);
}).bind(this));
- query.connect('point-removed', (function(obj, point, index) {
+ this._query.connect('point-removed', (function(obj, point, index) {
let row = this._entryList.get_row_at_index(index);
row.destroy();
}).bind(this));
@@ -133,17 +178,17 @@ const Sidebar = new Lang.Class({
if (type === RouteEntry.Type.FROM) {
routeEntry.button.connect('clicked', (function() {
let lastIndex = this._entryList.get_children().length;
- Application.routeService.query.addPoint(lastIndex - 1);
+ this._query.addPoint(lastIndex - 1);
}).bind(this));
this.bind_property('child-revealed',
routeEntry.entry, 'has_focus',
GObject.BindingFlags.DEFAULT);
} else if (type === RouteEntry.Type.VIA) {
- routeEntry.button.connect('clicked', function() {
+ routeEntry.button.connect('clicked', (function() {
let row = routeEntry.get_parent();
- Application.routeService.query.removePoint(row.get_index());
- });
+ this._query.removePoint(row.get_index());
+ }).bind(this));
}
this._initRouteDragAndDrop(routeEntry);
@@ -151,19 +196,18 @@ const Sidebar = new Lang.Class({
_initInstructionList: function() {
let route = Application.routeService.route;
- let query = Application.routeService.query;
route.connect('reset', (function() {
this._clearInstructions();
let length = this._entryList.get_children().length;
for (let index = 1; index < (length - 1); index++) {
- query.removePoint(index);
+ this._query.removePoint(index);
}
}).bind(this));
- query.connect('notify', (function() {
- if (query.isValid())
+ this._query.connect('notify', (function() {
+ if (this._query.isValid())
this._instructionStack.visible_child = this._instructionSpinner;
else
this._clearInstructions();
@@ -181,11 +225,11 @@ const Sidebar = new Lang.Class({
this._storeRouteTimeoutId = Mainloop.timeout_add(5000, (function() {
let placeStore = Application.placeStore;
- let places = query.filledPoints.map(function(point) {
+ let places = this._query.filledPoints.map(function(point) {
return point.place;
});
let storedRoute = new StoredRoute.StoredRoute({
- transportation: query.transportation,
+ transportation: this._query.transportation,
route: route,
places: places,
geoclue: Application.geoclue
@@ -215,6 +259,38 @@ const Sidebar = new Lang.Class({
}).bind(this));
},
+ _initTransitOptions: function() {
+ this._transitTimeOptionsComboBox.connect('changed',
+ this._onTransitTimeOptionsComboboxChanged.bind(this));
+ this._transitParametersMenuButton.connect('toggled',
+ this._onTransitParametersToggled.bind(this))
+ },
+
+ _onTransitTimeOptionsComboboxChanged: function() {
+ if (this._transitTimeOptionsComboBox.active_id === 'leaveNow') {
+ this._transitTimeEntry.visible = false;
+ this._transitDateButton.visible = false;
+ this._query.arriveBy = false;
+ } else {
+ this._transitTimeEntry.visible = true;
+ this._transitDateButton.visible = true;
+
+ if (this._transitTimeOptionsComboBox.active_id === 'arriveBy') {
+ this._query.arriveBy = true;
+ } else {
+ this._query.arriveBy = false;
+ /* TODO: if the user hasn't already manually entered a
+ * time, fill in the current time in the time entry */
+ }
+ }
+ },
+
+ _onTransitParametersToggled: function() {
+ if (!this._transitParametersMenuButton.active) {
+ Utils.debug('params selected');
+ }
+ },
+
_clearInstructions: function() {
let listBox = this._instructionList;
listBox.forall(listBox.remove.bind(listBox));
@@ -226,8 +302,7 @@ const Sidebar = new Lang.Class({
// Iterate over points and establish the new order of places
_reorderRoutePoints: function(srcIndex, destIndex) {
- let query = Application.routeService.query;
- let points = query.points;
+ let points = this._query.points;
let srcPlace = this._draggedPoint.place;
// Determine if we are swapping from "above" or "below"
@@ -235,19 +310,18 @@ const Sidebar = new Lang.Class({
// Hold off on notifying the changes to query.points until
// we have re-arranged the places.
- query.freeze_notify();
+ this._query.freeze_notify();
for (let i = destIndex; i !== (srcIndex + step); i += step) {
// swap
[points[i].place, srcPlace] = [srcPlace, points[i].place];
}
- query.thaw_notify();
+ this._query.thaw_notify();
},
_onDragDrop: function(row, context, x, y, time) {
- let query = Application.routeService.query;
- let srcIndex = query.points.indexOf(this._draggedPoint);
+ let srcIndex = this._query.points.indexOf(this._draggedPoint);
let destIndex = row.get_index();
this._reorderRoutePoints(srcIndex, destIndex);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]