1
/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
2
/* vim: set et ts=4 sw=4: */
4
* Copyright (c) 2011, 2012, 2013 Red Hat, Inc.
6
* GNOME Maps is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by the
8
* Free Software Foundation; either version 2 of the License, or (at your
9
* option) any later version.
11
* GNOME Maps is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
* You should have received a copy of the GNU General Public License along
17
* with GNOME Maps; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
23
const Clutter = imports.gi.Clutter;
24
const Champlain = imports.gi.Champlain;
25
const GObject = imports.gi.GObject;
27
const Lang = imports.lang;
28
const Mainloop = imports.mainloop;
30
const MapLocation = imports.mapLocation;
31
const Utils = imports.utils;
32
const Path = imports.path;
33
const _ = imports.gettext.gettext;
35
const UserLocation = new Lang.Class({
37
Extends: MapLocation.MapLocation,
39
show: function(layer) {
42
this._locationMarker = new Champlain.CustomMarker();
43
this._locationMarker.set_location(this.latitude, this.longitude);
44
this._locationMarker.connect('notify::size', (function() {
45
let translate_x = -Math.floor(this._locationMarker.get_width() / 2);
46
this._locationMarker.set_translation(translate_x,
47
-this._locationMarker.get_height(),
50
let pin_actor = Utils.CreateActorFromImageFile(Path.ICONS_DIR + "/pin.svg");
53
let bubbleActor = Utils.CreateActorFromImageFile(Path.ICONS_DIR + "/bubble.svg");
56
bubbleActor.set_x_expand(true);
57
bubbleActor.set_y_expand(true);
58
/* Translators: Showing name of place where user currently is and
59
accuracy of this information (which is translated
62
let text = _("%s\nPosition Accuracy: %s")
63
.format (this.description, this.getAccuracyDescription());
64
let textActor = new Clutter.Text({ text: text });
65
textActor.set_use_markup(true);
66
textActor.set_margin_left(6);
67
textActor.set_margin_right(6);
68
textActor.set_color(new Clutter.Color({ red: 255,
72
let layout = new Clutter.BinLayout();
73
let descriptionActor = new Clutter.Actor({ layout_manager: layout });
74
descriptionActor.add_child(bubbleActor);
75
descriptionActor.add_child(textActor);
77
layout = new Clutter.BoxLayout({ vertical: true });
78
let locationActor = new Clutter.Actor({ layout_manager: layout });
79
locationActor.add_child(descriptionActor);
80
locationActor.add_child(pin_actor);
82
this._locationMarker.add_actor(locationActor);
84
this._locationMarker.bind_property("selected",
85
descriptionActor, "visible",
86
GObject.BindingFlags.SYNC_CREATE);
88
if (this.accuracy === 0) {
89
layer.add_marker(this._locationMarker);
93
// FIXME: Perhaps this is a misuse of Champlain.Point class and we
94
// should draw the cirlce ourselves using Champlain.CustomMarker?
95
// Although for doing so we'll need to add a C lib as cairo isn't
96
// exactly introspectable.
97
this._accuracyMarker = new Champlain.Point();
98
this._accuracyMarker.set_color(new Clutter.Color({ red: 0,
102
this._accuracyMarker.set_location(this.latitude, this.longitude);
103
this._accuracyMarker.set_reactive(false);
105
this._updateAccuracyMarker();
106
if (this._selectedId > 0)
107
this._locationMarker.disconnect(this._selectedId);
108
this._selectedId = this._locationMarker.connect("notify::selected",
109
this._updateAccuracyMarker.bind(this));
111
layer.add_marker(this._accuracyMarker);
112
layer.add_marker(this._locationMarker);
114
if (this._zoomLevelId > 0)
115
this._view.disconnect(this._zoomLevelId);
116
this._zoomLevelId = this._view.connect("notify::zoom-level", this._updateAccuracyMarker.bind(this));
119
_updateAccuracyMarker: function() {
120
if (!this._locationMarker.get_selected()) {
121
this._accuracyMarker.hide();
125
let zoom = this._view.get_zoom_level();
126
let source = this._view.get_map_source();
127
let metersPerPixel = source.get_meters_per_pixel(zoom, this.latitude, this.longitude);
128
let size = this.accuracy * 2 / metersPerPixel;
129
let viewWidth = this._view.get_width();
130
let viewHeight = this._view.get_height();
131
if ((viewWidth > 0 && viewHeight > 0) &&
132
(size > viewWidth && size > viewHeight))
133
this._accuracyMarker.hide();
135
this._accuracyMarker.set_size(size);
136
this._accuracyMarker.show();