diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-01-24 11:03:06 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-01-24 11:03:06 +0100 | 
| commit | b683ce2789d95b2e9f221e75adc30efd91cfb901 (patch) | |
| tree | 7903b95887c3fbb995ec2e6a99b027053e617adf /src | |
| parent | 73201cab74e84e5372b6c4a1f72f7e70df5c0d5a (diff) | |
Imported Upstream version 0.5.7upstream/0.5.7
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/deamon.vala | 143 | ||||
| -rw-r--r-- | src/gui/aboutWindow.vala | 26 | ||||
| -rw-r--r-- | src/gui/iconSelectWindow.vala | 216 | ||||
| -rw-r--r-- | src/gui/indicator.vala | 13 | ||||
| -rw-r--r-- | src/gui/newSliceWindow.vala | 178 | ||||
| -rw-r--r-- | src/gui/newsWindow.vala | 40 | ||||
| -rw-r--r-- | src/gui/piePreview.vala | 198 | ||||
| -rw-r--r-- | src/gui/piePreviewCenter.vala | 65 | ||||
| -rw-r--r-- | src/gui/piePreviewRenderer.vala | 201 | ||||
| -rw-r--r-- | src/gui/preferencesWindow.vala | 231 | ||||
| -rw-r--r-- | src/gui/settingsWindow.vala | 88 | ||||
| -rw-r--r-- | src/gui/triggerSelectWindow.vala | 78 | ||||
| -rw-r--r-- | src/images/image.vala | 95 | ||||
| -rw-r--r-- | src/renderers/pieRenderer.vala | 150 | ||||
| -rw-r--r-- | src/renderers/pieWindow.vala | 38 | ||||
| -rw-r--r-- | src/utilities/color.vala | 87 | ||||
| -rw-r--r-- | src/utilities/config.vala | 62 | ||||
| -rw-r--r-- | src/utilities/focusGrabber.vala | 120 | 
19 files changed, 986 insertions, 1047 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7138fdd..ee08045 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,10 +12,6 @@ if (${INDICATOR3_FOUND})    LIST(APPEND DEFINES --define HAVE_APPINDICATOR)  endif(${INDICATOR3_FOUND}) -if (${GTK3_FOUND}) -  LIST(APPEND DEFINES --define HAVE_GTK_3) -endif(${GTK3_FOUND}) -  if (${GMENU3_FOUND})      LIST(APPEND DEFINES --define HAVE_GMENU_3)  endif (${GMENU3_FOUND}) diff --git a/src/deamon.vala b/src/deamon.vala index fb9618b..2e79d10 100644 --- a/src/deamon.vala +++ b/src/deamon.vala @@ -36,15 +36,12 @@ public class Deamon : GLib.Object {      /////////////////////////////////////////////////////////////////////      public static int main(string[] args) { -        version = "0.5.6"; +        version = "0.5.7";          Logger.init(); -        Gdk.threads_init();          Gtk.init(ref args);          Paths.init(); -        message("Welcome to Gnome-Pie " + version + "!"); -          // create the Deamon and run it          var deamon = new GnomePie.Deamon();          deamon.run(args); @@ -83,95 +80,51 @@ public class Deamon : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void run(string[] args) { -        // create command line options -        var context = new GLib.OptionContext(""); -        context.set_help_enabled(true); -        context.add_main_entries(options, null); -        context.add_group(Gtk.get_option_group (false)); - -        try { -            context.parse(ref args); -        } catch(GLib.OptionError error) { -            warning(error.message); -        } - -        if (Deamon.reset) { -            if (GLib.FileUtils.remove(Paths.pie_config) == 0) -                message("Removed file \"%s\"", Paths.pie_config); -            if (GLib.FileUtils.remove(Paths.settings) == 0) -                message("Removed file \"%s\"", Paths.settings); - -            return; -        }          // create unique application -        var app = new Unique.App("org.gnome.gnomepie", null); - -        #if HAVE_GTK_3 -            if (app.is_running()) { -        #else -            if (app.is_running) { -        #endif -            // inform the running instance of the pie to be opened -            if (open_pie != null) { -            	message("Gnome-Pie is already running. Sending request to open pie " + open_pie + "."); -                var data = new Unique.MessageData(); -                data.set_text(open_pie, open_pie.length); -                app.send_message(Unique.Command.ACTIVATE, data); - -                return; -            } - -            message("Gnome-Pie is already running. Sending request to open config menu."); -            app.send_message(Unique.Command.ACTIVATE, null); +        var app = new GLib.Application("org.gnome.gnomepie", GLib.ApplicationFlags.HANDLES_COMMAND_LINE); -            return; -        } - -        // wait for incoming messages -        app.message_received.connect((cmd, data, event_time) => { -            if (cmd == Unique.Command.ACTIVATE) { -                var pie = data.get_text(); - -                if (pie != null && pie != "") PieManager.open_pie(pie); -                else                          this.indicator.show_preferences(); - -                return Unique.Response.OK; +        app.command_line.connect((cmd) => { +            string[] tmp = cmd.get_arguments(); +            unowned string[] remote_args = tmp; +            if (!handle_command_line(remote_args, true)) { +                Gtk.main_quit();              } -            return Unique.Response.PASSTHROUGH; +            return 0;          }); -        Gdk.threads_enter(); +        app.startup.connect(() => { -        // init locale support -        Intl.bindtextdomain ("gnomepie", Paths.locales); -        Intl.textdomain ("gnomepie"); +            message("Welcome to Gnome-Pie " + version + "!"); -        // init toolkits and static stuff -        ActionRegistry.init(); -        GroupRegistry.init(); +            // init locale support +            Intl.bindtextdomain ("gnomepie", Paths.locales); +            Intl.textdomain ("gnomepie"); -        PieManager.init(); -        Icon.init(); +            // init toolkits and static stuff +            ActionRegistry.init(); +            GroupRegistry.init(); -        // launch the indicator -        this.indicator = new Indicator(); +            PieManager.init(); +            Icon.init(); -        // connect SigHandlers -        Posix.signal(Posix.SIGINT, sig_handler); -	    Posix.signal(Posix.SIGTERM, sig_handler); +            // launch the indicator +            this.indicator = new Indicator(); -	    // finished loading... so run the prog! -	    message("Started happily..."); +            // connect SigHandlers +            Posix.signal(Posix.SIGINT, sig_handler); +            Posix.signal(Posix.SIGTERM, sig_handler); -	    // open pie if neccessary -	    if (open_pie != null) -	        PieManager.open_pie(open_pie); +            // finished loading... so run the prog! +            message("Started happily..."); -	    Gtk.main(); +            if (handle_command_line(args, false)) { +                Gtk.main(); +            } +        }); -	    Gdk.threads_leave(); +        app.run(args);      }      ///////////////////////////////////////////////////////////////////// @@ -183,6 +136,42 @@ public class Deamon : GLib.Object {  		message("Caught signal (%d), bye!".printf(sig));  		Gtk.main_quit();  	} + +    ///////////////////////////////////////////////////////////////////// +    /// Handles command line parameters. +    ///////////////////////////////////////////////////////////////////// + +    private bool handle_command_line(string[] args, bool show_preferences) { +        // create command line options +        var context = new GLib.OptionContext(""); +        context.set_help_enabled(true); +        context.add_main_entries(options, null); +        context.add_group(Gtk.get_option_group (false)); + +        try { +            context.parse(ref args); +        } catch(GLib.OptionError error) { +            warning(error.message); +        } + +        if (reset) { +            if (GLib.FileUtils.remove(Paths.pie_config) == 0) +                message("Removed file \"%s\"", Paths.pie_config); +            if (GLib.FileUtils.remove(Paths.settings) == 0) +                message("Removed file \"%s\"", Paths.settings); + +            return false; +        } + +        if (open_pie != null && open_pie != "") { +            PieManager.open_pie(open_pie); +            open_pie = ""; +        } else if (show_preferences) { +            this.indicator.show_preferences(); +        } + +        return true; +    }  }  } diff --git a/src/gui/aboutWindow.vala b/src/gui/aboutWindow.vala index c6b7453..39258cb 100644 --- a/src/gui/aboutWindow.vala +++ b/src/gui/aboutWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,25 +12,25 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A simple about dialog.  /////////////////////////////////////////////////////////////////////////  public class AboutWindow: Gtk.AboutDialog { -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new about dialog. The entries are sorted alpha-      /// betically.      ///////////////////////////////////////////////////////////////////// -     +      public AboutWindow () {      	string[] devs = { -			"Simon Schneegans <code@simonschneegans.de>",  +			"Simon Schneegans <code@simonschneegans.de>",              "Francesco Piccinno <stack.box@gmail.com>"          };          string[] artists = { @@ -48,29 +48,29 @@ public class AboutWindow: Gtk.AboutDialog {              "Ting Zhou <tzhou@haverford.edu> (ZH-CN)",              "Martin Dinov <martindinov@yahoo.com> (BG)"      	}; -    	 +      	// sort translators      	GLib.List<string> translator_list = new GLib.List<string>();      	foreach (var translator in translators)      		translator_list.append(translator); -    		 +      	translator_list.sort((a, b) => {      		return a.ascii_casecmp(b);      	}); -    	 +      	string translator_string = "";      	foreach (var translator in translator_list)  	   		translator_string += translator + "\n"; -         +          GLib.Object (              artists : artists,              authors : devs,              translator_credits : translator_string, -            copyright : "Copyright (C) 2011-2012 Simon Schneegans <code@simonschneegans.de>", +            copyright : "Copyright (C) 2011-2015 Simon Schneegans <code@simonschneegans.de>",              program_name: "Gnome-Pie",              logo_icon_name: "gnome-pie", -            website: "http://www.simonschneegans.de/?page_id=12", -            website_label: "www.gnome-pie.simonschneegans.de", +            website: "http://simmesimme.github.io/gnome-pie.html", +            website_label: "Homepage",              version: Deamon.version          );      } diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala index 9159f15..2560811 100644 --- a/src/gui/iconSelectWindow.vala +++ b/src/gui/iconSelectWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,29 +12,29 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -/// A window which allows selection of an Icon of the user's current icon  +///////////////////////////////////////////////////////////////////////// +/// A window which allows selection of an Icon of the user's current icon  /// theme. Custom icons/images can be selested as well. Loading of icons  /// happens in an extra thread and a spinner is displayed while loading.  /////////////////////////////////////////////////////////////////////////  public class IconSelectWindow : GLib.Object { -    +      /////////////////////////////////////////////////////////////////////      /// This signal gets emitted when the user selects a new icon.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_ok(string icon_name); -     +      /////////////////////////////////////////////////////////////////////      /// Stores the currently selected icon.      ///////////////////////////////////////////////////////////////////// -     +      private string active_icon = "";      ///////////////////////////////////////////////////////////////////// @@ -42,64 +42,64 @@ public class IconSelectWindow : GLib.Object {      /////////////////////////////////////////////////////////////////////      private static Gtk.ListStore icon_list = null; -     +      /////////////////////////////////////////////////////////////////////      /// True, if the icon theme is currently reloaded.      ///////////////////////////////////////////////////////////////////// -     +      private static bool loading = false; -     +      /////////////////////////////////////////////////////////////////////      /// If set to true, the icon list will be reloaded next time the      /// window opens.      ///////////////////////////////////////////////////////////////////// -     +      private static bool need_reload = true; -     +      /////////////////////////////////////////////////////////////////////      /// Icons of these contexts won't appear in the list.      ///////////////////////////////////////////////////////////////////// -     +      private const string disabled_contexts = "Animations, FileSystems"; -     +      /////////////////////////////////////////////////////////////////////      /// The list of icons, filtered according to the chosen type and      /// filter string.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.TreeModelFilter icon_list_filtered = null; -     +      /////////////////////////////////////////////////////////////////////      /// The Gtk widget displaying the icons.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.IconView icon_view = null; -     +      /////////////////////////////////////////////////////////////////////      /// This spinner is displayed when the icons are loaded.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Spinner spinner = null; -     +      /////////////////////////////////////////////////////////////////////      /// A Gtk widget used for custom icon/image selection.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.FileChooserWidget file_chooser = null; -     +      /////////////////////////////////////////////////////////////////////      /// The notebook containing the different icon choice possibilities:      /// from the theme or custom.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Notebook tabs = null; -     +      /////////////////////////////////////////////////////////////////////      /// The main window.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Window window = null; -     +      /////////////////////////////////////////////////////////////////////      /// A little structure containing data for one icon in the icon_view.      ///////////////////////////////////////////////////////////////////// @@ -109,19 +109,19 @@ public class IconSelectWindow : GLib.Object {          public IconContext context;          public Gdk.Pixbuf pixbuf;      } -     +      /////////////////////////////////////////////////////////////////////      /// This queue is used for icon loading. A loading thread pushes      /// icons into it --- the main thread updates the icon_view      /// accordingly.      ///////////////////////////////////////////////////////////////////// -     +      private GLib.AsyncQueue<ListEntry?> load_queue; -     +      /////////////////////////////////////////////////////////////////////      /// Possible icon types.      ///////////////////////////////////////////////////////////////////// -     +      private enum IconContext {          ALL,          APPS, @@ -131,20 +131,20 @@ public class IconSelectWindow : GLib.Object {          EMOTES,          OTHER      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new IconSelectWindow.      ///////////////////////////////////////////////////////////////////// -     +      public IconSelectWindow(Gtk.Window parent) {          try {              this.load_queue = new GLib.AsyncQueue<ListEntry?>(); -             +              if (IconSelectWindow.icon_list == null) {                  IconSelectWindow.icon_list = new Gtk.ListStore(3, typeof(string), // icon name                                                        typeof(IconContext), // icon type                                                        typeof(Gdk.Pixbuf)); // the icon itself -                                                       +                  // disable sorting until all icons are loaded                  // else loading becomes horribly slow                  IconSelectWindow.icon_list.set_default_sort_func(() => {return 0;}); @@ -155,10 +155,10 @@ public class IconSelectWindow : GLib.Object {                      else IconSelectWindow.need_reload = true;                  });              } -             +              // make the icon_view filterable              this.icon_list_filtered = new Gtk.TreeModelFilter(IconSelectWindow.icon_list, null); -                 +              Gtk.Builder builder = new Gtk.Builder();              builder.add_from_file (Paths.ui_files + "/icon_select.ui"); @@ -166,42 +166,38 @@ public class IconSelectWindow : GLib.Object {              this.window = builder.get_object("window") as Gtk.Window;              this.window.set_transient_for(parent);              this.window.set_modal(true); -             +              this.tabs = builder.get_object("tabs") as Gtk.Notebook; -             +              this.spinner = builder.get_object("spinner") as Gtk.Spinner;              this.spinner.start(); -             +              (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked);              (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); -             -            var combo_box = builder.get_object("combo-box") as Gtk.VBox; -             + +            var combo_box = builder.get_object("combo-box") as Gtk.Box; +              // context combo -            #if HAVE_GTK_3 -                var context_combo = new Gtk.ComboBoxText(); -            #else -                var context_combo = new Gtk.ComboBox.text(); -            #endif -                context_combo.append_text(_("All icons")); -                context_combo.append_text(_("Applications")); -                context_combo.append_text(_("Actions")); -                context_combo.append_text(_("Places")); -                context_combo.append_text(_("File types")); -                context_combo.append_text(_("Emotes")); -                context_combo.append_text(_("Miscellaneous")); - -                context_combo.set_active(0); -                 -                context_combo.changed.connect(() => { -                    this.icon_list_filtered.refilter(); -                }); -                 +            var context_combo = new Gtk.ComboBoxText(); +            context_combo.append_text(_("All icons")); +            context_combo.append_text(_("Applications")); +            context_combo.append_text(_("Actions")); +            context_combo.append_text(_("Places")); +            context_combo.append_text(_("File types")); +            context_combo.append_text(_("Emotes")); +            context_combo.append_text(_("Miscellaneous")); + +            context_combo.set_active(0); + +            context_combo.changed.connect(() => { +                this.icon_list_filtered.refilter(); +            }); +              combo_box.pack_start(context_combo, false, false); -                 +              // string filter entry              var filter = builder.get_object("filter-entry") as Gtk.Entry; -                 +                  // only display items which have the selected type                  // and whose name contains the text entered in the entry                  this.icon_list_filtered.set_visible_func((model, iter) => { @@ -209,25 +205,25 @@ public class IconSelectWindow : GLib.Object {                      IconContext context = IconContext.ALL;                      model.get(iter, 0, out name);                      model.get(iter, 1, out context); -                     +                      if (name == null) return false; -                     +                      return (context_combo.get_active() == context ||                              context_combo.get_active() == IconContext.ALL) &&                              name.down().contains(filter.text.down());                  }); -                 +                  // clear when the users clicks on the "clear" icon                  filter.icon_release.connect((pos, event) => {                      if (pos == Gtk.EntryIconPosition.SECONDARY)                          filter.text = "";                  }); -                 +                  // refilter on input                  filter.notify["text"].connect(() => {                      this.icon_list_filtered.refilter();                  }); -             +              // container for the icon_view              var scroll = builder.get_object("icon-scrolledwindow") as Gtk.ScrolledWindow; @@ -237,7 +233,7 @@ public class IconSelectWindow : GLib.Object {                      this.icon_view.item_padding = 2;                      this.icon_view.pixbuf_column = 2;                      this.icon_view.tooltip_column = 0; -                     +                      // set active_icon if selection changes                      this.icon_view.selection_changed.connect(() => {                          foreach (var path in this.icon_view.get_selected_items()) { @@ -246,7 +242,7 @@ public class IconSelectWindow : GLib.Object {                              this.icon_list_filtered.get(iter, 0, out this.active_icon);                          }                      }); -                     +                      // hide this window when the user activates an icon                      this.icon_view.item_activated.connect((path) => {                          Gtk.TreeIter iter; @@ -255,46 +251,40 @@ public class IconSelectWindow : GLib.Object {                          this.on_ok(this.active_icon);                          this.window.hide();                      }); -             +                  scroll.add(this.icon_view); -                 +              // file chooser widget              this.file_chooser = builder.get_object("filechooser") as Gtk.FileChooserWidget;                  var file_filter = new Gtk.FileFilter();                      file_filter.add_pixbuf_formats(); -                     -                    #if HAVE_GTK_3 -                        file_filter.set_filter_name(_("All supported image formats")); -                    #else -                        file_filter.set_name(_("All supported image formats")); -                    #endif -                     +                    file_filter.set_filter_name(_("All supported image formats"));                      file_chooser.add_filter(file_filter); -                 +                  // set active_icon if the user selected a file                  file_chooser.selection_changed.connect(() => {                      if (file_chooser.get_filename() != null &&                          GLib.FileUtils.test(file_chooser.get_filename(),                                              GLib.FileTest.IS_REGULAR)) -                         +                          this.active_icon = file_chooser.get_filename();                  }); -                 +                  // hide this window when the user activates a file                  file_chooser.file_activated.connect(() => {                      this.active_icon = file_chooser.get_filename();                      this.on_ok(this.active_icon);                      this.window.hide();                  }); -             +              this.window.set_focus(this.icon_view);              this.window.delete_event.connect(this.window.hide_on_delete); -             +          } catch (GLib.Error e) {              error("Could not load UI: %s\n", e.message);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays the window. The icons are reloaded if neccessary.      ///////////////////////////////////////////////////////////////////// @@ -302,27 +292,27 @@ public class IconSelectWindow : GLib.Object {      public void show() {          this.window.show_all();          this.spinner.hide(); -         +          if (IconSelectWindow.need_reload) {              IconSelectWindow.need_reload = false;              this.load_icons();          } -    }  -     +    } +      public static void clear_icons() {          if (IconSelectWindow.icon_list != null) {              IconSelectWindow.need_reload = true;              IconSelectWindow.icon_list.clear();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes the window select the icon of the given Pie.      ///////////////////////////////////////////////////////////////////// -     +      public void set_icon(string icon) {          this.active_icon = icon; -         +          if (icon.contains("/")) {              this.file_chooser.set_filename(icon);              this.tabs.set_current_page(1); @@ -330,7 +320,7 @@ public class IconSelectWindow : GLib.Object {              this.icon_list_filtered.foreach((model, path, iter) => {                  string name = "";                  model.get(iter, 0, out name); -                 +                  if (name == icon) {                      this.icon_view.select_path(path);                      this.icon_view.scroll_to_path(path, true, 0.5f, 0.0f); @@ -338,38 +328,38 @@ public class IconSelectWindow : GLib.Object {                  }                  return (name == icon);              }); -             +              this.tabs.set_current_page(0);          } -    }  -     +    } +      /////////////////////////////////////////////////////////////////////      /// Called when the user clicks the ok button.      ///////////////////////////////////////////////////////////////////// -     +      private void on_ok_button_clicked() {          this.on_ok(this.active_icon);          this.window.hide();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user clicks the cancel button.      ///////////////////////////////////////////////////////////////////// -     +      private void on_cancel_button_clicked() {          this.window.hide();      } -     +      /////////////////////////////////////////////////////////////////////      /// (Re)load all icons.      ///////////////////////////////////////////////////////////////////// -     +      private void load_icons() {          // only if it's not loading currently          if (!IconSelectWindow.loading) {              IconSelectWindow.loading = true;              IconSelectWindow.icon_list.clear(); -             +              // display the spinner              if (spinner != null)                  this.spinner.visible = true; @@ -389,7 +379,7 @@ public class IconSelectWindow : GLib.Object {                                                  1, new_entry.context,                                                  2, new_entry.pixbuf);                  } -                 +                  // enable sorting of the icon_view if loading finished                  if (!IconSelectWindow.loading) {                      IconSelectWindow.icon_list.set_sort_column_id(0, Gtk.SortType.ASCENDING); @@ -399,19 +389,19 @@ public class IconSelectWindow : GLib.Object {              });          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all icons of an icon theme and pushes them into the      /// load_queue.      ///////////////////////////////////////////////////////////////////// -     +      private async void load_all() {          var icon_theme = Gtk.IconTheme.get_default(); -         +          foreach (var context in icon_theme.list_contexts()) {              if (!disabled_contexts.contains(context)) {                  foreach (var icon in icon_theme.list_icons(context)) { -                     +                      IconContext icon_context = IconContext.OTHER;                      switch(context) {                          case "Apps": case "Applications": @@ -426,31 +416,31 @@ public class IconSelectWindow : GLib.Object {                              icon_context = IconContext.ACTIONS; break;                          default: break;                      } -                     +                      Idle.add(load_all.callback);                      yield; -                     +                      try {                          // create a new entry for the queue                          var new_entry = new ListEntry();                          new_entry.name = icon;                          new_entry.context = icon_context;                          new_entry.pixbuf = icon_theme.load_icon(icon, 32, 0); -                         +                          // some icons have only weird sizes... do not include them                          if (new_entry.pixbuf.width == 32)                              this.load_queue.push(new_entry); -                             +                      } catch (GLib.Error e) {                          warning("Failed to load image " + icon);                      }                  }              }          } -         +          // finished loading          IconSelectWindow.loading = false; -         +          // hide the spinner          if (spinner != null)              spinner.visible = false; diff --git a/src/gui/indicator.vala b/src/gui/indicator.vala index 18d4e68..1277fb8 100644 --- a/src/gui/indicator.vala +++ b/src/gui/indicator.vala @@ -68,12 +68,9 @@ public class Indicator : GLib.Object {      public Indicator() {          string icon = ""; +        var screen = (Gdk.X11.Screen)Gdk.Screen.get_default(); -        #if HAVE_GTK_3 -            if (Gdk.X11Screen.get_window_manager_name(Gdk.Screen.get_default()) == "Mutter") -        #else -            if (Gdk.x11_screen_get_window_manager_name(Gdk.Screen.get_default()) == "Mutter") -        #endif +        if (screen.get_window_manager_name() == "Mutter")              icon = "gnome-pie";          else              icon = "gnome-pie-symbolic"; @@ -114,7 +111,7 @@ public class Indicator : GLib.Object {          this.prefs = new PreferencesWindow();          // preferences item -        var item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.PREFERENCES, null); +        var item = new Gtk.ImageMenuItem.with_mnemonic(_("_Preferences"));          item.activate.connect(() => {              this.prefs.show();          }); @@ -123,7 +120,7 @@ public class Indicator : GLib.Object {          menu.append(item);          // about item -        item = new Gtk.ImageMenuItem.from_stock (Gtk.Stock.ABOUT, null); +        item = new Gtk.ImageMenuItem.with_mnemonic(_("_About"));          item.show();          item.activate.connect(() => {              var about = new AboutWindow(); @@ -138,7 +135,7 @@ public class Indicator : GLib.Object {          menu.append(sepa);          // quit item -        item = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.QUIT, null); +        item = new Gtk.ImageMenuItem.with_mnemonic(_("_Quit"));          item.activate.connect(Gtk.main_quit);          item.show();          menu.append(item); diff --git a/src/gui/newSliceWindow.vala b/src/gui/newSliceWindow.vala index ade6432..92c7701 100644 --- a/src/gui/newSliceWindow.vala +++ b/src/gui/newSliceWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A window which allows selection of a new Slice which is about to be  /// added to a Pie. It can be also used to edit an existing Slice  ///////////////////////////////////////////////////////////////////////// @@ -28,7 +28,7 @@ public class NewSliceWindow : GLib.Object {      /// This signal gets emitted when the user confirms his selection.      ///////////////////////////////////////////////////////////////////// -    public signal void on_select(ActionGroup action, bool as_new_slice, int at_position);  +    public signal void on_select(ActionGroup action, bool as_new_slice, int at_position);      /////////////////////////////////////////////////////////////////////      /// The contained list of slice types. It contains both: Groups and @@ -36,78 +36,78 @@ public class NewSliceWindow : GLib.Object {      /////////////////////////////////////////////////////////////////////      private SliceTypeList slice_type_list = null; -     +      /////////////////////////////////////////////////////////////////////      /// The IconSelectWindow used for icon selection for a Slice.      ///////////////////////////////////////////////////////////////////// -     +      private IconSelectWindow? icon_window = null; -     +      /////////////////////////////////////////////////////////////////////      /// Some widgets of this window. Loaded by a ui-builder and stored      /// for later access.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Dialog window = null; -    private Gtk.HBox name_box = null; -    private Gtk.HBox command_box = null; +    private Gtk.Box name_box = null; +    private Gtk.Box command_box = null;      private Gtk.Button icon_button = null; -    private Gtk.VBox no_options_box = null; -    private Gtk.HBox pie_box = null; -    private Gtk.HBox hotkey_box = null; -    private Gtk.HBox uri_box = null; -    private Gtk.HBox quickaction_box = null; +    private Gtk.Box no_options_box = null; +    private Gtk.Box pie_box = null; +    private Gtk.Box hotkey_box = null; +    private Gtk.Box uri_box = null; +    private Gtk.Box quickaction_box = null;      private Gtk.Image icon = null;      private Gtk.Entry name_entry = null;      private Gtk.Entry command_entry = null;      private Gtk.Entry uri_entry = null;      private Gtk.CheckButton quickaction_checkbutton = null; -     +      /////////////////////////////////////////////////////////////////////      /// Two custom widgets. For Pie and hotkey selection respectively.      ///////////////////////////////////////////////////////////////////// -     +      private PieComboList pie_select = null;      private TriggerSelectButton key_select = null; -     +      /////////////////////////////////////////////////////////////////////      /// These members store information on the currently selected Slice.      ///////////////////////////////////////////////////////////////////// -     +      private string current_type = "";      private string current_icon = "";      private string current_id = "";      private string current_custom_icon = "";      private string current_hotkey = "";      private string current_pie_to_open = ""; -     +      /////////////////////////////////////////////////////////////////////      /// The position of the edited Slice in its parent Pie.      ///////////////////////////////////////////////////////////////////// -     +      private int slice_position = 0; -     +      /////////////////////////////////////////////////////////////////////      /// True, if the Slice i going to be added as a new Slice. Else it      /// will edit the Slice at slice_position in its parent Pie.      ///////////////////////////////////////////////////////////////////// -     +      private bool add_as_new_slice = true; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor creates a new window.      ///////////////////////////////////////////////////////////////////// -     +      public NewSliceWindow() {          try { -         +              Gtk.Builder builder = new Gtk.Builder();              builder.add_from_file (Paths.ui_files + "/slice_select.ui"); -             +              this.slice_type_list = new SliceTypeList();              this.slice_type_list.on_select.connect((type, icon) => { -                 +                  this.name_box.hide();                  this.command_box.hide();                  this.icon_button.sensitive = false; @@ -116,9 +116,9 @@ public class NewSliceWindow : GLib.Object {                  this.hotkey_box.hide();                  this.uri_box.hide();                  this.quickaction_box.hide(); -                 +                  this.current_type = type; -                 +                  switch (type) {                      case "bookmarks": case "clipboard": case "devices":                      case "menu": case "session": case "window_list": @@ -156,101 +156,101 @@ public class NewSliceWindow : GLib.Object {                          break;                  }              }); -             -            this.name_box = builder.get_object("name-box") as Gtk.HBox; -            this.command_box = builder.get_object("command-box") as Gtk.HBox; + +            this.name_box = builder.get_object("name-box") as Gtk.Box; +            this.command_box = builder.get_object("command-box") as Gtk.Box;              this.icon_button = builder.get_object("icon-button") as Gtk.Button; -            this.no_options_box = builder.get_object("no-options-box") as Gtk.VBox; -            this.pie_box = builder.get_object("pie-box") as Gtk.HBox; +            this.no_options_box = builder.get_object("no-options-box") as Gtk.Box; +            this.pie_box = builder.get_object("pie-box") as Gtk.Box;              this.pie_select = new PieComboList();              this.pie_select.on_select.connect((id) => {                  this.current_pie_to_open = id;                  this.set_icon(PieManager.all_pies[id].icon);              }); -             +              this.pie_box.pack_start(this.pie_select, true, true); -                 -            this.hotkey_box = builder.get_object("hotkey-box") as Gtk.HBox; + +            this.hotkey_box = builder.get_object("hotkey-box") as Gtk.Box;              this.key_select = new TriggerSelectButton(false);              this.hotkey_box.pack_start(this.key_select, false, true);              this.key_select.on_select.connect((trigger) => {                  this.current_hotkey = trigger.name;              }); -             -            this.uri_box = builder.get_object("uri-box") as Gtk.HBox; -             + +            this.uri_box = builder.get_object("uri-box") as Gtk.Box; +              this.name_entry = builder.get_object("name-entry") as Gtk.Entry;              this.uri_entry = builder.get_object("uri-entry") as Gtk.Entry;              this.command_entry = builder.get_object("command-entry") as Gtk.Entry;              this.quickaction_checkbutton = builder.get_object("quick-action-checkbutton") as Gtk.CheckButton; -             -            this.quickaction_box = builder.get_object("quickaction-box") as Gtk.HBox; -            this.icon = builder.get_object("icon") as Gtk.Image;             -             + +            this.quickaction_box = builder.get_object("quickaction-box") as Gtk.Box; +            this.icon = builder.get_object("icon") as Gtk.Image; +              this.icon_button.clicked.connect(on_icon_button_clicked); -             +              var scroll_area = builder.get_object("slice-scrolledwindow") as Gtk.ScrolledWindow;                  scroll_area.add(this.slice_type_list);              this.window = builder.get_object("window") as Gtk.Dialog; -             +              (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked);              (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); -             +              this.window.delete_event.connect(this.window.hide_on_delete); -                 +          } catch (GLib.Error e) {              error("Could not load UI: %s\n", e.message);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Sets the parent window, in order to make this window stay in      /// front.      ///////////////////////////////////////////////////////////////////// -     +      public void set_parent(Gtk.Window parent) {          this.window.set_transient_for(parent);      } -     +      /////////////////////////////////////////////////////////////////////      /// Sows the window on the screen.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.slice_type_list.select_first();          this.pie_select.select_first();          this.key_select.set_trigger(new Trigger());          this.window.show_all();      } -     +      /////////////////////////////////////////////////////////////////////      /// Reloads the window.      ///////////////////////////////////////////////////////////////////// -     +      public void reload() {          this.pie_select.reload();      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes all widgets display stuff according to the given action.      ///////////////////////////////////////////////////////////////////// -     +      public void set_action(ActionGroup group, int position) {          this.set_default(group.parent_id, position); -         +          this.add_as_new_slice = false;          string type = ""; -         +          if (group.get_type().depth() == 2) {              var action = group.actions[0];              type = ActionRegistry.descriptions[action.get_type().name()].id;              this.select_type(type); -             +              this.set_icon(action.icon);              this.quickaction_checkbutton.active = action.is_quickaction;              this.name_entry.text = action.name; -             +              switch (type) {                  case "app":                      this.current_custom_icon = action.icon; @@ -269,17 +269,17 @@ public class NewSliceWindow : GLib.Object {                      this.uri_entry.text = action.real_command;                      break;              } -             +          } else {              type = GroupRegistry.descriptions[group.get_type().name()].id;              this.select_type(type);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects a default action.      ///////////////////////////////////////////////////////////////////// -     +      public void set_default(string pie_id, int position) {          this.slice_position = position;          this.add_as_new_slice = true; @@ -292,25 +292,25 @@ public class NewSliceWindow : GLib.Object {          this.command_entry.text = "";          this.uri_entry.text = "";      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects a specific action type.      ///////////////////////////////////////////////////////////////////// -     +      private void select_type(string type) {          this.current_type = type;          this.slice_type_list.select(type);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called, when the user presses the ok button.      ///////////////////////////////////////////////////////////////////// -     +      private void on_ok_button_clicked() {          this.window.hide(); -         +          ActionGroup group = null; -         +          switch (this.current_type) {              case "bookmarks":   group = new BookmarkGroup(this.current_id);      break;              case "clipboard":   group = new ClipboardGroup(this.current_id);     break; @@ -321,44 +321,44 @@ public class NewSliceWindow : GLib.Object {              case "app":                  group = new ActionGroup(this.current_id); -                group.add_action(new AppAction(this.name_entry.text, this.current_icon,  -                                               this.command_entry.text,  +                group.add_action(new AppAction(this.name_entry.text, this.current_icon, +                                               this.command_entry.text,                                                 this.quickaction_checkbutton.active));                  break;              case "key":                  group = new ActionGroup(this.current_id); -                group.add_action(new KeyAction(this.name_entry.text, this.current_icon,  -                                               this.current_hotkey,  +                group.add_action(new KeyAction(this.name_entry.text, this.current_icon, +                                               this.current_hotkey,                                                 this.quickaction_checkbutton.active));                  break;              case "pie":                  group = new ActionGroup(this.current_id); -                group.add_action(new PieAction(this.current_pie_to_open,  +                group.add_action(new PieAction(this.current_pie_to_open,                                                 this.quickaction_checkbutton.active));                  break;              case "uri":                  group = new ActionGroup(this.current_id); -                group.add_action(new UriAction(this.name_entry.text, this.current_icon,  -                                               this.uri_entry.text,  +                group.add_action(new UriAction(this.name_entry.text, this.current_icon, +                                               this.uri_entry.text,                                                 this.quickaction_checkbutton.active));                  break;          } -         +          this.on_select(group, this.add_as_new_slice, this.slice_position);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user presses the cancel button.      ///////////////////////////////////////////////////////////////////// -     +      private void on_cancel_button_clicked() {          this.window.hide(); -    }    -     +    } +      /////////////////////////////////////////////////////////////////////      /// Called when the user presses the icon select button.      ///////////////////////////////////////////////////////////////////// -     +      private void on_icon_button_clicked(Gtk.Button button) {          if (this.icon_window == null) {              this.icon_window = new IconSelectWindow(this.window); @@ -367,30 +367,30 @@ public class NewSliceWindow : GLib.Object {                  this.set_icon(icon);              });          } -         +          this.icon_window.show();          this.icon_window.set_icon(this.current_icon);      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method which sets the icon of the icon select button.      /// It assures that both can be displayed: A customly chosen image      /// from or an icon from the current theme.      ///////////////////////////////////////////////////////////////////// -     +      private void set_icon(string icon) {          if (icon.contains("/"))              try { -                this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(icon, this.icon.get_pixel_size(),  +                this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(icon, this.icon.get_pixel_size(),                                                                       this.icon.get_pixel_size(), true);              } catch (GLib.Error error) {                  warning(error.message);              }          else              this.icon.icon_name = icon; -             +          this.current_icon = icon; -    }  +    }  }  } diff --git a/src/gui/newsWindow.vala b/src/gui/newsWindow.vala index 75de60e..373135f 100644 --- a/src/gui/newsWindow.vala +++ b/src/gui/newsWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,57 +12,57 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -///  +///////////////////////////////////////////////////////////////////////// +///  /////////////////////////////////////////////////////////////////////////  public class NewsWindow: Gtk.Dialog {      public static const int news_count = 2; -     +      ///////////////////////////////////////////////////////////////////// -    ///  +    ///      /////////////////////////////////////////////////////////////////////      public NewsWindow () {          this.title = "Gnome-Pie"; -         +          this.set_border_width(5); -         -        var box = new Gtk.VBox(false, 12); -         + +        var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 12); +              var image = new Gtk.Image.from_icon_name("gnome-pie", Gtk.IconSize.DIALOG);              box.pack_start(image); -         +              var news = new Gtk.Label("");                  news.wrap = true;                  news.set_width_chars(75);                  news.set_markup("<b>Thank you!</b>\n\n"); -                  +              box.pack_start(news, false, false); -             +              var check = new Gtk.CheckButton.with_label("Don't show this window again.");                  check.toggled.connect((check_box) => {                      var checky = check_box as Gtk.CheckButton; -                     +                      if (checky.active)  Config.global.showed_news = news_count;                      else                Config.global.showed_news = news_count-1; -                     +                      Config.global.save();                  }); -                 +              box.pack_end(check); -         +          (this.get_content_area() as Gtk.VBox).pack_start(box);          this.get_content_area().show_all(); -         -        this.add_button(Gtk.Stock.CLOSE, 0); -         + +        this.add_button(_("_Close"), 0); +          this.response.connect((id) => {              if (id == 0)                  this.hide(); diff --git a/src/gui/piePreview.vala b/src/gui/piePreview.vala index 3ddf6c8..0420d5e 100644 --- a/src/gui/piePreview.vala +++ b/src/gui/piePreview.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A custom widget displaying the preview of a Pie. It can be used to  /// configure the displayed Pie in various aspects.  ///////////////////////////////////////////////////////////////////////// @@ -31,42 +31,42 @@ class PiePreview : Gtk.DrawingArea {      public signal void on_last_slice_removed();      public signal void on_first_slice_added(); -     +      /////////////////////////////////////////////////////////////////////      /// The internally used renderer to draw the Pie.      /////////////////////////////////////////////////////////////////////      private PiePreviewRenderer renderer = null; -     +      /////////////////////////////////////////////////////////////////////      /// The window which pops up, when a Slice is added or edited.      ///////////////////////////////////////////////////////////////////// -     +      private NewSliceWindow? new_slice_window = null; -     +      /////////////////////////////////////////////////////////////////////      /// A timer used for calculating the frame time.      ///////////////////////////////////////////////////////////////////// -     +      private GLib.Timer timer; -     +      /////////////////////////////////////////////////////////////////////      /// True, when it is possible to drag a slice from this widget.      /// False, when the user currently hovers over the add sign.      ///////////////////////////////////////////////////////////////////// -     +      private bool drag_enabled = false; -     +      /////////////////////////////////////////////////////////////////////      /// The ID of the currently displayed Pie.      ///////////////////////////////////////////////////////////////////// -     +      private string current_id = ""; -     +      /////////////////////////////////////////////////////////////////////      /// The position from where a Slice-drag started.      ///////////////////////////////////////////////////////////////////// -     +      private int drag_start_index = -1;      private string drag_start_id = ""; @@ -75,50 +75,45 @@ class PiePreview : Gtk.DrawingArea {      /////////////////////////////////////////////////////////////////////      public PiePreview() { -        this.renderer = new PiePreviewRenderer(); -     -        #if HAVE_GTK_3 -            this.draw.connect(this.on_draw); -        #else -            this.expose_event.connect(this.on_draw); -        #endif -     +        this.renderer = new PiePreviewRenderer(this); + +        this.draw.connect(this.on_draw);          this.timer = new GLib.Timer(); -        this.set_events(Gdk.EventMask.POINTER_MOTION_MASK  +        this.set_events(Gdk.EventMask.POINTER_MOTION_MASK                        | Gdk.EventMask.LEAVE_NOTIFY_MASK                        | Gdk.EventMask.ENTER_NOTIFY_MASK); -         +          // setup drag and drop          this.enable_drag_source(); -         +          Gtk.TargetEntry uri_dest = {"text/uri-list", 0, 0};          Gtk.TargetEntry slice_dest = {"text/plain", Gtk.TargetFlags.SAME_WIDGET, 0};          Gtk.TargetEntry[] destinations = { uri_dest, slice_dest };          Gtk.drag_dest_set(this, Gtk.DestDefaults.ALL, destinations, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK); -         +          this.drag_begin.connect(this.on_start_drag);          this.drag_end.connect(this.on_end_drag);          this.drag_data_received.connect(this.on_dnd_received); -         +          // connect mouse events          this.drag_motion.connect(this.on_drag_move);          this.leave_notify_event.connect(this.on_mouse_leave); -        this.enter_notify_event.connect(this.on_mouse_enter);   +        this.enter_notify_event.connect(this.on_mouse_enter);          this.motion_notify_event.connect_after(this.on_mouse_move);          this.button_release_event.connect_after(this.on_button_release);          this.button_press_event.connect_after(this.on_button_press); -         +          this.new_slice_window = new NewSliceWindow();          this.new_slice_window.on_select.connect((new_action, as_new_slice, at_position) => {              var pie = PieManager.all_pies[this.current_id]; -             +              if (new_action.has_quickaction())                  renderer.disable_quickactions(); -             +              if (as_new_slice) {                  pie.add_group(new_action, at_position+1);                  this.renderer.add_group(new_action, at_position+1); -                 +                  if (this.renderer.slice_count() == 1)                      this.on_first_slice_added();              } else { @@ -126,72 +121,74 @@ class PiePreview : Gtk.DrawingArea {                  this.renderer.update_group(new_action, at_position);              }          }); -         +          this.renderer.on_edit_slice.connect((pos) => {              this.new_slice_window.reload(); -             +              this.new_slice_window.set_parent(this.get_toplevel() as Gtk.Window);              this.new_slice_window.show(); -             +              var pie = PieManager.all_pies[this.current_id];              this.new_slice_window.set_action(pie.action_groups[pos], pos);          }); -         +          this.renderer.on_add_slice.connect((pos) => {              this.new_slice_window.reload(); -             +              this.new_slice_window.set_parent(this.get_toplevel() as Gtk.Window);              this.new_slice_window.show(); -             +              this.new_slice_window.set_default(this.current_id, pos);          }); -         +          this.renderer.on_remove_slice.connect((pos) => { -             +              var dialog = new Gtk.MessageDialog(this.get_toplevel() as Gtk.Window, Gtk.DialogFlags.MODAL,                           Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,                           _("Do you really want to delete this Slice?")); -                                                      +              dialog.response.connect((response) => {                  if (response == Gtk.ResponseType.YES) {                      var pie = PieManager.all_pies[this.current_id]; -             +                      pie.remove_group(pos);                      this.renderer.remove_group(pos); -                     +                      if (this.renderer.slice_count() == 0)                          this.on_last_slice_removed();                  }              }); -             +              dialog.run();              dialog.destroy();          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Sets the currently displayed Pie to the Pie with the given ID.      ///////////////////////////////////////////////////////////////////// -     +      public void set_pie(string id) { +        var style = this.get_style_context(); +          this.current_id = id; -        this.modify_bg(Gtk.StateType.NORMAL, Gtk.rc_get_style(this).light[Gtk.StateType.NORMAL]); +        this.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL));          this.renderer.load_pie(PieManager.all_pies[id]); -         +          if (id == this.drag_start_id) {              this.renderer.hide_group(this.drag_start_index);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Begins the draw loop. It automatically ends, when the containing      /// window becomes invisible.      ///////////////////////////////////////////////////////////////////// -     +      public void draw_loop() {          this.timer.start();          this.queue_draw(); -         +          GLib.Timeout.add((uint)(1000.0/Config.global.refresh_rate), () => {              this.queue_draw();              return this.get_toplevel().visible; @@ -201,97 +198,92 @@ class PiePreview : Gtk.DrawingArea {      /////////////////////////////////////////////////////////////////////      /// Called every frame.      ///////////////////////////////////////////////////////////////////// -     -    #if HAVE_GTK_3 -         private bool on_draw(Cairo.Context ctx) {  -    #else -         private bool on_draw(Gtk.Widget da, Gdk.EventExpose event) {  -            var ctx = Gdk.cairo_create(this.get_window()); -    #endif + +    private bool on_draw(Cairo.Context ctx) {          // store the frame time          double frame_time = this.timer.elapsed();          this.timer.reset(); -         +          Gtk.Allocation allocation;          this.get_allocation(out allocation); -         +          ctx.translate((int)(allocation.width*0.5), (int)(allocation.height*0.5)); -         +          this.renderer.draw(frame_time, ctx); -         +          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse leaves the area of this widget.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_mouse_leave(Gdk.EventCrossing event) {          this.renderer.on_mouse_leave();          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse enters the area of this widget.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_mouse_enter(Gdk.EventCrossing event) {          this.renderer.on_mouse_enter();          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse moves in the area of this widget.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_mouse_move(Gdk.EventMotion event) {          this.renderer.set_dnd_mode(false);          Gtk.Allocation allocation;          this.get_allocation(out allocation);          this.renderer.on_mouse_move(event.x-allocation.width*0.5, event.y-allocation.height*0.5); -         +          if (this.renderer.get_active_slice() < 0) this.disable_drag_source();          else                                      this.enable_drag_source(); -         +          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a mouse button is pressed.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_button_press() {          this.renderer.on_button_press();          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a mouse button is released.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_button_release() { -        if (!this.renderer.drag_n_drop_mode)  +        if (!this.renderer.drag_n_drop_mode)              this.renderer.on_button_release();          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse is moved over this widget.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_drag_move(Gdk.DragContext ctx, int x, int y, uint time) {          this.renderer.set_dnd_mode(true);          Gtk.Allocation allocation;          this.get_allocation(out allocation);          this.renderer.on_mouse_move(x-allocation.width*0.5, y-allocation.height*0.5); -         +          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user tries to drag something from this widget.      ///////////////////////////////////////////////////////////////////// -     +      private void on_start_drag(Gdk.DragContext ctx) {          this.drag_start_index = this.renderer.get_active_slice();          this.drag_start_id = this.current_id; @@ -300,19 +292,19 @@ class PiePreview : Gtk.DrawingArea {          this.renderer.hide_group(this.drag_start_index);          Gtk.drag_set_icon_pixbuf(ctx, pixbuf, icon.size()/2, icon.size()/2); -         +          this.renderer.set_dnd_mode(true);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user finishes a drag operation on this widget.      /// Only used for Slice-movement.      ///////////////////////////////////////////////////////////////////// -     +      private void on_end_drag(Gdk.DragContext context) { -         +          if (context.list_targets() != null) { -         +              int target_index = this.renderer.get_active_slice();              this.renderer.set_dnd_mode(false); @@ -328,48 +320,48 @@ class PiePreview : Gtk.DrawingArea {                          var dst_pie = PieManager.all_pies[this.current_id];                          dst_pie.add_group(src_pie.action_groups[this.drag_start_index], target_index);                          this.renderer.add_group(dst_pie.action_groups[target_index], target_index); -                         +                          if (this.renderer.slices.size == 1)                              this.on_first_slice_added(); -                         +                          if ((context.get_actions() & Gdk.DragAction.COPY) == 0)                              src_pie.remove_group(this.drag_start_index);                      } -                 -                     + +                  }              }); -             +              this.drag_start_index = -1;              this.drag_start_id = ""; -        }   +        }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user finishes a drag operation on this widget.      /// Only used for external drags.      ///////////////////////////////////////////////////////////////////// -     -    private void on_dnd_received(Gdk.DragContext context, int x, int y,  + +    private void on_dnd_received(Gdk.DragContext context, int x, int y,                                   Gtk.SelectionData selection_data, uint info, uint time_) { -                                  +          var pie = PieManager.all_pies[this.current_id];          int position = this.renderer.get_active_slice();          this.renderer.set_dnd_mode(false); -         +          foreach (var uri in selection_data.get_uris()) {              pie.add_action(ActionRegistry.new_for_uri(uri), position);              this.renderer.add_group(pie.action_groups[position], position); -             +              if (this.renderer.slices.size == 1)                  this.on_first_slice_added();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Enables this widget to be a source for drag operations.      ///////////////////////////////////////////////////////////////////// -     +      private void enable_drag_source() {          if (!this.drag_enabled) {              this.drag_enabled = true; @@ -378,18 +370,18 @@ class PiePreview : Gtk.DrawingArea {              Gtk.drag_source_set(this, Gdk.ModifierType.BUTTON1_MASK, sources, Gdk.DragAction.MOVE | Gdk.DragAction.COPY);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Disables this widget to be a source for drag operations. -    /////////////////////////////////////////////////////////////////////    -        +    ///////////////////////////////////////////////////////////////////// +      private void disable_drag_source() {          if (this.drag_enabled) {              this.drag_enabled = false;              Gtk.drag_source_unset(this);          }      } -    +  }  } diff --git a/src/gui/piePreviewCenter.vala b/src/gui/piePreviewCenter.vala index 21bbd78..20527bc 100644 --- a/src/gui/piePreviewCenter.vala +++ b/src/gui/piePreviewCenter.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,79 +12,80 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -///  +///////////////////////////////////////////////////////////////////////// +///  /////////////////////////////////////////////////////////////////////////  public class PiePreviewCenter : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// THe Images displayed. When the displayed text changes the      /// currently displayed text becomes the old_text. So it's possible      /// to create a smooth transitions.      ///////////////////////////////////////////////////////////////////// -     +      private RenderedText text = null;      private RenderedText old_text = null; -     +      /////////////////////////////////////////////////////////////////////      /// Stores the currently displayed text in order to avoid frequent      /// and useless updates.      ///////////////////////////////////////////////////////////////////// -     +      private string current_text = null; -     +      /////////////////////////////////////////////////////////////////////      /// An AnimatedValue for smooth transitions.      ///////////////////////////////////////////////////////////////////// -     -    private AnimatedValue blend;  -     + +    private AnimatedValue blend; +      /////////////////////////////////////////////////////////////////////      /// The parent renderer.      ///////////////////////////////////////////////////////////////////// -     -    private unowned PiePreviewRenderer parent;   -     + +    private unowned PiePreviewRenderer parent; +      /////////////////////////////////////////////////////////////////////      /// C'tor, sets everything up.      ///////////////////////////////////////////////////////////////////// -     +      public PiePreviewCenter(PiePreviewRenderer parent) {          this.parent = parent;          this.blend = new AnimatedValue.linear(0, 0, 0); -         +          this.text = new RenderedText("", 1, 1, "", new Color(), 1.0);          this.old_text = text;      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the currently displayed text. It will be smoothly -    /// blended and may contain pango markup.  +    /// blended and may contain pango markup.      ///////////////////////////////////////////////////////////////////// -     +      public void set_text(string text) {          if (text != this.current_text) { -             -            var style = new Gtk.Style(); -             + +            var style = parent.parent.get_style_context(); +              this.old_text = this.text; -            this.text = new RenderedText.with_markup(text, 180, 180, style.font_desc.get_family()+" 10",  -                                                     new Color.from_gdk(style.fg[0]), 1.0); +            this.text = new RenderedText.with_markup( +                            text, 180, 180, style.get_font(Gtk.StateFlags.NORMAL).get_family()+" 10", +                            new Color.from_gdk(style.get_color(Gtk.StateFlags.NORMAL)), 1.0);              this.current_text = text; -             +              this.blend.reset_target(0.0, 0.0);              this.blend.reset_target(1.0, 0.1);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the center to the given context.      ///////////////////////////////////////////////////////////////////// @@ -92,15 +93,15 @@ public class PiePreviewCenter : GLib.Object {      public void draw(double frame_time, Cairo.Context ctx) {          this.blend.update(frame_time); -         +          ctx.save(); -         -        if (this.parent.slice_count() == 0)  + +        if (this.parent.slice_count() == 0)              ctx.translate(0, 40); -         +          this.old_text.paint_on(ctx, 1-this.blend.val);          this.text.paint_on(ctx, this.blend.val); -             +          ctx.restore();      }  } diff --git a/src/gui/piePreviewRenderer.vala b/src/gui/piePreviewRenderer.vala index 6fff397..626ab73 100644 --- a/src/gui/piePreviewRenderer.vala +++ b/src/gui/piePreviewRenderer.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,110 +12,117 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A complex class which is able to draw the preview of a Pie. It can  /// manipulate the displayed Pie as well.  /////////////////////////////////////////////////////////////////////////  public class PiePreviewRenderer : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// These signals get emitted when a slice is added, removed or      /// manipulated.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_add_slice(int position);      public signal void on_remove_slice(int position);      public signal void on_edit_slice(int position); -     +      /////////////////////////////////////////////////////////////////////      /// True, when there is currently a drag going on.      ///////////////////////////////////////////////////////////////////// -     +      public bool drag_n_drop_mode { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// A list containing all SliceRenderers of this Pie.      ///////////////////////////////////////////////////////////////////// -     +      public Gee.ArrayList<PiePreviewSliceRenderer?> slices; -     +      /////////////////////////////////////////////////////////////////////      /// When a Slice is moved within a Pie it is temporarily removed.      /// If so, it is stored in this member.      ///////////////////////////////////////////////////////////////////// -     +      public PiePreviewSliceRenderer hidden_group { get; private set; default=null; } -     +      /////////////////////////////////////////////////////////////////////      /// The add sign which indicates that a new Slice could be added.      ///////////////////////////////////////////////////////////////////// -     +      private PiePreviewAddSign add_sign = null; -     +      /////////////////////////////////////////////////////////////////////      /// The object which renders the name of the currently selected Slice      /// in the middle.      ///////////////////////////////////////////////////////////////////// -     +      private PiePreviewCenter center_renderer = null;      private enum CenterDisplay { NONE, ACTIVE_SLICE, DROP, ADD, DELETE } -     +      /////////////////////////////////////////////////////////////////////      /// Some members storing some inter-frame-information.      /////////////////////////////////////////////////////////////////////      private int active_slice = -1; -    private double angle = 0.0;     +    private double angle = 0.0;      private double mouse_x = 0.0;      private double mouse_y = 0.0; -     + +    ///////////////////////////////////////////////////////////////////// +    /// The parent DrawingArea. +    ///////////////////////////////////////////////////////////////////// + +    public unowned Gtk.DrawingArea parent; +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes members.      ///////////////////////////////////////////////////////////////////// -     -    public PiePreviewRenderer() { -        this.slices = new Gee.ArrayList<PiePreviewSliceRenderer?>();  + +    public PiePreviewRenderer(Gtk.DrawingArea parent) { +        this.parent = parent; +        this.slices = new Gee.ArrayList<PiePreviewSliceRenderer?>();          this.center_renderer = new PiePreviewCenter(this);          this.add_sign = new PiePreviewAddSign(this);          this.add_sign.load(); -         +          this.add_sign.on_clicked.connect((pos) => {              this.on_add_slice(pos);          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an Pie. All members are initialized accordingly.      ///////////////////////////////////////////////////////////////////// -     +      public void load_pie(Pie pie) {          this.slices.clear(); -     +          foreach (var group in pie.action_groups) {              var renderer = new PiePreviewSliceRenderer(this);              renderer.load(group); -             +              this.add_slice_renderer(renderer);              this.connect_siganls(renderer);          } -         +          this.active_slice = -1;          this.update_sizes();          this.update_positions(false);      } -     +      /////////////////////////////////////////////////////////////////////      /// Enables or disables the drag n dropn mode.      ///////////////////////////////////////////////////////////////////// -     +      public void set_dnd_mode(bool dnd) {          if (this.drag_n_drop_mode != dnd) {              this.drag_n_drop_mode = dnd; @@ -123,144 +130,144 @@ public class PiePreviewRenderer : GLib.Object {              this.update_sizes();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the number of Slices.      ///////////////////////////////////////////////////////////////////// -     +      public int slice_count() { -        if (this.drag_n_drop_mode && !(this.slices.size == 0))  +        if (this.drag_n_drop_mode && !(this.slices.size == 0))              return slices.size+1; -         +          return slices.size;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the index of the currently hovered Slice.      ///////////////////////////////////////////////////////////////////// -     +      public int get_active_slice() {          if (this.slices.size == 0)              return 0; -     +          if (this.drag_n_drop_mode)              return (int)(this.angle/(2*PI)*this.slice_count() + 0.5) % this.slice_count(); -             +          return this.active_slice;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the Icon of the currently hovered Slice.      ///////////////////////////////////////////////////////////////////// -     +      public Icon get_active_icon() {          if (this.active_slice >= 0 && this.active_slice < this.slices.size)              return this.slices[this.active_slice].icon;          else              return new Icon("", 24);      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the entire Pie to the given context.      ///////////////////////////////////////////////////////////////////// -     +      public void draw(double frame_time, Cairo.Context ctx) {          this.add_sign.draw(frame_time, ctx);          this.center_renderer.draw(frame_time, ctx); -         +          foreach (var slice in this.slices)              slice.draw(frame_time, ctx);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse leaves the drawing area of this renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_leave() {          this.add_sign.hide();          this.update_positions();          this.update_center(CenterDisplay.NONE); -         +          foreach (var slice in this.slices)              slice.on_mouse_leave();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse enters the drawing area of this renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_enter() {          this.add_sign.show();          this.update_positions();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse moves in the drawing area of this renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_move(double x, double y) {          this.mouse_x = x;          this.mouse_y = y; -         +          this.angle = acos(x/sqrt(x*x + y*y));          if (y < 0) this.angle = 2*PI - this.angle; -     +          if (!this.drag_n_drop_mode)              this.active_slice = -1; -         +          bool delete_hovered = false; -         +          for (int i=0; i<this.slices.size; ++i)              if (slices[i].on_mouse_move(this.angle, x, y) && !this.drag_n_drop_mode) {                  this.active_slice = i;                  delete_hovered = slices[i].delete_hovered;              } -         +          if (this.drag_n_drop_mode)      this.update_center(CenterDisplay.DROP);          else if (this.active_slice < 0) this.update_center(CenterDisplay.ADD);          else if (delete_hovered)        this.update_center(CenterDisplay.DELETE);          else                            this.update_center(CenterDisplay.ACTIVE_SLICE); -             +          this.add_sign.on_mouse_move(this.angle); -         +          this.update_positions();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a mouse button is pressed over this renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_press() {          for (int i=0; i<this.slices.size; ++i)              this.slices[i].on_button_press(this.mouse_x, this.mouse_y);          this.add_sign.on_button_press(this.mouse_x, this.mouse_y);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a mouse button is released over this renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_release() {          for (int i=0; i<this.slices.size; ++i)              this.slices[i].on_button_release(this.mouse_x, this.mouse_y);          this.add_sign.on_button_release(this.mouse_x, this.mouse_y);      } -     +      /////////////////////////////////////////////////////////////////////      /// Adds a new Slice to the renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void add_group(ActionGroup group, int at_position = -1) {          var renderer = new PiePreviewSliceRenderer(this);          renderer.load(group);          this.add_slice_renderer(renderer, at_position);          this.connect_siganls(renderer);      } -     +      /////////////////////////////////////////////////////////////////////      /// Removes a Slice from the renderer.      ///////////////////////////////////////////////////////////////////// -     +      public void remove_group(int index) {          if (this.slices.size > index) {              this.slices.remove_at(index); @@ -268,22 +275,22 @@ public class PiePreviewRenderer : GLib.Object {              this.update_sizes();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Hides the Slice at the given position temporarily.      ///////////////////////////////////////////////////////////////////// -     +      public void hide_group(int index) {          if (this.slices.size > index) {              this.hidden_group = this.slices[index];              this.remove_group(index);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Re-shows a Slice which has been hidden before.      ///////////////////////////////////////////////////////////////////// -     +      public void show_hidden_group_at(int index) {          if (this.slices.size >= index && this.hidden_group != null) {              this.hidden_group.set_position(index, false); @@ -291,78 +298,78 @@ public class PiePreviewRenderer : GLib.Object {              this.hidden_group = null;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates a Slice at the given position.      ///////////////////////////////////////////////////////////////////// -     +      public void update_group(ActionGroup group, int index) {          if (this.slices.size > index) {              var renderer = new PiePreviewSliceRenderer(this);              this.slices.set(index, renderer);              renderer.load(group); -             +              this.connect_siganls(renderer); -             +              this.update_positions(false);              this.update_sizes();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Disables all quickactions of this pie preview.      ///////////////////////////////////////////////////////////////////// -     +      public void disable_quickactions() {          foreach (var slice in this.slices)              slice.disable_quickactions();      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method which adds a new Slice to the given position.      ///////////////////////////////////////////////////////////////////// -     +      private void add_slice_renderer(PiePreviewSliceRenderer renderer, int at_position = -1) {          if (at_position < 0 || at_position >= this.slices.size)              this.slices.add(renderer);          else              this.slices.insert(at_position, renderer); -         +          this.update_positions(false);          this.update_sizes();      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method which connects all neccessary signals of a newly      /// added Slice.      ///////////////////////////////////////////////////////////////////// -     +      private void connect_siganls(PiePreviewSliceRenderer renderer) {          renderer.on_clicked.connect((pos) => {              this.on_edit_slice(pos);          }); -         +          renderer.on_remove.connect((pos) => {              this.on_remove_slice(pos);          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Moves all slices to their positions. This may happen smoothly if      /// desired.      ///////////////////////////////////////////////////////////////////// -     +      private void update_positions(bool smoothly = true) {          if (this.slices.size > 0) {              if (this.add_sign.visible) {                  int add_position = 0;                  add_position = (int)(this.angle/(2*PI)*this.slice_count()) % this.slice_count();                  this.add_sign.set_position(add_position); -                 +                  for (int i=0; i<this.slices.size; ++i) {                      this.slices[i].set_position(i, smoothly);                  } -             +              } else if (this.drag_n_drop_mode) {                  int add_position = 0;                  add_position = (int)(this.angle/(2*PI)*this.slice_count() + 0.5) % this.slice_count(); @@ -370,45 +377,45 @@ public class PiePreviewRenderer : GLib.Object {                  for (int i=0; i<this.slices.size; ++i) {                      this.slices[i].set_position(i >= add_position ? i+1 : i, smoothly);                  } -                 +                  this.update_center(CenterDisplay.DROP); -                 +              } else {                  for (int i=0; i<this.slices.size; ++i) {                      this.slices[i].set_position(i, smoothly);                  } -                 +                  if (this.active_slice < 0)  this.update_center(CenterDisplay.NONE);                  else                        this.update_center(CenterDisplay.ACTIVE_SLICE);              }          }      } -     +      ///////////////////////////////////////////////////////////////////// -    /// Resizes all slices to their new sizes. This may happen smoothly  +    /// Resizes all slices to their new sizes. This may happen smoothly      /// if desired.      ///////////////////////////////////////////////////////////////////// -         +      private void update_sizes() {          double size = 1.0;          if (this.slice_count() > 20)     size = 0.5;          else if (this.slice_count() > 8) size = 1.0 - (double)(this.slice_count() - 8)/24.0; -         +          this.add_sign.set_size(size); -         -        for (int i=0; i<this.slices.size; ++i)  + +        for (int i=0; i<this.slices.size; ++i)              this.slices[i].set_size(size);      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays a new text in the middle of the preview.      ///////////////////////////////////////////////////////////////////// -     +      private void update_center(CenterDisplay display) {          switch (display) {              case CenterDisplay.ACTIVE_SLICE:                  if (this.active_slice >= 0 && this.active_slice < this.slices.size) -                    this.center_renderer.set_text("<b>" + GLib.Markup.escape_text(slices[this.active_slice].name) + "</b>\n<small>"  +                    this.center_renderer.set_text("<b>" + GLib.Markup.escape_text(slices[this.active_slice].name) + "</b>\n<small>"                                              + _("Click to edit") + "\n" + _("Drag to move") + "</small>");                  break;              case CenterDisplay.ADD: @@ -423,7 +430,7 @@ public class PiePreviewRenderer : GLib.Object {                  break;              case CenterDisplay.DELETE:                  if (this.active_slice >= 0 && this.active_slice < this.slices.size) -                    this.center_renderer.set_text("<b>" + GLib.Markup.escape_text(slices[this.active_slice].name) + "</b>\n<small>"  +                    this.center_renderer.set_text("<b>" + GLib.Markup.escape_text(slices[this.active_slice].name) + "</b>\n<small>"                                              + _("Click to delete") + "\n" + _("Drag to move") + "</small>");                  break;              default: diff --git a/src/gui/preferencesWindow.vala b/src/gui/preferencesWindow.vala index 3055bc5..8cdc853 100644 --- a/src/gui/preferencesWindow.vala +++ b/src/gui/preferencesWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,164 +12,155 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// The settings menu of Gnome-Pie.  /////////////////////////////////////////////////////////////////////////  public class PreferencesWindow : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// The ID of the currently selected Pie.      ///////////////////////////////////////////////////////////////////// -     +      private string selected_id = ""; -     +      /////////////////////////////////////////////////////////////////////      /// Some Gtk widgets used by this window.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Window? window = null;      private Gtk.Label? id_label = null;      private Gtk.Label? name_label = null;      private Gtk.Label? hotkey_label = null;      private Gtk.Label? no_pie_label = null;      private Gtk.Label? no_slice_label = null; -    private Gtk.VBox? preview_box = null; +    private Gtk.Box? preview_box = null;      private Gtk.Image? icon = null;      private Gtk.EventBox? preview_background = null;      private Gtk.Button? icon_button = null;      private Gtk.Button? name_button = null;      private Gtk.Button? hotkey_button = null;      private Gtk.ToolButton? remove_pie_button = null; -     +      /////////////////////////////////////////////////////////////////////      /// Some custom widgets and dialogs used by this window.      ///////////////////////////////////////////////////////////////////// -     +      private PiePreview? preview = null;      private PieList? pie_list = null;      private SettingsWindow? settings_window = null;      private TriggerSelectWindow? trigger_window = null;      private IconSelectWindow? icon_window = null;      private RenameWindow? rename_window = null; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates the window.      ///////////////////////////////////////////////////////////////////// -     +      public PreferencesWindow() { -        try { -            var builder = new Gtk.Builder(); - -            builder.add_from_file (Paths.ui_files + "/preferences.ui"); - -            this.window = builder.get_object("window") as Gtk.Window; -             -            this.window.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK | -                        Gdk.EventMask.KEY_RELEASE_MASK | -                        Gdk.EventMask.KEY_PRESS_MASK | -                        Gdk.EventMask.POINTER_MOTION_MASK); -             -            #if HAVE_GTK_3 -                var toolbar = builder.get_object ("toolbar") as Gtk.Widget; -                toolbar.get_style_context().add_class("primary-toolbar"); -                 -                var inline_toolbar = builder.get_object ("pies-toolbar") as Gtk.Widget; -                inline_toolbar.get_style_context().add_class("inline-toolbar"); -            #endif -             -            this.pie_list = new PieList(); -            this.pie_list.on_select.connect(this.on_pie_select); -             -            var scroll_area = builder.get_object("pies-scrolledwindow") as Gtk.ScrolledWindow; -            scroll_area.add(this.pie_list); -             -            this.preview = new PiePreview(); -            this.preview.on_first_slice_added.connect(() => { -                this.no_slice_label.hide(); -            }); -             -            this.preview.on_last_slice_removed.connect(() => { -                this.no_slice_label.show(); -            }); -             -            preview_box = builder.get_object("preview-box") as Gtk.VBox; -            this.preview_box.pack_start(preview, true, true); -             -            this.id_label = builder.get_object("id-label") as Gtk.Label; -            this.name_label = builder.get_object("pie-name-label") as Gtk.Label; -            this.hotkey_label = builder.get_object("hotkey-label") as Gtk.Label; -            this.no_pie_label = builder.get_object("no-pie-label") as Gtk.Label; -            this.no_slice_label = builder.get_object("no-slice-label") as Gtk.Label; -            this.icon = builder.get_object("icon") as Gtk.Image; -            this.preview_background = builder.get_object("preview-background") as Gtk.EventBox; -                     -            (builder.get_object("settings-button") as Gtk.ToolButton).clicked.connect(on_settings_button_clicked); -             -            this.hotkey_button = builder.get_object("key-button") as Gtk.Button; -            this.hotkey_button.clicked.connect(on_key_button_clicked); -             -            this.icon_button = builder.get_object("icon-button") as Gtk.Button; -            this.icon_button.clicked.connect(on_icon_button_clicked); -             -            this.name_button = builder.get_object("rename-button") as Gtk.Button; -            this.name_button.clicked.connect(on_rename_button_clicked); -             -            this.remove_pie_button = builder.get_object("remove-pie-button") as Gtk.ToolButton; -            this.remove_pie_button.clicked.connect(on_remove_pie_button_clicked); -             -            (builder.get_object("add-pie-button") as Gtk.ToolButton).clicked.connect(on_add_pie_button_clicked); -             -            this.window.hide.connect(() => { -                // save settings on close -                Config.global.save(); -                Pies.save(); -                 -                Timeout.add(100, () => { -                    IconSelectWindow.clear_icons(); -                    return false; -                }); +        var builder = new Gtk.Builder.from_file(Paths.ui_files + "/preferences.ui"); + +        this.window = builder.get_object("window") as Gtk.Window; +        this.window.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK | +                    Gdk.EventMask.KEY_RELEASE_MASK | +                    Gdk.EventMask.KEY_PRESS_MASK | +                    Gdk.EventMask.POINTER_MOTION_MASK); + +        var toolbar = builder.get_object ("toolbar") as Gtk.Widget; +        toolbar.get_style_context().add_class("primary-toolbar"); + +        var inline_toolbar = builder.get_object ("pies-toolbar") as Gtk.Widget; +        inline_toolbar.get_style_context().add_class("inline-toolbar"); + +        this.pie_list = new PieList(); +        this.pie_list.on_select.connect(this.on_pie_select); + +        var scroll_area = builder.get_object("pies-scrolledwindow") as Gtk.ScrolledWindow; +        scroll_area.add(this.pie_list); + +        this.preview = new PiePreview(); +        this.preview.on_first_slice_added.connect(() => { +            this.no_slice_label.hide(); +        }); + +        this.preview.on_last_slice_removed.connect(() => { +            this.no_slice_label.show(); +        }); + +        preview_box = builder.get_object("preview-box") as Gtk.Box; +        this.preview_box.pack_start(preview, true, true); +        this.id_label = builder.get_object("id-label") as Gtk.Label; +        this.name_label = builder.get_object("pie-name-label") as Gtk.Label; +        this.hotkey_label = builder.get_object("hotkey-label") as Gtk.Label; +        this.no_pie_label = builder.get_object("no-pie-label") as Gtk.Label; +        this.no_slice_label = builder.get_object("no-slice-label") as Gtk.Label; +        this.icon = builder.get_object("icon") as Gtk.Image; +        this.preview_background = builder.get_object("preview-background") as Gtk.EventBox; + +        (builder.get_object("settings-button") as Gtk.ToolButton).clicked.connect(on_settings_button_clicked); + +        this.hotkey_button = builder.get_object("key-button") as Gtk.Button; +        this.hotkey_button.clicked.connect(on_key_button_clicked); + +        this.icon_button = builder.get_object("icon-button") as Gtk.Button; +        this.icon_button.clicked.connect(on_icon_button_clicked); + +        this.name_button = builder.get_object("rename-button") as Gtk.Button; +        this.name_button.clicked.connect(on_rename_button_clicked); + +        this.remove_pie_button = builder.get_object("remove-pie-button") as Gtk.ToolButton; +        this.remove_pie_button.clicked.connect(on_remove_pie_button_clicked); + +        (builder.get_object("add-pie-button") as Gtk.ToolButton).clicked.connect(on_add_pie_button_clicked); + +        this.window.hide.connect(() => { +            // save settings on close +            Config.global.save(); +            Pies.save(); + +            Timeout.add(100, () => { +                IconSelectWindow.clear_icons(); +                return false;              }); -             -            this.window.delete_event.connect(this.window.hide_on_delete); -                 -        } catch (GLib.Error e) { -            error("Could not load UI: %s\n", e.message); -        } +        }); + +        this.window.delete_event.connect(this.window.hide_on_delete);      } -     +      /////////////////////////////////////////////////////////////////////      /// Shows the window.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.preview.draw_loop();          this.window.show_all();          this.pie_list.select_first(); -        this.preview_background.modify_bg(Gtk.StateType.NORMAL, Gtk.rc_get_style(this.window).light[0]); + +        var style = this.preview_background.get_style_context(); +        this.preview_background.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL));      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a new Pie is selected in the PieList.      ///////////////////////////////////////////////////////////////////// -     +      private void on_pie_select(string id) {          selected_id = id; -         +          this.no_slice_label.hide();          this.no_pie_label.hide();          this.preview_box.hide(); -         +          this.name_button.sensitive = false;          this.hotkey_button.sensitive = false;          this.icon_button.sensitive = false;          this.remove_pie_button.sensitive = false; -         +          if (id == "") {              this.id_label.label = "";              this.name_label.label = _("No Pie selected."); @@ -182,51 +173,51 @@ public class PreferencesWindow : GLib.Object {              this.id_label.label = ("ID: %s").printf(pie.id);              this.name_label.label = PieManager.get_name_of(pie.id);              this.hotkey_label.set_markup(PieManager.get_accelerator_label_of(pie.id)); -             +              if (pie.icon.contains("/"))                  try { -                    this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(pie.icon,  +                    this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(pie.icon,                                              this.icon.get_pixel_size(), this.icon.get_pixel_size(), true);                  } catch (GLib.Error error) {                      warning(error.message);                  }              else                  this.icon.icon_name = pie.icon; -             +              this.preview.set_pie(id);              this.preview_box.show(); -             +              if (pie.action_groups.size == 0) {                  this.no_slice_label.show();              } -             +              this.name_button.sensitive = true;              this.hotkey_button.sensitive = true;              this.icon_button.sensitive = true;              this.remove_pie_button.sensitive = true;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the add Pie button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_add_pie_button_clicked(Gtk.ToolButton button) {          var new_pie = PieManager.create_persistent_pie(_("New Pie"), "stock_unknown", null);          this.pie_list.reload_all();          this.pie_list.select(new_pie.id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the remove Pie button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_remove_pie_button_clicked(Gtk.ToolButton button) {          if (this.selected_id != "") {              var dialog = new Gtk.MessageDialog((Gtk.Window)this.window.get_toplevel(), Gtk.DialogFlags.MODAL,                           Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,                           _("Do you really want to delete the selected Pie with all contained Slices?")); -                                                      +              dialog.response.connect((response) => {                  if (response == Gtk.ResponseType.YES) {                      PieManager.remove_pie(selected_id); @@ -234,16 +225,16 @@ public class PreferencesWindow : GLib.Object {                      this.pie_list.select_first();                  }              }); -             +              dialog.run();              dialog.destroy();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when rename Pie button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_rename_button_clicked(Gtk.Button button) {          if (this.rename_window == null) {              this.rename_window = new RenameWindow(); @@ -256,15 +247,15 @@ public class PreferencesWindow : GLib.Object {                  this.pie_list.reload_all();              });          } -         +          this.rename_window.set_pie(selected_id);          this.rename_window.show();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the hotkey button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_key_button_clicked(Gtk.Button button) {          if (this.trigger_window == null) {              this.trigger_window = new TriggerSelectWindow(); @@ -274,28 +265,28 @@ public class PreferencesWindow : GLib.Object {                  this.hotkey_label.set_markup(trigger.label_with_specials);              });          } -         +          this.trigger_window.set_pie(selected_id);          this.trigger_window.show();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the general settings button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_settings_button_clicked(Gtk.ToolButton button) {          if (this.settings_window == null) {              this.settings_window = new SettingsWindow();              this.settings_window.set_parent(this.window.get_toplevel() as Gtk.Window);          } -         +          this.settings_window.show();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the icon button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_icon_button_clicked(Gtk.Button button) {          if (this.icon_window == null) {              this.icon_window = new IconSelectWindow(this.window); @@ -306,7 +297,7 @@ public class PreferencesWindow : GLib.Object {                  this.pie_list.reload_all();              });          } -         +          this.icon_window.show();          this.icon_window.set_icon(PieManager.all_pies[selected_id].icon);      } diff --git a/src/gui/settingsWindow.vala b/src/gui/settingsWindow.vala index 81f8f7e..b03ae2f 100644 --- a/src/gui/settingsWindow.vala +++ b/src/gui/settingsWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,41 +12,41 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// The settings menu of Gnome-Pie, with options for theme switching and  /// some general options.  /////////////////////////////////////////////////////////////////////////  public class SettingsWindow : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// Some widgets.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Dialog? window = null;      private ThemeList? theme_list = null;      private Gtk.ToggleButton? indicator = null;      private Gtk.ToggleButton? autostart = null;      private Gtk.ToggleButton? captions = null; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor creates, the dialog.      ///////////////////////////////////////////////////////////////////// -     +      public SettingsWindow() {          try { -         +              Gtk.Builder builder = new Gtk.Builder();              builder.add_from_file (Paths.ui_files + "/settings.ui");              this.window = builder.get_object("window") as Gtk.Dialog; -             +              this.theme_list = new ThemeList();              this.theme_list.on_select_new.connect(() => {                  this.captions.active = Config.global.show_captions; @@ -56,26 +56,26 @@ public class SettingsWindow : GLib.Object {                      this.captions.sensitive = false;                  }              }); -             +              var scroll_area = builder.get_object("theme-scrolledwindow") as Gtk.ScrolledWindow;                  scroll_area.add(this.theme_list); -                 +              (builder.get_object("close-button") as Gtk.Button).clicked.connect(on_close_button_clicked); -             +              this.autostart = (builder.get_object("autostart-checkbox") as Gtk.ToggleButton);              this.autostart.toggled.connect(on_autostart_toggled); -             +              this.indicator = (builder.get_object("indicator-checkbox") as Gtk.ToggleButton);              this.indicator.toggled.connect(on_indicator_toggled); -             +              this.captions = (builder.get_object("captions-checkbox") as Gtk.ToggleButton);              this.captions.toggled.connect(on_captions_toggled); -             -            var scale_slider = (builder.get_object("scale-hscale") as Gtk.HScale); + +            var scale_slider = (builder.get_object("scale-hscale") as Gtk.Scale);                  scale_slider.set_range(0.5, 2.0);                  scale_slider.set_increments(0.05, 0.25);                  scale_slider.set_value(Config.global.global_scale); -                 +                  bool changing = false;                  bool changed_again = false; @@ -97,56 +97,64 @@ public class SettingsWindow : GLib.Object {                          changed_again = true;                      }                  }); -                 + +            var range_slider = (builder.get_object("range-hscale") as Gtk.Scale); +                range_slider.set_range(100, 2000); +                range_slider.set_increments(10, 100); +                range_slider.set_value(Config.global.activation_range); +                range_slider.value_changed.connect(() => { +                    Config.global.activation_range = (int)range_slider.get_value(); +                }); +              this.window.delete_event.connect(this.window.hide_on_delete); -                 +          } catch (GLib.Error e) {              error("Could not load UI: %s\n", e.message);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Sets the parent window, in order to make this window stay in      /// front.      ///////////////////////////////////////////////////////////////////// -     +      public void set_parent(Gtk.Window parent) {          this.window.set_transient_for(parent);      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays the window on the screen.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.indicator.active = Config.global.show_indicator; -        this.autostart.active = Config.global.auto_start;      +        this.autostart.active = Config.global.auto_start;          this.captions.active = Config.global.show_captions; -         +          if (Config.global.theme.has_slice_captions) {              this.captions.sensitive = true;          } else {              this.captions.sensitive = false;          } -         -        this.window.show_all();  + +        this.window.show_all();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the close button is clicked.      ///////////////////////////////////////////////////////////////////// -     +      private void on_close_button_clicked() {          this.window.hide();      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates or deletes the autostart file. This code is inspired      /// by project synapse as well.      ///////////////////////////////////////////////////////////////////// -     +      private void on_autostart_toggled(Gtk.ToggleButton check_box) { -     +          bool active = check_box.active;          if (!active && FileUtils.test(Paths.autostart, FileTest.EXISTS)) {              Config.global.auto_start = false; @@ -155,9 +163,9 @@ public class SettingsWindow : GLib.Object {          }          else if (active && !FileUtils.test(Paths.autostart, FileTest.EXISTS)) {              Config.global.auto_start = true; -             -            string autostart_entry =  -                "#!/usr/bin/env xdg-open\n" +  + +            string autostart_entry = +                "#!/usr/bin/env xdg-open\n" +                  "[Desktop Entry]\n" +                  "Name=Gnome-Pie\n" +                  "Exec=" + Paths.executable + "\n" + @@ -171,7 +179,7 @@ public class SettingsWindow : GLib.Object {              if (!FileUtils.test(autostart_dir, FileTest.EXISTS | FileTest.IS_DIR)) {                  DirUtils.create_with_parents(autostart_dir, 0755);              } -             +              try {                  FileUtils.set_contents(Paths.autostart, autostart_entry);                  FileUtils.chmod(Paths.autostart, 0755); @@ -183,20 +191,20 @@ public class SettingsWindow : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Shows or hides the indicator.      ///////////////////////////////////////////////////////////////////// -     +      private void on_indicator_toggled(Gtk.ToggleButton check_box) {          var check = check_box as Gtk.CheckButton;          Config.global.show_indicator = check.active;      } -     +      /////////////////////////////////////////////////////////////////////      /// Shows or hides the captions of Slices.      ///////////////////////////////////////////////////////////////////// -     +      private void on_captions_toggled(Gtk.ToggleButton check_box) {          var check = check_box as Gtk.CheckButton;          Config.global.show_captions = check.active; diff --git a/src/gui/triggerSelectWindow.vala b/src/gui/triggerSelectWindow.vala index 23eea3c..611c179 100644 --- a/src/gui/triggerSelectWindow.vala +++ b/src/gui/triggerSelectWindow.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,56 +12,56 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This window allows the selection of a hotkey. It is returned in form  /// of a Trigger. Therefore it can be either a keyboard driven hotkey or  /// a mouse based hotkey.  /////////////////////////////////////////////////////////////////////////  public class TriggerSelectWindow : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// This signal is emitted when the user selects a new hot key.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_ok(Trigger trigger); -     +      /////////////////////////////////////////////////////////////////////      /// Some private members which are needed by other methods.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Dialog window;      private Gtk.CheckButton turbo;      private Gtk.CheckButton delayed;      private Gtk.CheckButton centered;      private TriggerSelectButton button; -     +      /////////////////////////////////////////////////////////////////////      /// The currently configured trigger.      ///////////////////////////////////////////////////////////////////// -     +      private Trigger trigger = null; -     +      /////////////////////////////////////////////////////////////////////      /// The trigger which was active when this window was opened. It is      /// stored in order to check whether anything has changed when the      /// user clicks on OK.      ///////////////////////////////////////////////////////////////////// -     +      private Trigger original_trigger = null; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, constructs a new TriggerSelectWindow.      ///////////////////////////////////////////////////////////////////// -     +      public TriggerSelectWindow() {          try { -         +              Gtk.Builder builder = new Gtk.Builder();              builder.add_from_file (Paths.ui_files + "/trigger_select.ui"); @@ -69,7 +69,7 @@ public class TriggerSelectWindow : GLib.Object {              this.window = builder.get_object("window") as Gtk.Dialog;              this.button = new TriggerSelectButton(true);              this.button.show(); -             +              this.button.on_select.connect((trigger) => {                  this.trigger = new Trigger.from_values(trigger.key_sym,                                                         trigger.modifiers, @@ -78,80 +78,80 @@ public class TriggerSelectWindow : GLib.Object {                                                         this.delayed.active,                                                         this.centered.active);              }); -             -            (builder.get_object("trigger-box") as Gtk.VBox).pack_start(this.button, true, true); -             + +            (builder.get_object("trigger-box") as Gtk.Box).pack_start(this.button, true, true); +              (builder.get_object("ok-button") as Gtk.Button).clicked.connect(this.on_ok_button_clicked);              (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(this.on_cancel_button_clicked); -             +              this.turbo = builder.get_object("turbo-check") as Gtk.CheckButton;              this.turbo.toggled.connect(this.on_check_toggled); -             +              this.delayed = builder.get_object("delay-check") as Gtk.CheckButton;              this.delayed.toggled.connect(this.on_check_toggled); -             +              this.centered = builder.get_object("center-check") as Gtk.CheckButton;              this.centered.toggled.connect(this.on_check_toggled); -             +              this.window.delete_event.connect(this.window.hide_on_delete); -                 +          } catch (GLib.Error e) {              error("Could not load UI: %s\n", e.message);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Sets the parent window, in order to make this window stay in      /// front.      ///////////////////////////////////////////////////////////////////// -     +      public void set_parent(Gtk.Window parent) {          this.window.set_transient_for(parent);      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays the window on the screen.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.window.show_all();      } -     +      /////////////////////////////////////////////////////////////////////      /// Initilizes all members to match the Trigger of the Pie with the      /// given ID.      ///////////////////////////////////////////////////////////////////// -     +      public void set_pie(string id) {          var trigger = new Trigger.from_string(PieManager.get_accelerator_of(id)); -         +          this.turbo.active = trigger.turbo;          this.delayed.active = trigger.delayed;          this.centered.active = trigger.centered;          this.original_trigger = trigger;          this.trigger = trigger; -         +          this.button.set_trigger(trigger);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when one of the three checkoxes is toggled.      ///////////////////////////////////////////////////////////////////// -     +      private void on_check_toggled() {          if (this.trigger != null)              this.trigger = new Trigger.from_values(this.trigger.key_sym, this.trigger.modifiers,                                                     this.trigger.with_mouse, this.turbo.active,                                                     this.delayed.active, this.centered.active);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the OK-button is pressed.      ///////////////////////////////////////////////////////////////////// -     +      private void on_ok_button_clicked() {          var assigned_id = PieManager.get_assigned_id(this.trigger); -     +          if (this.trigger == this.original_trigger) {              // nothing did change              this.window.hide(); @@ -175,14 +175,14 @@ public class TriggerSelectWindow : GLib.Object {              this.window.hide();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the cancel button is pressed.      ///////////////////////////////////////////////////////////////////// -     +      private void on_cancel_button_clicked() {          this.window.hide(); -    }  +    }  }  } diff --git a/src/images/image.vala b/src/images/image.vala index 197523b..e65e34a 100644 --- a/src/images/image.vala +++ b/src/images/image.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,78 +12,73 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A class which loads image files. It can load image files in various -/// formats, including jpeg, png and svg.  +/// formats, including jpeg, png and svg.  /////////////////////////////////////////////////////////////////////////  public class Image : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// The internally used surface.      ///////////////////////////////////////////////////////////////////// -     +      public Cairo.ImageSurface surface { public get; protected set; default=null; } -     +      /////////////////////////////////////////////////////////////////////      /// Creates an empty Image.      ///////////////////////////////////////////////////////////////////// -     +      public Image.empty(int width, int height, Color? color = null) {          this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height); -         +          if (color != null) {              var ctx = this.context();              ctx.set_source_rgb(color.r, color.g, color.b);              ctx.paint();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates an image from the the given filename.      ///////////////////////////////////////////////////////////////////// -     +      public Image.from_file(string filename) {          this.load_file(filename);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates an image from the the given filename at a given size.      ///////////////////////////////////////////////////////////////////// -     +      public Image.from_file_at_size(string filename, int width, int height) {          this.load_file_at_size(filename, width, height);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates an image from the the given Gdk.Pixbuf.      ///////////////////////////////////////////////////////////////////// -     +      public Image.from_pixbuf(Gdk.Pixbuf pixbuf) {          if (pixbuf != null) this.load_pixbuf(pixbuf);          else                this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1);      } -     +      /////////////////////////////////////////////////////////////////////      /// Captures a part of the screen.      ///////////////////////////////////////////////////////////////////// -     +      public Image.capture_screen(int posx, int posy, int width, int height, bool hide_pies = true) {          Gdk.Window root = Gdk.get_default_root_window(); -        #if HAVE_GTK_3 -            Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_window(root, posx, posy, width, height); -        #else -            Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_drawable(null, root, null, posx, posy, 0, 0, width, height); -        #endif - +        Gdk.Pixbuf pixbuf = Gdk.pixbuf_get_from_window(root, posx, posy, width, height);          this.load_pixbuf(pixbuf); -         +          if (hide_pies) {              // check for opened pies              foreach (var window in PieManager.opened_windows) { @@ -93,21 +88,21 @@ public class Image : GLib.Object {                      window.get_size(out dx, out dy);                      var ctx = this.context(); -                    ctx.translate((int)(x-posx + (dx+3)/2), (int)(y-posy + (dy+3)/2));                     +                    ctx.translate((int)(x-posx + (dx+3)/2), (int)(y-posy + (dy+3)/2));                      window.background.paint_on(ctx);                  }              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an image from the the given filename.      ///////////////////////////////////////////////////////////////////// -     +      public void load_file(string filename) {          try {              var pixbuf = new Gdk.Pixbuf.from_file(filename); -             +              if (pixbuf != null) {                  this.load_pixbuf(pixbuf);              } else { @@ -119,64 +114,64 @@ public class Image : GLib.Object {              this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 1, 1);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an image from the the given filename at a given size.      ///////////////////////////////////////////////////////////////////// -     +      public void load_file_at_size(string filename, int width, int height) {          try {              var pixbuf = new Gdk.Pixbuf.from_file_at_size(filename, width, height); -             +              if (pixbuf != null) {                  this.load_pixbuf(pixbuf);              } else {                  warning("Failed to load " + filename + "!");                  this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);              } -             +          } catch (GLib.Error e) {              message("Error loading image file: %s", e.message);              this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an image from the the given Gdk.Pixbuf.      ///////////////////////////////////////////////////////////////////// -     +      public void load_pixbuf(Gdk.Pixbuf pixbuf) {          this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, pixbuf.width, pixbuf.height); -     +          var ctx = this.context();          Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 1.0, 1.0);          ctx.paint();      } -     +      /////////////////////////////////////////////////////////////////////      /// Paints the image onto the given Cairo.Context      ///////////////////////////////////////////////////////////////////// -     +      public void paint_on(Cairo.Context ctx, double alpha = 1.0) {          ctx.set_source_surface(this.surface, (int)(-0.5*this.width()-1), (int)(-0.5*this.height()-1));          if (alpha >= 1.0) ctx.paint();          else              ctx.paint_with_alpha(alpha);      } -     +      /////////////////////////////////////////////////////////////////////      /// Converts the image to a Gdk.Pixbuf.      ///////////////////////////////////////////////////////////////////// -     +      public Gdk.Pixbuf to_pixbuf() {          if (this.surface == null || this.surface.get_data().length <= 0)              return new Gdk.Pixbuf(Gdk.Colorspace.RGB, true, 8, 1, 1); -         -        var pixbuf = new Gdk.Pixbuf.from_data(this.surface.get_data(), Gdk.Colorspace.RGB, true, 8,  + +        var pixbuf = new Gdk.Pixbuf.from_data(this.surface.get_data(), Gdk.Colorspace.RGB, true, 8,                                                width(), height(), this.surface.get_stride(), null); -         +          pixbuf = pixbuf.copy(); -                                        -        // funny stuff here --- need to swap Red end Blue because Cairo  + +        // funny stuff here --- need to swap Red end Blue because Cairo          // and Gdk are different...          uint8* p = pixbuf.pixels;          for (int i=0; i<width()*height()*4-4; i+=4) { @@ -187,29 +182,29 @@ public class Image : GLib.Object {  		return pixbuf;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns a Cairo.Context for the Image.      ///////////////////////////////////////////////////////////////////// -     +      public Cairo.Context context() {          return new Cairo.Context(this.surface);      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the width of the image in pixels.      ///////////////////////////////////////////////////////////////////// -     +      public int width() {          if (this.surface != null)              return this.surface.get_width();          return 0;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the height of the image in pixels.      ///////////////////////////////////////////////////////////////////// -     +      public int height() {          if (this.surface != null)              return this.surface.get_height(); diff --git a/src/renderers/pieRenderer.vala b/src/renderers/pieRenderer.vala index 7135381..8085758 100644 --- a/src/renderers/pieRenderer.vala +++ b/src/renderers/pieRenderer.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,14 +12,14 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This class renders a Pie. In order to accomplish that, it owns a  /// CenterRenderer and some SliceRenderers.  ///////////////////////////////////////////////////////////////////////// @@ -35,14 +35,14 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      /// The index of the currently active slice. -    /////////////////////////////////////////////////////////////////////     -     +    ///////////////////////////////////////////////////////////////////// +      public int active_slice { get; private set; }      /////////////////////////////////////////////////////////////////////      /// True, if the hot keys are currently displayed.      ///////////////////////////////////////////////////////////////////// -     +      public bool show_hotkeys { get; set; }      ///////////////////////////////////////////////////////////////////// @@ -50,195 +50,195 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public int size { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// True if the pie should close when it's trigger is released.      ///////////////////////////////////////////////////////////////////// -     +      public bool turbo_mode { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// True if the pie is currently navigated with the keyboard. This is      /// set to false as soon as the mouse moves.      ///////////////////////////////////////////////////////////////////// -     +      public bool key_board_control { get; set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// All SliceRenderers used to draw this Pie.      ///////////////////////////////////////////////////////////////////// -     +      private Gee.ArrayList<SliceRenderer?> slices; -     +      /////////////////////////////////////////////////////////////////////      /// The renderer for the center of this pie.      ///////////////////////////////////////////////////////////////////// -     +      private CenterRenderer center; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes members.      ///////////////////////////////////////////////////////////////////// -     +      public PieRenderer() { -        this.slices = new Gee.ArrayList<SliceRenderer?>();  +        this.slices = new Gee.ArrayList<SliceRenderer?>();          this.center = new CenterRenderer(this);          this.quickaction = -1;          this.active_slice = -2;          this.size = 0;      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads a Pie. All members are initialized accordingly.      ///////////////////////////////////////////////////////////////////// -     +      public void load_pie(Pie pie) {          this.slices.clear(); -     +          int count = 0;          foreach (var group in pie.action_groups) {              foreach (var action in group.actions) {                  var renderer = new SliceRenderer(this);                  this.slices.add(renderer);                  renderer.load(action, slices.size-1); -                 +                  if (action.is_quickaction) {                      this.quickaction = count;                  } -                 +                  ++count;              }          } -         +          this.turbo_mode = PieManager.get_is_turbo(pie.id); -         +          this.set_highlighted_slice(this.quickaction); -         +          this.size = (int)fmax(2*Config.global.theme.radius + 2*Config.global.theme.slice_radius*Config.global.theme.max_zoom,                                2*Config.global.theme.center_radius); -         +          // increase size if there are many slices          if (slices.size > 0) {              this.size = (int)fmax(this.size, -                (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/slices.size))  +                (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/slices.size))                  + Config.global.theme.slice_radius)*2*Config.global.theme.max_zoom);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Activates the currently active slice.      ///////////////////////////////////////////////////////////////////// -     +      public void activate() {          if (this.active_slice >= 0 && this.active_slice < this.slices.size) {              slices[active_slice].activate();          } -         +          foreach (var slice in this.slices)              slice.fade_out(); -             +          center.fade_out();      } -     +      /////////////////////////////////////////////////////////////////////      /// Asks all renders to fade out.      ///////////////////////////////////////////////////////////////////// -     +      public void cancel() {          foreach (var slice in this.slices)              slice.fade_out(); -             +          center.fade_out();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the up-key is pressed. Selects the next slice towards -    /// the top.  +    /// the top.      ///////////////////////////////////////////////////////////////////// -     +      public void select_up() {          int bottom = this.slice_count()/4;          int top = this.slice_count()*3/4; -     +          if (this.active_slice == -1 || this.active_slice == bottom)             this.set_highlighted_slice(top);          else if (this.active_slice > bottom && this.active_slice < top)             this.set_highlighted_slice(this.active_slice+1);          else if (this.active_slice != top)             this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count()); -            +          this.key_board_control = true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the down-key is pressed. Selects the next slice -    /// towards the bottom.  +    /// towards the bottom.      ///////////////////////////////////////////////////////////////////// -     +      public void select_down() {          int bottom = this.slice_count()/4;          int top = this.slice_count()*3/4; -     +          if (this.active_slice == -1 || this.active_slice == top)             this.set_highlighted_slice(bottom);          else if (this.active_slice > bottom && this.active_slice < top)             this.set_highlighted_slice(this.active_slice-1);          else if (this.active_slice != bottom)             this.set_highlighted_slice((this.active_slice+1)%this.slice_count()); -            +          this.key_board_control = true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the left-key is pressed. Selects the next slice -    /// towards the left.  +    /// towards the left.      ///////////////////////////////////////////////////////////////////// -     +      public void select_left() {          int left = this.slice_count()/2;          int right = 0; -     +          if (this.active_slice == -1 || this.active_slice == right)             this.set_highlighted_slice(left);          else if (this.active_slice > left)             this.set_highlighted_slice(this.active_slice-1);          else if (this.active_slice < left)             this.set_highlighted_slice(this.active_slice+1); -         +          this.key_board_control = true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the right-key is pressed. Selects the next slice -    /// towards the right.  +    /// towards the right.      ///////////////////////////////////////////////////////////////////// -     +      public void select_right() {          int left = this.slice_count()/2;          int right = 0; -     +          if (this.active_slice == -1 || this.active_slice == left)             this.set_highlighted_slice(right);          else if (this.active_slice > left)             this.set_highlighted_slice((this.active_slice+1)%this.slice_count());          else if (this.active_slice < left && this.active_slice != right)             this.set_highlighted_slice((this.active_slice-1+this.slice_count())%this.slice_count()); -            +          this.key_board_control = true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the amount of slices in this pie.      ///////////////////////////////////////////////////////////////////// -     +      public int slice_count() {          return slices.size;      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the entire pie.      ///////////////////////////////////////////////////////////////////// -     +      public void draw(double frame_time, Cairo.Context ctx, int mouse_x, int mouse_y) {          if (this.size > 0) {  	        double distance = sqrt(mouse_x*mouse_x + mouse_y*mouse_y); @@ -247,62 +247,62 @@ public class PieRenderer : GLib.Object {  	        if (this.key_board_control) {  	            angle = 2.0*PI*this.active_slice/(double)slice_count();  	        } else { -	         +  	            if (distance > 0) {  	                angle = acos(mouse_x/distance); -		            if (mouse_y < 0)  +		            if (mouse_y < 0)  		                angle = 2*PI - angle;  	            } -	             +  	            int next_active_slice = this.active_slice; -	             +  	            if (distance < Config.global.theme.active_radius  	                && this.quickaction >= 0 && this.quickaction < this.slices.size) { -	              -	                next_active_slice = this.quickaction;    + +	                next_active_slice = this.quickaction;  	                angle = 2.0*PI*quickaction/(double)slice_count(); -	            } else if (distance > Config.global.theme.active_radius && this.slice_count() > 0) { +	            } else if (distance > Config.global.theme.active_radius && this.slice_count() > 0 && distance < Config.global.activation_range) {  	                next_active_slice = (int)(angle*slices.size/(2*PI) + 0.5) % this.slice_count();  	            } else {  	                next_active_slice = -1;  	            } -	         +  	            this.set_highlighted_slice(next_active_slice);  	        }              center.draw(frame_time, ctx, angle, distance); -	         +  	        foreach (var slice in this.slices)  		        slice.draw(frame_time, ctx, angle, distance);  		}      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user moves the mouse.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_move() {          this.key_board_control = false;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the currently active slice changes.      ///////////////////////////////////////////////////////////////////// -     +      public void set_highlighted_slice(int index) {          if (index != this.active_slice) { -            if (index >= 0 && index < this.slice_count())  +            if (index >= 0 && index < this.slice_count())                  this.active_slice = index;              else if (this.quickaction >= 0)                  this.active_slice = this.quickaction;              else                  this.active_slice = -1; -             +              SliceRenderer? active = (this.active_slice >= 0 && this.active_slice < this.slice_count()) ?                                       this.slices[this.active_slice] : null; -	                     +              center.set_active_slice(active); -             +              foreach (var slice in this.slices)                  slice.set_active_slice(active);          } diff --git a/src/renderers/pieWindow.vala b/src/renderers/pieWindow.vala index a95b3e3..da346dd 100644 --- a/src/renderers/pieWindow.vala +++ b/src/renderers/pieWindow.vala @@ -89,11 +89,7 @@ public class PieWindow : Gtk.Window {          // check for compositing          if (this.screen.is_composited()) { -            #if HAVE_GTK_3 -                this.set_visual(this.screen.get_rgba_visual()); -            #else -                this.set_colormap(this.screen.get_rgba_colormap()); -            #endif +            this.set_visual(this.screen.get_rgba_visual());              this.has_compositing = true;          } @@ -147,11 +143,7 @@ public class PieWindow : Gtk.Window {          });          // draw the pie on expose -        #if HAVE_GTK_3 -            this.draw.connect(this.draw_window); -        #else -            this.expose_event.connect(this.draw_window); -        #endif +        this.draw.connect(this.draw_window);      }      ///////////////////////////////////////////////////////////////////// @@ -214,13 +206,7 @@ public class PieWindow : Gtk.Window {      /// Draw the Pie.      ///////////////////////////////////////////////////////////////////// -    #if HAVE_GTK_3 -        private bool draw_window(Cairo.Context ctx) { -    #else -        private bool draw_window(Gtk.Widget da, Gdk.EventExpose event) { -            // clear the window -            var ctx = Gdk.cairo_create(this.get_window()); -    #endif +    private bool draw_window(Cairo.Context ctx) {          // paint the background image if there is no compositing          if (this.has_compositing) {              ctx.set_operator (Cairo.Operator.CLEAR); @@ -237,7 +223,17 @@ public class PieWindow : Gtk.Window {          // get the mouse position          double mouse_x = 0.0, mouse_y = 0.0; -        this.get_pointer(out mouse_x, out mouse_y); +        Gdk.ModifierType mask; + +        var display = Gdk.Display.get_default(); +        var manager = display.get_device_manager(); +        GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + +        foreach(var device in list) { +            if (device.input_source != Gdk.InputSource.KEYBOARD) { +                this.get_window().get_device_position_double(device, out mouse_x, out mouse_y, out mask); +            } +        }          // store the frame time          double frame_time = this.timer.elapsed(); @@ -260,7 +256,11 @@ public class PieWindow : Gtk.Window {              this.on_closing();              Gtk.grab_remove(this);              FocusGrabber.ungrab(); -            this.renderer.activate(); + +            GLib.Timeout.add(10, () => { +                this.renderer.activate(); +                return false; +            });              GLib.Timeout.add((uint)(Config.global.theme.fade_out_time*1000), () => {                  this.closed = true; diff --git a/src/utilities/color.vala b/src/utilities/color.vala index 836411e..bf60e3f 100644 --- a/src/utilities/color.vala +++ b/src/utilities/color.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,14 +12,14 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A Color class with full rgb/hsv support  /// and some useful utility methods.  ///////////////////////////////////////////////////////////////////////// @@ -35,15 +35,15 @@ public class Color: GLib.Object {      private float _g;      private float _b;      private float _a; -     +      /////////////////////////////////////////////////////////////////////      /// Creates a white Color.      ///////////////////////////////////////////////////////////////////// -     +      public Color() {          Color.from_rgb(1.0f, 1.0f, 1.0f);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a solid color with the given RGB values.      ///////////////////////////////////////////////////////////////////// @@ -51,47 +51,48 @@ public class Color: GLib.Object {      public Color.from_rgb(float red, float green, float blue) {          Color.from_rgba(red, green, blue, 1.0f);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a translucient color with the given RGBA values.      ///////////////////////////////////////////////////////////////////// -     +      public Color.from_rgba(float red, float green, float blue, float alpha) {          r = red;          g = green;          b = blue;          a = alpha;      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a color from the given Gdk.Color      ///////////////////////////////////////////////////////////////////// -     -    public Color.from_gdk(Gdk.Color color) { -        Color.from_rgb( -            (float)color.red/65535.0f, -            (float)color.green/65535.0f, -            (float)color.blue/65535.0f + +    public Color.from_gdk(Gdk.RGBA color) { +        Color.from_rgba( +            (float)color.red, +            (float)color.green, +            (float)color.blue, +            (float)color.alpha          );      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a color, parsed from a string, such as #22EE33      ///////////////////////////////////////////////////////////////////// -     +      public Color.from_string(string hex_string) { -        Gdk.Color color; -        Gdk.Color.parse(hex_string, out color); +        var color = Gdk.RGBA(); +        color.parse(hex_string);          Color.from_gdk(color);      } -     +      /////////////////////////////////////////////////////////////////////      /// Gets the main color from an Image. Code from Unity.      ///////////////////////////////////////////////////////////////////// -     +      public Color.from_icon(Image icon) {          unowned uchar[] data = icon.surface.get_data(); -     +          uint width = icon.surface.get_width();          uint height = icon.surface.get_height();          uint row_bytes = icon.surface.get_stride(); @@ -99,7 +100,7 @@ public class Color: GLib.Object {          double total = 0.0;          double rtotal = 0.0;          double gtotal = 0.0; -        double btotal = 0.0;  +        double btotal = 0.0;          for (uint i = 0; i < width; ++i) {              for (uint j = 0; j < height; ++j) { @@ -126,7 +127,7 @@ public class Color: GLib.Object {          v = 1.0f;      } -     +      /////////////////////////////////////////////////////////////////////      /// The reddish part of the color.      ///////////////////////////////////////////////////////////////////// @@ -138,14 +139,14 @@ public class Color: GLib.Object {          set {              if (value > 1.0f) _r = 1.0f;              else if (value < 0.0f) _r = 0.0f; -            else _r = value;  +            else _r = value;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The greenish part of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float g {          get {              return _g; @@ -153,14 +154,14 @@ public class Color: GLib.Object {          set {              if (value > 1.0f) _g = 1.0f;              else if (value < 0.0f) _g = 0.0f; -            else _g = value;  +            else _g = value;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The blueish part of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float b {          get {              return _b; @@ -168,14 +169,14 @@ public class Color: GLib.Object {          set {              if (value > 1.0f) _b = 1.0f;              else if (value < 0.0f) _b = 0.0f; -            else _b = value;  +            else _b = value;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The transparency of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float a {          get {              return _a; @@ -183,14 +184,14 @@ public class Color: GLib.Object {          set {              if (value > 1.0f) _a = 1.0f;              else if (value < 0.0f) _a = 0.0f; -            else _a = value;  +            else _a = value;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The hue of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float h {          get {              if (s > 0.0f) { @@ -210,11 +211,11 @@ public class Color: GLib.Object {              setHSV(value, s, v);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The saturation of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float s {          get {              if (v == 0.0f) return 0.0f; @@ -226,11 +227,11 @@ public class Color: GLib.Object {              else setHSV(h, value, v);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// The value of the color.      ///////////////////////////////////////////////////////////////////// -     +      public float v {          get {              return fmaxf(fmaxf(r, g), b); @@ -241,16 +242,16 @@ public class Color: GLib.Object {              else setHSV(h, s, value);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Inverts the color.      ///////////////////////////////////////////////////////////////////// -     +      public void invert() {          h += 180.0f;          v = 1.0f - v;      } -     +      /////////////////////////////////////////////////////////////////////      /// Private member, used to apply color changes.      ///////////////////////////////////////////////////////////////////// diff --git a/src/utilities/config.vala b/src/utilities/config.vala index 1d8b714..2ec2788 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A singleton class for storing global settings. These settings can  /// be loaded from and saved to an XML file.  ///////////////////////////////////////////////////////////////////////// @@ -29,11 +29,11 @@ public class Config : GLib.Object {      /////////////////////////////////////////////////////////////////////      private static Config _instance = null; -     +      /////////////////////////////////////////////////////////////////////      /// Returns the singleton instance.      ///////////////////////////////////////////////////////////////////// -     +      public static Config global {          get {              if (_instance == null) { @@ -46,7 +46,7 @@ public class Config : GLib.Object {              _instance = value;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// All settings variables.      ///////////////////////////////////////////////////////////////////// @@ -54,16 +54,17 @@ public class Config : GLib.Object {      public Theme theme { get; set; }      public double refresh_rate { get; set; default = 60.0; }      public double global_scale { get; set; default = 1.0; } +    public int  activation_range { get; set; default = 300; }      public bool show_indicator { get; set; default = true; }      public bool show_captions { get; set; default = true; }      public bool auto_start { get; set; default = false; }      public int showed_news { get; set; default = 0; }      public Gee.ArrayList<Theme?> themes { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Saves all above variables to a file.      ///////////////////////////////////////////////////////////////////// -     +      public void save() {          var writer = new Xml.TextWriter.filename(Paths.settings);          writer.start_document("1.0"); @@ -71,28 +72,29 @@ public class Config : GLib.Object {                  writer.write_attribute("theme", theme.name);                  writer.write_attribute("refresh_rate", refresh_rate.to_string());                  writer.write_attribute("global_scale", global_scale.to_string()); +                writer.write_attribute("activation_range", activation_range.to_string());                  writer.write_attribute("show_indicator", show_indicator ? "true" : "false");                  writer.write_attribute("show_captions", show_captions ? "true" : "false");                  writer.write_attribute("showed_news", showed_news.to_string());              writer.end_element();          writer.end_document();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all settings variables from a file.      ///////////////////////////////////////////////////////////////////// -     +      private void load() { -     +          // check for auto_start filename          this.auto_start = FileUtils.test(Paths.autostart, FileTest.EXISTS); -     +          // parse the settings file          Xml.Parser.init();          Xml.Doc* settingsXML = Xml.Parser.parse_file(Paths.settings);          bool   error_occrured = false;          string theme_name = ""; -         +          if (settingsXML != null) {              Xml.Node* root = settingsXML->get_root_element(); @@ -101,7 +103,7 @@ public class Config : GLib.Object {                  for (Xml.Attr* attribute = root->properties; attribute != null; attribute = attribute->next) {                      string attr_name = attribute->name.down();                      string attr_content = attribute->children->content; -                     +                      switch (attr_name) {                          case "theme":                              theme_name = attr_content; @@ -113,6 +115,10 @@ public class Config : GLib.Object {                              global_scale = double.parse(attr_content);                              global_scale.clamp(0.5, 2.0);                              break; +                        case "activation_range": +                            activation_range = int.parse(attr_content); +                            activation_range.clamp(100, 2000); +                            break;                          case "show_indicator":                              show_indicator = bool.parse(attr_content);                              break; @@ -127,45 +133,45 @@ public class Config : GLib.Object {                              break;                      }                  } -                +                  Xml.Parser.cleanup(); -                 +              } else {                  warning("Error loading settings: gnome-pie.conf is empty! Using defaults...");                  error_occrured = true;              } -             +              delete settingsXML; -             +          } else {              warning("Error loading settings: gnome-pie.conf not found! Using defaults...");              error_occrured = true;          } -         +          load_themes(theme_name);          if (error_occrured) save();      } -     +      /////////////////////////////////////////////////////////////////////      /// Registers all themes in the user's and in the global      /// theme directory.      ///////////////////////////////////////////////////////////////////// -     +      public void load_themes(string current) {          themes = new Gee.ArrayList<Theme?>();          try {              string name; -             +              // load global themes              var d = Dir.open(Paths.global_themes);              while ((name = d.read_name()) != null) {  	            var theme = new Theme(Paths.global_themes + "/" + name); -	             +  	            if (theme.load())  	            	themes.add(theme);              } -             +              // load local themes              d = Dir.open(Paths.local_themes);              while ((name = d.read_name()) != null) { @@ -173,11 +179,11 @@ public class Config : GLib.Object {                  if (theme.load())                      themes.add(theme);              } -             +          } catch (Error e) {              warning (e.message); -        }  -         +        } +          if (themes.size > 0) {              if (current == "") {                  current = "Unity"; @@ -197,7 +203,7 @@ public class Config : GLib.Object {          }          else error("No theme found!");      } -     +  }  } diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala index e5900d6..b551def 100644 --- a/src/utilities/focusGrabber.vala +++ b/src/utilities/focusGrabber.vala @@ -1,4 +1,4 @@ -/*  +/*  Copyright (c) 2011 by Simon Schneegans  This program is free software: you can redistribute it and/or modify it @@ -12,12 +12,12 @@ 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/>.  +this program.  If not, see <http://www.gnu.org/licenses/>.  */  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// Some helper methods which focus the input on a given Gtk.Window.  ///////////////////////////////////////////////////////////////////////// @@ -27,7 +27,7 @@ public class FocusGrabber : GLib.Object {      /// Utilities for grabbing focus.      /// Code roughly from Gnome-Do/Synapse.      ///////////////////////////////////////////////////////////////////// -     +      public static void grab(Gdk.Window window, bool keyboard = true, bool pointer = true, bool owner_events = true) {          if (keyboard || pointer) {              window.raise(); @@ -42,90 +42,56 @@ public class FocusGrabber : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Code roughly from Gnome-Do/Synapse.      ///////////////////////////////////////////////////////////////////// -     +      public static void ungrab(bool keyboard = true, bool pointer = true) { -        #if HAVE_GTK_3 -         -            var display = Gdk.Display.get_default(); -            var manager = display.get_device_manager(); -             -            #if VALA_0_16 || VALA_0_17 -                GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); -            #else -                unowned GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); -            #endif -             -            foreach(var device in list) { -                if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) -                 || (device.input_source != Gdk.InputSource.KEYBOARD && pointer))  -                  -                    device.ungrab(Gdk.CURRENT_TIME); -            } -             -        #else -         -            if (pointer)  Gdk.pointer_ungrab(Gdk.CURRENT_TIME); -            if (keyboard) Gdk.keyboard_ungrab(Gdk.CURRENT_TIME); -             -        #endif +        var display = Gdk.Display.get_default(); +        var manager = display.get_device_manager(); + +        GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + +        foreach(var device in list) { +            if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) +             || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) + +                device.ungrab(Gdk.CURRENT_TIME); +        }      } -     +      /////////////////////////////////////////////////////////////////////      /// Code roughly from Gnome-Do/Synapse.      ///////////////////////////////////////////////////////////////////// -     +      private static bool try_grab_window(Gdk.Window window, bool keyboard, bool pointer, bool owner_events) { -        #if HAVE_GTK_3 -         -            var display = Gdk.Display.get_default(); -            var manager = display.get_device_manager(); -             -            bool grabbed_all = true; -             -            #if VALA_0_16 -                GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); -            #else -                unowned GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); -            #endif -             -            foreach(var device in list) { -                if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard)  -                 || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { -                  -                    var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events,  -                                             Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); -                     -                    if (status != Gdk.GrabStatus.SUCCESS) -                        grabbed_all = false; -                } -            } -             -            if (grabbed_all) -                return true; -             -            ungrab(keyboard, pointer); -             -        #else -         -            if (!pointer || Gdk.pointer_grab(window, owner_events, Gdk.EventMask.BUTTON_PRESS_MASK | -                                             Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK, -                                 null, null, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { -                 -                if (!keyboard || Gdk.keyboard_grab(window, owner_events, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { -                    return true; -                } else if (pointer) { -                    ungrab(false, true); -                    return false; -                } +        var display = Gdk.Display.get_default(); +        var manager = display.get_device_manager(); + +        bool grabbed_all = true; + +        GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + +        foreach(var device in list) { +            if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) +             || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { + +                var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events, +                                         Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); + +                if (status != Gdk.GrabStatus.SUCCESS) +                    grabbed_all = false;              } -        #endif -         +        } + +        if (grabbed_all) +            return true; + +        ungrab(keyboard, pointer); +          return false; -    }   +    }  }  } | 
