Merge pull request #52 from jwrdegoede/master
Add compatibility with GNOME 3.34 and GNOME 3.36
@ -62,3 +62,5 @@ SUBDIRS = @CONFIGURE_SUBDIRS@
|
|||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
icondir = $(extensiondir)/../../../icons/gnome/scalable/apps
|
||||||
|
icon_DATA = utilities-teatime.svg
|
||||||
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB |
300
src/extension.js
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const GObject = imports.gi.GObject;
|
||||||
const Mainloop = imports.mainloop; // timer
|
const Mainloop = imports.mainloop; // timer
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -28,117 +28,10 @@ const N_ = function (e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let PopupTeaMenuItem = GObject.registerClass(
|
||||||
const TeaTimeFullscreenNotification = new Lang.Class({
|
class PopupTeaMenuItem extends PopupMenu.PopupBaseMenuItem {
|
||||||
Name: 'TeaTimeFullscreenNotification',
|
_init(sTeaname, nBrewtime, params) {
|
||||||
|
super._init(params);
|
||||||
_init: function () {
|
|
||||||
// this spans the whole monitor and contains
|
|
||||||
// the actual layout, which it displays in
|
|
||||||
// the center of itself
|
|
||||||
|
|
||||||
this._bin = new St.Bin({
|
|
||||||
x_align: St.Align.MIDDLE,
|
|
||||||
y_align: St.Align.MIDDLE
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof Layout.MonitorConstraint != 'undefined') {
|
|
||||||
// MonitorConstraint was introduced in gnome-3.6
|
|
||||||
this._monitorConstraint = new Layout.MonitorConstraint();
|
|
||||||
this._bin.add_constraint(this._monitorConstraint);
|
|
||||||
}
|
|
||||||
Main.uiGroup.add_actor(this._bin);
|
|
||||||
|
|
||||||
// a table imitating a vertical box layout to hold the texture and
|
|
||||||
// a label underneath it
|
|
||||||
this._layout = new St.BoxLayout({
|
|
||||||
vertical: true,
|
|
||||||
y_align: Clutter.ActorAlign.CENTER
|
|
||||||
});
|
|
||||||
this._bin.set_child(this._layout);
|
|
||||||
|
|
||||||
// find all the textures
|
|
||||||
let datadir = Me.dir.get_child("data");
|
|
||||||
this._textureFiles = [];
|
|
||||||
if (datadir.query_exists(null)) {
|
|
||||||
let enumerator = datadir.enumerate_children(Gio.FILE_ATTRIBUTE_STANDARD_NAME,
|
|
||||||
Gio.FileQueryInfoFlags.NONE,
|
|
||||||
null);
|
|
||||||
let info;
|
|
||||||
info = enumerator.next_file(null);
|
|
||||||
while (info != null) {
|
|
||||||
let filename = info.get_name();
|
|
||||||
if (filename.match(/^cup.*/)) {
|
|
||||||
this._textureFiles.push(datadir.get_child(filename).get_path());
|
|
||||||
}
|
|
||||||
info = enumerator.next_file(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._textureFiles.sort();
|
|
||||||
|
|
||||||
this._texture = new Clutter.Texture({
|
|
||||||
reactive: true,
|
|
||||||
keep_aspect_ratio: true
|
|
||||||
});
|
|
||||||
this._texture.connect("button-release-event", Lang.bind(this, this.hide));
|
|
||||||
this._layout.add_child(this._texture);
|
|
||||||
|
|
||||||
this._timeline = new Clutter.Timeline({
|
|
||||||
duration: 2000,
|
|
||||||
repeat_count: -1,
|
|
||||||
progress_mode: Clutter.AnimationMode.LINEAR
|
|
||||||
});
|
|
||||||
this._timeline.connect("new-frame", Lang.bind(this, this._newFrame));
|
|
||||||
|
|
||||||
this._label = new St.Label({
|
|
||||||
text: _("Your tea is ready!"),
|
|
||||||
style_class: "dash-label"
|
|
||||||
});
|
|
||||||
this._layout.add_child(this._label);
|
|
||||||
|
|
||||||
this._lightbox = new imports.ui.lightbox.Lightbox(Main.uiGroup); // Seems not to work on Gnome 3.10 { fadeInTime: 0.5, fadeOutTime: 0.5 }
|
|
||||||
this._lightbox.highlight(this._bin);
|
|
||||||
},
|
|
||||||
destroy: function () {
|
|
||||||
this.hide();
|
|
||||||
Main.popModal(this._bin);
|
|
||||||
this._bin.destroy();
|
|
||||||
this._lightbox.hide();
|
|
||||||
},
|
|
||||||
_newFrame: function (timeline, msecs, user) {
|
|
||||||
let progress = timeline.get_progress();
|
|
||||||
let idx = Math.round(progress * this._textureFiles.length) % this._textureFiles.length;
|
|
||||||
this._texture.set_from_file(this._textureFiles[idx]);
|
|
||||||
},
|
|
||||||
show: function () {
|
|
||||||
if (typeof Layout.MonitorConstraint != 'undefined') {
|
|
||||||
// global.display was introduced in gnome-shell 3.30
|
|
||||||
if (typeof global.screen != 'undefined') {
|
|
||||||
this._monitorConstraint.index = global.screen.get_current_monitor();
|
|
||||||
} else {
|
|
||||||
this._monitorConstraint.index = global.display.get_current_monitor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Main.pushModal(this._bin);
|
|
||||||
this._timeline.start();
|
|
||||||
this._lightbox.show();
|
|
||||||
this._bin.show_all();
|
|
||||||
},
|
|
||||||
hide: function () {
|
|
||||||
Main.popModal(this._bin);
|
|
||||||
this._bin.hide();
|
|
||||||
this._lightbox.hide();
|
|
||||||
this._timeline.stop();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const PopupTeaMenuItem = new Lang.Class({
|
|
||||||
Name: 'PopupTeaMenuItem',
|
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
|
||||||
|
|
||||||
_init: function (sTeaname, nBrewtime, params) {
|
|
||||||
this.parent(params);
|
|
||||||
|
|
||||||
this.tealabel = new St.Label({
|
this.tealabel = new St.Label({
|
||||||
text: sTeaname
|
text: sTeaname
|
||||||
@ -149,38 +42,25 @@ const PopupTeaMenuItem = new Lang.Class({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actor instanceof St.BoxLayout) {
|
this.add(this.tealabel);
|
||||||
// will be used for gnome-shell 3.10 and possibly above where this.actor is BoxLayout
|
|
||||||
this.actor.add(this.tealabel, {
|
|
||||||
expand: true
|
|
||||||
});
|
|
||||||
if (nBrewtime != 0) {
|
if (nBrewtime != 0) {
|
||||||
this.actor.add(this.timelabel);
|
this.add(this.timelabel);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.addActor(this.tealabel, {
|
|
||||||
expand: true
|
|
||||||
});
|
|
||||||
if (nBrewtime != 0) {
|
|
||||||
this.addActor(this.timelabel, {
|
|
||||||
expand: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._delegate = this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let TeaTime = GObject.registerClass(
|
||||||
|
class TeaTime extends PanelMenu.Button {
|
||||||
|
_init() {
|
||||||
|
super._init(1.0, "TeaTime");
|
||||||
|
|
||||||
const TeaTime = new Lang.Class({
|
this.config_keys = Utils.GetConfigKeys();
|
||||||
Name: 'TeaTime',
|
|
||||||
Extends: PanelMenu.Button,
|
|
||||||
|
|
||||||
_init: function () {
|
|
||||||
this.parent(null, "TeaTime");
|
|
||||||
|
|
||||||
this._settings = Utils.getSettings();
|
this._settings = Utils.getSettings();
|
||||||
|
|
||||||
this._logo = new Icon.TwoColorIcon(24, Icon.TeaPot);
|
this._logo = new Icon.TwoColorIcon(20, Icon.TeaPot);
|
||||||
|
|
||||||
// set timer widget
|
// set timer widget
|
||||||
this._textualTimer = new St.Label({
|
this._textualTimer = new St.Label({
|
||||||
@ -188,22 +68,23 @@ const TeaTime = new Lang.Class({
|
|||||||
x_align: Clutter.ActorAlign.END,
|
x_align: Clutter.ActorAlign.END,
|
||||||
y_align: Clutter.ActorAlign.CENTER
|
y_align: Clutter.ActorAlign.CENTER
|
||||||
});
|
});
|
||||||
this._graphicalTimer = new Icon.TwoColorIcon(24, Icon.Pie);
|
this._graphicalTimer = new Icon.TwoColorIcon(20, Icon.Pie);
|
||||||
|
|
||||||
this.actor.add_actor(this._logo);
|
this.add_actor(this._logo);
|
||||||
this.actor.add_style_class_name('panel-status-button');
|
this.add_style_class_name('panel-status-button');
|
||||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
this.connect('style-changed', this._onStyleChanged.bind(this));
|
||||||
|
|
||||||
this._idleTimeout = null;
|
this._idleTimeout = null;
|
||||||
|
|
||||||
this._createMenu();
|
this._createMenu();
|
||||||
},
|
}
|
||||||
_createMenu: function () {
|
|
||||||
|
_createMenu() {
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this._settings.connect("changed::" + this.config_keys.steep_times,
|
this._settings.connect("changed::" + this.config_keys.steep_times,
|
||||||
Lang.bind(this, this._updateTeaList));
|
this._updateTeaList.bind(this));
|
||||||
this._settings.connect("changed::" + this.config_keys.graphical_countdown,
|
this._settings.connect("changed::" + this.config_keys.graphical_countdown,
|
||||||
Lang.bind(this, this._updateCountdownType));
|
this._updateCountdownType.bind(this));
|
||||||
|
|
||||||
this.teaItemCont = new PopupMenu.PopupMenuSection();
|
this.teaItemCont = new PopupMenu.PopupMenuSection();
|
||||||
|
|
||||||
@ -212,7 +93,7 @@ const TeaTime = new Lang.Class({
|
|||||||
let head = new PopupMenu.PopupMenuSection();
|
let head = new PopupMenu.PopupMenuSection();
|
||||||
let item = new PopupMenu.PopupMenuItem(_("Show settings")); //, 'gtk-preferences');
|
let item = new PopupMenu.PopupMenuItem(_("Show settings")); //, 'gtk-preferences');
|
||||||
// item._icon.icon_size = 15;
|
// item._icon.icon_size = 15;
|
||||||
item.connect('activate', Lang.bind(this, this._showPreferences));
|
item.connect('activate', this._showPreferences.bind(this));
|
||||||
head.addMenuItem(item);
|
head.addMenuItem(item);
|
||||||
|
|
||||||
/*******************/
|
/*******************/
|
||||||
@ -223,7 +104,7 @@ const TeaTime = new Lang.Class({
|
|||||||
hint_text: _("min:sec")
|
hint_text: _("min:sec")
|
||||||
});
|
});
|
||||||
this._customEntry.get_clutter_text().set_max_length(10);
|
this._customEntry.get_clutter_text().set_max_length(10);
|
||||||
this._customEntry.get_clutter_text().connect("key-press-event", Lang.bind(this, this._createCustomTimer));
|
this._customEntry.get_clutter_text().connect("key-press-event", this._createCustomTimer.bind(this));
|
||||||
bottom.box.add(this._customEntry);
|
bottom.box.add(this._customEntry);
|
||||||
bottom.actor.set_style("padding: 0px 18px;")
|
bottom.actor.set_style("padding: 0px 18px;")
|
||||||
|
|
||||||
@ -236,58 +117,69 @@ const TeaTime = new Lang.Class({
|
|||||||
this.menu.addMenuItem(bottom);
|
this.menu.addMenuItem(bottom);
|
||||||
|
|
||||||
this._updateTeaList();
|
this._updateTeaList();
|
||||||
},
|
}
|
||||||
_updateTeaList: function (config, output) {
|
|
||||||
|
_updateTeaList(config, output) {
|
||||||
// make sure the menu is empty
|
// make sure the menu is empty
|
||||||
this.teaItemCont.removeAll();
|
this.teaItemCont.removeAll();
|
||||||
|
|
||||||
// fill with new teas
|
// fill with new teas
|
||||||
let list = this._settings.get_value(this.config_keys.steep_times).unpack();
|
let list = this._settings.get_value(this.config_keys.steep_times).unpack();
|
||||||
let menuItem = new PopupTeaMenuItem("Stop Timer", 0);
|
let menuItem = new PopupTeaMenuItem("Stop Timer", 0);
|
||||||
menuItem.connect('activate', Lang.bind(this, function () {
|
menuItem.connect('activate', function () {
|
||||||
this._stopCountdown();
|
this._stopCountdown();
|
||||||
}));
|
}.bind(this));
|
||||||
this.teaItemCont.addMenuItem(menuItem);
|
this.teaItemCont.addMenuItem(menuItem);
|
||||||
for (let teaname in list) {
|
for (let teaname in list) {
|
||||||
let time = list[teaname].get_uint32();
|
let time = list[teaname].get_uint32();
|
||||||
|
|
||||||
let menuItem = new PopupTeaMenuItem(_(teaname), time);
|
let menuItem = new PopupTeaMenuItem(_(teaname), time);
|
||||||
menuItem.connect('activate', Lang.bind(this, function () {
|
menuItem.connect('activate', function () {
|
||||||
this._initCountdown(time);
|
this._initCountdown(time);
|
||||||
}));
|
}.bind(this));
|
||||||
this.teaItemCont.addMenuItem(menuItem);
|
this.teaItemCont.addMenuItem(menuItem);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_updateCountdownType: function (config, output) {
|
|
||||||
|
_updateCountdownType(config, output) {
|
||||||
let bWantGraphicalCountdown = this._settings.get_boolean(this.config_keys.graphical_countdown);
|
let bWantGraphicalCountdown = this._settings.get_boolean(this.config_keys.graphical_countdown);
|
||||||
|
|
||||||
if (bWantGraphicalCountdown != this._bGraphicalCountdown) {
|
if (bWantGraphicalCountdown != this._bGraphicalCountdown) {
|
||||||
if (this._idleTimeout != null) {
|
if (this._idleTimeout != null) {
|
||||||
// we have a running countdown, replace the display
|
// we have a running countdown, replace the display
|
||||||
this.actor.remove_actor(this._bGraphicalCountdown ?
|
this.remove_actor(this._bGraphicalCountdown ?
|
||||||
this._graphicalTimer : this._textualTimer);
|
this._graphicalTimer : this._textualTimer);
|
||||||
this._bGraphicalCountdown = bWantGraphicalCountdown;
|
this._bGraphicalCountdown = bWantGraphicalCountdown;
|
||||||
this.actor.add_actor(this._bGraphicalCountdown ?
|
this.add_actor(this._bGraphicalCountdown ?
|
||||||
this._graphicalTimer : this._textualTimer);
|
this._graphicalTimer : this._textualTimer);
|
||||||
|
|
||||||
this._updateTimerDisplay(this._getRemainingSec());
|
this._updateTimerDisplay(this._getRemainingSec());
|
||||||
} // if timeout active
|
} // if timeout active
|
||||||
} // value changed
|
} // value changed
|
||||||
},
|
}
|
||||||
_createCustomTimer: function (text, event) {
|
|
||||||
|
_createCustomTimer(text, event) {
|
||||||
if (event.get_key_symbol() == Clutter.KEY_Enter ||
|
if (event.get_key_symbol() == Clutter.KEY_Enter ||
|
||||||
event.get_key_symbol() == Clutter.KEY_Return) {
|
event.get_key_symbol() == Clutter.KEY_Return ||
|
||||||
|
event.get_key_symbol() == Clutter.KEY_KP_Enter) {
|
||||||
|
|
||||||
let customTime = text.get_text();
|
let customTime = text.get_text();
|
||||||
let seconds = 0;
|
let seconds = 0;
|
||||||
let match = customTime.match(/^(?:(\d+)(?::(\d{0,2}))?|:(\d+))$/)
|
let match = customTime.match(/^(?:(\d+)(?::(\d{0,2}))?|:(\d+))$/)
|
||||||
if (match) {
|
if (match) {
|
||||||
let factor = 1;
|
let factor = 1;
|
||||||
|
if (match[3] === undefined) { // minutes and seconds?
|
||||||
for (var i = match.length - 2; i > 0; i--) {
|
for (var i = match.length - 2; i > 0; i--) {
|
||||||
let s = match[i].replace(/^0/, ''); // fix for elder GNOME <= 3.10 which don't like leading zeros
|
let s = match[i] === undefined ? "" : match[i].replace(/^0/, ''); // fix for elder GNOME <= 3.10 which don't like leading zeros
|
||||||
|
if (s.match(/^\d+$/)) { // only if something left
|
||||||
seconds += factor * parseInt(s);
|
seconds += factor * parseInt(s);
|
||||||
|
}
|
||||||
factor *= 60;
|
factor *= 60;
|
||||||
}
|
}
|
||||||
|
} else { // only seconds?
|
||||||
|
let s = match[3].replace(/^0/, '');
|
||||||
|
seconds = parseInt(s);
|
||||||
|
}
|
||||||
if (seconds > 0) {
|
if (seconds > 0) {
|
||||||
this._initCountdown(seconds);
|
this._initCountdown(seconds);
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
@ -295,33 +187,22 @@ const TeaTime = new Lang.Class({
|
|||||||
}
|
}
|
||||||
this._customEntry.set_text("");
|
this._customEntry.set_text("");
|
||||||
}
|
}
|
||||||
},
|
|
||||||
_showNotification: function (subject, text) {
|
|
||||||
let source = (Utils.isGnome34()) ?
|
|
||||||
new MessageTray.Source(_("TeaTime applet")) :
|
|
||||||
new MessageTray.Source(_("TeaTime applet"), 'utilities-teatime');
|
|
||||||
|
|
||||||
if (Utils.isGnome34()) {
|
|
||||||
source.createNotificationIcon =
|
|
||||||
function () {
|
|
||||||
let iconBox = new St.Bin();
|
|
||||||
iconBox._size = this.ICON_SIZE;
|
|
||||||
iconBox.child = new St.Icon({
|
|
||||||
icon_name: 'utilities-teatime',
|
|
||||||
icon_type: St.IconType.FULLCOLOR,
|
|
||||||
icon_size: iconBox._size
|
|
||||||
});
|
|
||||||
return iconBox;
|
|
||||||
} // createNotificationIcon
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_showNotification(subject, text) {
|
||||||
|
let source = new MessageTray.Source(_("TeaTime applet"), 'utilities-teatime');
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
|
|
||||||
let notification = new MessageTray.Notification(source, subject, text);
|
let notification = new MessageTray.Notification(source, subject, text);
|
||||||
notification.setTransient(true);
|
notification.setTransient(true);
|
||||||
|
if (typeof source.showNotification === 'function') {
|
||||||
|
source.showNotification(notification);
|
||||||
|
} else {
|
||||||
source.notify(notification);
|
source.notify(notification);
|
||||||
},
|
}
|
||||||
_initCountdown: function (time) {
|
}
|
||||||
|
|
||||||
|
_initCountdown(time) {
|
||||||
this._startTime = new Date();
|
this._startTime = new Date();
|
||||||
this._stopTime = new Date();
|
this._stopTime = new Date();
|
||||||
this._cntdownStart = time;
|
this._cntdownStart = time;
|
||||||
@ -335,66 +216,68 @@ const TeaTime = new Lang.Class({
|
|||||||
|
|
||||||
this._stopTime.setTime(this._startTime.getTime() + time * 1000); // in msec
|
this._stopTime.setTime(this._startTime.getTime() + time * 1000); // in msec
|
||||||
|
|
||||||
this.actor.remove_actor(this._logo); // show timer instead of default icon
|
this.remove_actor(this._logo); // show timer instead of default icon
|
||||||
|
|
||||||
this._updateTimerDisplay(time);
|
this._updateTimerDisplay(time);
|
||||||
|
|
||||||
this.actor.add_actor(this._bGraphicalCountdown ?
|
this.add_actor(this._bGraphicalCountdown ?
|
||||||
this._graphicalTimer : this._textualTimer);
|
this._graphicalTimer : this._textualTimer);
|
||||||
|
|
||||||
if (this._idleTimeout != null) Mainloop.source_remove(this._idleTimeout);
|
if (this._idleTimeout != null) Mainloop.source_remove(this._idleTimeout);
|
||||||
this._idleTimeout = Mainloop.timeout_add_seconds(dt, Lang.bind(this, this._doCountdown));
|
this._idleTimeout = Mainloop.timeout_add_seconds(dt, this._doCountdown.bind(this));
|
||||||
},
|
}
|
||||||
_stopCountdown: function () {
|
|
||||||
|
_stopCountdown() {
|
||||||
if (this._idleTimeout != null) Mainloop.source_remove(this._idleTimeout);
|
if (this._idleTimeout != null) Mainloop.source_remove(this._idleTimeout);
|
||||||
this.actor.remove_actor(this._bGraphicalCountdown ?
|
this.remove_actor(this._bGraphicalCountdown ?
|
||||||
this._graphicalTimer : this._textualTimer);
|
this._graphicalTimer : this._textualTimer);
|
||||||
this.actor.add_actor(this._logo);
|
this.add_actor(this._logo);
|
||||||
this._idleTimeout = null;
|
this._idleTimeout = null;
|
||||||
},
|
}
|
||||||
_getRemainingSec: function () {
|
|
||||||
|
_getRemainingSec() {
|
||||||
let a = new Date();
|
let a = new Date();
|
||||||
return (this._stopTime.getTime() - a.getTime()) * 1e-3;
|
return (this._stopTime.getTime() - a.getTime()) * 1e-3;
|
||||||
},
|
}
|
||||||
_updateTimerDisplay: function (remainingTime) {
|
|
||||||
|
_updateTimerDisplay(remainingTime) {
|
||||||
if (this._bGraphicalCountdown) {
|
if (this._bGraphicalCountdown) {
|
||||||
this._graphicalTimer.setStatus((this._cntdownStart - remainingTime) / this._cntdownStart);
|
this._graphicalTimer.setStatus((this._cntdownStart - remainingTime) / this._cntdownStart);
|
||||||
} else {
|
} else {
|
||||||
this._textualTimer.text = Utils.formatTime(remainingTime);
|
this._textualTimer.text = Utils.formatTime(remainingTime);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_doCountdown: function () {
|
|
||||||
|
_doCountdown() {
|
||||||
let remainingTime = this._getRemainingSec();
|
let remainingTime = this._getRemainingSec();
|
||||||
|
|
||||||
if (remainingTime <= 0) {
|
if (remainingTime <= 0) {
|
||||||
// count down finished, switch display again
|
// count down finished, switch display again
|
||||||
this._stopCountdown();
|
this._stopCountdown();
|
||||||
this._playSound();
|
this._playSound();
|
||||||
|
|
||||||
if (!Utils.isGnome34() && this._settings.get_boolean(this.config_keys.fullscreen_notification)) {
|
|
||||||
this.dialog = new TeaTimeFullscreenNotification();
|
|
||||||
this.dialog.show();
|
|
||||||
} else {
|
|
||||||
this._showNotification(_("Your tea is ready!"),
|
this._showNotification(_("Your tea is ready!"),
|
||||||
_("Drink it, while it is hot!"));
|
_("Drink it, while it is hot!"));
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
this._updateTimerDisplay(remainingTime);
|
this._updateTimerDisplay(remainingTime);
|
||||||
return true; // continue timer
|
return true; // continue timer
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_playSound: function () {
|
|
||||||
|
_playSound() {
|
||||||
let bPlayAlarmSound = this._settings.get_boolean(this.config_keys.use_alarm_sound);
|
let bPlayAlarmSound = this._settings.get_boolean(this.config_keys.use_alarm_sound);
|
||||||
if (bPlayAlarmSound) {
|
if (bPlayAlarmSound) {
|
||||||
Utils.playSound(this._settings.get_string(this.config_keys.alarm_sound));
|
Utils.playSound(this._settings.get_string(this.config_keys.alarm_sound));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_showPreferences: function () {
|
|
||||||
imports.misc.util.spawn(["gnome-shell-extension-prefs", ExtensionUtils.getCurrentExtension().metadata['uuid']]);
|
_showPreferences() {
|
||||||
|
const currExt = ExtensionUtils.getCurrentExtension();
|
||||||
|
imports.misc.util.spawn(["gnome-shell-extension-prefs", currExt.metadata['uuid']]);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
}
|
||||||
_onStyleChanged: function (actor) {
|
|
||||||
|
_onStyleChanged(actor) {
|
||||||
let themeNode = actor.get_theme_node();
|
let themeNode = actor.get_theme_node();
|
||||||
let color = themeNode.get_foreground_color()
|
let color = themeNode.get_foreground_color()
|
||||||
let [bHasPadding, padding] = themeNode.lookup_length("-natural-hpadding", false);
|
let [bHasPadding, padding] = themeNode.lookup_length("-natural-hpadding", false);
|
||||||
@ -418,13 +301,10 @@ const TeaTime = new Lang.Class({
|
|||||||
let scaling = Utils.getGlobalDisplayScaleFactor();
|
let scaling = Utils.getGlobalDisplayScaleFactor();
|
||||||
this._logo.setScaling(scaling);
|
this._logo.setScaling(scaling);
|
||||||
this._graphicalTimer.setScaling(scaling);
|
this._graphicalTimer.setScaling(scaling);
|
||||||
},
|
}
|
||||||
config_keys: Utils.GetConfigKeys()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function init(metadata) {
|
function init(metadata) {
|
||||||
let theme = imports.gi.Gtk.IconTheme.get_default();
|
|
||||||
theme.append_search_path(metadata.path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _TeaTime;
|
let _TeaTime;
|
||||||
@ -437,4 +317,4 @@ function enable() {
|
|||||||
function disable() {
|
function disable() {
|
||||||
if (_TeaTime._idleTimeout != null) Mainloop.source_remove(_TeaTime._idleTimeout);
|
if (_TeaTime._idleTimeout != null) Mainloop.source_remove(_TeaTime._idleTimeout);
|
||||||
_TeaTime.destroy();
|
_TeaTime.destroy();
|
||||||
};
|
}
|
||||||
|
54
src/icon.js
@ -10,28 +10,28 @@
|
|||||||
* If there is a better way for that stuff, please let me know ;)
|
* If there is a better way for that stuff, please let me know ;)
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
const Lang = imports.lang;
|
const GObject = imports.gi.GObject;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const ExUt = imports.misc.extensionUtils;
|
const ExUt = imports.misc.extensionUtils;
|
||||||
const Me = ExUt.getCurrentExtension();
|
const Me = ExUt.getCurrentExtension();
|
||||||
const Utils = Me.imports.utils;
|
const Utils = Me.imports.utils;
|
||||||
|
|
||||||
var TwoColorIcon = new Lang.Class({
|
var TwoColorIcon = GObject.registerClass(
|
||||||
Name: 'TwoColorIcon',
|
class TwoColorIcon extends St.DrawingArea {
|
||||||
Extends: St.DrawingArea,
|
_init(size, drawingObject) {
|
||||||
|
super._init({
|
||||||
_init: function (size, drawingObject) {
|
|
||||||
this.parent({
|
|
||||||
reactive: true,
|
reactive: true,
|
||||||
style: 'padding: 0px 2px'
|
style: 'padding: 0px 0px'
|
||||||
});
|
});
|
||||||
this._base_size = size;
|
this._base_size = size;
|
||||||
this.setScaling(Utils.getGlobalDisplayScaleFactor());
|
//this.setScaling(Utils.getGlobalDisplayScaleFactor());
|
||||||
|
|
||||||
this._drawingObject = drawingObject;
|
this._drawingObject = drawingObject;
|
||||||
|
|
||||||
this.connect('repaint', Lang.bind(this, this._drawIcon));
|
this.connect('repaint', function () {
|
||||||
|
this._drawIcon();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
// some fallback color
|
// some fallback color
|
||||||
this._primaryColor = new Clutter.Color({
|
this._primaryColor = new Clutter.Color({
|
||||||
@ -42,27 +42,32 @@ var TwoColorIcon = new Lang.Class({
|
|||||||
});
|
});
|
||||||
this._secundaryColor = this._primaryColor;
|
this._secundaryColor = this._primaryColor;
|
||||||
this._customStatus = null;
|
this._customStatus = null;
|
||||||
},
|
}
|
||||||
setPadding: function (padding) {
|
|
||||||
|
setPadding(padding) {
|
||||||
this.margin_left = padding;
|
this.margin_left = padding;
|
||||||
this.margin_right = padding;
|
this.margin_right = padding;
|
||||||
},
|
}
|
||||||
setColor: function (primary, secundary) {
|
|
||||||
|
setColor(primary, secundary) {
|
||||||
this._primaryColor = primary;
|
this._primaryColor = primary;
|
||||||
this._secundaryColor = secundary;
|
this._secundaryColor = secundary;
|
||||||
this.queue_repaint();
|
this.queue_repaint();
|
||||||
},
|
}
|
||||||
setScaling: function (newScale) {
|
|
||||||
|
setScaling(newScale) {
|
||||||
this._default_scale = newScale;
|
this._default_scale = newScale;
|
||||||
this.set_width(this._base_size * this._default_scale);
|
this.set_width(this._base_size * this._default_scale);
|
||||||
this.set_height(this._base_size * this._default_scale);
|
this.set_height(this._base_size * this._default_scale);
|
||||||
this.queue_repaint();
|
this.queue_repaint();
|
||||||
},
|
}
|
||||||
setStatus: function (newStatus) {
|
|
||||||
|
setStatus(newStatus) {
|
||||||
this._customStatus = newStatus;
|
this._customStatus = newStatus;
|
||||||
this.queue_repaint();
|
this.queue_repaint();
|
||||||
},
|
}
|
||||||
_drawIcon: function () {
|
|
||||||
|
_drawIcon() {
|
||||||
let cr = this.get_context();
|
let cr = this.get_context();
|
||||||
let orWdt = this._drawingObject.width;
|
let orWdt = this._drawingObject.width;
|
||||||
let orHgt = this._drawingObject.height;
|
let orHgt = this._drawingObject.height;
|
||||||
@ -77,19 +82,22 @@ var TwoColorIcon = new Lang.Class({
|
|||||||
let padding_y = (height - orHgt * scaling) * 0.5;
|
let padding_y = (height - orHgt * scaling) * 0.5;
|
||||||
|
|
||||||
cr.translate(padding_x, padding_y);
|
cr.translate(padding_x, padding_y);
|
||||||
|
try {
|
||||||
cr.scale(scaling, scaling);
|
cr.scale(scaling, scaling);
|
||||||
|
|
||||||
this._drawingObject.draw(cr, this._customStatus, this._primaryColor, this._secundaryColor);
|
this._drawingObject.draw(cr, this._customStatus, this._primaryColor, this._secundaryColor);
|
||||||
|
|
||||||
cr.restore();
|
cr.restore();
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var TeaPot = {
|
var TeaPot = {
|
||||||
width: 484,
|
width: 484,
|
||||||
height: 295,
|
height: 295,
|
||||||
draw: function (cr, stat, primary, secundary) {
|
draw(cr, stat, primary, secundary) {
|
||||||
// draw TeaPot
|
// draw TeaPot
|
||||||
// cairo commands generated from svg2cairo
|
// cairo commands generated from svg2cairo
|
||||||
// https://github.com/akrinke/svg2cairo
|
// https://github.com/akrinke/svg2cairo
|
||||||
@ -133,7 +141,7 @@ var TeaPot = {
|
|||||||
var Pie = {
|
var Pie = {
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
draw: function (cr, stat, primary, secundary) {
|
draw(cr, stat, primary, secundary) {
|
||||||
const pi = Math.PI;
|
const pi = Math.PI;
|
||||||
const r = 0.5;
|
const r = 0.5;
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
{"shell-version": ["3.4", "3.6", "3.8", "3.10", "3.12", "3.14", "3.16", "3.18", "3.20", "3.22", "3.24", "3.26"], "uuid": "TeaTime@oleid.mescharet.de", "name": "TeaTime", "settings-schema": "org.gnome.shell.extensions.teatime", "gettext-domain": "TeaTime", "description": "A tea steeping timer"}
|
{"shell-version": ["3.32"], "uuid": "TeaTime@oleid.mescharet.de", "name": "TeaTime", "settings-schema": "org.gnome.shell.extensions.teatime", "gettext-domain": "TeaTime", "description": "A tea steeping timer"}
|
||||||
|
108
src/prefs.js
@ -3,7 +3,6 @@
|
|||||||
Thomas Liebetraut <thomas@tommie-lie.de>
|
Thomas Liebetraut <thomas@tommie-lie.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
|
|
||||||
@ -23,12 +22,10 @@ const Columns = {
|
|||||||
ADJUSTMENT: 2
|
ADJUSTMENT: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
const TeaTimePrefsWidget = new Lang.Class({
|
var TeaTimePrefsWidget = GObject.registerClass(
|
||||||
Name: 'TeaTimePrefsWidget',
|
class TeaTimePrefsWidget extends Gtk.Grid {
|
||||||
Extends: Gtk.Grid,
|
_init() {
|
||||||
|
super._init({
|
||||||
_init: function () {
|
|
||||||
this.parent({
|
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
column_homogeneous: false,
|
column_homogeneous: false,
|
||||||
vexpand: true,
|
vexpand: true,
|
||||||
@ -36,6 +33,8 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
row_spacing: 5
|
row_spacing: 5
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.config_keys = Utils.GetConfigKeys();
|
||||||
|
|
||||||
this._tealist = new Gtk.ListStore();
|
this._tealist = new Gtk.ListStore();
|
||||||
this._tealist.set_column_types([
|
this._tealist.set_column_types([
|
||||||
GObject.TYPE_STRING,
|
GObject.TYPE_STRING,
|
||||||
@ -47,21 +46,17 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
|
|
||||||
this._settings = Utils.getSettings();
|
this._settings = Utils.getSettings();
|
||||||
this._inhibitUpdate = true;
|
this._inhibitUpdate = true;
|
||||||
this._settings.connect("changed", Lang.bind(this, this._refresh));
|
this._settings.connect("changed", this._refresh.bind(this));
|
||||||
|
|
||||||
this._initWindow();
|
this._initWindow();
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
this._refresh();
|
this._refresh();
|
||||||
this._tealist.connect("row-changed", Lang.bind(this, this._save));
|
this._tealist.connect("row-changed", this._save.bind(this));
|
||||||
this._tealist.connect("row-deleted", Lang.bind(this, this._save));
|
this._tealist.connect("row-deleted", this._save.bind(this));
|
||||||
},
|
}
|
||||||
_initWindow: function () {
|
|
||||||
|
_initWindow() {
|
||||||
let curRow = 0;
|
let curRow = 0;
|
||||||
let labelFN = new Gtk.Label({
|
|
||||||
label: _("Fullscreen Notifications"),
|
|
||||||
hexpand: true,
|
|
||||||
halign: Gtk.Align.START
|
|
||||||
});
|
|
||||||
let labelGC = new Gtk.Label({
|
let labelGC = new Gtk.Label({
|
||||||
label: _("Graphical Countdown"),
|
label: _("Graphical Countdown"),
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
@ -74,15 +69,12 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
halign: Gtk.Align.START
|
halign: Gtk.Align.START
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fullscreenNotificationSwitch = new Gtk.Switch();
|
|
||||||
this.fullscreenNotificationSwitch.connect("notify::active", Lang.bind(this, this._saveFullscreenNotifications));
|
|
||||||
|
|
||||||
this.graphicalCountdownSwitch = new Gtk.Switch();
|
this.graphicalCountdownSwitch = new Gtk.Switch();
|
||||||
this.graphicalCountdownSwitch.connect("notify::active", Lang.bind(this, this._saveGraphicalCountdown));
|
this.graphicalCountdownSwitch.connect("notify::active", this._saveGraphicalCountdown.bind(this));
|
||||||
|
|
||||||
// alarm sound file chooser
|
// alarm sound file chooser
|
||||||
this.alarmSoundSwitch = new Gtk.Switch();
|
this.alarmSoundSwitch = new Gtk.Switch();
|
||||||
this.alarmSoundSwitch.connect("notify::active", Lang.bind(this, this._saveUseAlarm));
|
this.alarmSoundSwitch.connect("notify::active", this._saveUseAlarm.bind(this));
|
||||||
|
|
||||||
|
|
||||||
this.alarmSoundFile = new Gtk.FileChooserButton({
|
this.alarmSoundFile = new Gtk.FileChooserButton({
|
||||||
@ -92,15 +84,7 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this.alarmSoundFileFilter = new Gtk.FileFilter();
|
this.alarmSoundFileFilter = new Gtk.FileFilter();
|
||||||
this.alarmSoundFile.set_filter(this.alarmSoundFileFilter);
|
this.alarmSoundFile.set_filter(this.alarmSoundFileFilter);
|
||||||
this.alarmSoundFileFilter.add_mime_type("audio/*");
|
this.alarmSoundFileFilter.add_mime_type("audio/*");
|
||||||
this.alarmSoundFile.connect("selection_changed", Lang.bind(this, this._saveSoundFile));
|
this.alarmSoundFile.connect("selection_changed", this._saveSoundFile.bind(this));
|
||||||
|
|
||||||
|
|
||||||
if (!Utils.isGnome34()) {
|
|
||||||
// Full screen notifications currently not working on GNOME 3.4, thus don't show the switch
|
|
||||||
this.attach(labelFN, 0 /*col*/ , curRow /*row*/ , 2 /*col span*/ , 1 /*row span*/ );
|
|
||||||
this.attach(this.fullscreenNotificationSwitch, 2, curRow, 1, 1);
|
|
||||||
curRow += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.attach(labelGC, 0 /*col*/ , curRow /*row*/ , 2 /*col span*/ , 1 /*row span*/ );
|
this.attach(labelGC, 0 /*col*/ , curRow /*row*/ , 2 /*col span*/ , 1 /*row span*/ );
|
||||||
this.attach(this.graphicalCountdownSwitch, 2, curRow, 1, 1);
|
this.attach(this.graphicalCountdownSwitch, 2, curRow, 1, 1);
|
||||||
@ -132,10 +116,10 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
// This makes life a little harder due to chaining of callbacks
|
// This makes life a little harder due to chaining of callbacks
|
||||||
// and the need for this._inhibitUpdate, but it feels a lot cleaner
|
// and the need for this._inhibitUpdate, but it feels a lot cleaner
|
||||||
// when the UI does not know about the config storage backend.
|
// when the UI does not know about the config storage backend.
|
||||||
renderer.connect("edited", Lang.bind(this, function (renderer, pathString, newValue) {
|
renderer.connect("edited", function (renderer, pathString, newValue) {
|
||||||
let [store, iter] = this._tealist.get_iter(Gtk.TreePath.new_from_string(pathString));
|
let [store, iter] = this._tealist.get_iter(Gtk.TreePath.new_from_string(pathString));
|
||||||
this._tealist.set(iter, [Columns.TEA_NAME], [newValue]);
|
this._tealist.set(iter, [Columns.TEA_NAME], [newValue]);
|
||||||
}));
|
}.bind(this));
|
||||||
teaname.pack_start(renderer, true);
|
teaname.pack_start(renderer, true);
|
||||||
teaname.add_attribute(renderer, "text", Columns.TEA_NAME);
|
teaname.add_attribute(renderer, "text", Columns.TEA_NAME);
|
||||||
this.treeview.append_column(teaname);
|
this.treeview.append_column(teaname);
|
||||||
@ -148,10 +132,10 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
editable: true
|
editable: true
|
||||||
});
|
});
|
||||||
// See comment above.
|
// See comment above.
|
||||||
spinrenderer.connect("edited", Lang.bind(this, function (renderer, pathString, newValue) {
|
spinrenderer.connect("edited", function (renderer, pathString, newValue) {
|
||||||
let [store, iter] = this._tealist.get_iter(Gtk.TreePath.new_from_string(pathString));
|
let [store, iter] = this._tealist.get_iter(Gtk.TreePath.new_from_string(pathString));
|
||||||
this._tealist.set(iter, [Columns.STEEP_TIME], [parseInt(newValue)]);
|
this._tealist.set(iter, [Columns.STEEP_TIME], [parseInt(newValue)]);
|
||||||
}));
|
}.bind(this));
|
||||||
|
|
||||||
steeptime.pack_start(spinrenderer, true);
|
steeptime.pack_start(spinrenderer, true);
|
||||||
steeptime.add_attribute(spinrenderer, "adjustment", Columns.ADJUSTMENT);
|
steeptime.add_attribute(spinrenderer, "adjustment", Columns.ADJUSTMENT);
|
||||||
@ -168,22 +152,21 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
icon_name: "list-add-symbolic",
|
icon_name: "list-add-symbolic",
|
||||||
use_action_appearance: false
|
use_action_appearance: false
|
||||||
});
|
});
|
||||||
this.addButton.connect("clicked", Lang.bind(this, this._addTea));
|
this.addButton.connect("clicked", this._addTea.bind(this));
|
||||||
this.toolbar.insert(this.addButton, -1);
|
this.toolbar.insert(this.addButton, -1);
|
||||||
this.removeButton = new Gtk.ToolButton({
|
this.removeButton = new Gtk.ToolButton({
|
||||||
icon_name: "list-remove-symbolic",
|
icon_name: "list-remove-symbolic",
|
||||||
use_action_appearance: false
|
use_action_appearance: false
|
||||||
});
|
});
|
||||||
this.removeButton.connect("clicked", Lang.bind(this, this._removeSelectedTea));
|
this.removeButton.connect("clicked", this._removeSelectedTea.bind(this));
|
||||||
this.toolbar.insert(this.removeButton, -1);
|
this.toolbar.insert(this.removeButton, -1);
|
||||||
},
|
}
|
||||||
_refresh: function () {
|
|
||||||
|
_refresh() {
|
||||||
// don't update the model if someone else is messing with the backend
|
// don't update the model if someone else is messing with the backend
|
||||||
if (this._inhibitUpdate)
|
if (this._inhibitUpdate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.fullscreenNotificationSwitch.active = this._settings.get_boolean(this.config_keys.fullscreen_notification)
|
|
||||||
|
|
||||||
this.graphicalCountdownSwitch.active = this._settings.get_boolean(this.config_keys.graphical_countdown)
|
this.graphicalCountdownSwitch.active = this._settings.get_boolean(this.config_keys.graphical_countdown)
|
||||||
this.alarmSoundSwitch.active = this._settings.get_boolean(this.config_keys.use_alarm_sound)
|
this.alarmSoundSwitch.active = this._settings.get_boolean(this.config_keys.use_alarm_sound)
|
||||||
let list = this._settings.get_value(this.config_keys.steep_times).unpack();
|
let list = this._settings.get_value(this.config_keys.steep_times).unpack();
|
||||||
@ -208,8 +191,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
},
|
}
|
||||||
_addTea: function () {
|
|
||||||
|
_addTea() {
|
||||||
let adj = new Gtk.Adjustment({
|
let adj = new Gtk.Adjustment({
|
||||||
lower: 1,
|
lower: 1,
|
||||||
step_increment: 1,
|
step_increment: 1,
|
||||||
@ -221,8 +205,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this.treeview.set_cursor(this._tealist.get_path(item),
|
this.treeview.set_cursor(this._tealist.get_path(item),
|
||||||
this.treeview.get_column(Columns.TEA_NAME),
|
this.treeview.get_column(Columns.TEA_NAME),
|
||||||
true);
|
true);
|
||||||
},
|
}
|
||||||
_removeSelectedTea: function () {
|
|
||||||
|
_removeSelectedTea() {
|
||||||
let [selection, store] = this.treeview.get_selection().get_selected_rows();
|
let [selection, store] = this.treeview.get_selection().get_selected_rows();
|
||||||
let iters = [];
|
let iters = [];
|
||||||
for (let i = 0; i < selection.length; ++i) {
|
for (let i = 0; i < selection.length; ++i) {
|
||||||
@ -237,17 +222,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.treeview.get_selection().unselect_all();
|
this.treeview.get_selection().unselect_all();
|
||||||
},
|
}
|
||||||
_saveFullscreenNotifications: function (sw, data) {
|
|
||||||
// don't update the backend if someone else is messing with the model
|
_saveGraphicalCountdown(sw, data) {
|
||||||
if (this._inhibitUpdate)
|
|
||||||
return;
|
|
||||||
this._inhibitUpdate = true;
|
|
||||||
this._settings.set_boolean(this.config_keys.fullscreen_notification,
|
|
||||||
sw.active);
|
|
||||||
this._inhibitUpdate = false;
|
|
||||||
},
|
|
||||||
_saveGraphicalCountdown: function (sw, data) {
|
|
||||||
// don't update the backend if someone else is messing with the model
|
// don't update the backend if someone else is messing with the model
|
||||||
if (this._inhibitUpdate)
|
if (this._inhibitUpdate)
|
||||||
return;
|
return;
|
||||||
@ -255,8 +232,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this._settings.set_boolean(this.config_keys.graphical_countdown,
|
this._settings.set_boolean(this.config_keys.graphical_countdown,
|
||||||
sw.active);
|
sw.active);
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
},
|
}
|
||||||
_saveUseAlarm: function (sw, data) {
|
|
||||||
|
_saveUseAlarm(sw, data) {
|
||||||
// don't update the backend if someone else is messing with the model
|
// don't update the backend if someone else is messing with the model
|
||||||
if (this._inhibitUpdate)
|
if (this._inhibitUpdate)
|
||||||
return;
|
return;
|
||||||
@ -264,8 +242,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this._settings.set_boolean(this.config_keys.use_alarm_sound,
|
this._settings.set_boolean(this.config_keys.use_alarm_sound,
|
||||||
sw.active);
|
sw.active);
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
},
|
}
|
||||||
_saveSoundFile: function (sw, data) {
|
|
||||||
|
_saveSoundFile(sw, data) {
|
||||||
// don't update the backend if someone else is messing with the model
|
// don't update the backend if someone else is messing with the model
|
||||||
if (this._inhibitUpdate)
|
if (this._inhibitUpdate)
|
||||||
return;
|
return;
|
||||||
@ -282,8 +261,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this._settings.set_string(this.config_keys.alarm_sound, alarm_sound);
|
this._settings.set_string(this.config_keys.alarm_sound, alarm_sound);
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_save: function (store, path_, iter_) {
|
|
||||||
|
_save(store, path_, iter_) {
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
|
||||||
// don't update the backend if someone else is messing with the model
|
// don't update the backend if someone else is messing with the model
|
||||||
@ -305,11 +285,9 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
this._settings.set_value(this.config_keys.steep_times, settingsValue);
|
this._settings.set_value(this.config_keys.steep_times, settingsValue);
|
||||||
|
|
||||||
this._inhibitUpdate = false;
|
this._inhibitUpdate = false;
|
||||||
},
|
}
|
||||||
config_keys: Utils.GetConfigKeys()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function init() {}
|
function init() {}
|
||||||
|
|
||||||
function buildPrefsWidget() {
|
function buildPrefsWidget() {
|
||||||
|
10
src/utils.js
@ -15,7 +15,6 @@ function debug(text) {
|
|||||||
function GetConfigKeys() {
|
function GetConfigKeys() {
|
||||||
return {
|
return {
|
||||||
steep_times: 'steep-times',
|
steep_times: 'steep-times',
|
||||||
fullscreen_notification: 'fullscreen-notification',
|
|
||||||
graphical_countdown: 'graphical-countdown',
|
graphical_countdown: 'graphical-countdown',
|
||||||
use_alarm_sound: 'use-alarm-sound',
|
use_alarm_sound: 'use-alarm-sound',
|
||||||
alarm_sound: 'alarm-sound-file'
|
alarm_sound: 'alarm-sound-file'
|
||||||
@ -116,7 +115,6 @@ function formatTime(sec_num) {
|
|||||||
|
|
||||||
function playSound(uri) {
|
function playSound(uri) {
|
||||||
const Gst = imports.gi.Gst;
|
const Gst = imports.gi.Gst;
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
debug("Playing " + uri);
|
debug("Playing " + uri);
|
||||||
|
|
||||||
@ -125,7 +123,7 @@ function playSound(uri) {
|
|||||||
this.player = Gst.ElementFactory.make("playbin", "player");
|
this.player = Gst.ElementFactory.make("playbin", "player");
|
||||||
this.playBus = this.player.get_bus();
|
this.playBus = this.player.get_bus();
|
||||||
this.playBus.add_signal_watch();
|
this.playBus.add_signal_watch();
|
||||||
this.playBus.connect("message", Lang.bind(this,
|
this.playBus.connect("message",
|
||||||
function (playBus, message) {
|
function (playBus, message) {
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
// IMPORTANT: to reuse the player, set state to READY
|
// IMPORTANT: to reuse the player, set state to READY
|
||||||
@ -134,7 +132,7 @@ function playSound(uri) {
|
|||||||
this.player.set_state(Gst.State.READY);
|
this.player.set_state(Gst.State.READY);
|
||||||
}
|
}
|
||||||
} // message handler
|
} // message handler
|
||||||
}));
|
}.bind(this));
|
||||||
} // if undefined
|
} // if undefined
|
||||||
this.player.set_property('uri', uri);
|
this.player.set_property('uri', uri);
|
||||||
this.player.set_state(Gst.State.PLAYING);
|
this.player.set_state(Gst.State.PLAYING);
|
||||||
@ -153,7 +151,3 @@ function getGlobalDisplayScaleFactor() {
|
|||||||
function isType(value, typename) {
|
function isType(value, typename) {
|
||||||
return typeof value == typename;
|
return typeof value == typename;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isGnome34() {
|
|
||||||
return imports.misc.extensionUtils.versionCheck(["3.4"], imports.misc.config.PACKAGE_VERSION);
|
|
||||||
}
|
|
||||||
|
@ -7,40 +7,45 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
version="1.0"
|
sodipodi:docname="utilities-teatime.svg"
|
||||||
width="484.0643"
|
inkscape:version="1.0beta2 (unknown)"
|
||||||
height="295.29187"
|
|
||||||
viewBox="0 0 387.25145 236.23349"
|
|
||||||
preserveAspectRatio="xMidYMid meet"
|
|
||||||
id="svg2"
|
id="svg2"
|
||||||
inkscape:version="0.48.4 r9939"
|
preserveAspectRatio="xMidYMid meet"
|
||||||
sodipodi:docname="utilities-teatime.svg">
|
viewBox="0 0 387.25143 387.25143"
|
||||||
|
height="387.25143"
|
||||||
|
width="387.25143"
|
||||||
|
version="1.0">
|
||||||
<defs
|
<defs
|
||||||
id="defs12" />
|
id="defs12" />
|
||||||
<sodipodi:namedview
|
<sodipodi:namedview
|
||||||
pagecolor="#ffffff"
|
viewbox-width="387.25144"
|
||||||
bordercolor="#666666"
|
viewbox-y="-75.50897"
|
||||||
borderopacity="1"
|
viewbox-height="387.25143"
|
||||||
objecttolerance="10"
|
scale-x="1"
|
||||||
gridtolerance="10"
|
inkscape:document-rotation="0"
|
||||||
guidetolerance="10"
|
inkscape:current-layer="g6"
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1027"
|
|
||||||
id="namedview10"
|
|
||||||
showgrid="false"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:zoom="0.26700352"
|
|
||||||
inkscape:cx="1738.6914"
|
|
||||||
inkscape:cy="-58.371397"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="g6" />
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:cy="17.137568"
|
||||||
|
inkscape:cx="1738.6914"
|
||||||
|
inkscape:zoom="0.26700352"
|
||||||
|
fit-margin-bottom="75.50897"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="75.50897"
|
||||||
|
showgrid="false"
|
||||||
|
id="namedview10"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
guidetolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
objecttolerance="10"
|
||||||
|
borderopacity="1"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata4">
|
id="metadata4">
|
||||||
Created by potrace 1.10, written by Peter Selinger 2001-2011
|
Created by potrace 1.10, written by Peter Selinger 2001-2011
|
||||||
@ -50,19 +55,19 @@ Created by potrace 1.10, written by Peter Selinger 2001-2011
|
|||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title />
|
<dc:title></dc:title>
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
<g
|
<g
|
||||||
transform="matrix(0.1,0,0,-0.1,-57.589577,378.57122)"
|
style="fill:#800000;stroke:none"
|
||||||
id="g6"
|
id="g6"
|
||||||
style="fill:#800000;stroke:none">
|
transform="matrix(0.1,0,0,-0.1,-57.589577,454.0802)">
|
||||||
<path
|
<path
|
||||||
style="fill:#cccccc;fill-opacity:0.94117647"
|
sodipodi:nodetypes="ccccccccccccccccccccccc"
|
||||||
d="m 1599.0437,1573.9177 c -235.4892,257.2771 -410.9172,307.0416 -639.52404,523.818 -239.98241,192.756 -444.12233,501.9215 -367.10697,821.8921 38.7852,200.5961 248.27611,336.0011 446.84671,290.8161 140.2785,-17.7787 266.8099,-85.0946 387.0129,-155.5415 74.2781,124.4657 298.1841,153.0228 229.5089,329.9101 109.3355,93.2904 275.201,94.5077 412.7117,124.4857 65.4385,24.6741 304.7317,-9.5508 144.7011,56.4876 -101.917,152.0308 154.8854,242.0949 276.2029,215.2013 221.301,17.1274 185.843,-251.1767 60.175,-252.1853 248.6206,-20.1446 504.4064,-33.9528 739.5175,-123.2683 84.1199,-70.036 -35.4555,-202.8042 111.3126,-240.3189 101.8205,-78.4406 164.8623,-338.5003 310.0326,-157.8318 135.2599,104.6132 214.2352,323.1066 418.3717,295.2474 93.5126,-2.8298 436.4814,5.3717 278.6869,-142.0678 -159.5297,-98.6124 -325.2795,-228.4326 -356.5455,-425.8986 -75.7637,-262.5934 -248.0386,-367.4119 -455.0358,-567.049 -164.5176,-129.6551 -89.2139,-307.7161 -486.3504,-668.5647 -214.1213,-95.3861 -1128.9411,-129.9962 -1510.5178,74.8676 z m -356.907,736.2999 c -39.4266,157.4822 53.2887,327.3731 16.2311,476.437 -97.7858,101.3794 -355.93876,159.0896 -327.80798,-45.542 35.80376,-97.6021 218.31118,-439.8564 311.57688,-430.895 z"
|
|
||||||
id="path8"
|
|
||||||
inkscape:connector-curvature="0"
|
inkscape:connector-curvature="0"
|
||||||
sodipodi:nodetypes="ccccccccccccccccccccccc" />
|
id="path8"
|
||||||
|
d="m 1599.0437,1573.9177 c -235.4892,257.2771 -410.9172,307.0416 -639.52404,523.818 -239.98241,192.756 -444.12233,501.9215 -367.10697,821.8921 38.7852,200.5961 248.27611,336.0011 446.84671,290.8161 140.2785,-17.7787 266.8099,-85.0946 387.0129,-155.5415 74.2781,124.4657 298.1841,153.0228 229.5089,329.9101 109.3355,93.2904 275.201,94.5077 412.7117,124.4857 65.4385,24.6741 304.7317,-9.5508 144.7011,56.4876 -101.917,152.0308 154.8854,242.0949 276.2029,215.2013 221.301,17.1274 185.843,-251.1767 60.175,-252.1853 248.6206,-20.1446 504.4064,-33.9528 739.5175,-123.2683 84.1199,-70.036 -35.4555,-202.8042 111.3126,-240.3189 101.8205,-78.4406 164.8623,-338.5003 310.0326,-157.8318 135.2599,104.6132 214.2352,323.1066 418.3717,295.2474 93.5126,-2.8298 436.4814,5.3717 278.6869,-142.0678 -159.5297,-98.6124 -325.2795,-228.4326 -356.5455,-425.8986 -75.7637,-262.5934 -248.0386,-367.4119 -455.0358,-567.049 -164.5176,-129.6551 -89.2139,-307.7161 -486.3504,-668.5647 -214.1213,-95.3861 -1128.9411,-129.9962 -1510.5178,74.8676 z m -356.907,736.2999 c -39.4266,157.4822 53.2887,327.3731 16.2311,476.437 -97.7858,101.3794 -355.93876,159.0896 -327.80798,-45.542 35.80376,-97.6021 218.31118,-439.8564 311.57688,-430.895 z"
|
||||||
|
style="fill:#cccccc;fill-opacity:0.941176" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.3 KiB |