summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/preferencesWindow.vala134
-rw-r--r--src/gui/themeList.vala20
-rw-r--r--src/gui/tipViewer.vala163
3 files changed, 307 insertions, 10 deletions
diff --git a/src/gui/preferencesWindow.vala b/src/gui/preferencesWindow.vala
index 5d22d6b..d671501 100644
--- a/src/gui/preferencesWindow.vala
+++ b/src/gui/preferencesWindow.vala
@@ -154,6 +154,17 @@ public class PreferencesWindow : GLib.Object {
scroll_area = builder.get_object("theme-scrolledwindow") as Gtk.ScrolledWindow;
scroll_area.add(this.theme_list);
+ (builder.get_object("theme-help-button") as Gtk.Button).clicked.connect(() => {
+ try{
+ GLib.AppInfo.launch_default_for_uri("http://simmesimme.github.io/lessons/2015/04/26/themes-for-gnome-pie/", null);
+ } catch (Error e) {
+ warning(e.message);
+ }
+ });
+
+ (builder.get_object("theme-export-button") as Gtk.Button).clicked.connect(on_export_theme_button_clicked);
+ (builder.get_object("theme-import-button") as Gtk.Button).clicked.connect(on_import_theme_button_clicked);
+
this.autostart = (builder.get_object("autostart-checkbox") as Gtk.ToggleButton);
this.autostart.toggled.connect(on_autostart_toggled);
@@ -209,6 +220,33 @@ public class PreferencesWindow : GLib.Object {
Config.global.max_visible_slices = (int)range_slices.get_value();
});
+ var info_box = (builder.get_object("info-box") as Gtk.Box);
+
+ // info label
+ var info_label = new TipViewer({
+ _("Pies can be opened with the terminal command \"gnome-pie --open=ID\"."),
+ _("Feel free to visit Gnome-Pie's homepage at %s!").printf("<a href='http://simmesimme.github.io/gnome-pie.html'>gnome-pie.simonschneegans.de</a>"),
+ _("If you want to give some feedback, please write an e-mail to %s!").printf("<a href='mailto:code@simonschneegans.de'>code@simonschneegans.de</a>"),
+ _("You can support the development of Gnome-Pie by donating via %s.").printf("<a href='https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=X65SUVC4ZTQSC'>Paypal</a>"),
+ _("Translating Gnome-Pie to your language is easy. Translations are managed at %s.").printf("<a href='https://translate.zanata.org/zanata/iteration/view/gnome-pie/develop'>Zanata</a>"),
+ _("It's easy to create new themes for Gnome-Pie. Read the <a href='%s'>Tutorial</a> online.").printf("http://simmesimme.github.io/lessons/2015/04/26/themes-for-gnome-pie/"),
+ _("It's usually a good practive to have at most twelve slices per pie."),
+ _("You can export themes you created and share them with the community!"),
+ _("The source code of Gnome-Pie is available on %s.").printf("<a href='https://github.com/Simmesimme/Gnome-Pie'>Github</a>"),
+ _("Bugs can be reported at %s!").printf("<a href='https://github.com/Simmesimme/Gnome-Pie/issues'>Github</a>"),
+ _("Suggestions can be posted on %s!").printf("<a href='https://github.com/Simmesimme/Gnome-Pie/issues'>Github</a>"),
+ _("An awesome companion of Gnome-Pie is %s. It will make using your computer feel like magic!").printf("<a href='https://github.com/thjaeger/easystroke/wiki'>Easystroke</a>"),
+ _("You can drag'n'drop applications from your main menu to the pie above."),
+ _("You may drag'n'drop URLs and bookmarks from your internet browser to the pie above."),
+ _("You can drag'n'drop files and folders from your file browser to the pie above."),
+ _("You can drag'n'drop pies from the list on the left into other pies in order to create sub-pies."),
+ _("You can drag'n'drop pies from the list on the left to your desktop or dock to create a launcher for this pie.")
+ });
+ this.window.show.connect(info_label.start_slide_show);
+ this.window.hide.connect(info_label.stop_slide_show);
+
+ info_box.pack_end(info_label);
+
this.window.hide.connect(() => {
// save settings on close
Config.global.save();
@@ -290,15 +328,105 @@ public class PreferencesWindow : GLib.Object {
FileUtils.set_contents(Paths.autostart, autostart_entry);
FileUtils.chmod(Paths.autostart, 0755);
} catch (Error e) {
- var d = new Gtk.MessageDialog (this.window, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE,
+ var d = new Gtk.MessageDialog(this.window, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE,
"%s", e.message);
- d.run ();
- d.destroy ();
+ d.run();
+ d.destroy();
}
}
}
/////////////////////////////////////////////////////////////////////
+ /// Saves the current theme to an archive.
+ /////////////////////////////////////////////////////////////////////
+
+ private void on_export_theme_button_clicked(Gtk.Button button) {
+ var dialog = new Gtk.FileChooserDialog("Pick a file", this.window,
+ Gtk.FileChooserAction.SAVE,
+ "_Cancel",
+ Gtk.ResponseType.CANCEL,
+ "_Save",
+ Gtk.ResponseType.ACCEPT);
+
+ dialog.set_do_overwrite_confirmation(true);
+ dialog.set_modal(true);
+ dialog.filter = new Gtk.FileFilter();
+ dialog.filter.add_pattern ("*.tar.gz");
+ dialog.set_current_name(Config.global.theme.name + ".tar.gz");
+
+ dialog.response.connect((d, result) => {
+ if (result == Gtk.ResponseType.ACCEPT) {
+ var file = dialog.get_filename();
+ if (!file.has_suffix(".tar.gz")) {
+ file = file + ".tar.gz";
+ }
+ Config.global.theme.export(file);
+ }
+ dialog.destroy();
+ });
+ dialog.show();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Imports a new theme from an archive.
+ /////////////////////////////////////////////////////////////////////
+
+ private void on_import_theme_button_clicked(Gtk.Button button) {
+ var dialog = new Gtk.FileChooserDialog("Pick a file", this.window,
+ Gtk.FileChooserAction.OPEN,
+ "_Cancel",
+ Gtk.ResponseType.CANCEL,
+ "_Open",
+ Gtk.ResponseType.ACCEPT);
+
+ dialog.set_modal(true);
+ dialog.filter = new Gtk.FileFilter();
+ dialog.filter.add_pattern ("*.tar.gz");
+
+ var result = Gtk.MessageType.INFO;
+ var message = _("Sucessfully imported new theme!");
+
+ dialog.response.connect((d, r) => {
+ if (r == Gtk.ResponseType.ACCEPT) {
+ var file = dialog.get_filename();
+
+ var a = new ThemeImporter();
+ if (a.open(file)) {
+ if (a.is_valid_theme) {
+ if (!Config.global.has_theme(a.theme_name)) {
+ if (a.extract_to(Paths.local_themes + "/" + a.theme_name)) {
+ Config.global.load_themes(a.theme_name);
+ this.theme_list.reload();
+ } else {
+ message = _("An error occured while importing the theme: Failed to extract theme!");
+ result = Gtk.MessageType.ERROR;
+ }
+ } else {
+ message = _("An error occured while importing the theme: A theme with this name does already exist!");
+ result = Gtk.MessageType.ERROR;
+ }
+ } else {
+ message = _("An error occured while importing the theme: Theme archive does not contain a valid theme!");
+ result = Gtk.MessageType.ERROR;
+ }
+ } else {
+ message = _("An error occured while importing the theme: Failed to open theme archive!");
+ result = Gtk.MessageType.ERROR;
+ }
+ a.close();
+
+ var result_dialog = new Gtk.MessageDialog(null, Gtk.DialogFlags.MODAL,
+ result, Gtk.ButtonsType.CLOSE, message);
+ result_dialog.run();
+ result_dialog.destroy();
+ }
+ dialog.destroy();
+
+ });
+ dialog.show();
+ }
+
+ /////////////////////////////////////////////////////////////////////
/// Shows or hides the indicator.
/////////////////////////////////////////////////////////////////////
diff --git a/src/gui/themeList.vala b/src/gui/themeList.vala
index 517c6d5..46ae876 100644
--- a/src/gui/themeList.vala
+++ b/src/gui/themeList.vala
@@ -51,9 +51,6 @@ class ThemeList : Gtk.TreeView {
public ThemeList() {
GLib.Object();
- var data = new Gtk.ListStore(2, typeof(Gdk.Pixbuf),
- typeof(string));
- this.set_model(data);
this.set_headers_visible(true);
this.set_grid_lines(Gtk.TreeViewGridLines.NONE);
this.set_fixed_height_mode(true);
@@ -79,7 +76,7 @@ class ThemeList : Gtk.TreeView {
Gtk.TreeIter active;
if (this.get_selection().get_selected(null, out active)) {
Timeout.add(10, () => {
- int index = int.parse(data.get_path(active).to_string());
+ int index = int.parse(this.model.get_path(active).to_string());
Config.global.theme = Config.global.themes[index];
this.on_select_new();
@@ -91,6 +88,15 @@ class ThemeList : Gtk.TreeView {
}
});
+ reload();
+ }
+
+ public void reload() {
+
+ var data = new Gtk.ListStore(2, typeof(Gdk.Pixbuf),
+ typeof(string));
+ this.set_model(data);
+
// load all themes into the list
var themes = Config.global.themes;
foreach(var theme in themes) {
@@ -99,10 +105,10 @@ class ThemeList : Gtk.TreeView {
data.set(current, DataPos.ICON, theme.preview_icon.to_pixbuf());
data.set(current, DataPos.NAME, GLib.Markup.escape_text(theme.name)+"\n"
+ "<span font-size='x-small'>" + GLib.Markup.escape_text(theme.description)
- + " - <i>"+GLib.Markup.escape_text(_("By")+" "+theme.author)
- + "</i></span>");
- if(theme == Config.global.theme)
+ + "</span>");
+ if(theme == Config.global.theme) {
get_selection().select_iter(current);
+ }
}
}
}
diff --git a/src/gui/tipViewer.vala b/src/gui/tipViewer.vala
new file mode 100644
index 0000000..e2158bd
--- /dev/null
+++ b/src/gui/tipViewer.vala
@@ -0,0 +1,163 @@
+/////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011-2015 by Simon Schneegans
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// 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, 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.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+/////////////////////////////////////////////////////////////////////////
+
+namespace GnomePie {
+
+/////////////////////////////////////////////////////////////////////////
+/// A widget showing tips. The tips are beautifully faded in and out.
+/////////////////////////////////////////////////////////////////////////
+
+public class TipViewer : Gtk.Label {
+
+ /////////////////////////////////////////////////////////////////////
+ /// Some settings tweaking the behavior of the TipViewer.
+ /////////////////////////////////////////////////////////////////////
+
+ private const double fade_time = 0.5;
+ private const double frame_rate = 20.0;
+ private const double base_delay = 3.0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// False, if the playback of tips is stopped.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool playing = false;
+
+ /////////////////////////////////////////////////////////////////////
+ /// An array containing all tips.
+ /////////////////////////////////////////////////////////////////////
+
+ private string[] tips;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The index of the currently displayed tip.
+ /////////////////////////////////////////////////////////////////////
+
+ private int index = -1;
+
+ /////////////////////////////////////////////////////////////////////
+ /// The fading value.
+ /////////////////////////////////////////////////////////////////////
+
+ private AnimatedValue alpha;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, initializes all members and sets the basic layout.
+ /////////////////////////////////////////////////////////////////////
+
+ public TipViewer(string[] tips) {
+ this.tips = tips;
+
+ this.alpha = new AnimatedValue.linear(0.0, 1.0, fade_time);
+
+ this.set_alignment (0.0f, 0.5f);
+ this.opacity = 0;
+ this.wrap = true;
+ this.valign = Gtk.Align.END;
+ this.set_use_markup(true);
+
+ this.override_font(Pango.FontDescription.from_string("8"));
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the playback of tips.
+ /////////////////////////////////////////////////////////////////////
+
+ public void start_slide_show() {
+ if (!this.playing && tips.length > 1) {
+ this.playing = true;
+ show_tip();
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Stops the playback of tips.
+ /////////////////////////////////////////////////////////////////////
+
+ public void stop_slide_show() {
+ this.playing = false;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the fading in.
+ /////////////////////////////////////////////////////////////////////
+
+ private void fade_in() {
+ this.alpha = new AnimatedValue.linear(this.alpha.val, 1.0, fade_time);
+
+ GLib.Timeout.add((uint)(1000.0/frame_rate), () => {
+ this.alpha.update(1.0/frame_rate);
+ this.opacity = this.alpha.val;
+
+ return (this.alpha.val != 1.0);
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Starts the fading out.
+ /////////////////////////////////////////////////////////////////////
+
+ private void fade_out() {
+ this.alpha = new AnimatedValue.linear(this.alpha.val, 0.0, fade_time);
+
+ GLib.Timeout.add((uint)(1000.0/frame_rate), () => {
+ this.alpha.update(1.0/frame_rate);
+ this.opacity = this.alpha.val;
+
+ return (this.alpha.val != 0.0);
+ });
+ }
+
+ private void show_tip() {
+
+ this.set_random_tip();
+
+ this.fade_in();
+
+ uint delay = (uint)(base_delay*1000.0) + tips[this.index].length*30;
+
+ GLib.Timeout.add(delay, () => {
+ this.fade_out();
+
+ if (this.playing) {
+ GLib.Timeout.add((uint)(1000.0*fade_time), () => {
+ this.show_tip();
+ return false;
+ });
+ }
+
+ return false;
+ });
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// Chooses the next random tip.
+ /////////////////////////////////////////////////////////////////////
+
+ private void set_random_tip() {
+ if (tips.length > 1) {
+ int next_index = -1;
+ do {
+ next_index = GLib.Random.int_range(0, tips.length);
+ } while (next_index == this.index);
+ this.index = next_index;
+ this.label = tips[this.index];
+ }
+ }
+}
+
+}