[gnome-weather] Rewrite as a JS application
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-weather] Rewrite as a JS application
- Date: Mon, 4 Mar 2013 22:04:21 +0000 (UTC)
commit 260211d1fd232cca21387c92257c872909dff13d
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sat Feb 23 01:33:09 2013 +0100
Rewrite as a JS application
JS is the language of choice for GNOME, and with this I can evaluate
the new gjs Package framework on a real application.
.gitmodules | 3 +
Makefile.am | 4 +-
autogen.sh | 6 ++
configure.ac | 11 ++-
data/Makefile.am | 6 +-
src/ui/custom.css => data/application.css | 0
libgd | 1 +
po/POTFILES.in | 13 ++--
src/Makefile.am | 39 ++++------
src/app.py | 90 --------------------
src/conditions.js | 66 +++++++++++++++
src/conditions.py | 57 -------------
src/forecast.js | 126 +++++++++++++++++++++++++++++
src/forecast.py | 106 ------------------------
src/gnome-weather.in | 67 +---------------
src/main.js | 62 ++++++++++++++
src/strings.js | 62 ++++++++++++++
src/strings.py | 58 -------------
src/util.js | 56 +++++++++++++
src/util.py | 5 -
src/view.js | 113 ++++++++++++++++++++++++++
src/widget.py | 126 -----------------------------
src/window.js | 113 ++++++++++++++++++++++++++
23 files changed, 644 insertions(+), 546 deletions(-)
---
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..bfd964e
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libgd"]
+ path = libgd
+ url = git://git.gnome.org/libgd
diff --git a/Makefile.am b/Makefile.am
index 09d6f10..0c2d064 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
-ACLOCAL_AMFLAGS = -I m4
+ACLOCAL_AMFLAGS = -I m4 -I libgd
-SUBDIRS = data src po
+SUBDIRS = po data libgd src
diff --git a/autogen.sh b/autogen.sh
index b39f842..ea09943 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,6 +4,7 @@
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
+ACLOCAL_FLAGS="-I libgd ${ACLOCAL_FLAGS}"
PKG_NAME="gnome-weather"
test -f $srcdir/configure.ac || {
@@ -17,4 +18,9 @@ which gnome-autogen.sh || {
echo "your OS vendor's package manager)."
exit 1
}
+
+(cd "$srcdir" ;
+test -d m4 || mkdir m4/ ;
+git submodule update --init --recursive ;
+)
. gnome-autogen.sh
diff --git a/configure.ac b/configure.ac
index d9b1edb..1cffcb3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@ AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([config])
-AM_INIT_AUTOMAKE([1.10 dist-bzip2 no-dist-gzip foreign tar-ustar])
+AM_INIT_AUTOMAKE([1.11 dist-xz foreign tar-ustar -Wno-portability])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
@@ -17,20 +17,21 @@ IT_PROG_INTLTOOL(0.26)
AC_PROG_CC
AM_PROG_CC_C_O
-LT_INIT
+LT_INIT([disable-static])
-PKG_PROG_PKG_CONFIG([0.22])
+LIBGD_INIT([header-bar revealer gir])
-PKG_CHECK_MODULES([GWEATHER], [gtk+-3.0 clutter-1.0 gdk-pixbuf-2.0 gio-2.0 gweather-3.0 >= 3.5.0])
+PKG_PROG_PKG_CONFIG([0.22])
GLIB_GSETTINGS
GOBJECT_INTROSPECTION_REQUIRE([1.30.0])
-AM_PATH_PYTHON([3.0])
+AC_PATH_PROG([GJS],[gjs])
AC_CONFIG_FILES([
Makefile
data/Makefile
+ libgd/Makefile
src/Makefile
po/Makefile.in
])
diff --git a/data/Makefile.am b/data/Makefile.am
index 339398b..60cbca3 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,8 +1,10 @@
-appsdir = $(datadir)/applications
+cssdir = $(pkgdatadir)
+css_DATA = application.css
+appsdir = $(datadir)/applications
apps_DATA = gnome-weather.desktop
@INTLTOOL_DESKTOP_RULE@
-dist_noinst_DATA = gnome-weather.desktop.in
+EXTRA_DIST = gnome-weather.desktop.in
CLEANFILES = $(apps_DATA)
diff --git a/src/ui/custom.css b/data/application.css
similarity index 100%
rename from src/ui/custom.css
rename to data/application.css
diff --git a/libgd b/libgd
new file mode 160000
index 0000000..006f5c8
--- /dev/null
+++ b/libgd
@@ -0,0 +1 @@
+Subproject commit 006f5c8619e98394c03e755ec1b72e2d5d908e35
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7eb67ac..926646b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,7 +1,8 @@
data/gnome-weather.desktop.in
-src/gnome-weather.in
-src/app.py
-src/widget.py
-src/conditions.py
-src/forecast.py
-src/strings.py
+src/conditions.js
+src/forecast.js
+src/main.js
+src/strings.js
+src/util.js
+src/view.js
+src/window.js
diff --git a/src/Makefile.am b/src/Makefile.am
index 76c35d3..aab4d64 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,30 +1,21 @@
NULL =
-bin_SCRIPTS = gnome-weather
+nodist_bin_SCRIPTS = gnome-weather
-gnome-weather: gnome-weather.in Makefile
- $(AM_V_GEN) sed -e "s|[ ]PYTHON@|$(PYTHON)|g" \
- -e "s|[ ]pkgdatadir@|$(pkgdatadir)|g" \
- -e "s|[ ]pkglibdir@|$(pkglibdir)|g" \
- -e "s|[ ]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
- -e "s|[ ]localedir@|$(datadir)/locale|g" \
- $< > $@
- @chmod +x $@
-
-pydir = $(pkglibdir)
-dist_py_PYTHON = \
- __init__.py \
- app.py \
- util.py \
- widget.py \
- forecast.py \
- conditions.py \
- strings.py \
+jsdir = $(pkgdatadir)
+dist_js_DATA = \
+ conditions.js \
+ forecast.js \
+ main.js \
+ strings.js \
+ util.js \
+ view.js \
+ window.js \
$(NULL)
-pkguidir = $(pkgdatadir)/ui
-dist_pkgui_DATA = \
- ui/custom.css
+gnome-weather: $(top_builddir)/config.status gnome-weather.in
+ $(AM_V_GEN) cd $(top_builddir) && $(SHELL) ./config.status --file $(subdir)/$@
+ @chmod +x $@
-dist_noinst_DATA = gnome-weather.in
-CLEANFILES = gnome-weather
+EXTRA_DIST = gnome-weather.in
+DISTCLEANFILES = gnome-weather
diff --git a/src/conditions.js b/src/conditions.js
new file mode 100644
index 0000000..fa5726f
--- /dev/null
+++ b/src/conditions.js
@@ -0,0 +1,66 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+const ConditionsSidebar = new Lang.Class({
+ Name: 'ConditionsSidebar',
+ Extends: Gtk.Grid,
+
+ _init: function(params) {
+ params = Params.fill(params, { orientation: Gtk.Orientation.VERTICAL });
+ this.parent(params);
+ this.get_style_context().add_class('white-background');
+
+ let title = new Gtk.Label({ label: '<b>' + _("Current conditions:") + '</b>',
+ use_markup: true,
+ xalign: 0.0,
+ wrap: true });
+ this.add(title);
+
+ this._conditions = new Gtk.Label({ xalign: 0.0, wrap: true });
+ this.add(this._conditions);
+
+ this._temperature = new Gtk.Label({ xalign: 0.0, wrap: true });
+ this.add(this._temperature);
+
+ this._wind = new Gtk.Label({ xalign: 0.0, wrap: true });
+ this.add(this._wind);
+
+ this._attribution = new Gtk.Label({ use_markup: true,
+ xalign: 0.0,
+ wrap: true,
+ max_width_chars: 30 });
+ this.add(this._attribution);
+ this.show_all();
+ },
+
+ update: function(info) {
+ this._conditions.label = info.get_weather_summary();
+ this._temperature.label = _("Temperature: ") +
+ info.get_temp_summary();
+ this._wind.label = _("Wind: ") + info.get_wind();
+
+ let attr = info.get_attribution();
+ if (attr) {
+ this._attribution.label = attr;
+ this._attribution.show();
+ } else {
+ this._attribution.hide();
+ }
+ }
+});
+
diff --git a/src/forecast.js b/src/forecast.js
new file mode 100644
index 0000000..c23d851
--- /dev/null
+++ b/src/forecast.js
@@ -0,0 +1,126 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+const Strings = imports.strings;
+const Util = imports.util;
+
+// In microseconds
+const ONE_DAY = 24*3600*1000*1000;
+const SIX_HOURS = 6*3600*1000*1000;
+
+const ForecastBox = new Lang.Class({
+ Name: 'ForecastBox',
+ Extends: Gtk.Grid,
+
+ _init: function(params) {
+ params = Params.fill({ orientation: Gtk.Orientation.HORIZONTAL,
+ column_spacing: 24,
+ column_homogeneous: true });
+ this.parent(params);
+ },
+
+ update: function(infos) {
+ let dates = infos.map(function(i) {
+ let [ok, date] = i.get_value_update();
+ return GLib.DateTime.new_from_unix_local(date);
+ });
+
+ let subday = this._hasSubdayResolution(dates);
+
+ let current;
+ let n = 0;
+ // limit to 5 infos max
+ for (let i = 0; i < dates.length && n < 5; i++) {
+ let info = infos[i];
+
+ // only show forecasts if they're separated by
+ // at least 6 hours
+ let [ok, date] = info.get_value_update();
+ let datetime = GLib.DateTime.new_from_unix_local(date);
+ if (current && datetime.difference(current) < SIX_HOURS)
+ continue;
+
+ let text = '<b>' + this._getDate(datetime, subday) + '</b>';
+ let label = new Gtk.Label({ label: text,
+ use_markup: true,
+ visible: true });
+ this.attach(label, n, 0, 1, 1);
+
+ let image = new Gtk.Image({ icon_name: info.get_icon_name(),
+ icon_size: Gtk.IconSize.DIALOG,
+ visible: true });
+ this.attach(image, n, 1, 1, 1);
+
+ let temperature = new Gtk.Label({ label: this._getTemperature(info),
+ visible: true });
+ this.attach(temperature, n, 2, 1, 1);
+
+ current = datetime;
+ n++;
+ }
+ },
+
+ clear: function() {
+ this.foreach(function(w) { w.destroy(); });
+ },
+
+ _hasSubdayResolution: function(dates) {
+ if (dates.length == 1)
+ return false;
+
+ if (dates[1].difference(dates[0]) < ONE_DAY)
+ return true;
+ else
+ return false;
+ },
+
+ _getDate: function(datetime, subday) {
+ let now = GLib.DateTime.new_now_local();
+ let tomorrow = now.add_days(1);
+
+ if (Util.arrayEqual(now.get_ymd(),
+ datetime.get_ymd())) {
+ if (subday)
+ return Strings.formatToday(datetime);
+ else
+ return _("Today");
+ } else if (Util.arrayEqual(tomorrow.get_ymd(),
+ datetime.get_ymd())) {
+ if (subday)
+ return Strings.formatTomorrow(datetime);
+ else
+ return _("Tomorrow");
+ } else {
+ if (subday)
+ return Strings.formatDayPart(datetime);
+ else
+ return datetime.format('%A');
+ }
+ },
+
+ _getTemperature: function(info) {
+ let [ok1, ] = info.get_value_temp_min(GWeather.TemperatureUnit.DEFAULT);
+ let [ok2, ] = info.get_value_temp_max(GWeather.TemperatureUnit.DEFAULT);
+
+ if (ok1 && ok2)
+ return _("%s / %s").format(info.get_temp_min(), info.get_temp_max());
+ else
+ return info.get_temp_summary();
+ }
+});
+
diff --git a/src/gnome-weather.in b/src/gnome-weather.in
old mode 100644
new mode 100755
index d09a392..ba55453
--- a/src/gnome-weather.in
+++ b/src/gnome-weather.in
@@ -1,66 +1,3 @@
-#! PYTHON@
+#!/bin/sh
+exec @GJS@ -c 'imports.package.start({ name: "@PACKAGE_NAME@", version: "@PACKAGE_VERSION@", prefix:
"@prefix@" })'
-# Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
-#
-# Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import sys, os, re
-import gettext
-
-def add_to_envvar(var, value):
- if var in os.environ:
- os.environ[var] += ':' + value
- else:
- os.environ[var] = value
-
-# HACK!
-# We need to remove python2 directories that are added
-# by jhbuild, or we end up loading pygobject for python 2!
-
-newpath = []
-for p in sys.path:
- is_python2 = False
- for d in p.split('/'):
- if d.startswith('python2'):
- is_python2 = True
- break
- if not is_python2:
- newpath.append(p)
-
-sys.path = newpath
-
-gettext.textdomain('@GETTEXT_PACKAGE@')
-
-if os.path.exists('./src'):
- # running from source tree
- gettext.bindtextdomain('@GETTEXT_PACKAGE@', './po')
- pkgdatadir = './src'
- pkglibdir = './src'
-else:
- gettext.bindtextdomain('@GETTEXT_PACKAGE@', '@localedir@')
- pkgdatadir = '@pkgdatadir@'
- pkglibdir = '@pkglibdir@'
-
-sys.path.append(pkglibdir)
-from gi.repository import GLib
-from app import GnomeWeatherApp
-
-class PathConfig:
- PKGLIBDIR = pkglibdir
- PKGDATADIR = pkgdatadir
- UIDIR = pkgdatadir + '/ui'
-
-GLib.set_prgname('gnome-weather')
-sys.exit(GnomeWeatherApp(PathConfig()).run(sys.argv))
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..f09b17e
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,62 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+pkg.initSubmodule('libgd');
+pkg.initGettext();
+pkg.initFormat();
+pkg.require({ 'Clutter': '1.0',
+ 'Gd': '1.0',
+ 'Gdk': '3.0',
+ 'GLib': '2.0',
+ 'GObject': '2.0',
+ 'Gtk': '3.0',
+ 'GtkClutter': '1.0',
+ 'GWeather': '3.0',
+ 'Lang': '1.0',
+ 'Mainloop': '1.0',
+ 'Params': '1.0' });
+
+const Util = imports.util;
+const Window = imports.window;
+
+const Application = new Lang.Class({
+ Name: 'WeatherApplication',
+ Extends: Gtk.Application,
+
+ _init: function() {
+ this.parent({ application_id: 'org.gnome.Weather.Application' });
+ GLib.set_application_name(_("Weather"));
+ },
+
+ vfunc_startup: function() {
+ GtkClutter.init(null);
+ this.parent();
+
+ Util.loadStyleSheet();
+
+ this.world = GWeather.Location.new_world(false);
+ },
+
+ vfunc_activate: function() {
+ (new Window.MainWindow({ application: this })).show();
+ }
+});
+
+function main(argv) {
+ return (new Application()).run(argv);
+}
diff --git a/src/strings.js b/src/strings.js
new file mode 100644
index 0000000..905bc4e
--- /dev/null
+++ b/src/strings.js
@@ -0,0 +1,62 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+const Gettext = imports.gettext;
+
+const DAY_PARTS = [
+ [N_("Monday night"), N_("Monday morning"), N_("Monday afternoon"), N_("Monday evening")],
+ [N_("Tuesday night"), N_("Tuesday morning"), N_("Tuesday afternoon"), N_("Tuesday evening")],
+ [N_("Wednesday night"), N_("Wednesday morning"), N_("Wednesday afternoon"), N_("Wednesday evening")],
+ [N_("Thursday night"), N_("Thursday morning"), N_("Thursday afternoon"), N_("Thursday evening")],
+ [N_("Friday night"), N_("Friday morning"), N_("Friday afternoon"), N_("Friday evening")],
+ [N_("Saturday night"), N_("Saturday morning"), N_("Saturday afternoon"), N_("Saturday evening")],
+ [N_("Sunday night"), N_("Sunday morning"), N_("Sunday afternoon"), N_("Sunday evening")],
+];
+
+const TODAY_PARTS = [N_("This night"), N_("This morning"), N_("This afternoon"), N_("This evening")];
+const TOMORROW_PARTS = [N_("Tomorrow night"), N_("Tomorrow morning"), N_("Tomorrow afternoon"), N_("Tomorrow
evening")];
+
+function _getDatetimePart(datetime) {
+ let h = datetime.get_hour();
+
+ if (h < 6 || h >= 21)
+ return 0;
+ else if (h < 12)
+ return 1;
+ else if (h < 18)
+ return 2;
+ else
+ return 3;
+}
+
+function formatToday(datetime) {
+ let part = _getDatetimePart(datetime);
+ return Gettext.gettext(TODAY_PARTS[part]);
+}
+
+function formatTomorrow(datetime) {
+ let part = _getDatetimePart(datetime);
+ return Gettext.gettext(TOMORROW_PARTS[part]);
+}
+
+function formatDayPart(datetime) {
+ let day = datetime.get_day_of_week() - 1;
+ let part = _getDatetimePart(datetime);
+
+ return Gettext.gettext(DAY_PARTS[day][part]);
+}
diff --git a/src/util.js b/src/util.js
new file mode 100644
index 0000000..7c9ca4d
--- /dev/null
+++ b/src/util.js
@@ -0,0 +1,56 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2013 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the GNOME Foundation nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function loadUI(file) {
+ file = file || 'main.ui';
+
+ let ui = new Gtk.Builder();
+ ui.add_from_file(GLib.build_filenamev([pkg.pkgdatadir,
+ file]));
+ return ui;
+}
+
+function loadStyleSheet(file) {
+ file = file || 'application.css';
+
+ let provider = new Gtk.CssProvider();
+ provider.load_from_path(GLib.build_filenamev([pkg.pkgdatadir,
+ file]));
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function arrayEqual(one, two) {
+ if (one.length != two.length)
+ return false;
+
+ for (let i = 0; i < one.length; i++)
+ if (one[i] != two[i])
+ return false;
+
+ return true;
+}
diff --git a/src/view.js b/src/view.js
new file mode 100644
index 0000000..6a10927
--- /dev/null
+++ b/src/view.js
@@ -0,0 +1,113 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+const Conditions = imports.conditions;
+const Forecast = imports.forecast;
+const Util = imports.util;
+
+const WeatherView = new Lang.Class({
+ Name: 'WeatherView',
+ Extends: GtkClutter.Embed,
+
+ _init: function(params) {
+ let filtered = Params.filter(params, { info: null });
+ params = Params.fill(params, { use_layout_size: true });
+ this.parent(params);
+
+ let iconBin = new GtkClutter.Actor();
+ iconBin.add_constraint(new Clutter.AlignConstraint({ align_axis: Clutter.AlignAxis.BOTH,
+ factor: 0.5,
+ source: this.get_stage() }));
+ this.get_stage().add_actor(iconBin);
+
+ this._icon = new Gtk.Image({ pixel_size: 256,
+ visible: true });
+ iconBin.get_widget().get_style_context().add_class('white-background');
+ iconBin.get_widget().add(this._icon);
+
+ let currentBox = new GtkClutter.Actor({ margin_right:15,
+ margin_top:15 });
+ currentBox.add_constraint(new Clutter.AlignConstraint({ align_axis: Clutter.AlignAxis.X_AXIS,
+ factor: 1.0,
+ source: this.get_stage() }));
+ currentBox.add_constraint(new Clutter.AlignConstraint({ align_axis: Clutter.AlignAxis.Y_AXIS,
+ factor: 0.0,
+ source: this.get_stage() }));
+ this.get_stage().add_actor(currentBox);
+ this._conditions = new Conditions.ConditionsSidebar();
+ currentBox.get_widget().add(this._conditions);
+ currentBox.get_widget().get_style_context().add_class('white-background');
+
+ let forecastsBin = new GtkClutter.Actor({ margin_bottom: 10,
+ margin_left: 5,
+ margin_right: 5 });
+ forecastsBin.add_constraint(new Clutter.AlignConstraint({ align_axis: Clutter.AlignAxis.Y_AXIS,
+ factor: 1.0,
+ source: this.get_stage() }));
+ forecastsBin.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.WIDTH,
+ source: this.get_stage() }));
+ this.get_stage().add_actor(forecastsBin);
+ this._forecasts = new Forecast.ForecastBox();
+ forecastsBin.get_widget().add(this._forecasts)
+ forecastsBin.get_widget().get_style_context().add_class('white-background')
+
+ let [ok, color] = Clutter.Color.from_string('#a0a0a0');
+ this._overlay = new Clutter.Actor({ background_color: color });
+ this._overlay.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.ALL,
+ source: this.get_stage() }));
+ this._overlay.show();
+ this.get_stage().add_actor(this._overlay);
+
+ this._info = filtered.info;
+ this._updateId = this._info.connect('updated',
+ Lang.bind(this, this._onUpdate));
+ },
+
+ vfunc_destroy: function() {
+ if (this._updateId) {
+ this._info.disconnect(this._updateId);
+ this._updateId = 0;
+ }
+
+ this.parent();
+ },
+
+ beginUpdate: function() {
+ this._forecasts.clear();
+ this._overlay.show();
+ this._overlay.opacity = 255;
+ },
+
+ _onUpdate: function(info) {
+ this._overlay.save_easing_state();
+ this._overlay.opacity = 0;
+ this._overlay.restore_easing_state();
+
+ this._conditions.update(info);
+
+ this._icon.icon_name = info.get_icon_name();
+
+ let forecasts = info.get_forecast_list();
+ if (forecasts.length > 0) {
+ this._forecasts.update(forecasts);
+ this._forecasts.show();
+ } else {
+ this._forecasts.hide();
+ }
+ }
+});
diff --git a/src/window.js b/src/window.js
new file mode 100644
index 0000000..9643dca
--- /dev/null
+++ b/src/window.js
@@ -0,0 +1,113 @@
+// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
+//
+// Copyright (c) 2012 Giovanni Campagna <scampa giovanni gmail com>
+//
+// Gnome Weather 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 Weather 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 Weather; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+const View = imports.view;
+
+function makeTitle(location) {
+ let city = location;
+ if (location.get_level() == GWeather.LocationLevel.WEATHER_STATION)
+ city = location.get_parent();
+
+ let country = city.get_parent();
+ while (country &&
+ country.get_level() > GWeather.LocationLevel.COUNTRY)
+ country = country.get_parent();
+
+ if (country)
+ return _("%s, %s").format(city.get_name(), country.get_name());
+ else
+ return city.get_name();
+}
+
+const MainWindow = new Lang.Class({
+ Name: 'MainWindow',
+ Extends: Gtk.ApplicationWindow,
+ Properties: {
+ 'location': GObject.ParamSpec.boxed('location', 'Location', '',
+ GObject.ParamFlags.READABLE |
+ GObject.ParamFlags.WRITABLE,
+ GWeather.Location),
+ },
+
+ _init: function(params) {
+ params = Params.fill(params, { default_width: 700,
+ default_height: 500 });
+ this.parent(params);
+
+ this._world = this.application.world;
+ this._info = new GWeather.Info({ world: this._world,
+ forecast_type: GWeather.ForecastType.LIST,
+ enabled_providers: GWeather.Provider.METAR |
+ GWeather.Provider.YR_NO });
+ this._location = this._info.get_location();
+
+ let grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+
+ this._header = new Gd.HeaderBar({ title: makeTitle(this._location),
+ hexpand: true });
+ this._search = new Gd.HeaderToggleButton({ symbolic_icon_name: 'edit-find-symbolic' });
+ this._header.pack_end(this._search);
+ grid.add(this._header);
+
+ this._locationEntry = new GWeather.LocationEntry({ top: this._world,
+ location: this._location,
+ width_request: 500,
+ halign: Gtk.Align.CENTER });
+ this._locationEntry.bind_property('location', this, 'location',
+ GObject.BindingFlags.DEFAULT);
+
+ let toolbar = new Gtk.Toolbar({ hexpand: true });
+ toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR);
+ let item = new Gtk.ToolItem();
+ item.set_expand(true);
+ item.add(this._locationEntry);
+ toolbar.insert(item, 0);
+
+ let revealer = new Gd.Revealer({ reveal_child: false,
+ child: toolbar });
+ this._search.bind_property('active', revealer, 'reveal-child',
+ GObject.BindingFlags.DEFAULT);
+ grid.add(revealer);
+
+ this._view = new View.WeatherView({ info: this._info,
+ hexpand: true,
+ vexpand: true });
+ grid.add(this._view);
+
+ this.add(grid);
+ grid.show_all();
+ },
+
+ get location() {
+ return this._location;
+ },
+
+ set location(l) {
+ this._location = l;
+ this._info.location = l;
+ this._header.title = makeTitle(l);
+ this.update();
+
+ this.notify('location');
+ },
+
+ update: function() {
+ this._view.beginUpdate();
+ this._info.update();
+ },
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]