dateMenu: Add world clock section

Rather than just offering to open Clocks when installed, pick up
configured locations and display their time directly in the popup.

https://bugzilla.gnome.org/show_bug.cgi?id=744817
This commit is contained in:
Florian Müllner 2015-02-07 00:47:27 +01:00
parent 7d1382afd3
commit efc0ec4740
3 changed files with 161 additions and 20 deletions

@ -1 +1 @@
Subproject commit f0fd5e109ff5499f42f7c6d31b4308b82f6b5879
Subproject commit 3f8a86fc461e098a7d97cc601c72248645ef9190

View File

@ -593,6 +593,7 @@ StScrollBar {
.calendar,
.datemenu-today-button,
.datemenu-displays-box,
.message-list-sections {
margin: 0 1.5em; }
@ -601,6 +602,7 @@ StScrollBar {
padding-bottom: 3em; }
.datemenu-today-button,
.world-clocks-button,
.message-list-section-title {
border-radius: 4px;
padding: .4em; }
@ -612,10 +614,13 @@ StScrollBar {
padding-right: .4em; }
.datemenu-today-button:hover, .datemenu-today-button:focus,
.world-clocks-button:hover,
.world-clocks-button:focus,
.message-list-section-title:hover,
.message-list-section-title:focus {
background-color: #454c4c; }
.datemenu-today-button:active,
.world-clocks-button:active,
.message-list-section-title:active {
color: white;
background-color: #215d9c; }
@ -623,10 +628,14 @@ StScrollBar {
.datemenu-today-button .date-label {
font-size: 1.5em; }
.world-clocks-header,
.message-list-section-title {
color: #8e8e80;
font-weight: bold; }
.world-clocks-grid {
spacing-rows: 0.4em; }
.calendar-month-label {
color: #e2e2df;
font-weight: bold;

View File

@ -4,6 +4,8 @@ const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Cairo = imports.cairo;
@ -79,6 +81,145 @@ const TodayButton = new Lang.Class({
}
});
const WorldClocksSection = new Lang.Class({
Name: 'WorldClocksSection',
_init: function() {
this._clock = new GnomeDesktop.WallClock();
this._settings = null;
this._clockNotifyId = 0;
this._changedId = 0;
this._locations = [];
this.actor = new St.Button({ style_class: 'world-clocks-button',
x_fill: true,
can_focus: true });
this.actor.connect('clicked', Lang.bind(this,
function() {
let app = this._getClockApp();
app.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}));
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
this._grid = new St.Widget({ style_class: 'world-clocks-grid',
layout_manager: layout });
layout.hookup_style(this._grid);
this.actor.child = this._grid;
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._sync));
this._sync();
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
},
_sync: function() {
this.actor.visible = (this._getClockApp() != null);
if (this.actor.visible) {
if (!this._settings) {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' });
this._changedId =
this._settings.connect('changed::world-clocks',
Lang.bind(this, this._clocksChanged));
this._clocksChanged();
}
} else {
if (this._settings)
this._settings.disconnect(this._changedId);
this._settings = null;
this._changedId = 0;
}
},
_clocksChanged: function() {
this._grid.destroy_all_children();
this._locations = [];
let world = GWeather.Location.get_world();
let clocks = this._settings.get_value('world-clocks').deep_unpack();
for (let i = 0; i < clocks.length; i++) {
let l = world.deserialize(clocks[i].location);
this._locations.push({ location: l });
}
this._locations.sort(function(a, b) {
return a.location.get_timezone().get_offset() -
b.location.get_timezone().get_offset();
});
let layout = this._grid.layout_manager;
let title = (this._locations.length == 0) ? _("Add world clocks…")
: _("World Clocks");
let header = new St.Label({ style_class: 'world-clocks-header',
x_align: Clutter.ActorAlign.START,
text: title });
layout.attach(header, 0, 0, 2, 1);
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i].location;
let label = new St.Label({ style_class: 'world-clocks-city',
text: l.get_city_name(),
x_align: Clutter.ActorAlign.START,
x_expand: true });
let time = new St.Label({ style_class: 'world-clocks-time',
x_align: Clutter.ActorAlign.END,
x_expand: true });
if (this._grid.text_direction == Clutter.TextDirection.RTL) {
layout.attach(time, 0, i + 1, 1, 1);
layout.attach(label, 1, i + 1, 1, 1);
} else {
layout.attach(label, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
}
this._locations[i].actor = time;
}
if (this._grid.get_n_children() > 1) {
if (!this._clockNotifyId)
this._clockNotifyId =
this._clock.connect('notify::clock', Lang.bind(this, this._updateLabels));
this._updateLabels();
} else {
if (this._clockNotifyId)
this._clock.disconnect(this._clockNotifyId);
this._clockNotifyId = 0;
}
},
_updateLabels: function() {
let desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
let clockFormat = desktopSettings.get_string('clock-format');
let hasAmPm = new Date().toLocaleFormat('%p') != '';
let format;
if (clockFormat == '24h' || !hasAmPm)
/* Translators: Time in 24h format */
format = N_("%H\u2236%M");
else
/* Translators: Time in 12h format */
format = N_("%l\u2236%M %p");
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i];
let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid());
let now = GLib.DateTime.new_now(tz);
l.actor.text = now.format(format);
}
}
});
const DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
@ -130,15 +271,18 @@ const DateMenuButton = new Lang.Class({
vbox.add(this._calendar.actor);
let separator = new PopupMenu.PopupSeparatorMenuItem();
vbox.add(separator.actor, { y_align: St.Align.END, expand: true, y_fill: false });
let scroll = new St.ScrollView({ style_class: 'vfade',
x_expand: true, x_fill: true,
overlay_scrollbars: true });
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
vbox.add_actor(scroll);
this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks"));
this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate));
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
let displaysBox = new St.BoxLayout({ vertical: true,
style_class: 'datemenu-displays-box' });
scroll.add_actor(displaysBox);
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._updateEventsVisibility));
this._clocksItem = new WorldClocksSection();
displaysBox.add(this._clocksItem.actor, { x_fill: true });
// Done with hbox for calendar and event list
@ -152,8 +296,6 @@ const DateMenuButton = new Lang.Class({
_updateEventsVisibility: function() {
let visible = this._eventSource.hasCalendars;
this._openClocksItem.actor.visible = visible &&
(this._getClockApp() != null);
this._messageList.actor.visible = visible;
},
@ -184,15 +326,5 @@ const DateMenuButton = new Lang.Class({
}
this._setEventSource(eventSource);
this._updateEventsVisibility();
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
},
_onOpenClocksActivate: function() {
this.menu.close();
let app = this._getClockApp();
app.activate();
}
});