diff --git a/.gitignore b/.gitignore
index 2c34026..dc785e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
*.mo
*~
+*/.project
+*/.settings/
diff --git a/gnome-shell-timer-config.py b/gnome-shell-timer-config.py
index 4d68b77..89fd43d 100755
--- a/gnome-shell-timer-config.py
+++ b/gnome-shell-timer-config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
@@ -26,6 +26,8 @@
"""
+import gi
+gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gio, Gdk, GLib
import os.path
diff --git a/make.sh b/make.sh
index 0711d5a..a486fca 100755
--- a/make.sh
+++ b/make.sh
@@ -1,28 +1,32 @@
#!/bin/bash
install() {
- sudo mkdir -p "/usr/share/gnome-shell/extensions"
- sudo cp -R "timer@olebowle.gmx.com" "/usr/share/gnome-shell/extensions/"
- sudo cp -R "kitchen_timer.ogg" "/usr/share/gnome-shell/extensions/timer@olebowle.gmx.com/"
+ $SUDO mkdir -p "$DEST"
+ $SUDO cp -R "timer@olebowle.gmx.com" "$DEST"
+ $SUDO cp -R "kitchen_timer.ogg" "$DEST/timer@olebowle.gmx.com/"
- sudo mkdir -p "/usr/share/glib-2.0/schemas"
- sudo cp "org.gnome.shell.extensions.timer.gschema.xml" "/usr/share/glib-2.0/schemas/"
- sudo glib-compile-schemas "/usr/share/glib-2.0/schemas"
+ cat org.gnome.shell.extensions.timer.gschema.xml.init | sed "s|__DEST__|${DEST}|" > org.gnome.shell.extensions.timer.gschema.xml
+ $SUDO mkdir -p "$USR_SHARE/glib-2.0/schemas"
+ $SUDO cp "org.gnome.shell.extensions.timer.gschema.xml" "$USR_SHARE/glib-2.0/schemas/"
+ $SUDO glib-compile-schemas "$USR_SHARE/glib-2.0/schemas"
+ #dconf write KEY VALUE
+ #dconf write /org/gnome/shell/extensions/timer/sound-uri "'file:///home/steeve/.local/share/gnome-shell/extensions/timer@olebowle.gmx.com/kitchen_timer.ogg'"
- sudo mkdir -p "/usr/share/icons/hicolor/scalable/apps"
- sudo cp "utilities-timer-symbolic.svg" "/usr/share/icons/hicolor/scalable/apps/"
- sudo cp "gnome-shell-timer-config.svg" "/usr/share/icons/hicolor/scalable/apps/"
- sudo gtk-update-icon-cache -q -t -f "/usr/share/icons/hicolor"
+ $SUDO mkdir -p "$USR_SHARE/icons/hicolor/scalable/apps"
+ $SUDO cp "utilities-timer-symbolic.svg" "$USR_SHARE/icons/hicolor/scalable/apps/"
+ $SUDO cp "gnome-shell-timer-config.svg" "$USR_SHARE/icons/hicolor/scalable/apps/"
+ $SUDO gtk-update-icon-cache -q -t -f "$USR_SHARE/icons/hicolor"
- sudo mkdir -p "/usr/bin"
- sudo cp "gnome-shell-timer-config.py" "/usr/bin/gnome-shell-timer-config"
- sudo mkdir -p "/usr/share/applications"
- sudo cp "gnome-shell-timer-config.desktop" "/usr/share/applications/"
+ $SUDO mkdir -p "/usr/bin"
+ $SUDO cp "gnome-shell-timer-config.py" "$DEST/timer@olebowle.gmx.com/gnome-shell-timer-config"
+ $SUDO mkdir -p "$USR_SHARE/applications"
+ $SUDO cp "gnome-shell-timer-config.desktop" "$USR_SHARE/applications/"
+ dconf write /org/gnome/shell/extensions/timer/timer-config "'""$DEST/timer@olebowle.gmx.com/gnome-shell-timer-config""'"
for lang in `locale -a | grep -o '^[[:alpha:]]\+_[[:alpha:]]\+'`; do
if [ -d "po/$lang" ]; then
- sudo mkdir -p "/usr/share/locale/$lang/LC_MESSAGES"
- sudo msgfmt -cv -o "/usr/share/locale/$lang/LC_MESSAGES/gnome-shell-timer.mo" "po/$lang/gnome-shell-timer.po"
+ $SUDO mkdir -p "$USR_SHARE/locale/$lang/LC_MESSAGES"
+ $SUDO msgfmt -cv -o "$USR_SHARE/locale/$lang/LC_MESSAGES/gnome-shell-timer.mo" "po/$lang/gnome-shell-timer.po"
fi
done
echo "timer-extension successfully installed"
@@ -30,35 +34,45 @@ install() {
}
uninstall() {
- sudo rm -R "/usr/share/gnome-shell/extensions/timer@olebowle.gmx.com"
- sudo rm "/usr/share/glib-2.0/schemas/org.gnome.shell.extensions.timer.gschema.xml"
- sudo glib-compile-schemas "/usr/share/glib-2.0/schemas"
+ $SUDO rm -R "$DEST/timer@olebowle.gmx.com"
+ $SUDO rm "$USR_SHARE/glib-2.0/schemas/org.gnome.shell.extensions.timer.gschema.xml"
+ $SUDO glib-compile-schemas "$USR_SHARE/glib-2.0/schemas"
dconf reset -f /org/gnome/shell/extensions/timer/
- sudo rm "/usr/share/icons/hicolor/scalable/apps/utilities-timer-symbolic.svg"
- sudo rm "/usr/share/icons/hicolor/scalable/apps/gnome-shell-timer-config.svg"
- sudo gtk-update-icon-cache -q -t -f "/usr/share/icons/hicolor"
+ $SUDO rm "$USR_SHARE/icons/hicolor/scalable/apps/utilities-timer-symbolic.svg"
+ $SUDO rm "$USR_SHARE/icons/hicolor/scalable/apps/gnome-shell-timer-config.svg"
+ $SUDO gtk-update-icon-cache -q -t -f "$USR_SHARE/icons/hicolor"
- sudo rm "/usr/bin/gnome-shell-timer-config"
- sudo rm "/usr/share/applications/gnome-shell-timer-config.desktop"
+ $SUDO rm "$USR_SHARE/timer@olebowle.gmx.com/gnome-shell-timer-config"
+ $SUDO rm "$USR_SHARE/applications/gnome-shell-timer-config.desktop"
- sudo find "/usr/share/locale/" -type f -name "gnome-shell-timer.mo" -exec rm {} \;
+ $SUDO find "$USR_SHARE/locale/" -type f -name "gnome-shell-timer.mo" -exec rm {} \;
echo "timer-extension successfully uninstalled"
echo "Press Alt+F2 and type 'r' to refresh"
}
-if [ $# -ne "1" ] || [ $1 = "help" ]; then
+if [ $# -lt 1 -o $# -gt 2 ] || [ $1 = "help" ]; then
echo "Usage:"
- echo " $0 install - Install timer-extension"
- echo " $0 uninstall - Uninstall timer-extension"
+ echo " $0 install [local] - Install timer-extension"
+ echo " $0 uninstall [local] - Uninstall timer-extension"
echo " $0 help - Show this help"
exit 0
fi
-if [ $1 = "install" ]; then
+SUDO="sudo"
+if [ "$2" == "local" ]; then
+ USR_SHARE=~/.local/share
+ SUDO=""
+else
+ USR_SHARE=/usr/share
+fi
+
+DEST="$USR_SHARE/gnome-shell/extensions"
+
+if [ $1 == "install" ]; then
install
fi
-if [ $1 = "uninstall" ]; then
+if [ $1 == "uninstall" ]; then
uninstall
fi
diff --git a/org.gnome.shell.extensions.timer.gschema.xml b/org.gnome.shell.extensions.timer.gschema.xml.init
similarity index 85%
rename from org.gnome.shell.extensions.timer.gschema.xml
rename to org.gnome.shell.extensions.timer.gschema.xml.init
index daf48e9..591c1d1 100644
--- a/org.gnome.shell.extensions.timer.gschema.xml
+++ b/org.gnome.shell.extensions.timer.gschema.xml.init
@@ -63,10 +63,15 @@
Loop sound until end of notification
Loop sound until end of notification
-
- "file:///usr/share/gnome-shell/extensions/timer@olebowle.gmx.com/kitchen_timer.ogg"
- Notification sound
- Enter uri for notification sound
-
+
+ "file://__DEST__/timer@olebowle.gmx.com/kitchen_timer.ogg"
+ Notification sound
+ Enter uri for notification sound
+
+
+ "__DEST__/timer@olebowle.gmx.com/gnome-shell-timer-config"
+ Path to timer config script
+ Enter path for timer config script
+
diff --git a/timer@olebowle.gmx.com/extension.js b/timer@olebowle.gmx.com/extension.js
index c53407c..ebe6eaa 100644
--- a/timer@olebowle.gmx.com/extension.js
+++ b/timer@olebowle.gmx.com/extension.js
@@ -9,7 +9,7 @@
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
-//This program is distributed in the hope that it will be useful,
+//This program 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.
@@ -42,9 +42,9 @@ imports.gi.versions.Gst = '1.0';
const Gst = imports.gi.Gst;
function getSettings(schema) {
- if (Gio.Settings.list_schemas().indexOf(schema) == -1)
- throw _("Schema \"%s\" not found.").format(schema);
- return new Gio.Settings({ schema: schema });
+ if (Gio.Settings.list_schemas().indexOf(schema) == -1)
+ throw _("Schema “%s” not found.").format(schema);
+ return new Gio.Settings({ schema: schema });
}
const Indicator = new Lang.Class({
@@ -56,372 +56,420 @@ const Indicator = new Lang.Class({
return gicon;
},
- _init: function() {
+ _init: function() {
this.parent(0.0, "Indicator");
+ // Load settings
+ this._settings = getSettings('org.gnome.shell.extensions.timer');
+ let load_time = Lang.bind(this, function() {
+ this._settings = getSettings('org.gnome.shell.extensions.timer');
+ this._hours = this._settings.get_int('manual-hours');
+ this._minutes = this._settings.get_int('manual-minutes');
+ this._seconds = this._settings.get_int('manual-seconds');
+ this._time = this._hours*3600 + this._minutes*60 + this._seconds;
+ });
+
+ let load_settings = Lang.bind(this, function() {
+ this._settings = getSettings('org.gnome.shell.extensions.timer');
+ this._showNotifications = this._settings.get_boolean('ui-notification');
+ this._showPersistentNotifications = this._settings.get_boolean('ui-persistent');
+ this._showElapsed = this._settings.get_boolean('ui-elapsed');
+ this._timer.visible = this._settings.get_boolean('ui-time');
+ this._pie.visible= this._settings.get_boolean('ui-chart');
+ this._darkColor = this._settings.get_string('ui-dark-color');
+ this._lightColor = this._settings.get_string('ui-light-color');
+ this._presets = this._settings.get_value('presets').deep_unpack();
+ this._sound_uri = this._settings.get_string('sound-uri');
+ this._sound_enable = this._settings.get_boolean('sound-enable');
+ this._sound_loop = this._settings.get_boolean('sound-loop');
+ this._timer_config = this._settings.get_string('timer-config');
+ });
+
+ // Watch settings for changes
+ this._settings.connect('changed::manual-hours', load_time);
+ this._settings.connect('changed::manual-minutes', load_time);
+ this._settings.connect('changed::manual-seconds', load_time);
+ this._settings.connect('changed::ui-notification', load_settings);
+ this._settings.connect('changed::ui-persistent', load_settings);
+ this._settings.connect('changed::ui-elapsed', load_settings);
+ this._settings.connect('changed::ui-time', load_settings);
+ this._settings.connect('changed::ui-chart', load_settings);
+ this._settings.connect('changed::ui-dark-color', load_settings);
+ this._settings.connect('changed::ui-light-color', load_settings);
+ this._settings.connect('changed::presets', load_settings);
+ this._settings.connect('changed::sound-uri', load_settings);
+ this._settings.connect('changed::sound-enable', load_settings);
+ this._settings.connect('changed::sound-loop', load_settings);
+
+ // Set Box
+ this._box = new St.BoxLayout({ name: 'panelStatusMenu' });
+
+ // Set Pie
+ this._pie = new St.DrawingArea({
+ y_align: Clutter.ActorAlign.CENTER,
+ y_expand: true
+ });
+
+ this._pie.set_width(30);
+ this._pie.set_height(25);
+ this._pie.connect('repaint', Lang.bind(this, this._draw));
+ this._box.add(this._pie);
+
+ // Set default menu
+ this._timer = new St.Label({
+ y_align: Clutter.ActorAlign.CENTER,
+ y_expand: true
+ });
+ //{
+ //y_align: St.Align.MIDDLE
+ //,y_expand: false
+ //});
+ this._box.add(this._timer);
+
+ this._timeSpent = 0;
+ this._stopTimer = true;
+ this._issuer = 'setTimer';
+ load_time();
+ load_settings();
+ // Set Logo
+ this._logo = new St.Icon({
+ icon_name: 'utilities-timer-symbolic',
+ style_class: 'system-status-icon'
+ });
+ this.add_actor(this._logo);
+
+ //this.menu.connect('open-state-changed', this._onOpenStateChanged.bind(this));
+ this.menu.connect('open-state-changed', Lang.bind(this, function() {
+ if (this.menu.isOpen) {
+ //log("Open state changed: this.menu");
+ this._presets = this._settings.get_value('presets').deep_unpack();
+ this._buildPresetsSection();
+ }
+ }));
+
+ this._presetsSection = new PopupMenu.PopupMenuSection();
+
+ this._buildPresetsSection();
+ this._buildPopupMenu();
+
+ // Create persistent message modal dialog
+ this._persistentMessageDialog = new ModalDialog.ModalDialog();
+ this._persistentMessageLabel = new St.Label({
+ style_class: 'persistent-message-label',
+ text: _("Timer finished!"),
+ x_expand: true,
+ y_expand: true
+ });
+ this._persistentMessageDialog.contentLayout.add(this._persistentMessageLabel);
+ this._persistentMessageDialog.setButtons([{ label: _("Close"),
+ action: Lang.bind(this, function(param) { this._persistentMessageDialog.close(); }),
+ key: Clutter.Escape
+ }]);
+ // Start the timer
+ this._refreshTimer();
+ },
+
+ _buildPresetsSection: function() {
+ this._presetsSection.removeAll();
+
+ // sort presets and process them in order
+ var presets_sorted = [];
+ for (var ke in this._presets) {
+ var val = this._presets[ke];
+ //log("ke="+ke+" time="+val);
+ presets_sorted.push([ke, val]);
+ }
+
+ presets_sorted.sort(function(a, b) {
+ return a[1] - b[1];
+ });
+
+ presets_sorted.forEach(Lang.bind(this, function(entry){
+ let key = entry[0];
+ let val = entry[1];
+ //log("ke="+ke+" time="+val);
+ let item = new PopupMenu.PopupMenuItem(_(key));
+ let label = new St.Label();
+ this._formatLabel(label, val);
+ let bin = new St.Bin({
+ x_expand: true,
+ x_align: St.Align.END
+ });
+ bin.child = label;
+ item.add(bin); //, { x_expand: true, x_align: St.Align.END });
+ item.connect('activate', Lang.bind(this, function() {
+ this._time = val;
+ this._issuer = key;
+ this._restartTimer();
+ }));
+ this._presetsSection.addMenuItem(item);
+ }));
+ },
+
+ _buildPopupMenu: function() {
+ // Toggle timer state button
+ this._widget = new PopupMenu.PopupSwitchMenuItem(_("Run Timer"), false);
+ this._widget.connect("toggled", Lang.bind(this, function() {
+ this._stopTimer = !(this._stopTimer);
+ this.remove_actor(this._logo);
+ this.add_actor(this._box);
+ this._refreshTimer();
+ }));
+ this.menu.addMenuItem(this._widget);
+ // Reset Timer Menu
+ let item = new PopupMenu.PopupMenuItem(_("Reset Timer"));
+ item.connect('activate', Lang.bind(this, this._resetTimer));
+ this.menu.addMenuItem(item);
+ // Restart Timer Menu
+ item = new PopupMenu.PopupMenuItem(_("Restart Timer"));
+ item.connect('activate', Lang.bind(this, function() {
+ this._timeSpent = 0;
+ this._restartTimer();
+ }));
+ this.menu.addMenuItem(item);
+
+ // Separator
+ this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+
+ // presets menu section
+ this.menu.addMenuItem(this._presetsSection);
+ // Separator only if there are presets
+ if (this._presetsSection.numMenuItems > 0) {
+ this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ }
+
+ // Set Timer SubMenu
+ this._timerMenu = new PopupMenu.PopupSubMenuMenuItem(_("Set Timer"));
+ this._buildTimerMenu();
+ this.menu.addMenuItem(this._timerMenu);
+ item = new PopupMenu.PopupMenuItem(_("Preferences…"));
+ item.connect('activate', Lang.bind(this, function () {
+ // log("timer-config="+this._timer_config);
+ Util.spawn( [ this._timer_config ] );
+ }));
+ this.menu.addMenuItem(item);
+ },
+
+ // Add sliders SubMenu to manually set the timer
+ _buildTimerMenu: function() {
+ // Hours
+ let item = new PopupMenu.PopupMenuItem(_("Hours"), { reactive: false });
+ this._hoursLabel = new St.Label({ text: this._hours.toString() + "h" });
+ let bin = new St.Bin({ x_expand: true, x_align: St.Align.END });
+ bin.child = this._hoursLabel;
+ item.add(bin);
+ this._timerMenu.menu.addMenuItem(item);
+ item = new PopupMenu.PopupBaseMenuItem({ activate: false });
+ this._hoursSlider = new Slider.Slider(0, {x_expand: true, y_expand:true});
+ this._hoursSlider._value = this._hours / 23;
+ this._hoursSlider.connect('notify::value', Lang.bind(this, function() {
+ this._hours = Math.ceil(this._hoursSlider._value*23);
+ this._hoursLabel.set_text(this._hours.toString() + "h");
+ this._time = this._hours*3600 + this._minutes*60 + this._seconds;
+ this._issuer = 'setTimer';
+ } ));
+ item.add(this._hoursSlider);
+ this._timerMenu.menu.addMenuItem(item);
+ // Minutes
+ item = new PopupMenu.PopupMenuItem(_("Minutes"), { reactive: false });
+ this._minutesLabel = new St.Label({ text: this._minutes.toString() + "m" });
+ bin = new St.Bin({ x_expand: true, x_align: St.Align.END });
+ bin.child = this._minutesLabel;
+ item.add(bin);
+ this._timerMenu.menu.addMenuItem(item);
+ item = new PopupMenu.PopupBaseMenuItem({ activate: false });
+ this._minutesSlider = new Slider.Slider(0, { x_expand: true });
+ this._minutesSlider._value = this._minutes / 59;
+ this._minutesSlider.connect('notify::value', Lang.bind(this, function() {
+ this._minutes = Math.ceil(this._minutesSlider._value*59);
+ this._minutesLabel.set_text(this._minutes.toString() + "m");
+ this._time = this._hours*3600 + this._minutes*60 + this._seconds;
+ this._issuer = 'setTimer';
+ } ));
+ item.add(this._minutesSlider);
+ this._timerMenu.menu.addMenuItem(item);
+ // Seconds
+ item = new PopupMenu.PopupMenuItem(_("Seconds"), { reactive: false });
+ this._secondsLabel = new St.Label({ text: this._seconds.toString() + "s" });
+ bin = new St.Bin({ x_expand: true, x_align: St.Align.END });
+ bin.child = this._secondsLabel;
+ item.add(bin);
+ this._timerMenu.menu.addMenuItem(item);
+ item = new PopupMenu.PopupBaseMenuItem({ activate: false });
+ this._secondsSlider = new Slider.Slider(0, { expand: true });
+ this._secondsSlider._value = this._seconds / 59;
+ this._secondsSlider.connect('notify::value', Lang.bind(this, function() {
+ this._seconds = Math.ceil(this._secondsSlider._value*59);
+ this._secondsLabel.set_text(this._seconds.toString() + "s");
+ this._time = this._hours*3600 + this._minutes*60 + this._seconds;
+ this._issuer = 'setTimer';
+ } ));
+ item.add(this._secondsSlider);
+ this._timerMenu.menu.addMenuItem(item);
+ },
+
+ // Draw Pie
+ _draw: function() {
+ let [width, height] = this._pie.get_surface_size();
+ let cr = this._pie.get_context();
+ let xc = width / 2;
+ let yc = height / 2;
+ let pi = Math.PI;
+ function arc(r, value, max, angle, lightColor, darkColor) {
+ if(max == 0) return;
+ let res;
+ let light;
+ let dark;
+ [res, light] = Clutter.Color.from_string(lightColor);
+ [res, dark] = Clutter.Color.from_string(darkColor);
+ Clutter.cairo_set_source_color(cr, light);
+ cr.arc(xc, yc, r, 0, 2*pi);
+ cr.fill();
+ Clutter.cairo_set_source_color(cr, dark);
+ let new_angle = angle + (value * 2 * pi / max);
+ cr.setLineWidth(1.3);
+ cr.arc(xc, yc, r, angle, new_angle);
+ cr.lineTo(xc,yc);
+ cr.closePath();
+ cr.fill();
+ }
+ /*
+ * let background = new Clutter.Color();
+ * background.from_string('#0000ffff');
+ * Clutter.cairo_set_source_color(cr, background); cr.rectangle(0, 0,
+ * width, height); cr.fill();
+ */
+ arc(8,this._timeSpent,this._time,-pi/2, this._lightColor, this._darkColor);
+ },
- // Load settings
- this._settings = getSettings('org.gnome.shell.extensions.timer');
-
- let load_time = Lang.bind(this, function() {
- this._hours = this._settings.get_int('manual-hours');
- this._minutes = this._settings.get_int('manual-minutes');
- this._seconds = this._settings.get_int('manual-seconds');
- this._time = this._hours*3600 + this._minutes*60 + this._seconds;
- });
-
- let load_settings = Lang.bind(this, function() {
- this._showNotifications = this._settings.get_boolean('ui-notification');
- this._showPersistentNotifications = this._settings.get_boolean('ui-persistent');
- this._showElapsed = this._settings.get_boolean('ui-elapsed');
- this._timer.visible = this._settings.get_boolean('ui-time');
- this._pie.visible= this._settings.get_boolean('ui-chart');
- this._darkColor = this._settings.get_string('ui-dark-color');
- this._lightColor = this._settings.get_string('ui-light-color');
- this._presets = this._settings.get_value('presets').deep_unpack();
- this._soundUri = this._settings.get_string('sound-uri');
- this._sound_enable = this._settings.get_boolean('sound-enable');
- this._sound_loop = this._settings.get_boolean('sound-loop');
- });
-
- // Watch settings for changes
- this._settings.connect('changed::manual-hours', load_time);
- this._settings.connect('changed::manual-minutes', load_time);
- this._settings.connect('changed::manual-seconds', load_time);
- this._settings.connect('changed::ui-notification', load_settings);
- this._settings.connect('changed::ui-persistent', load_settings);
- this._settings.connect('changed::ui-elapsed', load_settings);
- this._settings.connect('changed::ui-time', load_settings);
- this._settings.connect('changed::ui-chart', load_settings);
- this._settings.connect('changed::ui-dark-color', load_settings);
- this._settings.connect('changed::ui-light-color', load_settings);
- this._settings.connect('changed::presets', load_settings);
- this._settings.connect('changed::sound-uri', load_settings);
- this._settings.connect('changed::sound-enable', load_settings);
- this._settings.connect('changed::sound-loop', load_settings);
-
- //Set Box
- this._box = new St.BoxLayout({ name: 'panelStatusMenu' });
-
- //Set Pie
- this._pie = new St.DrawingArea({ reactive: false});
- this._pie.set_width(30);
- this._pie.set_height(25);
- this._pie.connect('repaint', Lang.bind(this, this._draw));
- this._box.add(this._pie, { y_align: St.Align.MIDDLE, y_fill: false });
- //Set default menu
- this._timer = new St.Label();
- this._box.add(this._timer, { y_align: St.Align.MIDDLE, y_fill: false });
-
- this._timeSpent = 0;
- this._stopTimer = true;
- this._issuer = 'setTimer';
- load_time();
- load_settings();
-
- //Set Logo
- this._logo = new St.Icon({ icon_name: 'utilities-timer-symbolic',
- style_class: 'system-status-icon'});
- this.actor.add_actor(this._logo);
-
- //Toggle timer state button
- this._widget = new PopupMenu.PopupSwitchMenuItem(_("Run Timer"), false);
- this._widget.connect("toggled", Lang.bind(this, function() {
- this._stopTimer = !(this._stopTimer);
- this.actor.remove_actor(this._logo);
- this.actor.add_actor(this._box);
- this._refreshTimer();
- }));
- this.menu.addMenuItem(this._widget);
-
- //Reset Timer Menu
- let item = new PopupMenu.PopupMenuItem(_("Reset Timer"));
- item.connect('activate', Lang.bind(this, this._resetTimer));
- this.menu.addMenuItem(item);
-
- //Restart Timer Menu
- item = new PopupMenu.PopupMenuItem(_("Restart Timer"));
- item.connect('activate', Lang.bind(this, function() {
- this._timeSpent = 0;
- this._restartTimer();
- }));
- this.menu.addMenuItem(item);
-
- //Separator
- this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-
- for (let ke in this._presets) {
- //introduce a new variable see:
- //https://mail.gnome.org/archives/gnome-shell-list/2011-August/msg00105.html
- let key = ke;
- let item = new PopupMenu.PopupMenuItem(_(key));
- let label = new St.Label();
- this._formatLabel(label, this._presets[key]);
- let bin = new St.Bin({ x_align: St.Align.END });
- bin.child = label;
-
- item.actor.add(bin, { expand: true, x_align: St.Align.END });
- item.connect('activate', Lang.bind(this, function() {
- this._time = this._presets[key];
- this._issuer = key;
- this._restartTimer();
- }));
- this.menu.addMenuItem(item);
- }
-
- //Separator only if there are presets
- for (let key in this._presets) {
- this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
- break;
- }
-
- //Set Timer SubMenu
- this._timerMenu = new PopupMenu.PopupSubMenuMenuItem(_("Set Timer"));
- this._buildTimerMenu();
- this.menu.addMenuItem(this._timerMenu);
-
- item = new PopupMenu.PopupMenuItem(_("Preferences..."));
- item.connect('activate', function () {
- Util.spawn(['gnome-shell-timer-config']);
- });
- this.menu.addMenuItem(item);
-
- //Create persistent message modal dialog
- this._persistentMessageDialog = new ModalDialog.ModalDialog();
- this._persistentMessageLabel = new St.Label({ style_class: 'persistent-message-label',
- text: _("Timer finished!") });
- this._persistentMessageDialog.contentLayout.add(this._persistentMessageLabel, { x_fill: true, y_fill: true });
- this._persistentMessageDialog.setButtons([{ label: _("Close"),
- action: Lang.bind(this, function(param) { this._persistentMessageDialog.close(); }),
- key: Clutter.Escape
- }]);
-
- //Start the timer
- this._refreshTimer();
- },
-
- //Add sliders SubMenu to manually set the timer
- _buildTimerMenu: function() {
- //Hours
- let item = new PopupMenu.PopupMenuItem(_("Hours"), { reactive: false });
- this._hoursLabel = new St.Label({ text: this._hours.toString() + "h" });
- let bin = new St.Bin({ x_align: St.Align.END });
- bin.child = this._hoursLabel;
- item.actor.add(bin, { expand: true, x_align: St.Align.END });
- this._timerMenu.menu.addMenuItem(item);
-
- item = new PopupMenu.PopupBaseMenuItem({ activate: false });
- this._hoursSlider = new Slider.Slider(0);
- this._hoursSlider._value = this._hours / 23;
- this._hoursSlider.connect('value-changed', Lang.bind(this, function() {
- this._hours = Math.ceil(this._hoursSlider._value*23);
- this._hoursLabel.set_text(this._hours.toString() + "h");
- this._time = this._hours*3600 + this._minutes*60 + this._seconds;
- this._issuer = 'setTimer';
- } ));
- item.actor.add(this._hoursSlider.actor, { expand: true });
- this._timerMenu.menu.addMenuItem(item);
-
- //Minutes
- item = new PopupMenu.PopupMenuItem(_("Minutes"), { reactive: false });
- this._minutesLabel = new St.Label({ text: this._minutes.toString() + "m" });
- bin = new St.Bin({ x_align: St.Align.END });
- bin.child = this._minutesLabel;
- item.actor.add(bin, { expand: true, x_align: St.Align.END });
- this._timerMenu.menu.addMenuItem(item);
-
- item = new PopupMenu.PopupBaseMenuItem({ activate: false });
- this._minutesSlider = new Slider.Slider(0);
- this._minutesSlider._value = this._minutes / 59;
- this._minutesSlider.connect('value-changed', Lang.bind(this, function() {
- this._minutes = Math.ceil(this._minutesSlider._value*59);
- this._minutesLabel.set_text(this._minutes.toString() + "m");
- this._time = this._hours*3600 + this._minutes*60 + this._seconds;
- this._issuer = 'setTimer';
- } ));
- item.actor.add(this._minutesSlider.actor, { expand: true });
- this._timerMenu.menu.addMenuItem(item);
-
- //Seconds
- item = new PopupMenu.PopupMenuItem(_("Seconds"), { reactive: false });
- this._secondsLabel = new St.Label({ text: this._seconds.toString() + "s" });
- bin = new St.Bin({ x_align: St.Align.END });
- bin.child = this._secondsLabel;
- item.actor.add(bin, { expand: true, x_align: St.Align.END });
- this._timerMenu.menu.addMenuItem(item);
-
- item = new PopupMenu.PopupBaseMenuItem({ activate: false });
- this._secondsSlider = new Slider.Slider(0);
- this._secondsSlider._value = this._seconds / 59;
- this._secondsSlider.connect('value-changed', Lang.bind(this, function() {
- this._seconds = Math.ceil(this._secondsSlider._value*59);
- this._secondsLabel.set_text(this._seconds.toString() + "s");
- this._time = this._hours*3600 + this._minutes*60 + this._seconds;
- this._issuer = 'setTimer';
- } ));
- item.actor.add(this._secondsSlider.actor, { expand: true });
- this._timerMenu.menu.addMenuItem(item);
- },
-
- //Draw Pie
- _draw: function() {
- let [width, height] = this._pie.get_surface_size();
- let cr = this._pie.get_context();
- let xc = width / 2;
- let yc = height / 2;
- let pi = Math.PI;
- function arc(r, value, max, angle, lightColor, darkColor) {
- if(max == 0) return;
- let res;
- let light;
- let dark;
- [res, light] = Clutter.Color.from_string(lightColor);
- [res, dark] = Clutter.Color.from_string(darkColor);
- Clutter.cairo_set_source_color(cr, light);
- cr.arc(xc, yc, r, 0, 2*pi);
- cr.fill();
- Clutter.cairo_set_source_color(cr, dark);
- let new_angle = angle + (value * 2 * pi / max);
- cr.setLineWidth(1.3);
- cr.arc(xc, yc, r, angle, new_angle);
- cr.lineTo(xc,yc);
- cr.closePath();
- cr.fill();
- }
- /*let background = new Clutter.Color();
- background.from_string('#0000ffff');
- Clutter.cairo_set_source_color(cr, background);
- cr.rectangle(0, 0, width, height);
- cr.fill();*/
- arc(8,this._timeSpent,this._time,-pi/2, this._lightColor, this._darkColor);
- },
-
- //Reset all counters and timers
- _restartTimer: function() {
- if(this._stopTimer) {
- this._widget.setToggleState(true);
- this.actor.remove_actor(this._logo);
- this.actor.add_actor(this._box);
- this._stopTimer = false;
- this._refreshTimer();
- }
- },
-
- //Reset all counters and timers
- _resetTimer: function() {
- this._widget.setToggleState(false);
- this.actor.remove_actor(this._box);
- this.actor.add_actor(this._logo);
- this._stopTimer = true;
- this._timeSpent = 0;
- },
-
- //Increment timeSpent and call function to update ui_timer
- _refreshTimer: function() {
- if (this._stopTimer == false) {
- this._pie.queue_repaint();
- this._timeSpent += 1;
- Mainloop.timeout_add_seconds(1, Lang.bind(this, this._refreshTimer));
- }
-
- if(this._timeSpent && this._time <= this._timeSpent) {
- this._resetTimer();
- this._playSound(this._soundUri);
-
- if(this._issuer == 'setTimer')
- this._notifyUser(_("Timer finished!"));
- else {
- this._notifyUser(_("Preset \"%s\" finished!").format(this._issuer));
- }
- }
- if(this._showElapsed)
- this._formatLabel(this._timer, this._timeSpent);
- else
- this._formatLabel(this._timer, this._time - this._timeSpent);
- },
-
- //Update timer_ui
- _formatLabel: function(label, seconds) {
- let hours = parseInt(seconds / 3600);
- seconds -= hours * 3600;
- let minutes = parseInt(seconds / 60);
- seconds -= minutes * 60;
-
- if(hours)
- label.set_text("%02d:%02d:%02d".format(hours,minutes,seconds));
- else
- label.set_text("%02d:%02d".format(minutes,seconds));
- },
-
- //Notify user of changes
- _notifyUser: function(text) {
- if(this._showNotifications) {
- let source = new MessageTray.SystemNotificationSource();
- Main.messageTray.add(source);
- let notification = new MessageTray.Notification(source, text, null);
- notification.setTransient(true);
- source.notify(notification);
- }
- if(this._showPersistentNotifications) {
- //Create persistent message modal dialog
- this._persistentMessageDialog = new ModalDialog.ModalDialog();
- this._persistentMessageLabel = new St.Label({ style_class: 'persistent-message-label',
- text: _(text) });
- this._persistentMessageDialog.contentLayout.add(this._persistentMessageLabel, { x_fill: true, y_fill: true });
- this._persistentMessageDialog.setButtons([{ label: _("Close"),
- action: Lang.bind(this, function(param) {
- this._persistentMessageDialog.close();
- if(this._sound_enable){
- this.player.set_state(Gst.State.NULL);
- }
- }),
- key: Clutter.Escape
- }]);
- this._persistentMessageDialog.open();
- }
- },
+ // Reset all counters and timers
+ _restartTimer: function() {
+ if(this._stopTimer) {
+ this._widget.setToggleState(true);
+ this.remove_actor(this._logo);
+ this.add_actor(this._box);
+ this._stopTimer = false;
+ this._refreshTimer();
+ }
+ },
+
+ // Reset all counters and timers
+ _resetTimer: function() {
+ this._widget.setToggleState(false);
+ this.remove_actor(this._box);
+ this.add_actor(this._logo);
+ this._stopTimer = true;
+ this._timeSpent = 0;
+ },
+
+ // Increment timeSpent and call function to update ui_timer
+ _refreshTimer: function() {
+ if (this._stopTimer == false) {
+ this._pie.queue_repaint();
+ this._timeSpent += 1;
+ Mainloop.timeout_add_seconds(1, Lang.bind(this, this._refreshTimer));
+ }
+ if(this._timeSpent && this._time <= this._timeSpent) {
+ this._resetTimer();
+ this._playSound(this._sound_uri);
+ if(this._issuer == 'setTimer')
+ this._notifyUser(_("Timer finished!"));
+ else {
+ this._notifyUser(_("Preset “%s” finished!").format(this._issuer));
+ }
+ }
+ if(this._showElapsed)
+ this._formatLabel(this._timer, this._timeSpent);
+ else
+ this._formatLabel(this._timer, this._time - this._timeSpent);
+ },
+
+ // Update timer_ui
+ _formatLabel: function(label, seconds) {
+ let hours = parseInt(seconds / 3600);
+ seconds -= hours * 3600;
+ let minutes = parseInt(seconds / 60);
+ seconds -= minutes * 60;
+ if(hours)
+ label.set_text("%02d:%02d:%02d".format(hours,minutes,seconds));
+ else
+ label.set_text("%02d:%02d".format(minutes,seconds));
+ },
+
+ // Notify user of changes
+ _notifyUser: function(text) {
+ if(this._showNotifications) {
+ let source = new MessageTray.SystemNotificationSource();
+ Main.messageTray.add(source);
+ let notification = new MessageTray.Notification(source, text, null);
+ notification.setTransient(true);
+ source.notify(notification);
+ }
+ if(this._showPersistentNotifications) {
+ // Create persistent message modal dialog
+ this._persistentMessageDialog = new ModalDialog.ModalDialog();
+
+ this._persistentMessageLabel = new St.Label({
+ style_class: 'persistent-message-label',
+ text: _(text),
+ x_expand: true,
+ y_expand: true
+ });
+ this._persistentMessageDialog.contentLayout.add(this._persistentMessageLabel);
+ this._persistentMessageDialog.setButtons([{
+ label: _("Close"),
+ action: Lang.bind(this, function(param) {
+ this._persistentMessageDialog.close();
+ if (this._sound_enable) {
+ this.player.set_state(Gst.State.NULL);
+ }
+ }),
+ key: Clutter.Escape
+ }]);
+ this._persistentMessageDialog.open();
+ }
+ },
// szm - from tea-time
_playSound: function(uri) {
- if (this._sound_enable) {
- if ( typeof this.player == 'undefined' ) {
- Gst.init(null);
- this.player = Gst.ElementFactory.make("playbin","player");
- this.playBus = this.player.get_bus();
- this.playBus.add_signal_watch();
- this.playBus.connect("message", Lang.bind(this,
- function(playBus, message) {
- if (message != null) {
- // IMPORTANT: to reuse the player, set state to READY
- let t = message.type;
- if ( t == Gst.MessageType.EOS || t == Gst.MessageType.ERROR) {
- this.player.set_state(Gst.State.READY);
- }
- if ( t == Gst.MessageType.EOS && this._sound_loop ){
- this.player.set_state(Gst.State.READY);
- this.player.set_property('uri', uri);
- this.player.set_state(Gst.State.PLAYING);
- }
- } // message handler
- }));
- } // if undefined
- //this._notifyUser("Playing uri="+uri);
- this.player.set_property('uri', uri);
- this.player.set_state(Gst.State.PLAYING);
+ if (this._sound_enable) {
+ if ( typeof this.player == 'undefined' ) {
+ Gst.init(null);
+ this.player = Gst.ElementFactory.make("playbin","player");
+ this.playBus = this.player.get_bus();
+ this.playBus.add_signal_watch();
+ this.playBus.connect("message", Lang.bind(this, function(playBus, message) {
+ if (message != null) {
+ // IMPORTANT: to reuse the player, set state to READY
+ let t = message.type;
+ if ( t == Gst.MessageType.EOS || t == Gst.MessageType.ERROR) {
+ this.player.set_state(Gst.State.READY);
+ }
+ if ( t == Gst.MessageType.EOS && this._sound_loop ){
+ this.player.set_state(Gst.State.READY);
+ this.player.set_property('uri', uri);
+ this.player.set_state(Gst.State.PLAYING);
+ }
+ } // message handler
+ }));
+ } // if undefined
+ // this._notifyUser("Playing uri="+uri);
+ this.player.set_property('uri', uri);
+ this.player.set_state(Gst.State.PLAYING);
}
}
});
-let indicator;
+var indicator;
-function init() {
+function init(meta) {
}
function enable() {
- indicator = new Indicator();
- Main.panel.addToStatusArea('Indicator', indicator);
+ indicator = new Indicator();
+ Main.panel.addToStatusArea('Indicator', indicator);
}
function disable() {
- indicator.destroy();
+ indicator.destroy();
}
diff --git a/timer@olebowle.gmx.com/metadata.json b/timer@olebowle.gmx.com/metadata.json
index df65712..f8fed84 100644
--- a/timer@olebowle.gmx.com/metadata.json
+++ b/timer@olebowle.gmx.com/metadata.json
@@ -1,5 +1,5 @@
{
- "shell-version": ["3.32"],
+ "shell-version": ["3.38"],
"uuid": "timer@olebowle.gmx.com",
"name": "Timer",
"url": "https://github.com/olebowle/gnome-shell-timer",