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:
parent
7d1382afd3
commit
efc0ec4740
@ -1 +1 @@
|
|||||||
Subproject commit f0fd5e109ff5499f42f7c6d31b4308b82f6b5879
|
Subproject commit 3f8a86fc461e098a7d97cc601c72248645ef9190
|
@ -593,6 +593,7 @@ StScrollBar {
|
|||||||
|
|
||||||
.calendar,
|
.calendar,
|
||||||
.datemenu-today-button,
|
.datemenu-today-button,
|
||||||
|
.datemenu-displays-box,
|
||||||
.message-list-sections {
|
.message-list-sections {
|
||||||
margin: 0 1.5em; }
|
margin: 0 1.5em; }
|
||||||
|
|
||||||
@ -601,6 +602,7 @@ StScrollBar {
|
|||||||
padding-bottom: 3em; }
|
padding-bottom: 3em; }
|
||||||
|
|
||||||
.datemenu-today-button,
|
.datemenu-today-button,
|
||||||
|
.world-clocks-button,
|
||||||
.message-list-section-title {
|
.message-list-section-title {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: .4em; }
|
padding: .4em; }
|
||||||
@ -612,10 +614,13 @@ StScrollBar {
|
|||||||
padding-right: .4em; }
|
padding-right: .4em; }
|
||||||
|
|
||||||
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
.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:hover,
|
||||||
.message-list-section-title:focus {
|
.message-list-section-title:focus {
|
||||||
background-color: #454c4c; }
|
background-color: #454c4c; }
|
||||||
.datemenu-today-button:active,
|
.datemenu-today-button:active,
|
||||||
|
.world-clocks-button:active,
|
||||||
.message-list-section-title:active {
|
.message-list-section-title:active {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #215d9c; }
|
background-color: #215d9c; }
|
||||||
@ -623,10 +628,14 @@ StScrollBar {
|
|||||||
.datemenu-today-button .date-label {
|
.datemenu-today-button .date-label {
|
||||||
font-size: 1.5em; }
|
font-size: 1.5em; }
|
||||||
|
|
||||||
|
.world-clocks-header,
|
||||||
.message-list-section-title {
|
.message-list-section-title {
|
||||||
color: #8e8e80;
|
color: #8e8e80;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
|
|
||||||
|
.world-clocks-grid {
|
||||||
|
spacing-rows: 0.4em; }
|
||||||
|
|
||||||
.calendar-month-label {
|
.calendar-month-label {
|
||||||
color: #e2e2df;
|
color: #e2e2df;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -4,6 +4,8 @@ const GLib = imports.gi.GLib;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const GWeather = imports.gi.GWeather;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Cairo = imports.cairo;
|
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({
|
const DateMenuButton = new Lang.Class({
|
||||||
Name: 'DateMenuButton',
|
Name: 'DateMenuButton',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
@ -130,15 +271,18 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
vbox.add(this._calendar.actor);
|
vbox.add(this._calendar.actor);
|
||||||
|
|
||||||
let separator = new PopupMenu.PopupSeparatorMenuItem();
|
let scroll = new St.ScrollView({ style_class: 'vfade',
|
||||||
vbox.add(separator.actor, { y_align: St.Align.END, expand: true, y_fill: false });
|
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"));
|
let displaysBox = new St.BoxLayout({ vertical: true,
|
||||||
this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate));
|
style_class: 'datemenu-displays-box' });
|
||||||
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
scroll.add_actor(displaysBox);
|
||||||
|
|
||||||
Shell.AppSystem.get_default().connect('installed-changed',
|
this._clocksItem = new WorldClocksSection();
|
||||||
Lang.bind(this, this._updateEventsVisibility));
|
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
||||||
|
|
||||||
|
|
||||||
// Done with hbox for calendar and event list
|
// Done with hbox for calendar and event list
|
||||||
@ -152,8 +296,6 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_updateEventsVisibility: function() {
|
_updateEventsVisibility: function() {
|
||||||
let visible = this._eventSource.hasCalendars;
|
let visible = this._eventSource.hasCalendars;
|
||||||
this._openClocksItem.actor.visible = visible &&
|
|
||||||
(this._getClockApp() != null);
|
|
||||||
this._messageList.actor.visible = visible;
|
this._messageList.actor.visible = visible;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -184,15 +326,5 @@ const DateMenuButton = new Lang.Class({
|
|||||||
}
|
}
|
||||||
this._setEventSource(eventSource);
|
this._setEventSource(eventSource);
|
||||||
this._updateEventsVisibility();
|
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();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user