[gnome-maps] Add UserLocationMarker



commit a088e903585e8b3be78bf3161a9dd5e58c80c20a
Author: Damián Nohales <damiannohales gmail com>
Date:   Sun Jun 22 14:05:17 2014 -0300

    Add UserLocationMarker
    
    The user location marker is now based on MapMarker class,
    supporting MapBubble to show a GtkPopover based UI for the
    user location information. This removes UserLocation which is
    based on MapLocation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722871

 data/gnome-maps.css               |    9 ++
 data/icons/Makefile.am            |    4 +-
 data/icons/bubble.svg             |   78 -------------------
 data/icons/user-location.png      |  Bin 0 -> 879 bytes
 po/POTFILES.in                    |    2 +-
 src/gnome-maps.data.gresource.xml |    1 +
 src/gnome-maps.js.gresource.xml   |    3 +-
 src/mapView.js                    |   16 +++--
 src/user-location-bubble.ui       |   85 +++++++++++++++++++++
 src/userLocation.js               |  150 -------------------------------------
 src/userLocationBubble.js         |   47 ++++++++++++
 src/userLocationMarker.js         |  110 +++++++++++++++++++++++++++
 12 files changed, 267 insertions(+), 238 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index ed8abbf..9a56bbc 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -99,3 +99,12 @@
 #instruction-list {
     border-top: 1px solid gray;
 }
+
+.bubble-title {
+    font-size: 120%;
+    font-weight: bold;
+}
+
+.bubble-subtitle {
+    font-size: 70%;
+}
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 50a5a00..34a4cab 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -22,9 +22,9 @@ public_icons =                                                \
 
 imagesdir = $(datadir)/gnome-maps/pixmaps
 images_DATA =                                   \
-       bubble.svg                              \
        pin.svg                                 \
-        $(NULL)
+       user-location.png                       \
+       $(NULL)
 
 noinst_DATA =                                  \
        gnome-maps.svg                          \
diff --git a/data/icons/user-location.png b/data/icons/user-location.png
new file mode 100644
index 0000000..5ae6fdc
Binary files /dev/null and b/data/icons/user-location.png differ
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e8a45f1..6225ef3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -13,5 +13,5 @@ src/mapView.js
 src/routeService.js
 src/sidebar.js
 [type: gettext/glade]src/sidebar.ui
-src/userLocation.js
+[type: gettext/glade]src/user-location-bubble.ui
 src/utils.js
diff --git a/src/gnome-maps.data.gresource.xml b/src/gnome-maps.data.gresource.xml
index 14edf1e..8bfd3f9 100644
--- a/src/gnome-maps.data.gresource.xml
+++ b/src/gnome-maps.data.gresource.xml
@@ -10,6 +10,7 @@
     <file preprocess="xml-stripblanks">context-menu.ui</file>
     <file preprocess="xml-stripblanks">layers-popover.ui</file>
     <file preprocess="xml-stripblanks">notification.ui</file>
+    <file preprocess="xml-stripblanks">user-location-bubble.ui</file>
     <file alias="application.css">../data/gnome-maps.css</file>
     <file alias="zoom-in.png">../data/media/zoom-in.png</file>
     <file alias="zoom-out.png">../data/media/zoom-out.png</file>
diff --git a/src/gnome-maps.js.gresource.xml b/src/gnome-maps.js.gresource.xml
index b37a5e8..fee0121 100644
--- a/src/gnome-maps.js.gresource.xml
+++ b/src/gnome-maps.js.gresource.xml
@@ -27,7 +27,8 @@
     <file>searchPopup.js</file>
     <file>settings.js</file>
     <file>sidebar.js</file>
-    <file>userLocation.js</file>
+    <file>userLocationMarker.js</file>
+    <file>userLocationBubble.js</file>
     <file>utils.js</file>
     <file>zoomControl.js</file>
   </gresource>
diff --git a/src/mapView.js b/src/mapView.js
index 95153d8..bfcc072 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -38,7 +38,7 @@ const Utils = imports.utils;
 const Path = imports.path;
 const MapLocation = imports.mapLocation;
 const MapWalker = imports.mapWalker;
-const UserLocation = imports.userLocation;
+const UserLocationMarker = imports.userLocationMarker;
 const _ = imports.gettext.gettext;
 
 const MapType = {
@@ -116,7 +116,7 @@ const MapView = new Lang.Class({
 
     gotoUserLocation: function(animate) {
         this.emit('going-to-user-location');
-        this._userLocation.once("gone-to", (function() {
+        Utils.once(this._userLocation, "gone-to", (function() {
             this.emit('gone-to-user-location');
         }).bind(this));
         this._userLocation.goTo(animate);
@@ -141,10 +141,14 @@ const MapView = new Lang.Class({
                                                     Geocode.PlaceType.UNKNOWN,
                                                     location);
 
-        let selected = this._userLocation && this._userLocation.getSelected();
-        this._userLocation = new UserLocation.UserLocation(place, this);
-        this._userLocation.show(this._userLocationLayer);
-        this._userLocation.setSelected(selected);
+        let previousSelected = this._userLocation && this._userLocation.selected;
+        this._userLocation = new UserLocationMarker.UserLocationMarker({ place: place,
+                                                                         mapView: this });
+        this._userLocationLayer.remove_all();
+        this._userLocation.addToLayer(this._userLocationLayer);
+
+        this._userLocation.selected = previousSelected;
+
         this.emit('user-location-changed');
     },
 
diff --git a/src/user-location-bubble.ui b/src/user-location-bubble.ui
new file mode 100644
index 0000000..a7e3e2b
--- /dev/null
+++ b/src/user-location-bubble.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+  <requires lib="gtk+" version="3.12"/>
+  <object class="GtkGrid" id="grid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_start">10</property>
+    <property name="margin_end">15</property>
+    <property name="margin_top">10</property>
+    <property name="margin_bottom">15</property>
+    <child>
+      <object class="GtkImage" id="image-user-location">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">start</property>
+        <property name="margin_top">5</property>
+        <property name="pixel_size">48</property>
+        <property name="icon_name">find-location-symbolic</property>
+        <property name="icon_size">0</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid-right">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_start">10</property>
+        <child>
+          <object class="GtkLabel" id="label-title">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Current location</property>
+            <style>
+              <class name="bubble-title"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-accuracy">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes" comments="To translators: %s can be 
&quot;Unknown&quot;, &quot;Exact&quot; or &quot;%f km²&quot;">Accuracy: %s</property>
+            <style>
+              <class name="bubble-subtitle"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label-coordinates">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="margin_top">3</property>
+            <property name="wrap">True</property>
+            <style>
+              <class name="bubble-subtitle"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/src/userLocationBubble.js b/src/userLocationBubble.js
new file mode 100644
index 0000000..cb92dc4
--- /dev/null
+++ b/src/userLocationBubble.js
@@ -0,0 +1,47 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Lang = imports.lang;
+
+const MapBubble = imports.mapBubble;
+const Utils = imports.utils;
+
+const UserLocationBubble = new Lang.Class({
+    Name: "UserLocationBubble",
+    Extends: MapBubble.MapBubble,
+
+    _init: function(params) {
+        this.parent(params);
+
+        let ui = Utils.getUIObject('user-location-bubble', [ 'grid',
+                                                             'label-accuracy',
+                                                             'label-coordinates' ]);
+
+        let accuracyDescription = Utils.getAccuracyDescription(this.place.location.accuracy);
+        ui.labelAccuracy.label = ui.labelAccuracy.label.format(accuracyDescription);
+        ui.labelCoordinates.label = this.place.location.latitude.toFixed(5)
+                                  + ', '
+                                  + this.place.location.longitude.toFixed(5);
+
+        this.add(ui.grid);
+    }
+});
\ No newline at end of file
diff --git a/src/userLocationMarker.js b/src/userLocationMarker.js
new file mode 100644
index 0000000..ea124d3
--- /dev/null
+++ b/src/userLocationMarker.js
@@ -0,0 +1,110 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Damián Nohales
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Damián Nohales <damiannohales gmail com>
+ */
+
+const Champlain = imports.gi.Champlain;
+const Clutter = imports.gi.Clutter;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+
+const MapMarker = imports.mapMarker;
+const Path = imports.path;
+const UserLocationBubble = imports.userLocationBubble;
+const Utils = imports.utils;
+const _ = imports.gettext.gettext;
+
+const AccuracyCircleMarker = new Lang.Class({
+    Name: 'AccuracyCircleMarker',
+    Extends: Champlain.Point,
+
+    _init: function(params) {
+        this.place = params.place;
+        delete params.place;
+
+        params.color = new Clutter.Color({ red: 0,
+                                           blue: 255,
+                                           green: 0,
+                                           alpha: 50 });
+        params.latitude = this.place.location.latitude;
+        params.longitude = this.place.location.longitude;
+        params.reactive = false;
+
+        this.parent(params);
+    },
+
+    refreshGeometry: function(view) {
+        let zoom = view.zoom_level;
+        let source = view.map_source;
+        let metersPerPixel = source.get_meters_per_pixel(zoom,
+                                                         this.latitude,
+                                                         this.longitude);
+        let size = this.place.location.accuracy * 2 / metersPerPixel;
+
+        if (size > view.width && size > view.height)
+            this.hide();
+        else {
+            this.size = size;
+            this.show();
+        }
+    }
+});
+
+const UserLocationMarker = new Lang.Class({
+    Name: 'UserLocationMarker',
+    Extends: MapMarker.MapMarker,
+
+    _init: function(params) {
+        this.parent(params);
+
+        let iconActor = Utils.CreateActorFromImageFile(Path.ICONS_DIR + '/user-location.png');
+        this.add_actor(iconActor);
+
+        if (this.place.location.accuracy !== 0) {
+            this._accuracyMarker = new AccuracyCircleMarker({ place: this.place });
+            this._accuracyMarker.refreshGeometry(this._view);
+            this._zoomLevelId = this._view.connect('notify::zoom-level',
+                                                   
this._accuracyMarker.refreshGeometry.bind(this._accuracyMarker));
+            this.connect('destroy', (function() {
+                this._view.disconnect(this._zoomLevelId);
+            }).bind(this));
+        }
+    },
+
+    get anchor() {
+        return { x: Math.floor(this.width / 2),
+                 y: Math.floor(this.height / 2) };
+    },
+
+    _createBubble: function() {
+        return new UserLocationBubble.UserLocationBubble({ place: this.place,
+                                                           mapView: this._mapView });
+    },
+
+    addToLayer: function(layer) {
+        if (this._accuracyMarker)
+            layer.add_marker(this._accuracyMarker);
+
+        layer.add_marker(this);
+    }
+});


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