summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2015-05-02 17:48:01 +0200
committerMatěj Cepl <mcepl@cepl.eu>2015-05-02 17:48:01 +0200
commit6cf5b918ad54b4d674b410c6ce27a4bcb704aa76 (patch)
tree128b6981f6412f15e9ddd0045862a8a01965fc82
downloadISS_Above-6cf5b918ad54b4d674b410c6ce27a4bcb704aa76.tar.gz
Foundations.
-rw-r--r--extension.js53
-rw-r--r--geoclue.js86
-rw-r--r--gnome-shell-ISS_Above.desktop9
-rw-r--r--metadata.json8
-rw-r--r--place.js230
-rw-r--r--stylesheet.css8
6 files changed, 394 insertions, 0 deletions
diff --git a/extension.js b/extension.js
new file mode 100644
index 0000000..260aef7
--- /dev/null
+++ b/extension.js
@@ -0,0 +1,53 @@
+
+const St = imports.gi.St;
+const Main = imports.ui.main;
+const Tweener = imports.ui.tweener;
+
+let text, button;
+
+function _hideHello() {
+ Main.uiGroup.remove_actor(text);
+ text = null;
+}
+
+function _showHello() {
+ if (!text) {
+ text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" });
+ Main.uiGroup.add_actor(text);
+ }
+
+ text.opacity = 255;
+
+ let monitor = Main.layoutManager.primaryMonitor;
+
+ text.set_position(monitor.x + Math.floor(monitor.width / 2 - text.width / 2),
+ monitor.y + Math.floor(monitor.height / 2 - text.height / 2));
+
+ Tweener.addTween(text,
+ { opacity: 0,
+ time: 2,
+ transition: 'easeOutQuad',
+ onComplete: _hideHello });
+}
+
+function init() {
+ button = new St.Bin({ style_class: 'panel-button',
+ reactive: true,
+ can_focus: true,
+ x_fill: true,
+ y_fill: false,
+ track_hover: true });
+ let icon = new St.Icon({ icon_name: 'system-run-symbolic',
+ style_class: 'system-status-icon' });
+
+ button.set_child(icon);
+ button.connect('button-press-event', _showHello);
+}
+
+function enable() {
+ Main.panel._rightBox.insert_child_at_index(button, 0);
+}
+
+function disable() {
+ Main.panel._rightBox.remove_child(button);
+}
diff --git a/geoclue.js b/geoclue.js
new file mode 100644
index 0000000..8cde221
--- /dev/null
+++ b/geoclue.js
@@ -0,0 +1,86 @@
+#!/usr/bin/gjs
+// Requires .desktop file installed in $XDG_DATA_DIRS/applications
+
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+const Geocode = imports.gi.GeocodeGlib;
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+
+const AccuracyLevel = {
+ COUNTRY: 1,
+ CITY: 4,
+ NEIGHBORHOOD: 5,
+ STREET: 6,
+ EXACT: 8
+};
+
+const ManagerIface = '<node> \
+ <interface name="org.freedesktop.GeoClue2.Manager"> \
+ <method name="GetClient"> \
+ <arg type="o" name="client" direction="out"/> \
+ </method> \
+ </interface> \
+</node>';
+const ManagerProxy = Gio.DBusProxy.makeProxyWrapper(ManagerIface);
+
+const ClientInterface = '<node> \
+<interface name="org.freedesktop.GeoClue2.Client"> \
+ <property name="Location" type="o" access="read"/> \
+ <property name="DesktopId" type="s" access="readwrite"/> \
+ <property name="RequestedAccuracyLevel" type="u" access="readwrite"/> \
+ <property name="DistanceThreshold" type="u" access="readwrite"/> \
+ <property name="Active" type="b" access="read"/> \
+ <method name="Start"/> \
+ <method name="Stop"/> \
+ <signal name="LocationUpdated"> \
+ <arg name="old" type="o"/> \
+ <arg name="new" type="o"/> \
+ </signal> \
+</interface> \
+</node>';
+const ClientProxy = Gio.DBusProxy.makeProxyWrapper(ClientInterface);
+
+const LocationInterface = '<node> \
+<interface name="org.freedesktop.GeoClue2.Location"> \
+ <property name="Latitude" type="d" access="read"/> \
+ <property name="Longitude" type="d" access="read"/> \
+ <property name="Accuracy" type="d" access="read"/> \
+ <property name="Description" type="s" access="read"/> \
+</interface> \
+</node>';
+const LocationProxy = Gio.DBusProxy.makeProxyWrapper(LocationInterface);
+
+
+function onLocationUpdated(proxy, sender, [oldPath, newPath]) {
+ let geoclueLocation = new LocationProxy(Gio.DBus.system,
+ "org.freedesktop.GeoClue2",
+ newPath);
+ let location = new Geocode.Location({ latitude: geoclueLocation.Latitude,
+ longitude: geoclueLocation.Longitude,
+ accuracy: geoclueLocation.Accuracy,
+ description: geoclueLocation.Description });
+ print('location:');
+ print('\tlatitude = ' + geoclueLocation.Latitude);
+ print('\tlongitude = ' + geoclueLocation.Longitude);
+ print('\taccuracy = ' + geoclueLocation.Accuracy);
+ print('\tdescription = ' + geoclueLocation.Description);
+ //this._updateLocation(location);
+ Mainloop.quit();
+}
+
+let _managerProxy = new ManagerProxy(Gio.DBus.system,
+ 'org.freedesktop.GeoClue2', '/org/freedesktop/GeoClue2/Manager');
+
+let [clientAddr] = _managerProxy.GetClientSync();
+
+let clientProxy = new ClientProxy(Gio.DBus.system,
+ 'org.freedesktop.GeoClue2', clientAddr);
+clientProxy.DesktopId = 'geoclue-test-simple';
+clientProxy.DistanceThreshold = 10000;
+clientProxy.RequestedAccuracyLevel = AccuracyLevel.EXACT;
+let updatedId = clientProxy.connectSignal('LocationUpdated',
+ onLocationUpdated);
+clientProxy.StartRemote();
+
+Mainloop.run();
diff --git a/gnome-shell-ISS_Above.desktop b/gnome-shell-ISS_Above.desktop
new file mode 100644
index 0000000..0870237
--- /dev/null
+++ b/gnome-shell-ISS_Above.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=ISS Above Gnome-Shell extension
+GenericName=ISS Above Gnome-Shell extension
+Keywords=geolocation;gnome-shell
+Exec=/home/matej/archiv/2015/projekty/ISS_Above@mcepl.cepl.eu/extension.js
+Icon=mark-location-symbolic
+NoDisplay=true
+Terminal=false
+Type=Application
diff --git a/metadata.json b/metadata.json
new file mode 100644
index 0000000..36960bd
--- /dev/null
+++ b/metadata.json
@@ -0,0 +1,8 @@
+{
+ "shell-version": [
+ "3.14.2"
+ ],
+ "uuid": "ISS_Above@mcepl.cepl.eu",
+ "name": "ISS Above",
+ "description": "Shows an icon when ISS is above you (+- 100km)"
+}
diff --git a/place.js b/place.js
new file mode 100644
index 0000000..91dd178
--- /dev/null
+++ b/place.js
@@ -0,0 +1,230 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2014 Jonas Danielsson
+ *
+ * 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: Jonas Danielsson <jonas@threetimestwo.org>
+ */
+
+const Geocode = imports.gi.GeocodeGlib;
+const GLib = imports.gi.GLib;
+const Lang = imports.lang;
+const Translations = imports.translations;
+
+const Place = new Lang.Class({
+ Name: 'Place',
+ Extends: Geocode.Place,
+
+ _init: function(params) {
+ this._population = params.population;
+ delete params.population;
+
+ this._wiki = params.wiki;
+ delete params.wiki;
+
+ this._openingHours = params.openingHours;
+ delete params.openingHours;
+
+ this._wheelchair = params.wheelchair;
+ delete params.wheelchair;
+
+ if (params.place) {
+ params = { osm_id: params.place.osm_id,
+ osm_type: params.place.osm_type,
+ name: params.place.name,
+ location: params.place.location,
+ bounding_box: params.place.bounding_box,
+ place_type: params.place.place_type,
+ street_address: params.place.street_address,
+ street: params.place.street,
+ building: params.place.building,
+ postal_code: params.place.postal_code,
+ area: params.place.area,
+ town: params.place.town,
+ state: params.place.state,
+ county: params.place.county,
+ country: params.place.country,
+ country_code: params.place.contry_code,
+ continent: params.place.continent };
+ }
+
+ for (let prop in params)
+ if (!params[prop])
+ delete params[prop];
+
+ this.parent(params);
+ },
+
+ get uniqueID() {
+ return this.osm_type + '-' + this.osm_id;
+ },
+
+ set population(v) {
+ this._population = v;
+ },
+
+ get population() {
+ return this._population;
+ },
+
+ set wiki(v) {
+ this._wiki = v;
+ },
+
+ get wiki() {
+ return this._wiki;
+ },
+
+ set openingHours(v) {
+ this._openingHours = v;
+ },
+
+ get openingHours() {
+ return this._openingHours;
+ },
+
+ get openingHoursTranslated() {
+ return Translations.translateOpeningHours(this._openingHours);
+ },
+
+ set wheelchair(v) {
+ this._wheelchair = v;
+ },
+
+ get wheelchair() {
+ return this._wheelchair;
+ },
+
+ get wheelchairTranslated() {
+ return this._translateWheelchair(this._wheelchair);
+ },
+
+ _translateWheelchair: function(string) {
+ switch(string) {
+ /* Translators:
+ * This means wheelchairs have full unrestricted access.
+ */
+ case 'yes': return _("yes");
+
+ /* Translators:
+ * This means wheelchairs have partial access (e.g some areas
+ * can be accessed and others not, areas requiring assistance
+ * by someone pushing up a steep gradient).
+ */
+ case 'limited': return _("limited");
+
+ /* Translators:
+ * This means wheelchairs have no unrestricted access
+ * (e.g. stair only access).
+ */
+ case 'no': return _("no");
+
+ /* Translators:
+ * This means that the way or area is designated or purpose built
+ * for wheelchairs (e.g. elevators designed for wheelchair access
+ * only). This is rarely used.
+ */
+ case 'designated': return _("designated");
+
+ default: return null;
+ }
+ },
+
+
+ toJSON: function() {
+ let bounding_box = null;
+
+ if (this.bounding_box) {
+ bounding_box = { top: this.bounding_box.top,
+ bottom: this.bounding_box.bottom,
+ left: this.bounding_box.left,
+ right: this.bounding_box.right };
+ }
+
+ let location = { latitude: this.location.latitude,
+ longitude: this.location.longitude,
+ altitude: this.location.altitude,
+ accuracy: this.location.accuracy };
+
+ return { id: this.osm_id,
+ osm_type: this.osm_type,
+ name: this.name,
+ bounding_box: bounding_box,
+ this_type: this.this_type,
+ location: location,
+ street_address: this.street_address,
+ street: this.street,
+ building: this.building,
+ postal_code: this.postal_code,
+ area: this.area,
+ town: this.town,
+ state: this.state,
+ county: this.county,
+ country: this.country,
+ country_code: this.contry_code,
+ continent: this.continent,
+ population: this.population,
+ wiki: this.wiki,
+ wheelchair: this.wheelchair,
+ openingHours: this.openingHours };
+ },
+
+ match: function(searchString) {
+ let name = this.name;
+
+ searchString = GLib.utf8_normalize(searchString, -1, GLib.NormalizeMode.ALL);
+ if (searchString === null)
+ return false;
+
+ if (searchString.length === 0)
+ return true;
+
+ name = GLib.utf8_normalize(name, -1, GLib.NormalizeMode.ALL);
+ if (name === null)
+ return false;
+
+ return name.toLowerCase().search(searchString.toLowerCase()) !== -1;
+ }
+});
+
+Place.fromJSON = function(obj) {
+ let props = { };
+
+ for (let key in obj) {
+ let prop = obj[key];
+
+ switch(key) {
+ case 'id':
+ props.osm_id = prop;
+ break;
+
+ case 'location':
+ props.location = new Geocode.Location(prop);
+ break;
+
+ case 'bounding_box':
+ if (prop)
+ props.bounding_box = new Geocode.BoundingBox(prop);
+ break;
+
+ default:
+ if (prop !== null && prop !== undefined)
+ props[key] = prop;
+ break;
+ }
+ }
+ return new Place(props);
+};
diff --git a/stylesheet.css b/stylesheet.css
new file mode 100644
index 0000000..432a360
--- /dev/null
+++ b/stylesheet.css
@@ -0,0 +1,8 @@
+.helloworld-label {
+ font-size: 36px;
+ font-weight: bold;
+ color: #ffffff;
+ background-color: rgba(10,10,10,0.7);
+ border-radius: 5px;
+ padding: .5em;
+}