hg graft commit "Added fullscreen notification (original teatime applet style)"
BIN
src/data/cup00.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/data/cup01.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/data/cup02.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup03.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup04.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup05.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup06.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup07.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup08.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup09.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup10.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup11.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup12.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup13.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup14.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup15.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup16.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup17.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup18.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup19.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup20.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/data/cup21.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup22.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/data/cup23.png
Normal file
After Width: | Height: | Size: 14 KiB |
@ -12,6 +12,8 @@ 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;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Layout = imports.ui.layout;
|
||||||
|
const FileUtils = imports.misc.fileUtils;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
@ -32,6 +34,80 @@ const N_ = function(e) { return e; };
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const TeaTimeFullscreenNotification = new Lang.Class({
|
||||||
|
Name: 'TeaTimeFullscreenNotification',
|
||||||
|
|
||||||
|
_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();
|
||||||
|
this._monitorConstraint = new Layout.MonitorConstraint();
|
||||||
|
this._bin.add_constraint(this._monitorConstraint);
|
||||||
|
Main.uiGroup.add_actor(this._bin);
|
||||||
|
|
||||||
|
// a vertical box layout to hold the texture and
|
||||||
|
// a label underneath it
|
||||||
|
this._layout = new St.BoxLayout({ vertical: true });
|
||||||
|
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;
|
||||||
|
while (info = enumerator.next_file(null)) {
|
||||||
|
let filename = info.get_name();
|
||||||
|
if (filename.match(/^cup.*/)) {
|
||||||
|
this._textureFiles.push(datadir.get_child(filename).get_path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, { 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() {
|
||||||
|
this._monitorConstraint.index = global.screen.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 TeaTime = new Lang.Class({
|
const TeaTime = new Lang.Class({
|
||||||
Name : 'TeaTime',
|
Name : 'TeaTime',
|
||||||
Extends : PanelMenu.Button,
|
Extends : PanelMenu.Button,
|
||||||
@ -116,8 +192,14 @@ const TeaTime = new Lang.Class({
|
|||||||
// count down finished, switch display again
|
// count down finished, switch display again
|
||||||
this.actor.remove_actor(this._timer);
|
this.actor.remove_actor(this._timer);
|
||||||
this.actor.add_actor(this._logo);
|
this.actor.add_actor(this._logo);
|
||||||
this._showNotification(_("Your tea is ready!"),
|
if (this._settings.get_boolean(Utils.TEATIME_FULLSCREEN_NOTIFICATION_KEY)) {
|
||||||
_("Drink it, while it is hot!"));
|
this.dialog = new TeaTimeFullscreenNotification();
|
||||||
|
this.dialog.show();
|
||||||
|
} else {
|
||||||
|
this._showNotification(_("Your tea is ready!"),
|
||||||
|
_("Drink it, while it is hot!"));
|
||||||
|
}
|
||||||
|
|
||||||
this._idleTimeout = null;
|
this._idleTimeout = null;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
33
src/prefs.js
@ -35,10 +35,14 @@ const Columns = {
|
|||||||
|
|
||||||
const TeaTimePrefsWidget = new Lang.Class({
|
const TeaTimePrefsWidget = new Lang.Class({
|
||||||
Name : 'TeaTimePrefsWidget',
|
Name : 'TeaTimePrefsWidget',
|
||||||
Extends : Gtk.Box,
|
Extends : Gtk.Grid,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent({ orientation: Gtk.Orientation.VERTICAL });
|
this.parent({ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
column_homogeneous: false,
|
||||||
|
vexpand: true,
|
||||||
|
margin: 5,
|
||||||
|
row_spacing: 5 });
|
||||||
|
|
||||||
this._tealist = new Gtk.ListStore();
|
this._tealist = new Gtk.ListStore();
|
||||||
this._tealist.set_column_types([
|
this._tealist.set_column_types([
|
||||||
@ -49,20 +53,26 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
|
|
||||||
this._settings = Utils.getSettings();
|
this._settings = Utils.getSettings();
|
||||||
this._inhibitUpdate = true;
|
this._inhibitUpdate = true;
|
||||||
this._settings.connect("changed::" + Utils.TEATIME_STEEP_TIMES_KEY,
|
this._settings.connect("changed", Lang.bind(this, this._refresh));
|
||||||
Lang.bind(this, this._refresh));
|
|
||||||
|
|
||||||
this._initWindow();
|
this._initWindow();
|
||||||
this.vexpand = true;
|
|
||||||
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", Lang.bind(this, this._save));
|
||||||
this._tealist.connect("row-deleted", Lang.bind(this, this._save));
|
this._tealist.connect("row-deleted", Lang.bind(this, this._save));
|
||||||
},
|
},
|
||||||
_initWindow: function() {
|
_initWindow: function() {
|
||||||
|
let label = new Gtk.Label({ label: "Fullscreen Notifications",
|
||||||
|
hexpand: true,
|
||||||
|
halign: Gtk.Align.START });
|
||||||
|
this.attach(label, 0 /*col*/, 0 /*row*/, 1 /*col span*/, 1 /*row span*/);
|
||||||
|
this.fullscreenNotificationSwitch = new Gtk.Switch();
|
||||||
|
this.fullscreenNotificationSwitch.connect("notify::active", Lang.bind(this, this._saveFullscreenNotifications));
|
||||||
|
this.attach(this.fullscreenNotificationSwitch, 1, 0, 1, 1);
|
||||||
|
|
||||||
this.treeview = new Gtk.TreeView({model: this._tealist, expand: true});
|
this.treeview = new Gtk.TreeView({model: this._tealist, expand: true});
|
||||||
this.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE);
|
this.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE);
|
||||||
this.add(this.treeview);
|
this.attach(this.treeview, 0, 1, 2, 1);
|
||||||
|
|
||||||
let teaname = new Gtk.TreeViewColumn({ title: _("Tea"), expand: true });
|
let teaname = new Gtk.TreeViewColumn({ title: _("Tea"), expand: true });
|
||||||
let renderer = new Gtk.CellRendererText({ editable: true });
|
let renderer = new Gtk.CellRendererText({ editable: true });
|
||||||
@ -108,6 +118,8 @@ const TeaTimePrefsWidget = new Lang.Class({
|
|||||||
if (this._inhibitUpdate)
|
if (this._inhibitUpdate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.fullscreenNotificationSwitch.active = this._settings.get_boolean(Utils.TEATIME_FULLSCREEN_NOTIFICATION_KEY)
|
||||||
|
|
||||||
let list = this._settings.get_value(Utils.TEATIME_STEEP_TIMES_KEY).unpack();
|
let list = this._settings.get_value(Utils.TEATIME_STEEP_TIMES_KEY).unpack();
|
||||||
|
|
||||||
// stop everyone from reacting to the changes we are about to produce
|
// stop everyone from reacting to the changes we are about to produce
|
||||||
@ -152,6 +164,15 @@ 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
|
||||||
|
if (this._inhibitUpdate)
|
||||||
|
return;
|
||||||
|
this._inhibitUpdate = true;
|
||||||
|
this._settings.set_boolean(Utils.TEATIME_FULLSCREEN_NOTIFICATION_KEY,
|
||||||
|
sw.active);
|
||||||
|
this._inhibitUpdate = false;
|
||||||
|
},
|
||||||
_save: function(store, path_, iter_) {
|
_save: function(store, path_, iter_) {
|
||||||
// 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)
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
<_summary>Tea drawing times list</_summary>
|
<_summary>Tea drawing times list</_summary>
|
||||||
<_description>A mapping of a teas to their corresponding drawing time in seconds.</_description>
|
<_description>A mapping of a teas to their corresponding drawing time in seconds.</_description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="fullscreen-notification" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Show fullscreen notifications.</summary>
|
||||||
|
<description>Displays a more disrupting, modal fullscreen notification when the timer has elapsed.</description>
|
||||||
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ const Me = ExtensionUtils.getCurrentExtension();
|
|||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
|
|
||||||
const TEATIME_STEEP_TIMES_KEY = 'steep-times';
|
const TEATIME_STEEP_TIMES_KEY = 'steep-times';
|
||||||
|
const TEATIME_FULLSCREEN_NOTIFICATION_KEY = 'fullscreen-notification';
|
||||||
|
|
||||||
function initTranslations(domain) {
|
function initTranslations(domain) {
|
||||||
let extension = ExtensionUtils.getCurrentExtension();
|
let extension = ExtensionUtils.getCurrentExtension();
|
||||||
|