[gnome-maps] Add widget to select transit options



commit ba3dc25ea12c5d1f453d0a9b1584603834474a73
Author: Marcus Lundblad <ml update uu se>
Date:   Sun Feb 12 23:00:36 2017 +0100

    Add widget to select transit options
    
    This is used from within the routing sidebar
    when transit mode is selected.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=755808

 data/org.gnome.Maps.data.gresource.xml |    1 +
 data/ui/transit-options-panel.ui       |  152 ++++++++++++++++++++++++
 src/org.gnome.Maps.src.gresource.xml   |    1 +
 src/transitOptionsPanel.js             |  200 ++++++++++++++++++++++++++++++++
 4 files changed, 354 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.Maps.data.gresource.xml b/data/org.gnome.Maps.data.gresource.xml
index d8cac68..e706ce7 100644
--- a/data/org.gnome.Maps.data.gresource.xml
+++ b/data/org.gnome.Maps.data.gresource.xml
@@ -35,6 +35,7 @@
     <file preprocess="xml-stripblanks">ui/transit-itinerary-row.ui</file>
     <file preprocess="xml-stripblanks">ui/transit-leg-row.ui</file>
     <file preprocess="xml-stripblanks">ui/transit-more-row.ui</file>
+    <file preprocess="xml-stripblanks">ui/transit-options-panel.ui</file>
     <file preprocess="xml-stripblanks">ui/transit-route-label.ui</file>
     <file preprocess="xml-stripblanks">ui/user-location-bubble.ui</file>
     <file preprocess="xml-stripblanks">ui/zoom-control.ui</file>
diff --git a/data/ui/transit-options-panel.ui b/data/ui/transit-options-panel.ui
new file mode 100644
index 0000000..d4b82f5
--- /dev/null
+++ b/data/ui/transit-options-panel.ui
@@ -0,0 +1,152 @@
+<interface>
+  <template class="Gjs_TransitOptionsPanel" parent="GtkGrid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="no-show-all">True</property>
+    <style>
+      <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">view-more-symbolic</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">3</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </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="halign">GTK_ALIGN_START</property>
+            <property name="label" translatable="yes">Show</property>
+            <property name="margin_start">6</property>
+            <style>
+              <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>
+  </object>
+</interface>
+  
diff --git a/src/org.gnome.Maps.src.gresource.xml b/src/org.gnome.Maps.src.gresource.xml
index c440866..1016b33 100644
--- a/src/org.gnome.Maps.src.gresource.xml
+++ b/src/org.gnome.Maps.src.gresource.xml
@@ -83,6 +83,7 @@
     <file>transitLegRow.js</file>
     <file>transitMoreRow.js</file>
     <file>transitOptions.js</file>
+    <file>transitOptionsPanel.js</file>
     <file>transitPlan.js</file>
     <file>transitRouteLabel.js</file>
     <file>translations.js</file>
diff --git a/src/transitOptionsPanel.js b/src/transitOptionsPanel.js
new file mode 100644
index 0000000..ac5e95b
--- /dev/null
+++ b/src/transitOptionsPanel.js
@@ -0,0 +1,200 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2017, Marcus Lundblad
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Marcus Lundblad <ml update uu se>
+ */
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
+
+const Application = imports.application;
+const Time = imports.time;
+const TransitOptions = imports.transitOptions;
+const TransitPlan = imports.transitPlan;
+
+// in org.gnome.desktop.interface
+const CLOCK_FORMAT_KEY = 'clock-format';
+
+let _desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
+let clockFormat = _desktopSettings.get_string(CLOCK_FORMAT_KEY);
+
+const TransitOptionsPanel = new Lang.Class({
+    Name: 'TransitOptionsPanel',
+    Extends: Gtk.Grid,
+    Template: 'resource:///org/gnome/Maps/ui/transit-options-panel.ui',
+    InternalChildren: ['transitTimeOptionsComboBox',
+                       'transitTimeEntry',
+                       'transitDateButton',
+                       'transitDateCalendar',
+                       'transitParametersMenuButton',
+                       'busCheckButton',
+                       'tramCheckButton',
+                       'trainCheckButton',
+                       'subwayCheckButton',
+                       'ferryCheckButton'],
+
+    _init: function(params) {
+        this._query = Application.routeQuery;
+        this.parent(params);
+        this._initTransitOptions();
+    },
+
+    reset: function() {
+        /* reset to indicate departure now and forget any previous manually
+         * set time and date
+         */
+        this._transitTimeOptionsComboBox.active_id = 'leaveNow';
+        this._timeSelected = false;
+        this._dateSelected = false;
+    },
+
+    _initTransitOptions: function() {
+        this._transitTimeOptionsComboBox.connect('changed',
+            this._onTransitTimeOptionsComboboxChanged.bind(this));
+        this._transitTimeEntry.connect('activate',
+            this._onTransitTimeEntryActivated.bind(this));
+        /* trigger an update of the query time as soon as focus leave the time
+         * entry, to allow the user to enter a time before selecting start
+         * and destination without having to press enter */
+        this._transitTimeEntry.connect('focus-out-event',
+            this._onTransitTimeEntryActivated.bind(this));
+        this._transitDateButton.popover.get_child().connect('day-selected-double-click',
+            this._onTransitDateCalenderDaySelected.bind(this));
+        this._transitDateButton.connect('toggled',
+            this._onTransitDateButtonToogled.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;
+            this._query.time = null;
+            this._query.date = null;
+            this._timeSelected = null;
+            this._dateSelected = null;
+        } else {
+            this._transitTimeEntry.visible = true;
+            this._transitDateButton.visible = true;
+
+            if (!this._timeSelected)
+                this._updateTransitTimeEntry(GLib.DateTime.new_now_local());
+
+            if (!this._dateSelected)
+                this._updateTransitDateButton(GLib.DateTime.new_now_local());
+
+            if (this._transitTimeOptionsComboBox.active_id === 'arriveBy') {
+                this._query.arriveBy = true;
+            } else {
+                this._query.arriveBy = false;
+            }
+        }
+    },
+
+    _updateTransitTimeEntry: function(time) {
+        if (clockFormat === '24h')
+            this._transitTimeEntry.text = time.format('%R');
+        else
+            this._transitTimeEntry.text = time.format('%r');
+    },
+
+    _onTransitTimeEntryActivated: function() {
+        let timeString = this._transitTimeEntry.text;
+
+        if (timeString && timeString.length > 0) {
+            timeString = Time.parseTimeString(timeString);
+
+            /* only trigger an update if a different time was entered */
+            if (timeString && timeString !== this._timeSelected) {
+                this._query.time = timeString;
+                /* remember that the user has selected a time */
+                this._timeSelected = timeString;
+            }
+        }
+    },
+
+    _updateTransitDateButton: function(date) {
+        /*
+         * Translators: this is a format string giving the equivalent to
+         * "may 29" according to the current locale's convensions.
+         */
+        this._transitDateButton.label =
+            date.format(C_("month-day-date", "%b %e"));
+    },
+
+    _onTransitDateCalenderDaySelected: function() {
+        let calendar = this._transitDateButton.popover.get_child();
+        let year = calendar.year;
+        let month = calendar.month + 1;
+        let day = calendar.day;
+        let date = '%04d-%02d-%02d'.format(year, month, day);
+
+        /* only trigger an update if a different date was selected */
+        if (date !== this._dateSelected) {
+            this._query.date = date;
+            this._transitDateButton.active = false;
+            this._updateTransitDateButton(GLib.DateTime.new_local(year, month, day,
+                                                                  0, 0, 0));
+            /* remember that the user has already selected a date */
+            this._dateSelected = date;
+        }
+    },
+
+    _onTransitDateButtonToogled: function() {
+        if (!this._transitDateButton.active)
+            this._onTransitDateCalenderDaySelected();
+    },
+
+    _createTransitOptions: function() {
+        let options = new TransitOptions.TransitOptions();
+        let busSelected = this._busCheckButton.active;
+        let tramSelected = this._tramCheckButton.active;
+        let trainSelected = this._trainCheckButton.active;
+      let subwaySelected = this._subwayCheckButton.active;
+        let ferrySelected = this._ferryCheckButton.active;
+
+        if (busSelected && tramSelected && trainSelected && subwaySelected &&
+            ferrySelected) {
+            options.showAllTransitTypes = true;
+        } else {
+            if (busSelected)
+                options.addTransitType(TransitPlan.RouteType.BUS);
+            if (tramSelected)
+                options.addTransitType(TransitPlan.RouteType.TRAM);
+            if (trainSelected)
+                options.addTransitType(TransitPlan.RouteType.TRAIN);
+            if (subwaySelected)
+                options.addTransitType(TransitPlan.RouteType.SUBWAY);
+            if (ferrySelected)
+                options.addTransitType(TransitPlan.RouteType.FERRY);
+        }
+
+        return options;
+    },
+
+    _onTransitParametersToggled: function() {
+        if (!this._transitParametersMenuButton.active) {
+            let options = this._createTransitOptions();
+            this._query.transitOptions = options;
+        }
+    }
+ });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]