[gnome-maps] mainWindow: Adaptive routing sidebar



commit c4f04275e82edd234acdc105cec149010d5e8e07
Author: James Westman <james flyingpimonster net>
Date:   Wed Jul 29 16:53:45 2020 -0500

    mainWindow: Adaptive routing sidebar
    
    Makes the routing sidebar adaptive using HdyLeaflet. When the routing sidebar
    is opened, if the window is too narrow, the map view will be hidden and only
    the sidebar will be shown. The headerbar will change to have a back button,
    which closes the sidebar.
    
    If the window is wide enough to fit both map and sidebar, nothing happens
    differently than before, except that the action bar no longer extends
    underneath the sidebar.
    
    Added libhandy as a dependency in order to use HdyLeaflet and HdyTitleBar.
    
    Fixes #264.

 data/gnome-maps.css    |   8 ---
 data/ui/main-window.ui | 189 +++++++++++++++++++++++++++++--------------------
 data/ui/route-entry.ui |   1 -
 data/ui/sidebar.ui     |   2 +-
 src/mainWindow.js      |  66 +++++++++++++++--
 src/sidebar.js         |  12 ++--
 src/transitLegRow.js   |  14 ++--
 7 files changed, 184 insertions(+), 108 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index ea4977fe..f425f00e 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -43,14 +43,6 @@
     padding: 4px 7px;
 }
 
-#sidebar {
-    border-left: 1px solid gray;
-}
-
-#sidebar:dir(rtl) {
-    border-right: 1px solid gray;
-}
-
 #instruction-list {
     border-right: 0px;
     border-left: 0px;
diff --git a/data/ui/main-window.ui b/data/ui/main-window.ui
index c3daf4d3..070b0399 100644
--- a/data/ui/main-window.ui
+++ b/data/ui/main-window.ui
@@ -33,102 +33,99 @@
     <property name="window-position">center</property>
     <property name="title" translatable="yes">Maps</property>
     <child type="titlebar">
-      <object class="GtkHeaderBar" id="headerBar">
+      <object class="HdyTitleBar" id="titleBar">
         <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="show-close-button">True</property>
-        <style>
-          <class name="titlebar"/>
-        </style>
         <child>
-          <object class="GtkMenuButton">
+          <object class="GtkStack" id="headerBarStack">
             <property name="visible">True</property>
-            <property name="halign">end</property>
-            <property name="valign">center</property>
-            <property name="menu-model">hamburgerMenu</property>
-            <accelerator key="F10" signal="clicked"/>
-            <child internal-child="accessible">
-              <object class="AtkObject">
-                <property name="accessible-name" translatable="yes">Primary menu</property>
+            <property name="transition-type">slide-left-right</property>
+            <child>
+              <object class="GtkHeaderBar" id="headerBar">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="show-close-button">True</property>
+                <child>
+                  <object class="GtkMenuButton">
+                    <property name="visible">True</property>
+                    <property name="halign">end</property>
+                    <property name="valign">center</property>
+                    <property name="menu-model">hamburgerMenu</property>
+                    <accelerator key="F10" signal="clicked"/>
+                    <child internal-child="accessible">
+                      <object class="AtkObject">
+                        <property name="accessible-name" translatable="yes">Primary menu</property>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="image-button"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">True</property>
+                        <property name="icon-size">1</property>
+                        <property name="icon-name">open-menu-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="pack-type">end</property>
+                  </packing>
+                </child>
               </object>
             </child>
-            <style>
-              <class name="image-button"/>
-            </style>
             <child>
-              <object class="GtkImage">
+              <object class="GtkHeaderBar" id="routingHeaderBar">
                 <property name="visible">True</property>
-                <property name="icon-size">1</property>
-                <property name="icon-name">open-menu-symbolic</property>
+                <property name="can-focus">False</property>
+                <property name="show-close-button">True</property>
+                <property name="title" translatable="yes">Find a Route</property>
+                <child>
+                  <object class="GtkButton">
+                    <property name="visible">True</property>
+                    <property name="action-name">win.toggle-sidebar</property>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">True</property>
+                        <property name="icon-name">go-previous-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
-          <packing>
-            <property name="pack-type">end</property>
-          </packing>
         </child>
       </object>
     </child>
     <child>
-      <object class="GtkGrid" id="grid">
+      <object class="GtkStack" id="mainStack">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
+        <property name="transition-type">crossfade</property>
         <child>
-          <object class="GtkStack" id="mainStack">
+          <object class="HdyLeaflet" id="leaflet">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="transition-type">crossfade</property>
+            <property name="transition-type">under</property>
             <child>
-              <object class="GtkGrid" id="mainGrid">
-                <property name="visible">True</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkSpinner" id="network-spinner">
-                <property name="visible">True</property>
-                <property name="active">True</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkGrid" id="noNetworkView">
+              <object class="GtkBox" id="mainBox">
                 <property name="visible">True</property>
                 <property name="orientation">vertical</property>
-                <property name="can_focus">False</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="row_spacing">6</property>
-                <property name="margin">18</property>
                 <child>
-                  <object class="GtkImage" id="no-network-conn-image">
+                  <object class="GtkBox" id="mapViewWrapper">
                     <property name="visible">True</property>
-                    <property name="pixel-size">100</property>
-                    <property name="icon-name">network-offline-symbolic</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="no-network-conn-header">
-                    <attributes>
-                      <attribute name="weight" value="bold" />
-                      <attribute name="scale" value="2" />
-                    </attributes>
-                    <property name="label" translatable="yes">Maps is offline!</property>
-                    <property name="justify">center</property>
                   </object>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="no-network-conn-text-1">
-                    <property name="wrap">True</property>
-                    <property name="max-width-chars">45</property>
-                    <property name="label" translatable="yes">Maps need an active internet connection to 
function properly, but one can’t be found.</property>
-                    <property name="justify">center</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="no-network-conn-text-2">
-                    <property name="wrap">True</property>
-                    <property name="max-width-chars">45</property>
-                    <property name="label" translatable="yes">Check your connection and proxy 
settings.</property>
-                    <property name="justify">center</property>
+                  <object class="GtkRevealer" id="actionBarRevealer">
+                    <property name="visible">True</property>
+                    <property name="reveal-child">False</property>
+                    <property name="transition-type">slide-up</property>
+                    <child>
+                      <object class="GtkActionBar" id="actionBar">
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
@@ -136,21 +133,57 @@
           </object>
         </child>
         <child>
-          <object class="GtkRevealer" id="actionBarRevealer">
+          <object class="GtkSpinner" id="network-spinner">
             <property name="visible">True</property>
-            <property name="reveal-child">False</property>
-            <property name="transition-type">slide-up</property>
+            <property name="active">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkGrid" id="noNetworkView">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="can_focus">False</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="row_spacing">6</property>
+            <property name="margin">18</property>
+            <child>
+              <object class="GtkImage" id="no-network-conn-image">
+                <property name="visible">True</property>
+                <property name="pixel-size">100</property>
+                <property name="icon-name">network-offline-symbolic</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="no-network-conn-header">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Maps is offline!</property>
+                <property name="justify">center</property>
+                <attributes>
+                  <attribute name="weight" value="bold" />
+                  <attribute name="scale" value="2" />
+                </attributes>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="no-network-conn-text-1">
+                <property name="visible">True</property>
+                <property name="wrap">True</property>
+                <property name="max-width-chars">45</property>
+                <property name="label" translatable="yes">Maps need an active internet connection to 
function properly, but one can’t be found.</property>
+                <property name="justify">center</property>
+              </object>
+            </child>
             <child>
-              <object class="GtkActionBar" id="actionBar">
+              <object class="GtkLabel" id="no-network-conn-text-2">
                 <property name="visible">True</property>
+                <property name="wrap">True</property>
+                <property name="max-width-chars">45</property>
+                <property name="label" translatable="yes">Check your connection and proxy 
settings.</property>
+                <property name="justify">center</property>
               </object>
             </child>
           </object>
-          <packing>
-            <property name="left-attach">0</property>
-            <property name="top-attach">1</property>
-            <property name="width">2</property>
-          </packing>
         </child>
       </object>
     </child>
diff --git a/data/ui/route-entry.ui b/data/ui/route-entry.ui
index b186e453..4339660b 100644
--- a/data/ui/route-entry.ui
+++ b/data/ui/route-entry.ui
@@ -27,7 +27,6 @@
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="width_request">230</property>
-        <property name="hexpand">False</property>
       </object>
     </child>
     <child>
diff --git a/data/ui/sidebar.ui b/data/ui/sidebar.ui
index ab7b3890..1fd6572b 100644
--- a/data/ui/sidebar.ui
+++ b/data/ui/sidebar.ui
@@ -6,7 +6,7 @@
     <property name="visible">True</property>
     <property name="transition_type">slide-left</property>
     <property name="transition_duration">400</property>
-    <property name="halign">end</property>
+    <property name="halign">fill</property>
     <property name="valign">fill</property>
     <style>
       <class name="maps-sidebar"/>
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 10830667..02d811ee 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -28,6 +28,7 @@ const GObject = imports.gi.GObject;
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
+const Hdy = imports.gi.Handy;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
@@ -79,10 +80,13 @@ var ShapeLayerFileChooser = GObject.registerClass({
 var MainWindow = GObject.registerClass({
     Template: 'resource:///org/gnome/Maps/ui/main-window.ui',
     InternalChildren: [ 'headerBar',
-                        'grid',
+                        'headerBarStack',
+                        'leaflet',
+                        'mainBox',
                         'mainStack',
-                        'mainGrid',
+                        'mapViewWrapper',
                         'noNetworkView',
+                        'routingHeaderBar',
                         'actionBar',
                         'actionBarRevealer' ]
 }, class MainWindow extends Gtk.ApplicationWindow {
@@ -101,7 +105,7 @@ var MainWindow = GObject.registerClass({
                 MapView.MapType.LOCAL : undefined,
             mainWindow: this });
 
-        this._mainGrid.add(this._mapView);
+        this._mapViewWrapper.add(this._mapView);
 
         this._mapView.gotoUserLocation(false);
 
@@ -116,9 +120,9 @@ var MainWindow = GObject.registerClass({
         this._restoreWindowGeometry();
         this._initDND();
 
-        this._grid.attach(this._sidebar, 1, 0, 1, 1);
+        this._leaflet.add(this._sidebar);
 
-        this._grid.show_all();
+        this._leaflet.show_all();
 
         /* for some reason, setting the title of the window through the .ui
          * template does not work anymore (maybe has something to do with
@@ -150,8 +154,33 @@ var MainWindow = GObject.registerClass({
         return placeEntry;
     }
 
+    showTurnPoint(turnPoint) {
+        /* Used by the sidebar when an instruction row is clicked. Shows the
+        turn point on the map, and makes sure the map is visible in the
+        leaflet. */
+
+        this._mapView.showTurnPoint(turnPoint);
+
+        /* if leaflet is folded, hide the sidebar */
+        if (this._leaflet.folded) {
+            this._setRevealSidebar(false);
+        }
+    }
+
+    showTransitStop(transitStop, transitLeg) {
+        /* Used by the sidebar when a transit stop is clicked. Shows the
+        stop on the map, and makes sure the map is visible in the leaflet. */
+
+        this._mapView.showTransitStop(transitStop, transitLeg);
+
+        /* if leaflet is folded, hide the sidebar */
+        if (this._leaflet.folded) {
+            this._setRevealSidebar(false);
+        }
+    }
+
     _createSidebar() {
-        let sidebar = new Sidebar.Sidebar(this._mapView);
+        let sidebar = new Sidebar.Sidebar(this);
 
         Application.routeQuery.connect('notify', () => this._setRevealSidebar(true));
         this.application.bind_property('connected',
@@ -257,7 +286,7 @@ var MainWindow = GObject.registerClass({
 
         this.application.connect('notify::connected', () => {
             if (this.application.connected || this.application.local_tile_path)
-                this._mainStack.visible_child = this._mainGrid;
+                this._mainStack.visible_child = this._leaflet;
             else
                 this._mainStack.visible_child = this._noNetworkView;
         });
@@ -384,6 +413,10 @@ var MainWindow = GObject.registerClass({
                 this._placeEntry.set_margin_end(_PLACE_ENTRY_MARGIN);
             }
         });
+
+        // Show routing headerbar when the leaflet is folded, showing only the
+        // routing sidebar
+        this._leaflet.connect('notify::folded', this._updateRoutingHeaderBar.bind(this));
     }
 
     _saveWindowGeometry() {
@@ -542,11 +575,30 @@ var MainWindow = GObject.registerClass({
         }
     }
 
+    _updateRoutingHeaderBar() {
+        let folded = this._leaflet.folded;
+        let sidebarVisible = this._leaflet.visible_child == this._sidebar;
+
+        if (folded && sidebarVisible) {
+            this._headerBarStack.set_visible_child(this._routingHeaderBar);
+        } else {
+            this._headerBarStack.set_visible_child(this._headerBar);
+        }
+    }
+
     _onToggleSidebarChangeState(action, variant) {
         action.set_state(variant);
 
         let reveal = variant.get_boolean();
         this._sidebar.set_reveal_child(reveal);
+
+        if (reveal) {
+            this._leaflet.set_visible_child(this._sidebar);
+        } else {
+            this._leaflet.set_visible_child(this._mainBox);
+        }
+
+        this._updateRoutingHeaderBar();
     }
 
     _setRevealSidebar(value) {
diff --git a/src/sidebar.js b/src/sidebar.js
index d3f84316..a35ffb67 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -68,10 +68,10 @@ var Sidebar = GObject.registerClass({
                         'transitAttributionLabel']
 }, class Sidebar extends Gtk.Revealer {
 
-    _init(mapView) {
+    _init(mainWindow) {
         super._init({ transition_type: Gtk.RevealerTransitionType.SLIDE_LEFT });
 
-        this._mapView = mapView;
+        this._mainWindow = mainWindow;
 
         this._query = Application.routeQuery;
         this._initInstructionList();
@@ -187,7 +187,7 @@ var Sidebar = GObject.registerClass({
 
         let routeEntry = new RouteEntry.RouteEntry({ type: type,
                                                      point: point,
-                                                     mapView: this._mapView });
+                                                     mapView: this._mainWindow.mapView });
 
         // add handler overriding tab focus behavior on route entries
         routeEntry.entry.connect('focus', this._onRouteEntryFocus.bind(this));
@@ -361,7 +361,7 @@ var Sidebar = GObject.registerClass({
 
         this._instructionList.connect('row-selected', (listbox, row) => {
             if (row)
-                this._mapView.showTurnPoint(row.turnPoint);
+                this._mainWindow.showTurnPoint(row.turnPoint);
         });
 
         transitPlan.connect('update', () => {
@@ -487,14 +487,14 @@ var Sidebar = GObject.registerClass({
             let leg = itinerary.legs[i];
             let row = new TransitLegRow.TransitLegRow({ leg: leg,
                                                         start: i === 0,
-                                                        mapView: this._mapView });
+                                                        mainWindow: this._mainWindow });
             this._transitItineraryListBox.add(row);
         }
 
         /* insert the additional arrival row, showing the arrival place and time */
         this._transitItineraryListBox.add(
             new TransitArrivalRow.TransitArrivalRow({ itinerary: itinerary,
-                                                      mapView: this._mapView }));
+                                                      mapView: this._mainWindow.mapView }));
     }
 
 
diff --git a/src/transitLegRow.js b/src/transitLegRow.js
index 142cf7c9..5cba495f 100644
--- a/src/transitLegRow.js
+++ b/src/transitLegRow.js
@@ -55,8 +55,8 @@ var TransitLegRow = GObject.registerClass({
         this._start = params.start;
         delete params.start;
 
-        this._mapView = params.mapView;
-        delete params.mapView;
+        this._mainWindow = params.mainWindow;
+        delete params.mainWindow;
 
         super._init(params);
 
@@ -122,9 +122,9 @@ var TransitLegRow = GObject.registerClass({
         this._instructionList.connect('row-selected', (listbox, row) => {
             if (row) {
                 if (row.turnPoint)
-                    this._mapView.showTurnPoint(row.turnPoint);
+                    this._mainWindow.showTurnPoint(row.turnPoint);
                 else
-                    this._mapView.showTransitStop(row.stop, this._leg);
+                    this._mainWindow.showTransitStop(row.stop, this._leg);
             }
         });
 
@@ -145,9 +145,9 @@ var TransitLegRow = GObject.registerClass({
             if (this._isExpanded) {
                 this._collaps();
             } else {
-                this._mapView.view.zoom_level = 16;
-                this._mapView.view.center_on(this._leg.fromCoordinate[0],
-                                             this._leg.fromCoordinate[1]);
+                this._mainWindow.mapView.view.zoom_level = 16;
+                this._mainWindow.mapView.view.center_on(this._leg.fromCoordinate[0],
+                                                        this._leg.fromCoordinate[1]);
                 if (this._hasIntructions())
                     this._expand();
             }


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