diff options
Diffstat (limited to 'src')
62 files changed, 3572 insertions, 2597 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee08045..af412a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,69 +33,69 @@ add_executable(gnome-pie ${VALA_C})  # install executable  install( -	TARGETS -		gnome-pie -	RUNTIME DESTINATION -		${CMAKE_INSTALL_PREFIX}/bin +    TARGETS +        gnome-pie +    RUNTIME DESTINATION +        ${CMAKE_INSTALL_PREFIX}/bin  )  # install credits  install( -	FILES -		${CMAKE_SOURCE_DIR}/README.md -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/doc/gnome-pie +    FILES +        ${CMAKE_SOURCE_DIR}/README.md +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/doc/gnome-pie  )  # install locales  install( -	DIRECTORY -		${CMAKE_SOURCE_DIR}/resources/locale -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share -	PATTERN *.po EXCLUDE -	PATTERN *.pot EXCLUDE -	PATTERN *.sh EXCLUDE +    DIRECTORY +        ${CMAKE_SOURCE_DIR}/resources/locale +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share +    PATTERN *.po EXCLUDE +    PATTERN *.pot EXCLUDE +    PATTERN *.sh EXCLUDE  )  # install themes  install( -	DIRECTORY -		${CMAKE_SOURCE_DIR}/resources/themes -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/gnome-pie +    DIRECTORY +        ${CMAKE_SOURCE_DIR}/resources/themes +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/gnome-pie  )  # install UI files  install( -	DIRECTORY -		${CMAKE_SOURCE_DIR}/resources/ui -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/gnome-pie +    DIRECTORY +        ${CMAKE_SOURCE_DIR}/resources/ui +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/gnome-pie  )  # install icons  install( -	FILES -		${CMAKE_SOURCE_DIR}/resources/gnome-pie.svg -		${CMAKE_SOURCE_DIR}/resources/gnome-pie-symbolic.svg -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps +    FILES +        ${CMAKE_SOURCE_DIR}/resources/gnome-pie.svg +        ${CMAKE_SOURCE_DIR}/resources/gnome-pie-symbolic.svg +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps  )  # desktop file  install( -	FILES -		${CMAKE_SOURCE_DIR}/resources/gnome-pie.desktop -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/applications +    FILES +        ${CMAKE_SOURCE_DIR}/resources/gnome-pie.desktop +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/applications  )  # install manpage  install( -	FILES -		${CMAKE_SOURCE_DIR}/resources/gnome-pie.1 -	DESTINATION -		${CMAKE_INSTALL_PREFIX}/share/man/man1 +    FILES +        ${CMAKE_SOURCE_DIR}/resources/gnome-pie.1 +    DESTINATION +        ${CMAKE_INSTALL_PREFIX}/share/man/man1  ) diff --git a/src/actionGroups/actionGroup.vala b/src/actionGroups/actionGroup.vala index c54be2f..8bbcde4 100644 --- a/src/actionGroups/actionGroup.vala +++ b/src/actionGroups/actionGroup.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////	 +/////////////////////////////////////////////////////////////////////////  // A base class storing a set of Actions. Derived classes may define  // how these Actions are created. This base class serves for custom  // actions, defined by the user. @@ -28,67 +28,67 @@ public class ActionGroup : GLib.Object {      /////////////////////////////////////////////////////////////////////      /// A list of all stored actions.      ///////////////////////////////////////////////////////////////////// -     +      public Gee.ArrayList<Action?> actions { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// The ID of the pie to which this group is attached.      ///////////////////////////////////////////////////////////////////// -     +      public string parent_id { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public ActionGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      construct {          this.actions = new Gee.ArrayList<Action?>();      } -     +      /////////////////////////////////////////////////////////////////////      /// This one is called, when the ActionGroup is deleted.      ///////////////////////////////////////////////////////////////////// -     +      public virtual void on_remove() {} -     +      /////////////////////////////////////////////////////////////////////      /// Adds a new Action to the group.      ///////////////////////////////////////////////////////////////////// -     +      public void add_action(Action new_action) {         this.actions.add(new_action);      } -     +      /////////////////////////////////////////////////////////////////////      /// Removes all Actions from the group.      ///////////////////////////////////////////////////////////////////// -     +      public void delete_all() {          actions.clear();      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes all contained Slices no Quick Actions.      ///////////////////////////////////////////////////////////////////// -     +      public void disable_quickactions() {          foreach (var action in actions)              action.is_quickaction = false;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns true, if one o the contained Slices is a Quick Action      ///////////////////////////////////////////////////////////////////// -     +      public bool has_quickaction() {          foreach (var action in actions)              if (action.is_quickaction)                  return true; -                 +          return false;      }  } diff --git a/src/actionGroups/bookmarkGroup.vala b/src/actionGroups/bookmarkGroup.vala index 0a560c5..791d609 100644 --- a/src/actionGroups/bookmarkGroup.vala +++ b/src/actionGroups/bookmarkGroup.vala @@ -1,36 +1,36 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A group of Actions, which represent the users gtk-bookmarks, his home -/// directory, desktop and trash. It stay up-to-date, even if the  +/// directory, desktop and trash. It stay up-to-date, even if the  /// bookmarks change.  /////////////////////////////////////////////////////////////////////////  public class BookmarkGroup : ActionGroup { -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Bookmarks"); @@ -41,34 +41,34 @@ public class BookmarkGroup : ActionGroup {      }      ///////////////////////////////////////////////////////////////////// -    /// Two members needed to avoid useless, frequent changes of the  +    /// Two members needed to avoid useless, frequent changes of the      /// stored Actions.      /////////////////////////////////////////////////////////////////////      private bool changing = false;      private bool changed_again = false; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public BookmarkGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Construct block loads the bookmarks of the user and adds a file      /// monitor in order to update the BookmarkGroup when the bookmarks      /// of the user change.      ///////////////////////////////////////////////////////////////////// -     +      construct {          this.load(); -         +          // add monitor          var bookmark_file = GLib.File.new_for_path(              GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks"); -             +          if (bookmark_file.query_exists()) {              try {                  var monitor = bookmark_file.monitor(GLib.FileMonitorFlags.NONE); @@ -78,31 +78,31 @@ public class BookmarkGroup : ActionGroup {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Adds Actions for each gtk-bookmark of the user and for his home      /// folder, desktop and trash.      ///////////////////////////////////////////////////////////////////// -     +      private void load() {          // add home folder          this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_home_dir())); -         +          // add .gtk-bookmarks          var bookmark_file = GLib.File.new_for_path(              GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks"); -             +          if (!bookmark_file.query_exists()) {              warning("Failed to find file \".gtk-bookmarks\"!");              return;          } -         +          try {              var dis = new DataInputStream(bookmark_file.read());              string line;              while ((line = dis.read_line(null)) != null) {                  var parts = line.split(" "); -                 +                  string uri = parts[0];                  string name = parts[1]; @@ -111,19 +111,19 @@ public class BookmarkGroup : ActionGroup {          } catch (Error e) {              error ("%s", e.message);          } -         +          // add trash          this.add_action(ActionRegistry.new_for_uri("trash://")); -         +          // add desktop          this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_user_special_dir(GLib.UserDirectory.DESKTOP)));      } -     +      /////////////////////////////////////////////////////////////////////      /// Reloads all Bookmarks. Is called when the user's gtk-bookmarks      /// file changes.      ///////////////////////////////////////////////////////////////////// -     +      private void reload() {          // avoid too frequent changes...          if (!this.changing) { @@ -138,13 +138,13 @@ public class BookmarkGroup : ActionGroup {                  message("Bookmarks changed...");                  this.delete_all();                  this.load(); -                 +                  this.changing = false;                  return false;              });          } else {              this.changed_again = true; -        }     +        }      }  } diff --git a/src/actionGroups/clipboardGroup.vala b/src/actionGroups/clipboardGroup.vala index c104d62..ad18740 100644 --- a/src/actionGroups/clipboardGroup.vala +++ b/src/actionGroups/clipboardGroup.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This Group keeps a history of the last used Clipboard entries.  /// Experimental. Not enabled.  ///////////////////////////////////////////////////////////////////////// @@ -25,40 +25,40 @@ namespace GnomePie {  public class ClipboardGroup : ActionGroup {      ///////////////////////////////////////////////////////////////////// -    ///  +    ///      /////////////////////////////////////////////////////////////////////      private class ClipboardItem : GLib.Object { -         +          public string name { get; private set; }          public string icon { get; private set; } -         +          private Gtk.SelectionData contents; -     +          public ClipboardItem(Gtk.SelectionData contents) {              this.contents = contents.copy();              this.name = this.contents.get_text() ?? "";              this.icon = "edit-paste";          } -         +          public void paste() {              debug(name);          }      } -     +      public ClipboardGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      /////////////////////////////////////////////////////////////////////      ///////////////////////////////////////////////////////////////////// -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Clipboard"); @@ -67,45 +67,45 @@ public class ClipboardGroup : ActionGroup {          description.id = "clipboard";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// The clipboard to be monitored.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Clipboard clipboard; -     -     + +      /////////////////////////////////////////////////////////////////////      /// The maximum remembered items of the clipboard.      ///////////////////////////////////////////////////////////////////// -     +      private static const int max_items = 6; -     +      private Gee.ArrayList<ClipboardItem?> items; -     +      construct {          this.items = new Gee.ArrayList<ClipboardItem?>();          this.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);          this.clipboard.owner_change.connect(this.on_change);      } -     +      private void on_change() {          if (this.clipboard.wait_is_text_available()) {              this.clipboard.request_contents(Gdk.Atom.intern("text/plain", false), this.add_item);          }      } -     +      private void add_item(Gtk.Clipboard c, Gtk.SelectionData contents) {          var new_item = new ClipboardItem(contents); -         +          if (this.items.size == ClipboardGroup.max_items)              this.items.remove_at(0); -         +          this.items.add(new_item); -         +          // update slices          this.delete_all(); -         +          for (int i=0; i<this.items.size; ++i) {              var action = new SigAction(items[i].name, items[i].icon, i.to_string());              action.activated.connect(() => { diff --git a/src/actionGroups/devicesGroup.vala b/src/actionGroups/devicesGroup.vala index d3892fe..1078296 100644 --- a/src/actionGroups/devicesGroup.vala +++ b/src/actionGroups/devicesGroup.vala @@ -1,35 +1,35 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie {  ///////////////////////////////////////////////////////////////////// -/// An ActionGroup which contains all currently plugged-in devices,  +/// An ActionGroup which contains all currently plugged-in devices,  /// such as CD-ROM's or USB-sticks.  /////////////////////////////////////////////////////////////////////  public class DevicesGroup : ActionGroup { -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Devices"); @@ -40,63 +40,63 @@ public class DevicesGroup : ActionGroup {      }      ///////////////////////////////////////////////////////////////////// -    /// Two members needed to avoid useless, frequent changes of the  +    /// Two members needed to avoid useless, frequent changes of the      /// stored Actions.      /////////////////////////////////////////////////////////////////////      private bool changing = false;      private bool changed_again = false; -     +      /////////////////////////////////////////////////////////////////////      /// The VolumeMonitor used to check for added or removed devices.      ///////////////////////////////////////////////////////////////////// -     +      private GLib.VolumeMonitor monitor; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public DevicesGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Construct block loads all currently plugged-in devices and      /// connects signal handlers to the VolumeMonitor.      ///////////////////////////////////////////////////////////////////// -     +      construct {          this.monitor = GLib.VolumeMonitor.get(); -         +          this.load();          // add monitor          this.monitor.mount_added.connect(this.reload);          this.monitor.mount_removed.connect(this.reload);      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all currently plugged-in devices.      ///////////////////////////////////////////////////////////////////// -     +      private void load() {          // add root device          this.add_action(new UriAction(_("Root"), "harddrive", "file:///")); -     +          // add all other devices          foreach(var mount in this.monitor.get_mounts()) {              // get icon              var icon = mount.get_icon(); -             +              this.add_action(new UriAction(mount.get_name(), Icon.get_icon_name(icon), mount.get_root().get_uri()));          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Reloads all devices. Is called when the VolumeMonitor changes.      ///////////////////////////////////////////////////////////////////// -     +      private void reload() {          // avoid too frequent changes...          if (!this.changing) { @@ -111,13 +111,13 @@ public class DevicesGroup : ActionGroup {                  message("Devices changed...");                  this.delete_all();                  this.load(); -                 +                  this.changing = false;                  return false;              });          } else {              this.changed_again = true; -        }     +        }      }  } diff --git a/src/actionGroups/groupRegistry.vala b/src/actionGroups/groupRegistry.vala index 7510a03..ca0dc4d 100644 --- a/src/actionGroups/groupRegistry.vala +++ b/src/actionGroups/groupRegistry.vala @@ -1,83 +1,83 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A which has knowledge on all possible acion group types.  /////////////////////////////////////////////////////////////////////////  public class GroupRegistry : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// A list containing all available ActionGroup types.      ///////////////////////////////////////////////////////////////////// -     +      public static Gee.ArrayList<string> types { get; private set; } -     +      ///////////////////////////////////////////////////////////////////// -    /// A map associating a displayable name for each ActionGroup,  +    /// A map associating a displayable name for each ActionGroup,      /// an icon name and a name for the pies.conf file with it's type.      ///////////////////////////////////////////////////////////////////// -     +      public static Gee.HashMap<string, TypeDescription?> descriptions { get; private set; } -     +      public class TypeDescription {          public string name { get; set; default=""; }          public string icon { get; set; default=""; }          public string description { get; set; default=""; }          public string id { get; set; default=""; }      } -     +      /////////////////////////////////////////////////////////////////////      /// Registers all ActionGroup types.      ///////////////////////////////////////////////////////////////////// -     +      public static void init() {          types = new Gee.ArrayList<string>();          descriptions = new Gee.HashMap<string, TypeDescription?>(); -     +          TypeDescription type_description; -         +          type_description = BookmarkGroup.register();          types.add(typeof(BookmarkGroup).name());          descriptions.set(typeof(BookmarkGroup).name(), type_description); -         +          type_description = DevicesGroup.register();          types.add(typeof(DevicesGroup).name());          descriptions.set(typeof(DevicesGroup).name(), type_description); -         +          type_description = MenuGroup.register();          types.add(typeof(MenuGroup).name());          descriptions.set(typeof(MenuGroup).name(), type_description); -         +          type_description = SessionGroup.register();          types.add(typeof(SessionGroup).name());          descriptions.set(typeof(SessionGroup).name(), type_description); -         +          type_description = WindowListGroup.register();          types.add(typeof(WindowListGroup).name());          descriptions.set(typeof(WindowListGroup).name(), type_description);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a Group for a given type name.      ///////////////////////////////////////////////////////////////////// -     +      public static ActionGroup? create_group(string type_id, string parent_id) {          switch (type_id) {              case "bookmarks": return new BookmarkGroup(parent_id); @@ -86,7 +86,7 @@ public class GroupRegistry : GLib.Object {              case "session": return new SessionGroup(parent_id);              case "window_list": return new WindowListGroup(parent_id);          } -         +          return null;      }  } diff --git a/src/actionGroups/menuGroup.vala b/src/actionGroups/menuGroup.vala index 26a2662..7a1e344 100644 --- a/src/actionGroups/menuGroup.vala +++ b/src/actionGroups/menuGroup.vala @@ -1,35 +1,35 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// An ActionGroup which displays the user's main menu. It's a bit ugly,  /// but it supports both, an older version and libgnome-menus-3 at the  /// same time.  ///////////////////////////////////////////////////////////////////////// -         +  public class MenuGroup : ActionGroup {      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Main menu"); @@ -38,50 +38,50 @@ public class MenuGroup : ActionGroup {          description.id = "menu";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// True, if this MenuGroup is the top most menu.      ///////////////////////////////////////////////////////////////////// -     +      public bool is_toplevel {get; construct set; default = true;} -     +      /////////////////////////////////////////////////////////////////////      /// The menu tree displayed by the MenuGroup. Only set for the      /// toplevel MenuGroup.      ///////////////////////////////////////////////////////////////////// -     +      private GMenu.Tree menu = null; -     +      /////////////////////////////////////////////////////////////////////      /// A list of all sub menus of this MenuGroup.      ///////////////////////////////////////////////////////////////////// -     +      private Gee.ArrayList<MenuGroup?> childs; -     +      ///////////////////////////////////////////////////////////////////// -    /// Two members needed to avoid useless, frequent changes of the  +    /// Two members needed to avoid useless, frequent changes of the      /// stored Actions.      ///////////////////////////////////////////////////////////////////// -     +      private bool changing = false;      private bool changed_again = false; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members. Used for the toplevel menu.      ///////////////////////////////////////////////////////////////////// -     +      public MenuGroup(string parent_id) {          GLib.Object(parent_id : parent_id, is_toplevel : true);      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members. Used for sub menus.      ///////////////////////////////////////////////////////////////////// -     +      public MenuGroup.sub_menu(string parent_id) {          GLib.Object(parent_id : parent_id, is_toplevel : false);      } -     +      construct {          this.childs = new Gee.ArrayList<MenuGroup?>(); @@ -89,16 +89,16 @@ public class MenuGroup : ActionGroup {              #if HAVE_GMENU_3                  this.menu = new GMenu.Tree("applications.menu", GMenu.TreeFlags.INCLUDE_EXCLUDED);                  this.menu.changed.connect(this.reload); -            #endif  -             -            this.load_toplevel();  -        }  +            #endif + +            this.load_toplevel(); +        }      } -     +      /////////////////////////////////////////////////////////////////////      /// Starts to load the menu.      ///////////////////////////////////////////////////////////////////// -     +      private void load_toplevel() {          #if HAVE_GMENU_3              try { @@ -113,13 +113,13 @@ public class MenuGroup : ActionGroup {              this.menu.add_monitor(this.reload);              var dir = this.menu.get_root_directory();              this.load_contents(dir, this.parent_id); -        #endif  +        #endif      }      /////////////////////////////////////////////////////////////////////      /// Parses the main menu recursively.      ///////////////////////////////////////////////////////////////////// -     +      private void load_contents(GMenu.TreeDirectory dir, string parent_id) {          #if HAVE_GMENU_3              var item = dir.iter(); @@ -128,35 +128,35 @@ public class MenuGroup : ActionGroup {                  var type = item.next();                  if (type == GMenu.TreeItemType.INVALID)                      break; -                     +                  if (type == GMenu.TreeItemType.DIRECTORY && !item.get_directory().get_is_nodisplay()) { -                    // create a MenuGroup for sub menus  -                     +                    // create a MenuGroup for sub menus +                      // get icon                      var icon = item.get_directory().get_icon(); -                     +                      var sub_menu = PieManager.create_dynamic_pie(item.get_directory().get_name(), Icon.get_icon_name(icon));                      var group = new MenuGroup.sub_menu(sub_menu.id);                      group.add_action(new PieAction(parent_id, true));                      group.load_contents(item.get_directory(), sub_menu.id);                      childs.add(group); -                                                       +                      sub_menu.add_group(group); -                     -                    this.add_action(new PieAction(sub_menu.id));  + +                    this.add_action(new PieAction(sub_menu.id));                  } else if (type == GMenu.TreeItemType.ENTRY ) {                      // create an AppAction for entries                      if (!item.get_entry().get_is_excluded()) { -                        this.add_action(ActionRegistry.new_for_app_info(item.get_entry().get_app_info()));  -                    }  +                        this.add_action(ActionRegistry.new_for_app_info(item.get_entry().get_app_info())); +                    }                  }              }          #else              foreach (var item in dir.get_contents()) {                  switch(item.get_type()) {                      case GMenu.TreeItemType.DIRECTORY: -                        // create a MenuGroup for sub menus  +                        // create a MenuGroup for sub menus                          if (!((GMenu.TreeDirectory)item).get_is_nodisplay()) {                              var sub_menu = PieManager.create_dynamic_pie(                                                                ((GMenu.TreeDirectory)item).get_name(), @@ -165,30 +165,30 @@ public class MenuGroup : ActionGroup {                              group.add_action(new PieAction(parent_id, true));                              group.load_contents((GMenu.TreeDirectory)item, sub_menu.id);                              childs.add(group); -                                                               +                              sub_menu.add_group(group); -                             -                            this.add_action(new PieAction(sub_menu.id));  -                        }  + +                            this.add_action(new PieAction(sub_menu.id)); +                        }                          break; -                         +                      case GMenu.TreeItemType.ENTRY:                          // create an AppAction for entries                          if (!((GMenu.TreeEntry)item).get_is_nodisplay() && !((GMenu.TreeEntry)item).get_is_excluded()) { -                            this.add_action(new AppAction(((GMenu.TreeEntry)item).get_name(),  -                                                          ((GMenu.TreeEntry)item).get_icon(),  -                                                          ((GMenu.TreeEntry)item).get_exec()));  -                        }  +                            this.add_action(new AppAction(((GMenu.TreeEntry)item).get_name(), +                                                          ((GMenu.TreeEntry)item).get_icon(), +                                                          ((GMenu.TreeEntry)item).get_exec())); +                        }                          break;                  }              }          #endif      } -     +      /////////////////////////////////////////////////////////////////////      /// Reloads the menu.      ///////////////////////////////////////////////////////////////////// -     +      private void reload() {          // avoid too frequent changes...          if (!this.changing) { @@ -204,46 +204,46 @@ public class MenuGroup : ActionGroup {                  #if !HAVE_GMENU_3                      this.menu.remove_monitor(this.reload);                  #endif -                 +                  this.clear();                  this.load_toplevel(); -                 +                  this.changing = false;                  return false;              });          } else {              this.changed_again = true; -        }   +        }      } -     +      /////////////////////////////////////////////////////////////////////      /// Deletes all generated Pies, when the toplevel menu is deleted.      ///////////////////////////////////////////////////////////////////// -     +      public override void on_remove() {          if (this.is_toplevel)              this.clear();      } -     +      /////////////////////////////////////////////////////////////////////      /// Clears this ActionGroup recursively.      ///////////////////////////////////////////////////////////////////// -     +      private void clear() {          foreach (var child in childs)              child.clear();          if (!this.is_toplevel)              PieManager.remove_pie(this.parent_id); -             +          this.delete_all(); -         +          this.childs.clear(); -         +          #if !HAVE_GMENU_3              this.menu = null;          #endif -         +      }  } diff --git a/src/actionGroups/sessionGroup.vala b/src/actionGroups/sessionGroup.vala index 26f8ebc..7b989a6 100644 --- a/src/actionGroups/sessionGroup.vala +++ b/src/actionGroups/sessionGroup.vala @@ -1,19 +1,19 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -23,13 +23,13 @@ namespace GnomePie {  /////////////////////////////////////////////////////////////////////  public class SessionGroup : ActionGroup { -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Session Control"); @@ -38,38 +38,38 @@ public class SessionGroup : ActionGroup {          description.id = "session";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public SessionGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Construct block adds the three Actions.      ///////////////////////////////////////////////////////////////////// -     +      construct { -//    	string iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.gnome.SessionManager", "/org/gnome/SessionManager"); -//		iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer"); -//    	iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.kde.ksmserver", "/KSMServer"); -//    	iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager"); -     -        this.add_action(new AppAction(_("Shutdown"), "gnome-shutdown",  +//        string iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.gnome.SessionManager", "/org/gnome/SessionManager"); +//        iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer"); +//        iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.kde.ksmserver", "/KSMServer"); +//        iface = GLib.Bus.get_proxy_sync(GLib.BusType.SESSION, "org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager"); + +        this.add_action(new AppAction(_("Shutdown"), "gnome-shutdown",              "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.RequestShutdown")); -             -        this.add_action(new AppAction(_("Logout"), "gnome-session-logout",  + +        this.add_action(new AppAction(_("Logout"), "gnome-session-logout",              "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.Logout uint32:1")); -             -        this.add_action(new AppAction(_("Reboot"), "gnome-session-reboot",  + +        this.add_action(new AppAction(_("Reboot"), "gnome-session-reboot",              "dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.RequestReboot"));      } -     +      // TODO: check for available interfaces --- these may work too:      // dbus-send --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown -    // dbus-send --print-reply --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 2 2  +    // dbus-send --print-reply --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 2 2      // dbus-send --print-reply --dest="org.freedesktop.ConsoleKit" /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop  } diff --git a/src/actionGroups/windowListGroup.vala b/src/actionGroups/windowListGroup.vala index 774666f..a2dc19c 100644 --- a/src/actionGroups/windowListGroup.vala +++ b/src/actionGroups/windowListGroup.vala @@ -1,19 +1,19 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -22,13 +22,13 @@ namespace GnomePie {  /////////////////////////////////////////////////////////////////////  public class WindowListGroup : ActionGroup { -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of ActionGroup. It sets the display -    /// name for this ActionGroup, it's icon name and the string used in  +    /// name for this ActionGroup, it's icon name and the string used in      /// the pies.conf file for this kind of ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public static GroupRegistry.TypeDescription register() {          var description = new GroupRegistry.TypeDescription();          description.name = _("Group: Window List"); @@ -39,86 +39,86 @@ public class WindowListGroup : ActionGroup {      }      ///////////////////////////////////////////////////////////////////// -    /// Two members needed to avoid useless, frequent changes of the  +    /// Two members needed to avoid useless, frequent changes of the      /// stored Actions.      /////////////////////////////////////////////////////////////////////      private bool changing = false;      private bool changed_again = false; -     +      private Wnck.Screen screen; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public WindowListGroup(string parent_id) {          GLib.Object(parent_id : parent_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all windows.      ///////////////////////////////////////////////////////////////////// -     +      construct {          this.screen = Wnck.Screen.get_default(); -     +          this.screen.window_opened.connect(reload);          this.screen.window_closed.connect(reload); -         +          this.load();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all currently opened windows and creates actions for them.      ///////////////////////////////////////////////////////////////////// -     +      private void load() {          unowned GLib.List<Wnck.Window?> windows = this.screen.get_windows(); -         +          var matcher = Bamf.Matcher.get_default();          foreach (var window in windows) {              if (window.get_window_type() == Wnck.WindowType.NORMAL -            	&& !window.is_skip_pager() && !window.is_skip_tasklist()) { +                && !window.is_skip_pager() && !window.is_skip_tasklist()) {                  var application = window.get_application();                  var bamf_app = matcher.get_application_for_xid((uint32)window.get_xid()); -                 +                  string name = window.get_name(); -                 +                  if (name.length > 30)                      name = name.substring(0, 30) + "..."; -                 +                  var action = new SigAction(                      name,                      (bamf_app == null) ? application.get_icon_name().down() : bamf_app.get_icon(), -                    "%lu".printf(window.get_xid())  +                    "%lu".printf(window.get_xid())                  );                  action.activated.connect(() => {                      Wnck.Screen.get_default().force_update(); -                 +                      var xid = (X.Window)uint64.parse(action.real_command);                      var win = Wnck.Window.get(xid); -                    var time = Gtk.get_current_event_time();  -                     -                    if (win.get_workspace() != null  -                        && win.get_workspace() != win.get_screen().get_active_workspace())  -				        win.get_workspace().activate(time); -			 -			        if (win.is_minimized())  -				        win.unminimize(time); -			 -			        win.activate_transient(time); +                    var time = Gtk.get_current_event_time(); + +                    if (win.get_workspace() != null +                        && win.get_workspace() != win.get_screen().get_active_workspace()) +                        win.get_workspace().activate(time); + +                    if (win.is_minimized()) +                        win.unminimize(time); + +                    win.activate_transient(time);                  });                  this.add_action(action);              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Reloads all running applications.      ///////////////////////////////////////////////////////////////////// -     +      private void reload() {          // avoid too frequent changes...          if (!this.changing) { @@ -132,13 +132,13 @@ public class WindowListGroup : ActionGroup {                  // reload                  this.delete_all();                  this.load(); -                 +                  this.changing = false;                  return false;              });          } else {              this.changed_again = true; -        }     +        }      }  } diff --git a/src/actions/action.vala b/src/actions/action.vala index ff0e9cd..91fc448 100644 --- a/src/actions/action.vala +++ b/src/actions/action.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A base class for actions, which are executed when the user  /// activates a pie's slice.  ///////////////////////////////////////////////////////////////////////// @@ -30,33 +30,33 @@ public abstract class Action : GLib.Object {      /////////////////////////////////////////////////////////////////////      public abstract string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// The command displayed to the user. It should be a bit more      /// beautiful than the real_command.      ///////////////////////////////////////////////////////////////////// -     -    public abstract string display_command { get; }   -     + +    public abstract string display_command { get; } +      /////////////////////////////////////////////////////////////////////      /// The name of the Action. -    /////////////////////////////////////////////////////////////////////   +    /////////////////////////////////////////////////////////////////////      public virtual string name { get; set; } -     +      /////////////////////////////////////////////////////////////////////      /// The name of the icon of this Action. It should be in the users      /// current icon theme.      ///////////////////////////////////////////////////////////////////// -     +      public virtual string icon { get; set; } -     +      /////////////////////////////////////////////////////////////////////      /// True, if this Action is the quickAction of the associated Pie.      /// The quickAction of a Pie gets executed when the users clicks on      /// the center of a Pie.      ///////////////////////////////////////////////////////////////////// -     +      public virtual bool is_quickaction { get; set; }      ///////////////////////////////////////////////////////////////////// diff --git a/src/actions/actionRegistry.vala b/src/actions/actionRegistry.vala index 24cc1fe..9a22cc7 100644 --- a/src/actions/actionRegistry.vala +++ b/src/actions/actionRegistry.vala @@ -1,46 +1,46 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A which has knowledge on all possible acion types.  /////////////////////////////////////////////////////////////////////////  public class ActionRegistry : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// A list containing all available Action types.      ///////////////////////////////////////////////////////////////////// -     +      public static Gee.ArrayList<string> types { get; private set; } -     +      ///////////////////////////////////////////////////////////////////// -    /// A map associating a displayable name for each Action,  +    /// A map associating a displayable name for each Action,      /// whether it has a custom icon and a name for the pies.conf      /// file with it's type.      ///////////////////////////////////////////////////////////////////// -     +      public static Gee.HashMap<string, TypeDescription?> descriptions { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// A helper class storing information on a Action type.      ///////////////////////////////////////////////////////////////////// -     +      public class TypeDescription {          public string name { get; set; default=""; }          public string icon { get; set; default=""; } @@ -48,38 +48,38 @@ public class ActionRegistry : GLib.Object {          public string id { get; set; default=""; }          public bool icon_name_editable { get; set; default=false; }      } -     +      /////////////////////////////////////////////////////////////////////      /// Registers all Action types.      ///////////////////////////////////////////////////////////////////// -     +      public static void init() {          types = new Gee.ArrayList<string>();          descriptions = new Gee.HashMap<string, TypeDescription?>(); -     +          TypeDescription type_description; -         +          types.add(typeof(AppAction).name());          type_description = AppAction.register();          descriptions.set(typeof(AppAction).name(), type_description); -         +          types.add(typeof(KeyAction).name());          type_description = KeyAction.register();          descriptions.set(typeof(KeyAction).name(), type_description); -         +          types.add(typeof(PieAction).name());          type_description = PieAction.register();          descriptions.set(typeof(PieAction).name(), type_description); -         +          types.add(typeof(UriAction).name());          type_description = UriAction.register();          descriptions.set(typeof(UriAction).name(), type_description);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new Action from the given type name.      ///////////////////////////////////////////////////////////////////// -     +      public static Action? create_action(string type_id, string name, string icon, string command, bool quickaction) {          switch (type_id) {              case "app": return new AppAction(name, icon, command, quickaction); @@ -87,131 +87,131 @@ public class ActionRegistry : GLib.Object {              case "uri": return new UriAction(name, icon, command, quickaction);              case "pie": return new PieAction(command, quickaction);          } -         +          return null;      } -     +      ///////////////////////////////////////////////////////////////////// -    /// A helper method which creates an Action, appropriate for the  +    /// A helper method which creates an Action, appropriate for the      /// given URI. This can result in an UriAction or in an AppAction, -    /// depending on the Type of the URI.  +    /// depending on the Type of the URI.      /////////////////////////////////////////////////////////////////////      public static Action? new_for_uri(string uri, string? name = null) {          var file = GLib.File.new_for_uri(uri);          var scheme = file.get_uri_scheme(); -         +          string final_icon = "";          string final_name = file.get_basename();          switch (scheme) {              case "application":                  var file_name = uri.split("//")[1]; -                 +                  var desktop_file = GLib.File.new_for_path("/usr/share/applications/" + file_name);                  if (desktop_file.query_exists())                      return new_for_desktop_file(desktop_file.get_path());                  break; -                 +              case "trash":                  final_icon = "user-trash";                  final_name = _("Trash");                  break; -                 +              case "http": case "https":                  final_icon = "www";                  final_name = get_domain_name(uri);                  break; -                 +              case "ftp": case "sftp":                  final_icon = "folder-remote";                  final_name = get_domain_name(uri);                  break; -                 +              default:                  try {                      var info = file.query_info("*", GLib.FileQueryInfoFlags.NONE); -                     +                      if (info.get_content_type() == "application/x-desktop")                          return new_for_desktop_file(file.get_parse_name()); -                     +                      // search for an appropriate icon -                    var icon = info.get_icon();                 +                    var icon = info.get_icon();                      final_icon = Icon.get_icon_name(icon); -                     +                  } catch (GLib.Error e) {                      warning(e.message);                  }                  break;          } -         +          if (!Gtk.IconTheme.get_default().has_icon(final_icon))                  final_icon = "stock_unknown"; -         +          if (name != null)              final_name = name; -         +          return new UriAction(final_name, final_icon, uri);      } -     +      /////////////////////////////////////////////////////////////////////      /// A helper method which creates an AppAction for given AppInfo.      ///////////////////////////////////////////////////////////////////// -     -    public static Action? new_for_app_info(GLib.AppInfo info) {    + +    public static Action? new_for_app_info(GLib.AppInfo info) {          // get icon -        var icon = info.get_icon();      -         +        var icon = info.get_icon(); +          return new AppAction(info.get_display_name(), Icon.get_icon_name(icon), info.get_commandline());      } -     +      /////////////////////////////////////////////////////////////////////      /// A helper method which creates an AppAction for given *.desktop      /// file.      ///////////////////////////////////////////////////////////////////// -     +      public static Action? new_for_desktop_file(string file_name) {          // check whether its a desktop file to open one of Gnome-Pie's pies          if (file_name.has_prefix(Paths.launchers)) {              string id = file_name.substring((long)file_name.length - 11, 3);              return new PieAction(id);          } -         +          var info = new DesktopAppInfo.from_filename(file_name);          return new_for_app_info(info);      } -     +      /////////////////////////////////////////////////////////////////////      /// A helper method which creates an AppAction for given mime type.      ///////////////////////////////////////////////////////////////////// -     +      public static Action? default_for_mime_type(string type) {          var info = AppInfo.get_default_for_type(type, false);          return new_for_app_info(info);      } -     +      /////////////////////////////////////////////////////////////////////      /// A helper method which creates an AppAction for given uri scheme.      ///////////////////////////////////////////////////////////////////// -     +      public static Action? default_for_uri(string uri) {          var info = AppInfo.get_default_for_uri_scheme(uri);          return new_for_app_info(info);      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns for example www.google.com when http://www.google.de/?q=h      /// is given.      ///////////////////////////////////////////////////////////////////// -     +      private static string get_domain_name(string url) {          int domain_end = url.index_of_char('/', 7);          int domain_begin = url.index_of_char('/', 0) + 2; -         +          if (domain_begin < domain_end) return url.substring(domain_begin, domain_end-domain_begin); -         +          return url;      }  } diff --git a/src/actions/appAction.vala b/src/actions/appAction.vala index 2371f7c..859baf8 100644 --- a/src/actions/appAction.vala +++ b/src/actions/appAction.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This type of Action launches an application or a custom command.  ///////////////////////////////////////////////////////////////////////// @@ -38,17 +38,17 @@ public class AppAction : Action {          description.id = "app";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// Stores the command line.      /////////////////////////////////////////////////////////////////////      public override string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// Simply returns the real_command. No beautification.      ///////////////////////////////////////////////////////////////////// -     +      public override string display_command { get {return real_command;} }      ///////////////////////////////////////////////////////////////////// @@ -67,10 +67,10 @@ public class AppAction : Action {          try{              var item = GLib.AppInfo.create_from_commandline(this.real_command, null, GLib.AppInfoCreateFlags.NONE);              item.launch(null, null); -    	} catch (Error e) { -	        warning(e.message); +        } catch (Error e) { +            warning(e.message);          } -    }  +    }  }  } diff --git a/src/actions/keyAction.vala b/src/actions/keyAction.vala index 3816686..68a2ec1 100644 --- a/src/actions/keyAction.vala +++ b/src/actions/keyAction.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This type of Action "presses" a key stroke.  ///////////////////////////////////////////////////////////////////////// @@ -37,24 +37,24 @@ public class KeyAction : Action {          description.icon_name_editable = true;          description.id = "key";          return description; -    }    -     +    } +      /////////////////////////////////////////////////////////////////////      /// Stores the accelerator of this action.      ///////////////////////////////////////////////////////////////////// -     +      public override string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// Returns a human readable form of the accelerator.      ///////////////////////////////////////////////////////////////////// -     +      public override string display_command { get {return key.label;} } -     +      /////////////////////////////////////////////////////////////////////      /// The simulated key which gets 'pressed' on execution.      ///////////////////////////////////////////////////////////////////// -     +      public Key key { get; set; }      ///////////////////////////////////////////////////////////////////// @@ -64,11 +64,11 @@ public class KeyAction : Action {      public KeyAction(string name, string icon, string command, bool is_quickaction = false) {          GLib.Object(name : name, icon : icon, real_command : command, is_quickaction : is_quickaction);      } -     +      construct {          this.key = new Key.from_string(real_command);      } -     +      /////////////////////////////////////////////////////////////////////      /// Presses the desired key.      ///////////////////////////////////////////////////////////////////// diff --git a/src/actions/pieAction.vala b/src/actions/pieAction.vala index c65c1d6..8069ff3 100644 --- a/src/actions/pieAction.vala +++ b/src/actions/pieAction.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This Action opens another pie.  ///////////////////////////////////////////////////////////////////////// @@ -38,23 +38,23 @@ public class PieAction : Action {          description.id = "pie";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// Stores the ID of the referenced Pie.      /////////////////////////////////////////////////////////////////////      public override string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the name of the referenced Pie.      ///////////////////////////////////////////////////////////////////// -     +      public override string display_command { get {return name;} } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the name of the referenced Pie.      ///////////////////////////////////////////////////////////////////// -     +      public override string name {          get {              var referee = PieManager.all_pies[real_command]; @@ -66,13 +66,13 @@ public class PieAction : Action {          }          protected set {}      } -     +      private string owned_name; -     +      /////////////////////////////////////////////////////////////////////      /// Returns the icon of the referenced Pie.      ///////////////////////////////////////////////////////////////////// -     +      public override string icon {          get {              var referee = PieManager.all_pies[real_command]; @@ -90,14 +90,14 @@ public class PieAction : Action {      public PieAction(string id, bool is_quickaction = false) {          GLib.Object(name : "", icon : "", real_command : id, is_quickaction : is_quickaction);      } -     +      /////////////////////////////////////////////////////////////////////      /// Opens the desired Pie.      /////////////////////////////////////////////////////////////////////      public override void activate() {          PieManager.open_pie(real_command); -    }  +    }  }  } diff --git a/src/actions/sigAction.vala b/src/actions/sigAction.vala index 1edbc08..4eebbca 100644 --- a/src/actions/sigAction.vala +++ b/src/actions/sigAction.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This type of Action can't be selected by the user, therefore there is  /// no register() method for this class. But it may be useful for  /// ActionGroups: It emits a signal on activation. @@ -30,19 +30,19 @@ public class SigAction : Action {      /////////////////////////////////////////////////////////////////////      public signal void activated(); -     +      /////////////////////////////////////////////////////////////////////      /// This may store something useful.      /////////////////////////////////////////////////////////////////////      public override string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// Only for inheritance... Greetings to Liskov.      ///////////////////////////////////////////////////////////////////// -     +      public override string display_command { get {return real_command;} } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// @@ -57,7 +57,7 @@ public class SigAction : Action {      public override void activate() {          this.activated(); -    }  +    }  }  } diff --git a/src/actions/uriAction.vala b/src/actions/uriAction.vala index f407f6c..dfc1029 100644 --- a/src/actions/uriAction.vala +++ b/src/actions/uriAction.vala @@ -1,34 +1,34 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This type of Action opens the default application for an URI.  /////////////////////////////////////////////////////////////////////////  public class UriAction : Action { -     +      /////////////////////////////////////////////////////////////////////      /// Used to register this type of Action. It sets the display name      /// for this Action, whether it has a custom Icon/Name and the string      /// used in the pies.conf file for this kind of Actions.      ///////////////////////////////////////////////////////////////////// -     +      public static ActionRegistry.TypeDescription register() {          var description = new ActionRegistry.TypeDescription();          description.name = _("Open URI"); @@ -38,17 +38,17 @@ public class UriAction : Action {          description.id = "uri";          return description;      } -     +      /////////////////////////////////////////////////////////////////////      /// The URI of this Action.      ///////////////////////////////////////////////////////////////////// -     +      public override string real_command { get; construct set; } -     +      /////////////////////////////////////////////////////////////////////      /// Returns only the real URI. An URI can't be beautified.      ///////////////////////////////////////////////////////////////////// -     +      public override string display_command { get {return real_command;} }      ///////////////////////////////////////////////////////////////////// @@ -56,8 +56,8 @@ public class UriAction : Action {      /////////////////////////////////////////////////////////////////////      public UriAction(string name, string icon, string command, bool is_quickaction = false) { -        GLib.Object(name : name, icon : icon,  -                    real_command : command.has_prefix("www") ? "http://" + command : command,  +        GLib.Object(name : name, icon : icon, +                    real_command : command.has_prefix("www") ? "http://" + command : command,                      is_quickaction : is_quickaction);      } @@ -68,10 +68,10 @@ public class UriAction : Action {      public override void activate() {          try{              GLib.AppInfo.launch_default_for_uri(real_command, null); -    	} catch (Error e) { -	        warning(e.message); +        } catch (Error e) { +            warning(e.message);          } -    }  +    }  }  } diff --git a/src/deamon.vala b/src/deamon.vala index 2e79d10..daa6d9d 100644 --- a/src/deamon.vala +++ b/src/deamon.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -36,7 +36,7 @@ public class Deamon : GLib.Object {      /////////////////////////////////////////////////////////////////////      public static int main(string[] args) { -        version = "0.5.7"; +        version = "0.6.0";          Logger.init();          Gtk.init(ref args); @@ -133,9 +133,9 @@ public class Deamon : GLib.Object {      private static void sig_handler(int sig) {          stdout.printf("\n"); -		message("Caught signal (%d), bye!".printf(sig)); -		Gtk.main_quit(); -	} +        message("Caught signal (%d), bye!".printf(sig)); +        Gtk.main_quit(); +    }      /////////////////////////////////////////////////////////////////////      /// Handles command line parameters. diff --git a/src/gui/aboutWindow.vala b/src/gui/aboutWindow.vala index 39258cb..cf1ce8a 100644 --- a/src/gui/aboutWindow.vala +++ b/src/gui/aboutWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -29,38 +29,40 @@ public class AboutWindow: Gtk.AboutDialog {      /////////////////////////////////////////////////////////////////////      public AboutWindow () { -    	string[] devs = { -			"Simon Schneegans <code@simonschneegans.de>", +        string[] devs = { +            "Simon Schneegans <code@simonschneegans.de>", +            "Gabriel Dubatti <gdubatti@gmail.com>",              "Francesco Piccinno <stack.box@gmail.com>"          };          string[] artists = { -			"Simon Schneegans <code@simonschneegans.de>" +            "Simon Schneegans <code@simonschneegans.de>"          }; -    	string[] translators = { -    		"Simon Schneegans <code@simonschneegans.de> (DE, EN)", -    		"Riccardo Traverso <gr3yfox.fw@gmail.com> (IT)", -    		"Magnun Leno <magnun@codecommunity.org> (PT-BR)", -    		"Kim Boram <Boramism@gmail.com> (KO)", +        string[] translators = { +            "Simon Schneegans <code@simonschneegans.de> (DE, EN)", +            "Riccardo Traverso <gr3yfox.fw@gmail.com> (IT)", +            "Magnun Leno <magnun@codecommunity.org> (PT-BR)", +            "Kim Boram <Boramism@gmail.com> (KO)",              "Eduardo Anabalon <lalo1412@gmail.com> (ES)", +            "Gabriel Dubatti <gdubatti@gmail.com> (ES)",              "Grégoire Bellon-Gervais <greggbg@gmail.com> (FR)",              "Alex Maxime <cad.maxime@gmail.com> (FR)",              "Eugene Roskin <pams@imail.ru> (RU)",              "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); +        // 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); -    	}); +        translator_list.sort((a, b) => { +            return a.ascii_casecmp(b); +        }); -    	string translator_string = ""; -    	foreach (var translator in translator_list) -	   		translator_string += translator + "\n"; +        string translator_string = ""; +        foreach (var translator in translator_list) +               translator_string += translator + "\n";          GLib.Object (              artists : artists, diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala index 2560811..ce610ea 100644 --- a/src/gui/iconSelectWindow.vala +++ b/src/gui/iconSelectWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/indicator.vala b/src/gui/indicator.vala index 1277fb8..b46ee59 100644 --- a/src/gui/indicator.vala +++ b/src/gui/indicator.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/newSliceWindow.vala b/src/gui/newSliceWindow.vala index 92c7701..a17c819 100644 --- a/src/gui/newSliceWindow.vala +++ b/src/gui/newSliceWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/newsWindow.vala b/src/gui/newsWindow.vala index 373135f..cc1a77d 100644 --- a/src/gui/newsWindow.vala +++ b/src/gui/newsWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/pieComboList.vala b/src/gui/pieComboList.vala index 3be3bff..f0fd22f 100644 --- a/src/gui/pieComboList.vala +++ b/src/gui/pieComboList.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A drop-down list, containing one entry for each existing Pie.  ///////////////////////////////////////////////////////////////////////// @@ -26,19 +26,19 @@ class PieComboList : Gtk.ComboBox {      /////////////////////////////////////////////////////////////////////      /// This signal gets emitted when the user selects a new Pie.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_select(string id); -     +      /////////////////////////////////////////////////////////////////////      /// The currently selected row.      ///////////////////////////////////////////////////////////////////// -     +      public string current_id { get; private set; default=""; } -     +      /////////////////////////////////////////////////////////////////////      /// Stores the data internally.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.ListStore data;      private enum DataPos {ICON, NAME, ID} @@ -48,25 +48,25 @@ class PieComboList : Gtk.ComboBox {      public PieComboList() {          GLib.Object(); -         -        this.data = new Gtk.ListStore(3, typeof(Gdk.Pixbuf),    + +        this.data = new Gtk.ListStore(3, typeof(Gdk.Pixbuf),                                           typeof(string),                                           typeof(string)); -                                          +          this.data.set_sort_column_id(1, Gtk.SortType.ASCENDING); -         +          base.set_model(this.data); -         +          var icon_render = new Gtk.CellRendererPixbuf();              icon_render.xpad = 4;              this.pack_start(icon_render, false); -     +          var name_render = new Gtk.CellRendererText();              this.pack_start(name_render, true); -         +          this.add_attribute(icon_render, "pixbuf", DataPos.ICON);          this.add_attribute(name_render, "text", DataPos.NAME); -         +          this.changed.connect(() => {              Gtk.TreeIter active;              if (this.get_active_iter(out active)) { @@ -76,36 +76,36 @@ class PieComboList : Gtk.ComboBox {                  this.current_id = id;              }          }); -         +          reload();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all existing Pies to the list.      ///////////////////////////////////////////////////////////////////// -     +      public void reload() {          Gtk.TreeIter active;          string id = "";          if (this.get_active_iter(out active))              this.data.get(active, DataPos.ID, out id); -     +          data.clear();          foreach (var pie in PieManager.all_pies.entries) {              this.load_pie(pie.value);          } -         +          select_first();          select(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects the first Pie.      ///////////////////////////////////////////////////////////////////// -     +      public void select_first() {          Gtk.TreeIter active; -         +          if(this.data.get_iter_first(out active) ) {              this.set_active_iter(active);              string id = ""; @@ -117,37 +117,37 @@ class PieComboList : Gtk.ComboBox {              this.current_id = "";          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects the Pie with the given ID.      ///////////////////////////////////////////////////////////////////// -     +      public void select(string id) {          this.data.foreach((model, path, iter) => {              string pie_id;              this.data.get(iter, DataPos.ID, out pie_id); -             +              if (id == pie_id) {                  this.set_active_iter(iter);                  return true;              } -             +              return false;          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads one given pie to the list.      ///////////////////////////////////////////////////////////////////// -     +      private void load_pie(Pie pie) {          if (pie.id.length == 3) {              Gtk.TreeIter last;              this.data.append(out last);              var icon = new Icon(pie.icon, 24); -            this.data.set(last, DataPos.ICON, icon.to_pixbuf(),  +            this.data.set(last, DataPos.ICON, icon.to_pixbuf(),                                  DataPos.NAME, pie.name, -                                DataPos.ID, pie.id);  +                                DataPos.ID, pie.id);          }      }  } diff --git a/src/gui/pieList.vala b/src/gui/pieList.vala index f9fb54b..29c0a1e 100644 --- a/src/gui/pieList.vala +++ b/src/gui/pieList.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A list, containing one entry for each existing Pie.  ///////////////////////////////////////////////////////////////////////// @@ -26,22 +26,22 @@ class PieList : Gtk.TreeView {      /////////////////////////////////////////////////////////////////////      /// This signal gets emitted when the user selects a new Pie.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_select(string id); -     +      /////////////////////////////////////////////////////////////////////      /// Stores the data internally.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.ListStore data;      private enum DataPos {ICON, ICON_NAME, NAME, ID} -     +      /////////////////////////////////////////////////////////////////////      /// Stores where a drag startet.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.TreeIter? drag_start = null; -     +      /////////////////////////////////////////////////////////////////////      /// Rembers the time when a last drag move event was reported. Used      /// to avoid frequent changes of selected Pie when a Pie is dragged @@ -49,45 +49,45 @@ class PieList : Gtk.TreeView {      /////////////////////////////////////////////////////////////////////      private uint last_hover = 0; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, constructs the Widget.      /////////////////////////////////////////////////////////////////////      public PieList() {          GLib.Object(); -         -        this.data = new Gtk.ListStore(4, typeof(Gdk.Pixbuf),    + +        this.data = new Gtk.ListStore(4, typeof(Gdk.Pixbuf),                                           typeof(string),                                           typeof(string),                                           typeof(string)); -                                          +          this.data.set_sort_column_id(DataPos.NAME, Gtk.SortType.ASCENDING); -         +          this.set_model(this.data);          this.set_headers_visible(false);          this.set_grid_lines(Gtk.TreeViewGridLines.NONE);          this.width_request = 170;          this.set_enable_search(false); -         +          this.set_events(Gdk.EventMask.POINTER_MOTION_MASK); -         +          var main_column = new Gtk.TreeViewColumn();              var icon_render = new Gtk.CellRendererPixbuf();                  icon_render.xpad = 4;                  icon_render.ypad = 4;                  main_column.pack_start(icon_render, false); -         +              var name_render = new Gtk.CellRendererText();                  name_render.ellipsize = Pango.EllipsizeMode.END;                  name_render.ellipsize_set = true;                  main_column.pack_start(name_render, true); -         +          base.append_column(main_column); -         +          main_column.add_attribute(icon_render, "pixbuf", DataPos.ICON);          main_column.add_attribute(name_render, "text", DataPos.NAME); -         +          // setup drag'n'drop          Gtk.TargetEntry uri_source = {"text/uri-list", 0, 0};          Gtk.TargetEntry[] entries = { uri_source }; @@ -100,7 +100,7 @@ class PieList : Gtk.TreeView {          this.drag_leave.connect(() => {              this.last_hover = 0;          }); -         +          this.get_selection().changed.connect(() => {              Gtk.TreeIter active;              if (this.get_selection().get_selected(null, out active)) { @@ -109,35 +109,35 @@ class PieList : Gtk.TreeView {                  this.on_select(id);              }          }); -         +          reload_all();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all existing Pies to the list.      ///////////////////////////////////////////////////////////////////// -     +      public void reload_all() {          Gtk.TreeIter active;          string id = "";          if (this.get_selection().get_selected(null, out active))              this.data.get(active, DataPos.ID, out id); -     +          data.clear();          foreach (var pie in PieManager.all_pies.entries) {              this.load_pie(pie.value);          } -         +          select(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects the first Pie.      ///////////////////////////////////////////////////////////////////// -     +      public void select_first() {          Gtk.TreeIter active; -         +          if(this.data.get_iter_first(out active) ) {              this.get_selection().select_iter(active);              string id = ""; @@ -147,45 +147,45 @@ class PieList : Gtk.TreeView {              this.on_select("");          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects the Pie with the given ID.      ///////////////////////////////////////////////////////////////////// -     +      public void select(string id) {          this.data.foreach((model, path, iter) => {              string pie_id;              this.data.get(iter, DataPos.ID, out pie_id); -             +              if (id == pie_id) {                  this.get_selection().select_iter(iter);                  return true;              } -             +              return false;          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads one given pie to the list.      ///////////////////////////////////////////////////////////////////// -     +      private void load_pie(Pie pie) {          if (pie.id.length == 3) {              Gtk.TreeIter last;              this.data.append(out last);              var icon = new Icon(pie.icon, 24); -            this.data.set(last, DataPos.ICON, icon.to_pixbuf(),  +            this.data.set(last, DataPos.ICON, icon.to_pixbuf(),                                  DataPos.ICON_NAME, pie.icon,                                  DataPos.NAME, pie.name, -                                DataPos.ID, pie.id);  +                                DataPos.ID, pie.id);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a drag which started on this Widget was successfull.      ///////////////////////////////////////////////////////////////////// -     +      private void on_dnd_source(Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_) {          if (this.drag_start != null) {              string id = ""; @@ -193,72 +193,72 @@ class PieList : Gtk.TreeView {              selection_data.set_uris({"file://" + Paths.launchers + "/" + id + ".desktop"});          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a drag operation is started on this Widget.      ///////////////////////////////////////////////////////////////////// -     +      private void on_start_drag(Gdk.DragContext ctx) {          if (this.get_selection().get_selected(null, out this.drag_start)) {              string icon_name = "";              this.data.get(this.drag_start, DataPos.ICON_NAME, out icon_name); -             +              var icon = new Icon(icon_name, 48);              var pixbuf = icon.to_pixbuf();              Gtk.drag_set_icon_pixbuf(ctx, pixbuf, icon.size()/2, icon.size()/2);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when something is dragged over this Widget.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_drag_move(Gdk.DragContext context, int x, int y, uint time) { -     +          Gtk.TreeViewDropPosition position;          Gtk.TreePath path; -         +          if (!this.get_dest_row_at_pos(x, y, out path, out position))              return false; -         +          if (position == Gtk.TreeViewDropPosition.BEFORE)              this.set_drag_dest_row(path, Gtk.TreeViewDropPosition.INTO_OR_BEFORE);          else if (position == Gtk.TreeViewDropPosition.AFTER)              this.set_drag_dest_row(path, Gtk.TreeViewDropPosition.INTO_OR_AFTER);          Gdk.drag_status(context, context.get_suggested_action(), time); -         +          // avoid too frequent selection...          this.last_hover = time; -         +          GLib.Timeout.add(150, () => {              if (this.last_hover == time) -                this.get_selection().select_path(path);  +                this.get_selection().select_path(path);              return false;          }); -         +          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// 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_) { -         +          Gtk.TreeIter active;          if (this.get_selection().get_selected(null, out active)) {              string id = "";              this.data.get(active, DataPos.ID, out id); -             +              var pie = PieManager.all_pies[id]; -             +              foreach (var uri in selection_data.get_uris()) {                  pie.add_action(ActionRegistry.new_for_uri(uri), 0);              } -             +              this.on_select(id);          }      } diff --git a/src/gui/piePreview.vala b/src/gui/piePreview.vala index 0420d5e..ce1ba96 100644 --- a/src/gui/piePreview.vala +++ b/src/gui/piePreview.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/piePreviewAddSign.vala b/src/gui/piePreviewAddSign.vala index ee8c14b..fb5e9fa 100644 --- a/src/gui/piePreviewAddSign.vala +++ b/src/gui/piePreviewAddSign.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A liitle plus-sign displayed on the preview widget to indicate where  /// the user may add a new Slice.  ///////////////////////////////////////////////////////////////////////// @@ -31,57 +31,57 @@ public class PiePreviewAddSign : GLib.Object {      /////////////////////////////////////////////////////////////////////      public signal void on_clicked(int position); -     +      /////////////////////////////////////////////////////////////////////      /// The image used to display this oject.      ///////////////////////////////////////////////////////////////////// -     +      public Image icon { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// True, when the add sign is currently visible.      ///////////////////////////////////////////////////////////////////// -     +      public bool visible { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// The position of the sign in its parent Pie. May be 2.5 for      /// example.      ///////////////////////////////////////////////////////////////////// -     +      private double position = 0; -     +      /////////////////////////////////////////////////////////////////////      /// The parent renderer.      ///////////////////////////////////////////////////////////////////// -    private unowned PiePreviewRenderer parent;   -     +    private unowned PiePreviewRenderer parent; +      /////////////////////////////////////////////////////////////////////      /// Some values used for displaying this sign.      ///////////////////////////////////////////////////////////////////// -     +      private double time = 0; -    private double max_size = 0;  -    private double angle = 0;  -    private AnimatedValue size;  -    private AnimatedValue alpha;  -    private AnimatedValue activity;  -    private AnimatedValue clicked;  -     +    private double max_size = 0; +    private double angle = 0; +    private AnimatedValue size; +    private AnimatedValue alpha; +    private AnimatedValue activity; +    private AnimatedValue clicked; +      /////////////////////////////////////////////////////////////////////      /// C'tor, sets everything up.      /////////////////////////////////////////////////////////////////////      public PiePreviewAddSign(PiePreviewRenderer parent) {          this.parent = parent; -         +          this.size = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 0, 0, 0, 2.0);          this.alpha = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 0, 0, 0, 0.0);          this.activity = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, -3, -3, 0, 0.0);          this.clicked = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 1, 1, 0, 0.0);      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads the desired icon for this sign.      ///////////////////////////////////////////////////////////////////// @@ -89,41 +89,41 @@ public class PiePreviewAddSign : GLib.Object {      public void load() {          this.icon = new Icon("add", 36);      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the position where this object should be displayed.      /////////////////////////////////////////////////////////////////////      public void set_position(int position) {          double new_position = position; -         +          if (!this.parent.drag_n_drop_mode)              new_position += 0.5;          this.position = new_position;          this.angle = 2.0 * PI * new_position/parent.slice_count();      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes this object visible.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.visible = true; -        this.size.reset_target(this.max_size, 0.3);  -        this.alpha.reset_target(1.0, 0.3);    +        this.size.reset_target(this.max_size, 0.3); +        this.alpha.reset_target(1.0, 0.3);      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes this object invisible.      ///////////////////////////////////////////////////////////////////// -     +      public void hide() {          this.visible = false; -        this.size.reset_target(0.0, 0.3);  -        this.alpha.reset_target(0.0, 0.3);      +        this.size.reset_target(0.0, 0.3); +        this.alpha.reset_target(0.0, 0.3);      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the size of this object. All transitions will be smooth.      ///////////////////////////////////////////////////////////////////// @@ -132,7 +132,7 @@ public class PiePreviewAddSign : GLib.Object {          this.max_size = size;          this.size.reset_target(size, 0.5);      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the sign to the given context.      ///////////////////////////////////////////////////////////////////// @@ -140,75 +140,75 @@ public class PiePreviewAddSign : GLib.Object {      public void draw(double frame_time, Cairo.Context ctx) {          this.time += frame_time; -         +          this.size.update(frame_time);          this.alpha.update(frame_time);          this.activity.update(frame_time);          this.clicked.update(frame_time); -         +          if (this.parent.slice_count() == 0) {              ctx.save(); -             -            double scale = this.clicked.val  + +            double scale = this.clicked.val                           + GLib.Math.sin(this.time*10)*0.02*this.alpha.val                           + this.alpha.val*0.08 - 0.1;              ctx.scale(scale, scale); -         +              // paint the image              icon.paint_on(ctx); -                 +              ctx.restore(); -             +          } else if (this.alpha.val*this.activity.val > 0) {              ctx.save(); -             +              // distance from the center              double radius = 120; -             +              // transform the context              ctx.translate(cos(this.angle)*radius, sin(this.angle)*radius); -            double scale = this.size.val*this.clicked.val  +            double scale = this.size.val*this.clicked.val                           + this.activity.val*0.07                           + GLib.Math.sin(this.time*10)*0.03*this.activity.val                           - 0.1;              ctx.scale(scale, scale); -         +              // paint the image              icon.paint_on(ctx, this.alpha.val*this.activity.val); -                 +              ctx.restore();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse moves to another position.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_move(double angle) {          double direction = 2.0 * PI * position/parent.slice_count();          double diff = fabs(angle-direction); -         +          if (diff > PI) -	        diff = 2 * PI - diff; -	     -	    if (diff < 0.5*PI/parent.slice_count()) this.activity.reset_target(1.0, 1.0); +            diff = 2 * PI - diff; + +        if (diff < 0.5*PI/parent.slice_count()) this.activity.reset_target(1.0, 1.0);          else                                    this.activity.reset_target(-3.0, 1.5);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is pressed.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_press(double x, double y) {          if (this.activity.end == 1.0) {              this.clicked.reset_target(0.9, 0.1);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is released.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_release(double x, double y) {          if (this.clicked.end == 0.9) {              this.clicked.reset_target(1.0, 0.1); diff --git a/src/gui/piePreviewCenter.vala b/src/gui/piePreviewCenter.vala index 20527bc..2a163b6 100644 --- a/src/gui/piePreviewCenter.vala +++ b/src/gui/piePreviewCenter.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; diff --git a/src/gui/piePreviewDeleteSign.vala b/src/gui/piePreviewDeleteSign.vala index 500d876..6ba4dcb 100644 --- a/src/gui/piePreviewDeleteSign.vala +++ b/src/gui/piePreviewDeleteSign.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// The delete sign, displayed in the upper right corner of each  /// Slice.  ///////////////////////////////////////////////////////////////////////// @@ -31,17 +31,17 @@ public class PiePreviewDeleteSign : GLib.Object {      /////////////////////////////////////////////////////////////////////      public signal void on_clicked(); -     +      /////////////////////////////////////////////////////////////////////      /// The image used to display this oject.      ///////////////////////////////////////////////////////////////////// -     +      public Image icon { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Some constants determining the look and behaviour of this Slice.      ///////////////////////////////////////////////////////////////////// -     +      private static const int radius = 18;      private static const double globale_scale = 0.8;      private static const double click_cancel_treshold = 5; @@ -51,24 +51,24 @@ public class PiePreviewDeleteSign : GLib.Object {      /////////////////////////////////////////////////////////////////////      private bool visible = false; -     +      /////////////////////////////////////////////////////////////////////      /// Some AnimatedValues for smooth transitions.      ///////////////////////////////////////////////////////////////////// -     +      private AnimatedValue size; -    private AnimatedValue alpha;  -    private AnimatedValue activity;  -    private AnimatedValue clicked;  -     +    private AnimatedValue alpha; +    private AnimatedValue activity; +    private AnimatedValue clicked; +      /////////////////////////////////////////////////////////////////////      /// Storing the position where a mouse click was executed. Useful for      /// canceling the click when the mouse moves some pixels.      ///////////////////////////////////////////////////////////////////// -     +      private double clicked_x = 0.0;      private double clicked_y = 0.0; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, sets everything up.      ///////////////////////////////////////////////////////////////////// @@ -79,7 +79,7 @@ public class PiePreviewDeleteSign : GLib.Object {          this.activity = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, -3, -3, 0, 0.0);          this.clicked = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 1, 1, 0, 0.0);      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an Action. All members are initialized accordingly.      ///////////////////////////////////////////////////////////////////// @@ -87,26 +87,26 @@ public class PiePreviewDeleteSign : GLib.Object {      public void load() {          this.icon = new Icon("stock_delete", PiePreviewDeleteSign.radius*2);      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes this object visible.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          if (!this.visible) {              this.visible = true; -            this.alpha.reset_target(1.0, 0.3);    +            this.alpha.reset_target(1.0, 0.3);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes this object invisible.      ///////////////////////////////////////////////////////////////////// -     +      public void hide() {          if (this.visible) {              this.visible = false; -            this.alpha.reset_target(0.0, 0.3);      +            this.alpha.reset_target(0.0, 0.3);          }      } @@ -117,7 +117,7 @@ public class PiePreviewDeleteSign : GLib.Object {      public void set_size(double size) {          this.size.reset_target(size, 0.2);      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the sign to the given context.      ///////////////////////////////////////////////////////////////////// @@ -127,46 +127,46 @@ public class PiePreviewDeleteSign : GLib.Object {          this.alpha.update(frame_time);          this.activity.update(frame_time);          this.clicked.update(frame_time); -         +          if (this.alpha.val > 0) {              ctx.save(); -             +              // transform the context -            double scale = (this.size.val*this.clicked.val  +            double scale = (this.size.val*this.clicked.val                           + this.activity.val*0.2 - 0.2)*PiePreviewDeleteSign.globale_scale;              ctx.scale(scale, scale); -         +              // paint the image              icon.paint_on(ctx, this.alpha.val); -                 +              ctx.restore();          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse moves to another position.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_mouse_move(double x, double y) {          if (this.clicked.end == 0.9) {              double dist = GLib.Math.pow(x-this.clicked_x, 2) + GLib.Math.pow(y-this.clicked_y, 2);              if (dist > PiePreviewDeleteSign.click_cancel_treshold*PiePreviewDeleteSign.click_cancel_treshold)                  this.clicked.reset_target(1.0, 0.1);          } -     -	    if (GLib.Math.fabs(x) <= PiePreviewDeleteSign.radius*PiePreviewDeleteSign.globale_scale && GLib.Math.fabs(y) <= PiePreviewDeleteSign.radius*PiePreviewDeleteSign.globale_scale) { -	        this.activity.reset_target(1.0, 0.2); -	        return true; -        }  -         + +        if (GLib.Math.fabs(x) <= PiePreviewDeleteSign.radius*PiePreviewDeleteSign.globale_scale && GLib.Math.fabs(y) <= PiePreviewDeleteSign.radius*PiePreviewDeleteSign.globale_scale) { +            this.activity.reset_target(1.0, 0.2); +            return true; +        } +          this.activity.reset_target(0.0, 0.2);          return false;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is pressed.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_button_press(double x, double y) {          if (this.activity.end == 1.0) {              this.clicked.reset_target(0.9, 0.1); @@ -176,16 +176,16 @@ public class PiePreviewDeleteSign : GLib.Object {          }          return false;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is released.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_button_release(double x, double y) {          if (this.clicked.end == 0.9) {              this.clicked.reset_target(1.0, 0.1);              this.on_clicked(); -             +              return true;          }          return false; diff --git a/src/gui/piePreviewRenderer.vala b/src/gui/piePreviewRenderer.vala index 626ab73..53dd2fb 100644 --- a/src/gui/piePreviewRenderer.vala +++ b/src/gui/piePreviewRenderer.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; diff --git a/src/gui/piePreviewSliceRenderer.vala b/src/gui/piePreviewSliceRenderer.vala index 6a12a47..5b4d939 100644 --- a/src/gui/piePreviewSliceRenderer.vala +++ b/src/gui/piePreviewSliceRenderer.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// Displays the preview of a Slice.  ///////////////////////////////////////////////////////////////////////// @@ -30,17 +30,17 @@ public class PiePreviewSliceRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public signal void on_clicked(int position); -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user clicked on the delete sign.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_remove(int position); -     +      /////////////////////////////////////////////////////////////////////      /// The image used to display this oject.      ///////////////////////////////////////////////////////////////////// -     +      public Icon icon { get; private set; }      public ActionGroup action_group { get; private set; }      public string name { get; private set; default=""; } @@ -50,47 +50,47 @@ public class PiePreviewSliceRenderer : GLib.Object {      /// The parent renderer.      ///////////////////////////////////////////////////////////////////// -    private unowned PiePreviewRenderer parent;   -     +    private unowned PiePreviewRenderer parent; +      /////////////////////////////////////////////////////////////////////      /// The delete sign, displayed in the upper right corner of each      /// Slice.      ///////////////////////////////////////////////////////////////////// -     +      private PiePreviewDeleteSign delete_sign = null; -     +      /////////////////////////////////////////////////////////////////////      /// Some AnimatedValues for smooth transitions.      ///////////////////////////////////////////////////////////////////// -     -    private AnimatedValue angle;  -    private AnimatedValue size;  -    private AnimatedValue activity;  -    private AnimatedValue clicked;  -     + +    private AnimatedValue angle; +    private AnimatedValue size; +    private AnimatedValue activity; +    private AnimatedValue clicked; +      /////////////////////////////////////////////////////////////////////      /// Some constants determining the look and behaviour of this Slice.      ///////////////////////////////////////////////////////////////////// -     +      private static const double pie_radius = 126;      private static const double radius = 24;      private static const double delete_x = 13;      private static const double delete_y = -13;      private static const double click_cancel_treshold = 5; -     +      /////////////////////////////////////////////////////////////////////      /// Storing the position where a mouse click was executed. Useful for      /// canceling the click when the mouse moves some pixels.      ///////////////////////////////////////////////////////////////////// -     +      private double clicked_x = 0.0;      private double clicked_y = 0.0; -     +      /////////////////////////////////////////////////////////////////////      /// The index of this slice in a pie. Clockwise assigned, starting      /// from the right-most slice.      ///////////////////////////////////////////////////////////////////// -     +      private int position;      ///////////////////////////////////////////////////////////////////// @@ -103,21 +103,21 @@ public class PiePreviewSliceRenderer : GLib.Object {          this.delete_sign.on_clicked.connect(() => {              this.on_remove(this.position);          }); -     +          this.parent = parent;          this.angle = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 0, 0, 0, 0.5);          this.size = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 0, 0, 0, 1.0);          this.activity = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 0, 0, 0, 0.0);          this.clicked = new AnimatedValue.cubic(AnimatedValue.Direction.OUT, 1, 1, 0, 1.0);      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an Action. All members are initialized accordingly.      /////////////////////////////////////////////////////////////////////      public void load(ActionGroup group) {          this.action_group = group; -         +          // if it's a custom ActionGroup          if (group.get_type().depth() == 2 && group.actions.size > 0) {              this.icon = new Icon(group.actions[0].icon, (int)(PiePreviewSliceRenderer.radius*2)); @@ -127,23 +127,23 @@ public class PiePreviewSliceRenderer : GLib.Object {              this.name = GroupRegistry.descriptions[group.get_type().name()].name;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the position where this object should be displayed.      /////////////////////////////////////////////////////////////////////      public void set_position(int position, bool smoothly = true) {          double direction = 2.0 * PI * position/parent.slice_count(); -         +          if (direction != this.angle.end) {              this.position = position;              this.angle.reset_target(direction, smoothly ? 0.5 : 0.0); -             +              if (!smoothly)                  this.angle.update(1.0);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the size of this object. All transitions will be smooth.      ///////////////////////////////////////////////////////////////////// @@ -152,15 +152,15 @@ public class PiePreviewSliceRenderer : GLib.Object {          this.size.reset_target(size, 0.5);          this.delete_sign.set_size(size);      } -     +      /////////////////////////////////////////////////////////////////////      /// Notifies that all quick actions should be disabled.      ///////////////////////////////////////////////////////////////////// -     +      public void disable_quickactions() {          this.action_group.disable_quickactions();      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws the slice to the given context.      ///////////////////////////////////////////////////////////////////// @@ -172,100 +172,100 @@ public class PiePreviewSliceRenderer : GLib.Object {          this.clicked.update(frame_time);          ctx.save(); -         +              // transform the context              ctx.translate(cos(this.angle.val)*PiePreviewSliceRenderer.pie_radius, sin(this.angle.val)*PiePreviewSliceRenderer.pie_radius); -             -            double scale = this.size.val*this.clicked.val  + +            double scale = this.size.val*this.clicked.val                           + this.activity.val*0.1 - 0.1; -            ctx.save();      -                         +            ctx.save(); +                  ctx.scale(scale, scale); -             +                  // paint the image                  icon.paint_on(ctx); -             +              ctx.restore(); -             +              ctx.translate(PiePreviewSliceRenderer.delete_x*this.size.val, PiePreviewSliceRenderer.delete_y*this.size.val);              this.delete_sign.draw(frame_time, ctx); -             +          ctx.restore();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse moves to another position.      ///////////////////////////////////////////////////////////////////// -     +      public bool on_mouse_move(double angle, double x, double y) {          double direction = 2.0 * PI * position/parent.slice_count();          double diff = fabs(angle-direction); -         +          if (diff > PI) -	        diff = 2 * PI - diff; -	         -	    bool active = diff < 0.5*PI/parent.slice_count(); -	     -	    if (active) { -	        this.activity.reset_target(1.0, 0.3); -	        this.delete_sign.show(); +            diff = 2 * PI - diff; + +        bool active = diff < 0.5*PI/parent.slice_count(); + +        if (active) { +            this.activity.reset_target(1.0, 0.3); +            this.delete_sign.show();          } else {              this.activity.reset_target(0.0, 0.3);              this.delete_sign.hide(); -        }                                   -         +        } +          if (this.clicked.end == 0.9) {              double dist = GLib.Math.pow(x-this.clicked_x, 2) + GLib.Math.pow(y-this.clicked_y, 2);              if (dist > PiePreviewSliceRenderer.click_cancel_treshold*PiePreviewSliceRenderer.click_cancel_treshold)                  this.clicked.reset_target(1.0, 0.1);          } -         +          double own_x = cos(this.angle.val)*PiePreviewSliceRenderer.pie_radius;          double own_y = sin(this.angle.val)*PiePreviewSliceRenderer.pie_radius; -        this.delete_hovered = this.delete_sign.on_mouse_move(x - own_x - PiePreviewSliceRenderer.delete_x*this.size.val,  +        this.delete_hovered = this.delete_sign.on_mouse_move(x - own_x - PiePreviewSliceRenderer.delete_x*this.size.val,                                                               y - own_y - PiePreviewSliceRenderer.delete_y*this.size.val); -                                        +          return active;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the mouse leaves the area of this widget.      ///////////////////////////////////////////////////////////////////// -     +      public void on_mouse_leave() {          this.activity.reset_target(0.0, 0.3);          this.delete_sign.hide();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is pressed.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_press(double x, double y) {          bool delete_pressed = false;          if (this.activity.end == 1.0) {              double own_x = cos(this.angle.val)*PiePreviewSliceRenderer.pie_radius;              double own_y = sin(this.angle.val)*PiePreviewSliceRenderer.pie_radius; -            delete_pressed = this.delete_sign.on_button_press(x - own_x - PiePreviewSliceRenderer.delete_x*this.size.val,  +            delete_pressed = this.delete_sign.on_button_press(x - own_x - PiePreviewSliceRenderer.delete_x*this.size.val,                                                                y - own_y - PiePreviewSliceRenderer.delete_y*this.size.val);          } -     +          if (!delete_pressed && this.activity.end == 1.0) {              this.clicked.reset_target(0.9, 0.1);              this.clicked_x = x;              this.clicked_y = y;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when a button of the mouse is released.      ///////////////////////////////////////////////////////////////////// -     +      public void on_button_release(double x, double y) {          bool deleted = false;          if (this.activity.end == 1.0)              deleted = this.delete_sign.on_button_release(x, y); -         +          if (!deleted && this.clicked.end == 0.9) {              this.clicked.reset_target(1.0, 0.1);              this.on_clicked(this.position); diff --git a/src/gui/preferencesWindow.vala b/src/gui/preferencesWindow.vala index 8cdc853..29b5250 100644 --- a/src/gui/preferencesWindow.vala +++ b/src/gui/preferencesWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/gui/renameWindow.vala b/src/gui/renameWindow.vala index 389b460..de65069 100644 --- a/src/gui/renameWindow.vala +++ b/src/gui/renameWindow.vala @@ -1,106 +1,106 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A window which allows selection of a new name for a Pie.  /////////////////////////////////////////////////////////////////////////  public class RenameWindow : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// Gets emitted when the user selects a new name.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_ok(string new_name); -     +      /////////////////////////////////////////////////////////////////////      /// Some Widgets used by this dialog.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.Dialog window = null;      private Gtk.Entry entry = null; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, constructs the Widget.      ///////////////////////////////////////////////////////////////////// -     +      public RenameWindow() {          try { -         +              Gtk.Builder builder = new Gtk.Builder();              builder.add_from_file (Paths.ui_files + "/rename_pie.ui");              window = builder.get_object("window") as Gtk.Dialog;              entry = builder.get_object("name-entry") as Gtk.Entry; -             +              entry.activate.connect(this.on_ok_button_clicked); -             +              (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);      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays the window on the screen.      ///////////////////////////////////////////////////////////////////// -     +      public void show() {          this.window.show_all();          this.entry.is_focus = true; -    }   -     +    } +      /////////////////////////////////////////////////////////////////////      /// Make the text entry display the name of the Pie with given ID.      ///////////////////////////////////////////////////////////////////// -     +      public void set_pie(string id) {          entry.text = PieManager.get_name_of(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the ok button is pressed.      ///////////////////////////////////////////////////////////////////// -     +      private void on_ok_button_clicked() {          this.on_ok(entry.text);          this.window.hide();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the cancel button is pressed.      ///////////////////////////////////////////////////////////////////// -     +      private void on_cancel_button_clicked() {          this.window.hide();      } diff --git a/src/gui/settingsWindow.vala b/src/gui/settingsWindow.vala index b03ae2f..6bb10c1 100644 --- a/src/gui/settingsWindow.vala +++ b/src/gui/settingsWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -99,13 +99,21 @@ public class SettingsWindow : GLib.Object {                  });              var range_slider = (builder.get_object("range-hscale") as Gtk.Scale); -                range_slider.set_range(100, 2000); +                range_slider.set_range(0, 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();                  }); +            var range_slices = (builder.get_object("range-slices") as Gtk.Scale); +                range_slices.set_range(12, 96); +                range_slices.set_increments(4, 12); +                range_slices.set_value(Config.global.max_visible_slices); +                range_slices.value_changed.connect(() => { +                    Config.global.max_visible_slices = (int)range_slices.get_value(); +                }); +              this.window.delete_event.connect(this.window.hide_on_delete);          } catch (GLib.Error e) { diff --git a/src/gui/sliceTypeList.vala b/src/gui/sliceTypeList.vala index a339e5e..e164dea 100644 --- a/src/gui/sliceTypeList.vala +++ b/src/gui/sliceTypeList.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A list displaying all available Action types and ActionGroup types.  ///////////////////////////////////////////////////////////////////////// @@ -26,13 +26,13 @@ class SliceTypeList : Gtk.TreeView {      /////////////////////////////////////////////////////////////////////      /// This signal gets emitted when the user selects a new Type.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_select(string id, string icon_name); -     +      /////////////////////////////////////////////////////////////////////      /// The listore which staroes all types internally.      ///////////////////////////////////////////////////////////////////// -     +      private Gtk.ListStore data;      private enum DataPos {ICON, ICON_NAME, NAME, ID} @@ -42,33 +42,33 @@ class SliceTypeList : Gtk.TreeView {      public SliceTypeList() {          GLib.Object(); -         -        this.data = new Gtk.ListStore(4, typeof(Gdk.Pixbuf),    + +        this.data = new Gtk.ListStore(4, typeof(Gdk.Pixbuf),                                           typeof(string),                                           typeof(string),                                           typeof(string)); -                                          +          this.data.set_sort_column_id(2, Gtk.SortType.ASCENDING); -         +          base.set_model(this.data);          base.set_headers_visible(true);          base.set_grid_lines(Gtk.TreeViewGridLines.NONE);          this.set_fixed_height_mode(true); -         +          var main_column = new Gtk.TreeViewColumn();              main_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED);              main_column.title = _("Slice types");              var icon_render = new Gtk.CellRendererPixbuf();                  main_column.pack_start(icon_render, false); -         +              var name_render = new Gtk.CellRendererText();                  main_column.pack_start(name_render, true); -         +          base.append_column(main_column); -         +          main_column.add_attribute(icon_render, "pixbuf", DataPos.ICON);          main_column.add_attribute(name_render, "markup", DataPos.NAME); -         +          this.get_selection().changed.connect(() => {              Gtk.TreeIter active;              if (this.get_selection().get_selected(null, out active)) { @@ -79,59 +79,59 @@ class SliceTypeList : Gtk.TreeView {                  this.on_select(id, icon);              }          }); -         +          reload_all();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads a registered actions and action groups.      ///////////////////////////////////////////////////////////////////// -     +      public void reload_all() {          Gtk.TreeIter active;          string current_id = "";          if (this.get_selection().get_selected(null, out active))              this.data.get(active, DataPos.ID, out current_id); -     +          data.clear(); -         +          foreach (var action_type in ActionRegistry.types) {              var description = ActionRegistry.descriptions[action_type]; -             +              Gtk.TreeIter current;              data.append(out current);              var icon = new Icon(description.icon, 36); -            data.set(current, DataPos.ICON, icon.to_pixbuf());  -            data.set(current, DataPos.ICON_NAME, description.icon);  +            data.set(current, DataPos.ICON, icon.to_pixbuf()); +            data.set(current, DataPos.ICON_NAME, description.icon);              data.set(current, DataPos.NAME, "<b>" + GLib.Markup.escape_text(description.name) + "</b>\n" -                                 + "<small>" + GLib.Markup.escape_text(description.description) + "</small>");  -            data.set(current, DataPos.ID, description.id);  +                                 + "<small>" + GLib.Markup.escape_text(description.description) + "</small>"); +            data.set(current, DataPos.ID, description.id);          } -         +          foreach (var group_type in GroupRegistry.types) {              var description = GroupRegistry.descriptions[group_type]; -             +              Gtk.TreeIter current;              data.append(out current);              var icon = new Icon(description.icon, 36); -            data.set(current, DataPos.ICON, icon.to_pixbuf());  +            data.set(current, DataPos.ICON, icon.to_pixbuf());              data.set(current, DataPos.ICON_NAME, description.icon);              data.set(current, DataPos.NAME, "<b>" + GLib.Markup.escape_text(description.name) + "</b>\n" -                                 + "<small>" + GLib.Markup.escape_text(description.description) + "</small>");  -            data.set(current, DataPos.ID, description.id);  +                                 + "<small>" + GLib.Markup.escape_text(description.description) + "</small>"); +            data.set(current, DataPos.ID, description.id);          } -         +          select_first();          select(current_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Selects the first type in the list.      ///////////////////////////////////////////////////////////////////// -     +      public void select_first() {          Gtk.TreeIter active; -         +          if(this.data.get_iter_first(out active) ) {              this.get_selection().select_iter(active);              string id = ""; @@ -143,16 +143,16 @@ class SliceTypeList : Gtk.TreeView {              this.on_select("", "stock_unknown");          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Select the given slice type.      ///////////////////////////////////////////////////////////////////// -     +      public void select(string id) {          this.data.foreach((model, path, iter) => {              string pie_id;              this.data.get(iter, DataPos.ID, out pie_id); -             +              if (id == pie_id) {                  this.get_selection().select_iter(iter);                  string icon = ""; @@ -160,10 +160,10 @@ class SliceTypeList : Gtk.TreeView {                  this.on_select(pie_id, icon);                  this.scroll_to_cell(path, null, true, 0.5f, 0.5f);                  this.has_focus = true; -                 +                  return true;              } -             +              return false;          });      } diff --git a/src/gui/themeList.vala b/src/gui/themeList.vala index 1c038a9..4173819 100644 --- a/src/gui/themeList.vala +++ b/src/gui/themeList.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A widget displaying all available themes of Gnome-Pie.  ///////////////////////////////////////////////////////////////////////// @@ -26,7 +26,7 @@ class ThemeList : Gtk.TreeView {      /////////////////////////////////////////////////////////////////////      /// This signal gets emitted, when a new theme is selected by the      /// user. This new theme is applied automatically, with this signal -    /// actions may be triggered which should be executed AFTER the  +    /// actions may be triggered which should be executed AFTER the      /// change to a new theme.      ///////////////////////////////////////////////////////////////////// @@ -37,11 +37,11 @@ class ThemeList : Gtk.TreeView {      /////////////////////////////////////////////////////////////////////      private Gtk.TreeIter active { private get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// The positions in the data list store.      ///////////////////////////////////////////////////////////////////// -     +      private enum DataPos {ICON, NAME}      ///////////////////////////////////////////////////////////////////// @@ -50,57 +50,57 @@ class ThemeList : Gtk.TreeView {      public ThemeList() {          GLib.Object(); -         -        var data = new Gtk.ListStore(2, typeof(Gdk.Pixbuf),  + +        var data = new Gtk.ListStore(2, typeof(Gdk.Pixbuf),                                          typeof(string));          this.set_model(data);          this.set_headers_visible(true);          this.set_grid_lines(Gtk.TreeViewGridLines.NONE);          this.set_fixed_height_mode(true); -         +          var main_column = new Gtk.TreeViewColumn();              main_column.title = _("Themes");              main_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED);              var icon_render = new Gtk.CellRendererPixbuf();                  main_column.pack_start(icon_render, false); -         +              var theme_render = new Gtk.CellRendererText();                  main_column.pack_start(theme_render, true); -         +          this.append_column(main_column); -         +          main_column.add_attribute(icon_render, "pixbuf", DataPos.ICON);          main_column.add_attribute(theme_render, "markup", DataPos.NAME); -         +          this.get_selection().changed.connect(() => {              Gtk.TreeIter active;              if (this.get_selection().get_selected(null, out active)) {                  Timeout.add(10, () => {                      int index = int.parse(data.get_path(active).to_string());                      Config.global.theme = Config.global.themes[index]; -                     +                      this.on_select_new(); -     +                      Config.global.theme.load();                      Config.global.theme.load_images();                      return false; -                });   +                });              }          }); -         +          // load all themes into the list          var themes = Config.global.themes;          foreach(var theme in themes) {              Gtk.TreeIter current;              data.append(out current); -            data.set(current, DataPos.ICON, theme.preview_icon.to_pixbuf());  +            data.set(current, DataPos.ICON, theme.preview_icon.to_pixbuf());              data.set(current, DataPos.NAME, "<b>"+GLib.Markup.escape_text(theme.name)+"</b><small>  -  "                                              +GLib.Markup.escape_text(theme.description)+"\n"                                              +"<i>"+GLib.Markup.escape_text(_("By")+" "+theme.author) -                                            +"</i></small>");  +                                            +"</i></small>");              if(theme == Config.global.theme)                  get_selection().select_iter(current); -        }   +        }      }  } diff --git a/src/gui/triggerSelectButton.vala b/src/gui/triggerSelectButton.vala index 7132220..92cd8a3 100644 --- a/src/gui/triggerSelectButton.vala +++ b/src/gui/triggerSelectButton.vala @@ -1,64 +1,64 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// 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 TriggerSelectButton : Gtk.ToggleButton { -     +      /////////////////////////////////////////////////////////////////////      /// This signal is emitted when the user selects a new hot key.      ///////////////////////////////////////////////////////////////////// -     +      public signal void on_select(Trigger trigger); -     +      /////////////////////////////////////////////////////////////////////      /// The currently contained Trigger.      ///////////////////////////////////////////////////////////////////// -     +      private Trigger trigger = null; -     +      /////////////////////////////////////////////////////////////////////      /// True, if mouse buttons can be bound as well.      ///////////////////////////////////////////////////////////////////// -      +      private bool enable_mouse = false; -     +      /////////////////////////////////////////////////////////////////////      /// These modifiers are ignored.      ///////////////////////////////////////////////////////////////////// -     +      private Gdk.ModifierType lock_modifiers = Gdk.ModifierType.MOD2_MASK                                               |Gdk.ModifierType.SUPER_MASK                                               |Gdk.ModifierType.LOCK_MASK                                               |Gdk.ModifierType.MOD5_MASK; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, constructs a new TriggerSelectWindow.      ///////////////////////////////////////////////////////////////////// -     +      public TriggerSelectButton(bool enable_mouse) {          this.enable_mouse = enable_mouse; -     +          this.toggled.connect(() => {              if (this.active) {                  this.set_label(_("Press a hotkey ...")); @@ -66,49 +66,49 @@ public class TriggerSelectButton : Gtk.ToggleButton {                  FocusGrabber.grab(this.get_window(), true, true, true);              }          }); -         +          this.button_press_event.connect(this.on_button_press);          this.key_press_event.connect(this.on_key_press);          this.set_trigger(new Trigger());      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes the button display the given Trigger.      ///////////////////////////////////////////////////////////////////// -     +      public void set_trigger(Trigger trigger) {          this.trigger = trigger;          this.set_label(trigger.label);      } -     +      /////////////////////////////////////////////////////////////////////      /// Can be called to cancel the selection process.      ///////////////////////////////////////////////////////////////////// -     +      private void cancel() {          this.set_label(trigger.label);          this.set_active(false);          Gtk.grab_remove(this);          FocusGrabber.ungrab(true, true);      } -     +      /////////////////////////////////////////////////////////////////////      /// Makes the button display the given Trigger.      ///////////////////////////////////////////////////////////////////// -     +      private void update_trigger(Trigger trigger) {          if (this.trigger.name != trigger.name) {              this.set_trigger(trigger);              this.on_select(this.trigger);          } -         +          this.cancel();      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user presses a keyboard key.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_key_press(Gdk.EventKey event) {          if (this.active) {              if (Gdk.keyval_name(event.keyval) == "Escape") { @@ -117,44 +117,45 @@ public class TriggerSelectButton : Gtk.ToggleButton {                  this.update_trigger(new Trigger());              } else if (event.is_modifier == 0) {                  Gdk.ModifierType state = event.state & ~ this.lock_modifiers; -                this.update_trigger(new Trigger.from_values(event.keyval, state, false, false, false, false)); +                this.update_trigger(new Trigger.from_values(event.keyval, state, false, false, false, +                            false, false, 5));              } -             +              return true;          }          return false;      } -     +      /////////////////////////////////////////////////////////////////////      /// Called when the user presses a button of the mouse.      ///////////////////////////////////////////////////////////////////// -     +      private bool on_button_press(Gdk.EventButton event) {          if (this.active) {                  Gtk.Allocation rect;                  this.get_allocation(out rect);                  if (event.x < 0 || event.x > rect.width                   || event.y < 0 || event.y > rect.height) { -                  +                      this.cancel();                      return true;                  }              } -             +              if (this.active && this.enable_mouse) {                  Gdk.ModifierType state = event.state & ~ this.lock_modifiers;                  var new_trigger = new Trigger.from_values((int)event.button, state, true, -                                                          false, false, false); -                                                           +                                                          false, false, false, false, 5); +                  if (new_trigger.key_code != 1) this.update_trigger(new_trigger);                  else                           this.cancel(); -                 +                  return true;              } else if (this.active) {                  this.cancel();                  return true;              } -             +              return false;      }  } diff --git a/src/gui/triggerSelectWindow.vala b/src/gui/triggerSelectWindow.vala index 611c179..56781b4 100644 --- a/src/gui/triggerSelectWindow.vala +++ b/src/gui/triggerSelectWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -39,6 +39,8 @@ public class TriggerSelectWindow : GLib.Object {      private Gtk.CheckButton turbo;      private Gtk.CheckButton delayed;      private Gtk.CheckButton centered; +    private Gtk.CheckButton warp; +    private Gtk.RadioButton rshape[10];      private TriggerSelectButton button;      ///////////////////////////////////////////////////////////////////// @@ -56,6 +58,13 @@ public class TriggerSelectWindow : GLib.Object {      private Trigger original_trigger = null;      ///////////////////////////////////////////////////////////////////// +    /// Radioboxes call toggled() twice per selection change. +    /// This flag is used to discard one of the two notifications. +    ///////////////////////////////////////////////////////////////////// + +    private static int notify_toggle= 0; + +    /////////////////////////////////////////////////////////////////////      /// C'tor, constructs a new TriggerSelectWindow.      ///////////////////////////////////////////////////////////////////// @@ -76,7 +85,9 @@ public class TriggerSelectWindow : GLib.Object {                                                         trigger.with_mouse,                                                         this.turbo.active,                                                         this.delayed.active, -                                                       this.centered.active); +                                                       this.centered.active, +                                                       this.warp.active, +                                                       this.get_radio_shape());              });              (builder.get_object("trigger-box") as Gtk.Box).pack_start(this.button, true, true); @@ -93,6 +104,14 @@ public class TriggerSelectWindow : GLib.Object {              this.centered = builder.get_object("center-check") as Gtk.CheckButton;              this.centered.toggled.connect(this.on_check_toggled); +            this.warp = builder.get_object("warp-check") as Gtk.CheckButton; +            this.warp.toggled.connect(this.on_check_toggled); + +            for (int i= 0; i < 10; i++) { +                this.rshape[i] = builder.get_object("rshape%d".printf(i)) as Gtk.RadioButton; +                this.rshape[i].toggled.connect(this.on_radio_toggled); +            } +              this.window.delete_event.connect(this.window.hide_on_delete);          } catch (GLib.Error e) { @@ -128,6 +147,8 @@ public class TriggerSelectWindow : GLib.Object {          this.turbo.active = trigger.turbo;          this.delayed.active = trigger.delayed;          this.centered.active = trigger.centered; +        this.warp.active = trigger.warp; +        this.set_radio_shape( trigger.shape );          this.original_trigger = trigger;          this.trigger = trigger; @@ -135,14 +156,53 @@ public class TriggerSelectWindow : GLib.Object {      }      ///////////////////////////////////////////////////////////////////// -    /// Called when one of the three checkoxes is toggled. +    /// Called when one of the checkboxes 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); +                                                   this.delayed.active, this.centered.active, +                                                   this.warp.active, +                                                   this.get_radio_shape()); +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns the current selected radio-button shape: 0= automatic +    /// 5= full pie; 1,3,7,8= quarters; 2,4,6,8=halves +    /// 1 | 4 | 7 +    /// 2 | 5 | 8 +    /// 3 | 6 | 9 +    ///////////////////////////////////////////////////////////////////// + +    private int get_radio_shape() { +        int rs; +        for (rs= 0; rs < 10; rs++) +            if (this.rshape[rs].active) +                break; +        return rs; +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Sets the current selected radio-button shape: 0= automatic +    /// 5= full pie; 1,3,7,8= quarters; 2,4,6,8=halves +    ///////////////////////////////////////////////////////////////////// + +    private void set_radio_shape(int rs) { +        if (rs < 0 || rs > 9) +            rs= 5;  //replace invalid value with default= full pie +        this.rshape[rs].active= true; +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Called twice when one of the radioboxes is toggled. +    ///////////////////////////////////////////////////////////////////// + +    private void on_radio_toggled() { +        notify_toggle= 1 - notify_toggle; +        if (notify_toggle == 1) +            on_check_toggled(); //just call once      }      ///////////////////////////////////////////////////////////////////// diff --git a/src/images/icon.vala b/src/images/icon.vala index 6dfb53b..9cfccf8 100644 --- a/src/images/icon.vala +++ b/src/images/icon.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  ///  A class representing a square-shaped icon, loaded from the users  /// icon theme.  ///////////////////////////////////////////////////////////////////////// @@ -30,34 +30,34 @@ public class Icon : Image {      /////////////////////////////////////////////////////////////////////      private static Gee.HashMap<string, Cairo.ImageSurface?> cache { private get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Initializes the cache.      ///////////////////////////////////////////////////////////////////// -     +      public static void init() {          clear_cache(); -         +          Gtk.IconTheme.get_default().changed.connect(() => {              clear_cache();          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Clears the cache.      ///////////////////////////////////////////////////////////////////// -     +      public static void clear_cache() {          cache = new Gee.HashMap<string, Cairo.ImageSurface?>();      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads an icon from the current icon theme of the user.      ///////////////////////////////////////////////////////////////////// -     +      public Icon(string icon_name, int size) {          var cached = Icon.cache.get("%s@%u".printf(icon_name, size)); -         +          if (cached == null) {              this.load_file_at_size(Icon.get_icon_file(icon_name, size), size, size);              Icon.cache.set("%s@%u".printf(icon_name, size), this.surface); @@ -65,56 +65,56 @@ public class Icon : Image {              this.surface = cached;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the size of the icon in pixels. Greetings to Liskov.      ///////////////////////////////////////////////////////////////////// -     +      public int size() {          return base.width();      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the icon name for a given GLib.Icon.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_icon_name(GLib.Icon? icon) {          if (icon != null) {              var icon_names = icon.to_string().split(" "); -             +              foreach (var icon_name in icon_names) {                  if (Gtk.IconTheme.get_default().has_icon(icon_name)) {                      return icon_name;                  }              }          } -         +          return "";      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the filename for a given system icon.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_icon_file(string icon_name, int size) {          string result = ""; -         +          if (icon_name.contains("/")) {              var file = GLib.File.new_for_path(icon_name);              if(file.query_exists())                  return icon_name; -             +              warning("Icon \"" + icon_name + "\" not found! Using default icon...");          } -             -         + +          var icon_theme = Gtk.IconTheme.get_default();          var file = icon_theme.lookup_icon(icon_name, size, 0);          if (file != null) result = file.get_filename(); -         +          if (result == "") {              warning("Icon \"" + icon_name + "\" not found! Using default icon..."); -         +              string[] default_icons = {"application-default-icon", "stock_unknown"};              foreach (var icon in default_icons) {                  file = icon_theme.lookup_icon(icon, size, 0); @@ -123,11 +123,11 @@ public class Icon : Image {                      break;                  }              } -             +              if (result == "")                  warning("No default icon found! Will be ugly...");          } -          +          return result;      }  } diff --git a/src/images/image.vala b/src/images/image.vala index e65e34a..a903493 100644 --- a/src/images/image.vala +++ b/src/images/image.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -163,10 +163,10 @@ public class Image : GLib.Object {      /////////////////////////////////////////////////////////////////////      public Gdk.Pixbuf to_pixbuf() { -        if (this.surface == null || this.surface.get_data().length <= 0) +        if (this.surface == null || this.surface.get_data() == null)              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.with_unowned_data(this.surface.get_data(), Gdk.Colorspace.RGB, true, 8,                                                width(), height(), this.surface.get_stride(), null);          pixbuf = pixbuf.copy(); @@ -180,7 +180,7 @@ public class Image : GLib.Object {              *(p + i + 2) = tmp;          } -		return pixbuf; +        return pixbuf;      }      ///////////////////////////////////////////////////////////////////// diff --git a/src/images/renderedText.vala b/src/images/renderedText.vala index 544af1f..2f4b82f 100644 --- a/src/images/renderedText.vala +++ b/src/images/renderedText.vala @@ -1,149 +1,149 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  ///  A class representing string, rendered on an Image.  /////////////////////////////////////////////////////////////////////////  public class RenderedText : Image { -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new image representation of a string.      ///////////////////////////////////////////////////////////////////// -     +      public RenderedText(string text, int width, int height, string font,                          Color color, double scale) { -                         +          this.render_text(text, width, height, font, color, scale);      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new image representation of a string. This      /// string may contain markup information.      ///////////////////////////////////////////////////////////////////// -     +      public RenderedText.with_markup(string text, int width, int height, string font,                          Color color, double scale) {          this.render_markup(text, width, height, font, color, scale);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new transparent image, with text written onto.      ///////////////////////////////////////////////////////////////////// -     -    public void render_text(string text, int width, int height, string font,  + +    public void render_text(string text, int width, int height, string font,                              Color color, double scale) { -                   +          this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);          if (text != "") {              var ctx = this.context(); -             +              // set the color              ctx.set_source_rgb(color.r, color.g, color.g); -             -            var layout = Pango.cairo_create_layout(ctx);         + +            var layout = Pango.cairo_create_layout(ctx);              layout.set_width(Pango.units_from_double(width)); -             +              var font_description = Pango.FontDescription.from_string(font);              font_description.set_size((int)(font_description.get_size() * scale)); -             +              layout.set_font_description(font_description);              layout.set_text(text, -1); -             +              // add newlines at the end of each line, in order to allow ellipsizing              string broken_string = ""; -             +              for (int i=0; i<layout.get_line_count(); ++i) { -             +                  string next_line = ""; -                if (i == layout.get_line_count() -1)  +                if (i == layout.get_line_count() -1)                      next_line = text.substring(layout.get_line(i).start_index, -1); -                else                                  +                else                      next_line = text.substring(layout.get_line(i).start_index, layout.get_line(i).length); -                 +                  if (broken_string == "") {                      broken_string = next_line;                  } else if (next_line != "") {                      // test whether the addition of a line would cause the height to become too large                      string broken_string_tmp = broken_string + "\n" + next_line; -                     -                    var layout_tmp = Pango.cairo_create_layout(ctx);         + +                    var layout_tmp = Pango.cairo_create_layout(ctx);                      layout_tmp.set_width(Pango.units_from_double(width)); -                     +                      layout_tmp.set_font_description(font_description); -             +                      layout_tmp.set_text(broken_string_tmp, -1);                      Pango.Rectangle extents;                      layout_tmp.get_pixel_extents(null, out extents); -                     +                      if (extents.height > height) broken_string = broken_string + next_line;                      else                         broken_string = broken_string_tmp;                  }              } -             +              layout.set_text(broken_string, -1); -             +              layout.set_ellipsize(Pango.EllipsizeMode.END);              layout.set_alignment(Pango.Alignment.CENTER); -             +              Pango.Rectangle extents;              layout.get_pixel_extents(null, out extents);              ctx.move_to(0, (int)(0.5*(height - extents.height))); -             +              Pango.cairo_update_layout(ctx, layout);              Pango.cairo_show_layout(ctx, layout);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new transparent image, with text written onto.      ///////////////////////////////////////////////////////////////////// -     -    public void render_markup(string text, int width, int height, string font,  + +    public void render_markup(string text, int width, int height, string font,                              Color color, double scale) { -                             +          this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);          var ctx = this.context(); -         -        // set the color  + +        // set the color          ctx.set_source_rgb(color.r, color.g, color.g); -         -        var layout = Pango.cairo_create_layout(ctx);         + +        var layout = Pango.cairo_create_layout(ctx);          layout.set_width(Pango.units_from_double(width)); -         +          var font_description = Pango.FontDescription.from_string(font);          font_description.set_size((int)(font_description.get_size() * scale)); -         +          layout.set_font_description(font_description);          layout.set_markup(text, -1); -         +          layout.set_ellipsize(Pango.EllipsizeMode.END);          layout.set_alignment(Pango.Alignment.CENTER); -         +          Pango.Rectangle extents;          layout.get_pixel_extents(null, out extents);          ctx.move_to(0, (int)(0.5*(height - extents.height))); -         +          Pango.cairo_update_layout(ctx, layout);          Pango.cairo_show_layout(ctx, layout);      } diff --git a/src/images/themedIcon.vala b/src/images/themedIcon.vala index f816e0f..b7b6f74 100644 --- a/src/images/themedIcon.vala +++ b/src/images/themedIcon.vala @@ -1,96 +1,96 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A class representing a square-shaped icon, themed according to the  /// current theme of Gnome-Pie.  /////////////////////////////////////////////////////////////////////////  public class ThemedIcon : Image { -     +      /////////////////////////////////////////////////////////////////////      /// Paint a slice icon according to the current theme.      ///////////////////////////////////////////////////////////////////// -     +      public ThemedIcon(string caption, string icon_name, bool active) { -     +          // get layers for the desired slice type          var layers = active ? Config.global.theme.active_slice_layers : Config.global.theme.inactive_slice_layers; -         +          // get max size          int size = 1;          foreach (var layer in layers) { -            if (layer.image != null && layer.image.width() > size)  +            if (layer.image != null && layer.image.width() > size)                  size = layer.image.width();          } -         +          this.surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, size, size); -         +          // get size of icon layer          int icon_size = size;          foreach (var layer in layers) {              if (layer.image != null && layer.layer_type == SliceLayer.Type.ICON)                  icon_size = layer.image.width();          } -     +          Image icon;          if (icon_name.contains("/"))              icon = new Image.from_file_at_size(icon_name, icon_size, icon_size);          else              icon = new Icon(icon_name, icon_size); -         +          var color = new Color.from_icon(icon);          var ctx = this.context(); -         +          ctx.translate(size/2, size/2);          ctx.set_operator(Cairo.Operator.OVER); -         +          // now render all layers on top of each other          foreach (var layer in layers) { -         -            if (layer.visibility == SliceLayer.Visibility.ANY ||  + +            if (layer.visibility == SliceLayer.Visibility.ANY ||                  (Config.global.show_captions == (layer.visibility == SliceLayer.Visibility.WITH_CAPTION))) { -             +                  if (layer.colorize) {                      ctx.push_group();                  } -                         +                  if (layer.layer_type == SliceLayer.Type.ICON) {                      ctx.push_group(); -                     +                      layer.image.paint_on(ctx); -                     +                      ctx.set_operator(Cairo.Operator.IN); -                     +                      if (layer.image.width() != icon_size) {                          if (icon_name.contains("/"))                              icon = new Image.from_file_at_size(icon_name, layer.image.width(), layer.image.width());                          else                              icon = new Icon(icon_name,layer.image.width());                      } -                     +                      icon.paint_on(ctx);                      ctx.pop_group_to_source();                      ctx.paint();                      ctx.set_operator(Cairo.Operator.OVER); -                     +                  } else if (layer.layer_type == SliceLayer.Type.CAPTION) {                      Image text = new RenderedText(caption, layer.width, layer.height, layer.font, layer.color, Config.global.global_scale);                      ctx.translate(0, layer.position); @@ -99,13 +99,13 @@ public class ThemedIcon : Image {                  } else if (layer.layer_type == SliceLayer.Type.FILE) {                      layer.image.paint_on(ctx);                  } -                 +                  // colorize the whole layer if neccasary                  if (layer.colorize) {                      ctx.set_operator(Cairo.Operator.ATOP);                      ctx.set_source_rgb(color.r, color.g, color.b);                      ctx.paint(); -                     +                      ctx.set_operator(Cairo.Operator.OVER);                      ctx.pop_group_to_source();                      ctx.paint(); @@ -113,11 +113,11 @@ public class ThemedIcon : Image {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the size of the icon in pixels. Greetings to Liskov.      ///////////////////////////////////////////////////////////////////// -     +      public int size() {          return base.width();      } diff --git a/src/pies/defaultConfig.vala b/src/pies/defaultConfig.vala index 87fd30d..6ca45e4 100644 --- a/src/pies/defaultConfig.vala +++ b/src/pies/defaultConfig.vala @@ -1,37 +1,37 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A helper class which creates a user-specific default configuration.  /////////////////////////////////////////////////////////////////////////  namespace Pies {      public void create_default_config() { -         +          // add a pie with playback controls          var multimedia = PieManager.create_persistent_pie(_("Multimedia"), "stock_media-play", new Trigger.from_string("<Control><Alt>m"));              multimedia.add_action(new KeyAction(_("Next Track"), "stock_media-next", "XF86AudioNext", true));              multimedia.add_action(new KeyAction(_("Stop"), "stock_media-stop", "XF86AudioStop"));              multimedia.add_action(new KeyAction(_("Previous Track"), "stock_media-prev", "XF86AudioPrev"));              multimedia.add_action(new KeyAction(_("Play/Pause"), "stock_media-play", "XF86AudioPlay")); -         +          // add a pie with the users default applications          var apps = PieManager.create_persistent_pie(_("Applications"), "applications-accessories", new Trigger.from_string("<Control><Alt>a"));              apps.add_action(ActionRegistry.default_for_mime_type("text/plain")); @@ -40,20 +40,20 @@ namespace Pies {              apps.add_action(ActionRegistry.default_for_mime_type("image/jpg"));              apps.add_action(ActionRegistry.default_for_uri("http"));              apps.add_action(ActionRegistry.default_for_uri("mailto")); -         +          // add a pie with the users bookmarks and devices          var bookmarks = PieManager.create_persistent_pie(_("Bookmarks"), "user-bookmarks", new Trigger.from_string("<Control><Alt>b"));              bookmarks.add_group(new BookmarkGroup(bookmarks.id));              bookmarks.add_group(new DevicesGroup(bookmarks.id)); -         +          // add a pie with session controls          var session = PieManager.create_persistent_pie(_("Session"), "gnome-session-halt", new Trigger.from_string("<Control><Alt>q"));              session.add_group(new SessionGroup(session.id)); -         +          // add a pie with a main menu          var menu = PieManager.create_persistent_pie(_("Main Menu"), "alacarte", new Trigger.from_string("<Control><Alt>space"));              menu.add_group(new MenuGroup(menu.id)); -         +          // add a pie with window controls          var window = PieManager.create_persistent_pie(_("Window"), "gnome-window-manager", new Trigger.from_string("<Control><Alt>w"));              window.add_action(new KeyAction(_("Scale"), "top", "<Control><Alt>s")); @@ -61,7 +61,7 @@ namespace Pies {              window.add_action(new KeyAction(_("Close"), "window-close", "<Alt>F4"));              window.add_action(new KeyAction(_("Maximize"), "window_fullscreen", "<Alt>F10"));              window.add_action(new KeyAction(_("Restore"), "window_nofullscreen", "<Alt>F5")); -     +          // save the configuration to file          Pies.save();      } diff --git a/src/pies/load.vala b/src/pies/load.vala index cb08a8a..7402094 100644 --- a/src/pies/load.vala +++ b/src/pies/load.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/         +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A helper method which loads pies according to the configuration file.  ///////////////////////////////////////////////////////////////////////// @@ -28,7 +28,7 @@ namespace Pies {      /////////////////////////////////////////////////////////////////////      /// Loads all Pies from the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      public void load() {          // check whether the config file exists          if (!GLib.File.new_for_path(Paths.pie_config).query_exists()) { @@ -36,13 +36,13 @@ namespace Pies {              Pies.create_default_config();              return;          } -         +          message("Loading Pies from \"" + Paths.pie_config + "\"."); -     +          // load the settings file          Xml.Parser.init();          Xml.Doc* piesXML = Xml.Parser.parse_file(Paths.pie_config); -         +          if (piesXML != null) {              // begin parsing at the root element              Xml.Node* root = piesXML->get_root_element(); @@ -57,36 +57,36 @@ namespace Pies {                              default:                                  warning("Invalid child element <" + node_name + "> in <pies> element pies.conf!");                                  break; -                        }  +                        }                      }                  }              } else {                  warning("Error loading pies: pies.conf is empty! The cake is a lie...");              } -             +              delete piesXML; -             +          } else {              warning("Error loading pies: pies.conf not found! The cake is a lie...");          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <pie> element from the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      private static void parse_pie(Xml.Node* node) {          string hotkey = "";          string name = "";          string icon = "";          string id = "";          int quickaction = -1; -         +          // parse all attributes of this node          for (Xml.Attr* attribute = node->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                  case "hotkey":                      hotkey = attr_content; @@ -108,15 +108,15 @@ namespace Pies {                      break;              }          } -         +          if (name == "") {              warning("Invalid <pie> element in pies.conf: No name specified!");              return;          } -         +          // add a new Pie with the loaded properties          var pie = PieManager.create_persistent_pie(name, icon, new Trigger.from_string(hotkey), id); -         +          // and parse all child elements          for (Xml.Node* slice = node->children; slice != null; slice = slice->next) {              if (slice->type == Xml.ElementType.ELEMENT_NODE) { @@ -131,22 +131,22 @@ namespace Pies {                      default:                          warning("Invalid child element <" + node_name + "> in <pie> element in pies.conf!");                          break; -                }  +                }              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <slice> element from the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      private static void parse_slice(Xml.Node* slice, Pie pie) {          string name="";          string icon="";          string command="";          string type="";          bool quickaction = false; -         +          // parse all attributes of this node          for (Xml.Attr* attribute = slice->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down(); @@ -173,20 +173,20 @@ namespace Pies {                      break;              }          } -         +          // create a new Action according to the loaded type          Action action = ActionRegistry.create_action(type, name, icon, command, quickaction); -         +          if (action != null) pie.add_action(action);      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <group> element from the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      private static void parse_group(Xml.Node* slice, Pie pie) {          string type=""; -         +          // parse all attributes of this node          for (Xml.Attr* attribute = slice->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down(); @@ -201,7 +201,7 @@ namespace Pies {                      break;              }          } -         +          ActionGroup group = GroupRegistry.create_group(type, pie.id);          if (group != null) pie.add_group(group); diff --git a/src/pies/pie.vala b/src/pies/pie.vala index fa205c7..1699ada 100644 --- a/src/pies/pie.vala +++ b/src/pies/pie.vala @@ -1,109 +1,109 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -/// This class stores information on a pie. A pie consists of a name, an  +///////////////////////////////////////////////////////////////////////// +/// This class stores information on a pie. A pie consists of a name, an  /// icon name and an unique ID. Furthermore it has an arbitrary amount  /// of ActionGroups storing Actions.  /////////////////////////////////////////////////////////////////////////  public class Pie : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// The name of this Pie. It has not to be unique.      ///////////////////////////////////////////////////////////////////// -     +      public string name { get; set; } -     +      /////////////////////////////////////////////////////////////////////      /// The name of the icon to be used for this Pie. It should exist in      /// the users current icon theme, else a standard icon will be used.      ///////////////////////////////////////////////////////////////////// -     +      public string icon { get; set; } -     +      /////////////////////////////////////////////////////////////////////      /// The ID of this Pie. It has to be unique among all Pies. This ID -    /// consists of three digits when the Pie was created by the user,  -    /// of four digits when it was created dynamically by another class,  +    /// consists of three digits when the Pie was created by the user, +    /// of four digits when it was created dynamically by another class,      /// for example by an ActionGroup.      ///////////////////////////////////////////////////////////////////// -     +      public string id { get; construct; } -     +      /////////////////////////////////////////////////////////////////////      /// Stores all ActionGroups of this Pie.      ///////////////////////////////////////////////////////////////////// -     +      public Gee.ArrayList<ActionGroup?> action_groups { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all given members.      ///////////////////////////////////////////////////////////////////// -     +      public Pie(string id, string name, string icon) {          GLib.Object(id: id, name: name, icon:icon); -         +          this.action_groups = new Gee.ArrayList<ActionGroup?>();      } -     +      /////////////////////////////////////////////////////////////////////      /// Should be called when this Pie is deleted, in order to clean up      /// stuff created by contained ActionGroups.      ///////////////////////////////////////////////////////////////////// -     +      public virtual void on_remove() {          foreach (var action_group in action_groups)              action_group.on_remove();      } -     +      /////////////////////////////////////////////////////////////////////      /// Adds an Action to this Pie.      ///////////////////////////////////////////////////////////////////// -     +      public void add_action(Action action, int at_position = -1) {          var group = new ActionGroup(this.id);              group.add_action(action);          this.add_group(group, at_position);      } -     +      /////////////////////////////////////////////////////////////////////      /// Adds an ActionGroup to this Pie.      ///////////////////////////////////////////////////////////////////// -     -    public void add_group(ActionGroup group, int at_position = -1) {      + +    public void add_group(ActionGroup group, int at_position = -1) {          if (group.has_quickaction()) {              foreach (var action_group in action_groups)                  action_group.disable_quickactions();          } -             -        if (at_position < 0 || at_position >= this.action_groups.size)  + +        if (at_position < 0 || at_position >= this.action_groups.size)              this.action_groups.add(group);          else              this.action_groups.insert(at_position, group);      } -     +      public void remove_group(int index) {          if (this.action_groups.size > index)              this.action_groups.remove_at(index);      } -     +      public void move_group(int from, int to) {          if (this.action_groups.size > from && this.action_groups.size > to) {              var tmp = this.action_groups[from]; @@ -111,7 +111,7 @@ public class Pie : GLib.Object {              this.add_group(tmp, to);          }      } -     +      public void update_group(ActionGroup group, int index) {          if (this.action_groups.size > index)              this.action_groups.set(index, group); diff --git a/src/pies/pieManager.vala b/src/pies/pieManager.vala index 83a8309..55cb353 100644 --- a/src/pies/pieManager.vala +++ b/src/pies/pieManager.vala @@ -1,24 +1,24 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -/// A static class which stores all Pies. It can be used to add, delete  +///////////////////////////////////////////////////////////////////////// +/// A static class which stores all Pies. It can be used to add, delete  /// and open Pies.  ///////////////////////////////////////////////////////////////////////// @@ -30,196 +30,227 @@ public class PieManager : GLib.Object {      /////////////////////////////////////////////////////////////////////      public static Gee.HashMap<string, Pie?> all_pies { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Stores all PieWindows which are currently opened. Should be      /// rarely more than two...      ///////////////////////////////////////////////////////////////////// -     +      public static Gee.HashSet<PieWindow?> opened_windows { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Stores all global hotkeys.      ///////////////////////////////////////////////////////////////////// -     +      private static BindingManager bindings; -     +      /////////////////////////////////////////////////////////////////////      /// True, if any pie has the current focus. If it is closing this      /// will be false already.      ///////////////////////////////////////////////////////////////////// -     +      private static bool a_pie_is_active = false; -     +      /////////////////////////////////////////////////////////////////////      /// Storing the position of the last Pie. Used for subpies, which are      /// opened at their parents location.      ///////////////////////////////////////////////////////////////////// -     +      private static int last_x = 0;      private static int last_y = 0; -     +      /////////////////////////////////////////////////////////////////////      /// Initializes all Pies. They are loaded from the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      public static void init() {          all_pies = new Gee.HashMap<string, Pie?>();          opened_windows = new Gee.HashSet<PieWindow?>();          bindings = new BindingManager(); -         +          // load all Pies from th pies.conf file          Pies.load(); -         +          // open the according pie if it's hotkey is pressed          bindings.on_press.connect((id) => {              open_pie(id);          });      } -     +      /////////////////////////////////////////////////////////////////////      /// Opens the Pie with the given ID, if it exists.      ///////////////////////////////////////////////////////////////////// -     +      public static void open_pie(string id) {          if (!a_pie_is_active) {              Pie? pie = all_pies[id]; -             +              if (pie != null) { -                 +                  a_pie_is_active = true; -                 + +                //change WM_CLASS so launchers can track windows properly +                Gdk.set_program_class("gnome-pie-" + id); +                  var window = new PieWindow();                  window.load_pie(pie); -                 +                  window.open(); -                 +                  opened_windows.add(window); -                 +                  window.on_closed.connect(() => {                      opened_windows.remove(window);                      if (opened_windows.size == 0) {                          Icon.clear_cache();                      }                  }); -                 +                  window.on_closing.connect(() => {                      window.get_center_pos(out last_x, out last_y);                      a_pie_is_active = false;                  }); -                 -                 + + +                //restore default WM_CLASS after window open +                Gdk.set_program_class("gnome-pie"); +              } else {                  warning("Failed to open pie with ID \"" + id + "\": ID does not exist!");              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the hotkey which the Pie with the given ID is bound to.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_accelerator_of(string id) {          return bindings.get_accelerator_of(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns a human-readable version of the hotkey which the Pie      /// with the given ID is bound to.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_accelerator_label_of(string id) {          return bindings.get_accelerator_label_of(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Bind the Pie with the given ID to the given trigger.      ///////////////////////////////////////////////////////////////////// -     +      public static void bind_trigger(Trigger trigger, string id) {          bindings.unbind(id);          bindings.bind(trigger, id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns true if the pie with the given id is in turbo mode.      ///////////////////////////////////////////////////////////////////// -     +      public static bool get_is_turbo(string id) {          return bindings.get_is_turbo(id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns true if the pie with the given id opens in the middle of      /// the screen.      ///////////////////////////////////////////////////////////////////// -     +      public static bool get_is_centered(string id) {          return bindings.get_is_centered(id);      } -     + +    ///////////////////////////////////////////////////////////////////// +    /// Returns true if the mouse pointer will be warped to the center of +    /// the pie. +    ///////////////////////////////////////////////////////////////////// + +    public static bool get_is_warp(string id) { +        return bindings.get_is_warp(id); +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns true if the pie with the given id is auto shaped +    ///////////////////////////////////////////////////////////////////// + +    public static bool get_is_auto_shape(string id) { +        return bindings.get_is_auto_shape(id); +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns the prefered pie shape number +    ///////////////////////////////////////////////////////////////////// + +    public static int get_shape_number(string id) { +        return bindings.get_shape_number(id); +    } +      /////////////////////////////////////////////////////////////////////      /// Returns the name of the Pie with the given ID.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_name_of(string id) {          Pie? pie = all_pies[id];          if (pie == null) return "";          else             return pie.name;      } -     +      /////////////////////////////////////////////////////////////////////      /// Returns the name ID of the Pie bound to the given Trigger.      /// Returns "" if there is nothing bound to this trigger.      ///////////////////////////////////////////////////////////////////// -     +      public static string get_assigned_id(Trigger trigger) {          return bindings.get_assigned_id(trigger);      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new Pie which is displayed in the configuration dialog      /// and gets saved.      ///////////////////////////////////////////////////////////////////// -     +      public static Pie create_persistent_pie(string name, string icon_name, Trigger? hotkey, string? desired_id = null) {          Pie pie = create_pie(name, icon_name, 100, 999, desired_id);          if (hotkey != null) bindings.bind(hotkey, pie.id); -         +          create_launcher(pie.id); -         +          return pie;      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new Pie which is not displayed in the configuration      /// dialog and is not saved.      ///////////////////////////////////////////////////////////////////// -     +      public static Pie create_dynamic_pie(string name, string icon_name, string? desired_id = null) {          return create_pie(name, icon_name, 1000, 9999, desired_id);      } -     +      /////////////////////////////////////////////////////////////////////      /// Adds a new Pie. Can't be accesd from outer scope. Use      /// create_persistent_pie or create_dynamic_pie instead.      ///////////////////////////////////////////////////////////////////// -     +      private static Pie create_pie(string name, string icon_name, int min_id, int max_id, string? desired_id = null) {           var random = new GLib.Rand(); -         +          string final_id; -         -        if (desired_id == null)  + +        if (desired_id == null)              final_id = random.int_range(min_id, max_id).to_string();          else {              final_id = desired_id;              final_id.canon("0123456789", '_');              final_id = final_id.replace("_", ""); -             +              int id = int.parse(final_id); -             +              if (id < min_id || id > max_id) {                  final_id = random.int_range(min_id, max_id).to_string();                  warning("The ID for pie \"" + name + "\" should be in range %u - %u! Using \"" + final_id + "\" instead of \"" + desired_id + "\"...", min_id, max_id); @@ -237,21 +268,21 @@ public class PieManager : GLib.Object {          Pie pie = new Pie(final_id, name, icon_name);          all_pies.set(final_id, pie); -         +          return pie;      } -     +      /////////////////////////////////////////////////////////////////////      /// Removes the Pie with the given ID if it exists. Additionally it      /// unbinds it's global hotkey.      ///////////////////////////////////////////////////////////////////// -     +      public static void remove_pie(string id) {          if (all_pies.has_key(id)) {              all_pies[id].on_remove();              all_pies.unset(id);              bindings.unbind(id); -             +              if (id.length == 3)                  remove_launcher(id);          } @@ -259,27 +290,28 @@ public class PieManager : GLib.Object {              warning("Failed to remove pie with ID \"" + id + "\": ID does not exist!");          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a desktop file for which opens the Pie with given ID.      ///////////////////////////////////////////////////////////////////// -     +      public static void create_launcher(string id) {          if (all_pies.has_key(id)) {              Pie? pie = all_pies[id]; -             -            string launcher_entry =  -                "#!/usr/bin/env xdg-open\n" +  + +            string launcher_entry = +                "#!/usr/bin/env xdg-open\n" +                  "[Desktop Entry]\n" +                  "Name=%s\n".printf(pie.name) +                  "Exec=%s -o %s\n".printf(Paths.executable, pie.id) +                  "Encoding=UTF-8\n" +                  "Type=Application\n" + -                "Icon=%s\n".printf(pie.icon); +                "Icon=%s\n".printf(pie.icon) + +                "StartupWMClass=gnome-pie-%s\n".printf(pie.id);              // create the launcher file              string launcher = Paths.launchers + "/%s.desktop".printf(pie.id); -             +              try {                  FileUtils.set_contents(launcher, launcher_entry);                  FileUtils.chmod(launcher, 0755); @@ -288,11 +320,11 @@ public class PieManager : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Deletes the desktop file for the Pie with the given ID.      ///////////////////////////////////////////////////////////////////// -     +      private static void remove_launcher(string id) {          string launcher = Paths.launchers + "/%s.desktop".printf(id);          if (FileUtils.test(launcher, FileTest.EXISTS)) { diff --git a/src/pies/save.vala b/src/pies/save.vala index 60fc0b2..9760cce 100644 --- a/src/pies/save.vala +++ b/src/pies/save.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/         +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A helper method which saves pies in a configuration file.  ///////////////////////////////////////////////////////////////////////// @@ -28,23 +28,23 @@ namespace Pies {      /////////////////////////////////////////////////////////////////////      /// Saves all Pies of the PieManager to the pies.conf file.      ///////////////////////////////////////////////////////////////////// -     +      public void save() {          message("Saving Pies to \"" + Paths.pie_config + "\"."); -          +          // initializes the XML-Writer          var writer = new Xml.TextWriter.filename(Paths.pie_config);          writer.set_indent(true);          writer.start_document("1.0");          writer.start_element("pies"); -         +          // iterate through all Pies          foreach (var pie_entry in PieManager.all_pies.entries) {              var pie = pie_entry.value; -             +              // if it's no dynamically created Pie              if (pie.id.length == 3) { -                int slice_count = 0;                 +                int slice_count = 0;                  // write all attributes of the Pie                  writer.start_element("pie"); @@ -52,7 +52,7 @@ namespace Pies {                  writer.write_attribute("id", pie.id);                  writer.write_attribute("icon", pie.icon);                  writer.write_attribute("hotkey", PieManager.get_accelerator_of(pie.id)); -                 +                  // and all of it's Actions                  foreach (var group in pie.action_groups) {                      // if it's a custom ActionGroup @@ -67,14 +67,14 @@ namespace Pies {                              writer.write_attribute("command", action.real_command);                              writer.write_attribute("quickAction", action.is_quickaction ? "true" : "false");                              writer.end_element(); -                             +                              ++ slice_count;                          }                      } else {                          writer.start_element("group");                              writer.write_attribute("type", GroupRegistry.descriptions[group.get_type().name()].id);                          writer.end_element(); -                         +                          slice_count += group.actions.size;                      }                  } diff --git a/src/renderers/centerRenderer.vala b/src/renderers/centerRenderer.vala index fab633e..e94714f 100644 --- a/src/renderers/centerRenderer.vala +++ b/src/renderers/centerRenderer.vala @@ -1,25 +1,25 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  ///  Renders the center of a Pie.  ///////////////////////////////////////////////////////////////////////// @@ -30,26 +30,26 @@ public class CenterRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      private unowned PieRenderer parent; -     +      /////////////////////////////////////////////////////////////////////      /// The caption drawn in the center. Changes when the active slice      /// changes.      ///////////////////////////////////////////////////////////////////// -     +      private unowned Image? caption; -     +      /////////////////////////////////////////////////////////////////////      /// The color of the currently active slice. Used to colorize layers.      ///////////////////////////////////////////////////////////////////// -     +      private Color color; -     +      /////////////////////////////////////////////////////////////////////      /// Two AnimatedValues: alpha is for global transparency (when      /// fading in/out), activity is 1.0 if there is an active slice and      /// 0.0 if there is no active slice.      ///////////////////////////////////////////////////////////////////// -     +      private AnimatedValue activity;      private AnimatedValue alpha; @@ -64,22 +64,22 @@ public class CenterRenderer : GLib.Object {          this.color = new Color();          this.caption = null;      } -     +      /////////////////////////////////////////////////////////////////////      /// Initiates the fade-out animation by resetting the targets of the      /// AnimatedValues to 0.0.      ///////////////////////////////////////////////////////////////////// -     +      public void fade_out() {          this.activity.reset_target(0.0, Config.global.theme.fade_out_time);          this.alpha.reset_target(0.0, Config.global.theme.fade_out_time);      } -     +      /////////////////////////////////////////////////////////////////////      /// Should be called if the active slice of the PieRenderer changes.      /// The members activity, caption and color are set accordingly.      ///////////////////////////////////////////////////////////////////// -     +      public void set_active_slice(SliceRenderer? active_slice) {          if (active_slice == null) {              this.activity.reset_target(0.0, Config.global.theme.transition_time); @@ -89,104 +89,136 @@ public class CenterRenderer : GLib.Object {              this.color   = active_slice.color;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Draws all center layers and the caption.      ///////////////////////////////////////////////////////////////////// -     -    public void draw(double frame_time, Cairo.Context ctx, double angle, double distance) { + +    public void draw(double frame_time, Cairo.Context ctx, double angle, int slice_track) {          // get all center_layers -	    var layers = Config.global.theme.center_layers; -         +        var layers = Config.global.theme.center_layers; +          // update the AnimatedValues          this.activity.update(frame_time);          this.alpha.update(frame_time); -	 -	    // draw each layer -	    foreach (var layer in layers) { -	        ctx.save(); + +        // draw each layer +        foreach (var layer in layers) { +            ctx.save();              // calculate all values needed for animation/drawing -            double active_speed = (layer.active_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?  +            double active_speed = (layer.active_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?                  0.0 : layer.active_rotation_speed; -            double inactive_speed = (layer.inactive_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?  +            double inactive_speed = (layer.inactive_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?                  0.0 : layer.inactive_rotation_speed; -	        double max_scale = layer.active_scale*this.activity.val  -	            + layer.inactive_scale*(1.0-this.activity.val); -            double max_alpha = layer.active_alpha*this.activity.val  +            double max_scale = layer.active_scale*this.activity.val +                + layer.inactive_scale*(1.0-this.activity.val); +            double max_alpha = layer.active_alpha*this.activity.val                  + layer.inactive_alpha*(1.0-this.activity.val); -            double colorize = ((layer.active_colorize == true) ? this.activity.val : 0.0)  +            double colorize = ((layer.active_colorize == true) ? this.activity.val : 0.0)                  + ((layer.inactive_colorize == true) ? 1.0 - this.activity.val : 0.0); -            double max_rotation_speed = active_speed*this.activity.val  +            double max_rotation_speed = active_speed*this.activity.val                  + inactive_speed*(1.0-this.activity.val); -            CenterLayer.RotationMode rotation_mode = ((this.activity.val > 0.5) ?  +            CenterLayer.RotationMode rotation_mode = ((this.activity.val > 0.5) ?                  layer.active_rotation_mode : layer.inactive_rotation_mode); -	         -	        if (rotation_mode == CenterLayer.RotationMode.TO_MOUSE) { -	            double diff = angle-layer.rotation; -	            max_rotation_speed = layer.active_rotation_speed*this.activity.val  -	                + layer.inactive_rotation_speed*(1.0-this.activity.val); -	            double smoothy = fabs(diff) < 0.9 ? fabs(diff) + 0.1 : 1.0;  -	            double step = max_rotation_speed*frame_time*smoothy; -	             + +            if (rotation_mode == CenterLayer.RotationMode.TO_MOUSE) { +                double diff = angle-layer.rotation; +                max_rotation_speed = layer.active_rotation_speed*this.activity.val +                    + layer.inactive_rotation_speed*(1.0-this.activity.val); +                double smoothy = fabs(diff) < 0.9 ? fabs(diff) + 0.1 : 1.0; +                double step = max_rotation_speed*frame_time*smoothy; +                  if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step) -		            layer.rotation = angle; -	            else { -	                if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step; -		            else            		                   layer.rotation -= step; +                    layer.rotation = angle; +                else { +                    if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step; +                    else                                       layer.rotation -= step;                  } -                 -	        } else if (rotation_mode == CenterLayer.RotationMode.TO_ACTIVE) { -	            max_rotation_speed *= this.activity.val; -	             -	            double slice_angle = parent.slice_count() > 0 ? 2*PI/parent.slice_count() : 0; -	            double direction = (int)((angle+0.5*slice_angle) / (slice_angle))*slice_angle; -	            double diff = direction-layer.rotation; -	            double step = max_rotation_speed*frame_time; -	             + +            } else if (rotation_mode == CenterLayer.RotationMode.TO_ACTIVE) { +                max_rotation_speed *= this.activity.val; + +                double slice_angle = parent.total_slice_count > 0 ? 2*PI/parent.total_slice_count : 0; +                double direction = (int)((angle+0.5*slice_angle) / (slice_angle))*slice_angle; +                double diff = direction-layer.rotation; +                double step = max_rotation_speed*frame_time; +                  if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step) -		            layer.rotation = direction; -	            else { -	                if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step; -		            else            		                   layer.rotation -= step; +                    layer.rotation = direction; +                else { +                    if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step; +                    else                                       layer.rotation -= step;                  } -	             -	        } else layer.rotation += max_rotation_speed*frame_time; -	         -	        layer.rotation = fmod(layer.rotation+2*PI, 2*PI); -	         -	        if (colorize > 0.0) ctx.push_group(); -	         -	        // transform the context -	        ctx.rotate(layer.rotation); -	        ctx.scale(max_scale, max_scale); -	         -	        // paint the layer -	        layer.image.paint_on(ctx, this.alpha.val*max_alpha); -             + +            } else layer.rotation += max_rotation_speed*frame_time; + +            layer.rotation = fmod(layer.rotation+2*PI, 2*PI); + +            if (colorize > 0.0) ctx.push_group(); + +            // transform the context +            ctx.rotate(layer.rotation); +            ctx.scale(max_scale, max_scale); + +            // paint the layer +            layer.image.paint_on(ctx, this.alpha.val*max_alpha); +              // colorize it, if necessary              if (colorize > 0.0) {                  ctx.set_operator(Cairo.Operator.ATOP);                  ctx.set_source_rgb(this.color.r, this.color.g, this.color.b);                  ctx.paint_with_alpha(colorize); -                 +                  ctx.set_operator(Cairo.Operator.OVER);                  ctx.pop_group_to_source(); -	            ctx.paint(); -	        } -             +                ctx.paint(); +            } +              ctx.restore();          } -         +          // draw caption          if (Config.global.theme.caption && caption != null && this.activity.val > 0) { -		    ctx.save(); +            ctx.save();              ctx.identity_matrix(); -            int pos = this.parent.size/2; -            ctx.translate(pos, (int)(Config.global.theme.caption_position) + pos); +            ctx.translate(this.parent.center_x, (int)(Config.global.theme.caption_position) + this.parent.center_y);              caption.paint_on(ctx, this.activity.val*this.alpha.val);              ctx.restore();          } + +        //scroll pie +        if (this.alpha.val > 0.1 +            && this.parent.original_visible_slice_count < this.parent.slice_count() +            && this.parent.original_visible_slice_count > 0) { +            int np= (this.parent.slice_count()+this.parent.original_visible_slice_count -1)/this.parent.original_visible_slice_count; +            int cp= this.parent.first_slice_idx / this.parent.original_visible_slice_count; +            int r= 8;       //circle radious +            int dy= 20;     //distance between circles +            double a= 0.8 * this.alpha.val; +            int dx= (int)Config.global.theme.center_radius + r + 10; +            if (this.parent.center_x + dx > this.parent.size_w) +                dx= -dx;    //no right side, put scroll in the left size +            ctx.save(); +            ctx.identity_matrix(); +            ctx.translate(this.parent.center_x + dx, this.parent.center_y - (np-1)*dy/2); +            for (int i=0; i<np; i++) { +                ctx.arc( 0, 0, r, 0, 2*PI ); +                if (i == cp){ +                    ctx.set_source_rgba(0.3,0.3,0.3, a);    //light gray stroke +                    ctx.stroke_preserve(); +                    ctx.set_source_rgba(1,1,1, a);          //white fill +                    ctx.fill(); //current +                } else { +                    ctx.set_source_rgba(1,1,1, a);          //white stroke +                    ctx.stroke_preserve(); +                    ctx.set_source_rgba(0.3,0.3,0.3, a/4);  //light gray fill +                    ctx.fill(); //current +                } +                ctx.translate(0, dy); +            } +            ctx.restore(); +        }      }  } diff --git a/src/renderers/pieRenderer.vala b/src/renderers/pieRenderer.vala index 8085758..2edee09 100644 --- a/src/renderers/pieRenderer.vala +++ b/src/renderers/pieRenderer.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; @@ -49,13 +49,89 @@ public class PieRenderer : GLib.Object {      /// The width and height of the Pie in pixels.      ///////////////////////////////////////////////////////////////////// -    public int size { get; private set; } +    public int size_w { get; private set; } +    public int size_h { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// Center position relative to window top-left corner +    ///////////////////////////////////////////////////////////////////// + +    public int center_x { get; private set; } +    public int center_y { get; private set; } + +    //////////////////////////////////////////////////////////////////// +    /// Possible show pie modes. +    /// FULL_PIE:       Show the pie as a complete circle. +    /// HPIE_LEFT:      Eat half pie so it can be shown at the left of the screen. +    /// HPIE_RIGHT:     Eat half pie so it can be shown at the right of the screen. +    /// HPIE_TOP:       Eat half pie so it can be shown at the top of the screen. +    /// HPIE_BOTTOM:    Eat half pie so it can be shown at the bottom of the screen. +    /// CPIE_TOP_LEFT:  Eat  3/4 pie so it can be shown at the top-left corner. +    /// CPIE_TOP_RIGHT: Eat  3/4 pie so it can be shown at the top-right corner. +    /// CPIE_BOT_LEFT:  Eat  3/4 pie so it can be shown at the bottom-left corner. +    /// CPIE_BOT_RIGHT: Eat  3/4 pie so it can be shown at the bottom-right corner.      ///////////////////////////////////////////////////////////////////// -    /// True if the pie should close when it's trigger is released. + +    public enum ShowPieMode { +        FULL_PIE, +        HPIE_LEFT, HPIE_RIGHT, HPIE_TOP, HPIE_BOTTOM, +        CPIE_TOP_LEFT, CPIE_TOP_RIGHT, CPIE_BOT_LEFT, CPIE_BOT_RIGHT} +      ///////////////////////////////////////////////////////////////////// +    ///  Show pie mode: full, half-circle, corner +    ///////////////////////////////////////////////////////////////////// + +    public ShowPieMode pie_show_mode { get; private set; default= ShowPieMode.FULL_PIE; } + +    ///////////////////////////////////////////////////////////////////// +    /// Number of visible slices +    ///////////////////////////////////////////////////////////////////// + +    public int visible_slice_count { get; private set; } -    public bool turbo_mode { get; private set; default=false; } +    public int original_visible_slice_count { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// Number of slices in full pie (visible or not) +    ///////////////////////////////////////////////////////////////////// + +    public int total_slice_count { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// Maximun number of visible slices in a full pie +    ///////////////////////////////////////////////////////////////////// + +    public int max_visible_slices { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// The index of the first visible slice +    ///////////////////////////////////////////////////////////////////// + +    public int first_slice_idx { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// Angular position of the first visible slice +    ///////////////////////////////////////////////////////////////////// + +    public double first_slice_angle { get; private set; } + +    ///////////////////////////////////////////////////////////////////// +    /// Index of the slice where to go when up/down/left/right key is pressed +    /// or -1 if that side of the pie was eaten +    ///////////////////////////////////////////////////////////////////// + +    public int up_slice_idx { get; private set; } +    public int down_slice_idx { get; private set; } +    public int left_slice_idx { get; private set; } +    public int right_slice_idx { get; private set; } + + +    ///////////////////////////////////////////////////////////////////// +    /// The ID of the currently loaded Pie. +    ///////////////////////////////////////////////////////////////////// + +    public string id { get; private set; }      /////////////////////////////////////////////////////////////////////      /// True if the pie is currently navigated with the keyboard. This is @@ -77,6 +153,11 @@ public class PieRenderer : GLib.Object {      private CenterRenderer center;      ///////////////////////////////////////////////////////////////////// +    /// Maximum distance from the center that activates the slices +    ///////////////////////////////////////////////////////////////////// +    private int activation_range; + +    /////////////////////////////////////////////////////////////////////      /// C'tor, initializes members.      ///////////////////////////////////////////////////////////////////// @@ -85,7 +166,35 @@ public class PieRenderer : GLib.Object {          this.center = new CenterRenderer(this);          this.quickaction = -1;          this.active_slice = -2; -        this.size = 0; +        this.size_w = 0; +        this.size_h = 0; +        this.activation_range= 300; + +        this.max_visible_slices= Config.global.max_visible_slices; + +        set_show_mode(ShowPieMode.FULL_PIE); +    } + + +    private void get_mouse_and_screen(out int mousex, out int mousey, out int screenx, out int screeny) { +        // get the mouse position and screen resolution +        double x = 0.0; +        double y = 0.0; + +        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) { +                Gdk.Screen screen; +                device.get_position( out screen, out x, out y ); +            } +        } +        mousex= (int) x; +        mousey= (int) y; +        screenx= Gdk.Screen.width(); +        screeny= Gdk.Screen.height();      }      ///////////////////////////////////////////////////////////////////// @@ -95,6 +204,8 @@ public class PieRenderer : GLib.Object {      public void load_pie(Pie pie) {          this.slices.clear(); +        this.id = pie.id; +          int count = 0;          foreach (var group in pie.action_groups) {              foreach (var action in group.actions) { @@ -110,18 +221,200 @@ public class PieRenderer : GLib.Object {              }          } -        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); +        ShowPieMode showpie= ShowPieMode.FULL_PIE; +        //set full pie to determine the number of visible slices +        set_show_mode(showpie); + +        int sz0= (int)fmax(2*Config.global.theme.radius + 2*Config.global.theme.visible_slice_radius*Config.global.theme.max_zoom, +                           2*Config.global.theme.center_radius); + +        int sz= sz0;          // 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)*2*Config.global.theme.max_zoom); +        if (this.total_slice_count > 0) { +            sz = (int)fmax(sz0, +                (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/this.total_slice_count)) +                 + Config.global.theme.visible_slice_radius)*2*Config.global.theme.max_zoom); +        } + + + + +        // get mouse position and screen resolution +        int mouse_x, mouse_y, screen_x, screen_y; +        get_mouse_and_screen( out mouse_x, out mouse_y, out screen_x, out screen_y ); + +        //reduce the window size if needed to get closer to the actual mouse position +        int reduce_szx= 1; +        int reduce_szy= 1; + +        if (PieManager.get_is_auto_shape(pie.id) && !PieManager.get_is_centered(pie.id)) { +            //set the best show mode that put the mouse near the center +            if (mouse_x < sz/2) { +                if (mouse_y < sz/2) +                    showpie= ShowPieMode.CPIE_TOP_LEFT;         //show 1/4 pie +                else if (screen_y > 0 && screen_y-mouse_y < sz/2) +                    showpie= ShowPieMode.CPIE_BOT_LEFT;         //show 1/4 pie +                else +                    showpie= ShowPieMode.HPIE_LEFT;             //show 1/2 pie + +            } else if (mouse_y < sz/2) { +                if (screen_x > 0 && screen_x-mouse_x < sz/2) +                    showpie= ShowPieMode.CPIE_TOP_RIGHT;        //show 1/4 pie +                else +                    showpie= ShowPieMode.HPIE_TOP;              //show 1/2 pie + +            } else if (screen_x > 0 && screen_x-mouse_x < sz/2) { +                if (screen_y > 0 && screen_y-mouse_y < sz/2) +                    showpie= ShowPieMode.CPIE_BOT_RIGHT;        //show 1/4 pie +                else +                    showpie= ShowPieMode.HPIE_RIGHT;            //show 1/2 pie + +            } else if (screen_y > 0 && screen_y-mouse_y < sz/2) +                showpie= ShowPieMode.HPIE_BOTTOM;               //show 1/2 pie + + +        } else { +            //if the pie is centered in the screen, don't reduce the size +            if (PieManager.get_is_centered(pie.id)) { +                reduce_szx= 0; +                reduce_szy= 0; +            } + +            //select the configured shape +            //convert from radio-buttum number to ShowPieMode enum +            switch( PieManager.get_shape_number(pie.id) ) { +            case 1: +                showpie= ShowPieMode.CPIE_BOT_RIGHT; +                if (screen_x-mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                if (screen_y-mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            case 2: +                showpie= ShowPieMode.HPIE_RIGHT; +                if (screen_x-mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                break; +            case 3: +                showpie= ShowPieMode.CPIE_TOP_RIGHT; +                if (screen_x-mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                if (mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            case 4: +                showpie= ShowPieMode.HPIE_BOTTOM; +                if (screen_y-mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            case 6: +                showpie= ShowPieMode.HPIE_TOP; +                if (mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            case 7: +                showpie= ShowPieMode.CPIE_BOT_LEFT; +                if (mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                if (screen_y-mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            case 8: +                showpie= ShowPieMode.HPIE_LEFT; +                if (mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                break; +            case 9: +                showpie= ShowPieMode.CPIE_TOP_LEFT; +                if (mouse_x > sz/2) +                    reduce_szx= 0; //keep full width +                if (mouse_y > sz/2) +                    reduce_szy= 0; //keep full height +                break; +            } +        } +        //set the new show pie mode +        set_show_mode(showpie); + +        //recalc size +        sz = sz0; +        if (this.total_slice_count > 0) { +            sz = (int)fmax(sz0, +                (((Config.global.theme.slice_radius + Config.global.theme.slice_gap)/tan(PI/this.total_slice_count)) +                 + Config.global.theme.visible_slice_radius)*2*Config.global.theme.max_zoom); +        } +        //activation_range = normal pie radius + "outer" activation_range +        this.activation_range= (int)((double)Config.global.activation_range + sz/(2*Config.global.theme.max_zoom)); + +        int szx = 1; //full width +        int szy = 1; //full height +        switch(this.pie_show_mode) { +            //half pie +            case ShowPieMode.HPIE_LEFT: +                szx = 0; //half width, center to the left +                break; +            case ShowPieMode.HPIE_RIGHT: +                szx = 2; //half width, center to the right +                break; +            case ShowPieMode.HPIE_TOP: +                szy = 0; //half height, center to the top +                break; +            case ShowPieMode.HPIE_BOTTOM: +                szy = 2; //half height, center to the bottom +                break; + +            //cuarter pie +            case ShowPieMode.CPIE_TOP_LEFT: +                szx = 0; //half width, center to the left +                szy = 0; //half height, center to the top +                break; +            case ShowPieMode.CPIE_TOP_RIGHT: +                szx = 2; //half width, center to the right +                szy = 0; //half height, center to the top +                break; +            case ShowPieMode.CPIE_BOT_LEFT: +                szx = 0; //half width, center to the left +                szy = 2; //half height, center to the bottom +                break; +            case ShowPieMode.CPIE_BOT_RIGHT: +                szx = 2; //half width, center to the right +                szy = 2; //half height, center to the bottom +                break; +        } +        if (reduce_szx == 0) +            szx = 1;    //don't reduce width +        if (reduce_szy == 0) +            szy = 1;    //don't reduce height + +        int rc = (int)Config.global.theme.center_radius; +        if (szx == 1 ) { +            //full width +            this.size_w = sz; +            this.center_x = sz/2;    //center position +        } else { +            //half width +            this.size_w = sz/2 + rc; +            if (szx == 0) { +                this.center_x = rc;    //center to the left +            } else { +                this.center_x = this.size_w-rc;    //center to the right +            } +        } +        if (szy == 1) { +            //full heigth +            this.size_h = sz; +            this.center_y = sz/2;    //center position +        } else { +            //half heigth +            this.size_h = sz/2 + rc; +            if (szy == 0) { +                this.center_y = rc;    //center to the top +            } else { +                this.center_y = this.size_h-rc;    //center to the bottom +            }          }      } @@ -130,12 +423,16 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void activate() { -        if (this.active_slice >= 0 && this.active_slice < this.slices.size) { +        if (this.active_slice >= this.first_slice_idx +            && this.active_slice < this.first_slice_idx+this.visible_slice_count) {              slices[active_slice].activate();          } -        foreach (var slice in this.slices) -            slice.fade_out(); +        //foreach (var slice in this.slices) +        //    slice.fade_out(); +        for (int i= 0; i < this.visible_slice_count; ++i) { +            this.slices[ i+this.first_slice_idx ].fade_out(); +        }          center.fade_out();      } @@ -145,29 +442,23 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void cancel() { -        foreach (var slice in this.slices) -            slice.fade_out(); +        //foreach (var slice in this.slices) +        //    slice.fade_out(); +        for (int i= 0; i < this.visible_slice_count; ++i) { +            this.slices[ i+this.first_slice_idx ].fade_out(); +        }          center.fade_out();      } +      /////////////////////////////////////////////////////////////////////      /// Called when the up-key is pressed. Selects the next slice towards      /// 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; +        move_active_slice(this.up_slice_idx, this.down_slice_idx);      }      ///////////////////////////////////////////////////////////////////// @@ -176,17 +467,7 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      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; +        move_active_slice(this.down_slice_idx, this.up_slice_idx);      }      ///////////////////////////////////////////////////////////////////// @@ -195,17 +476,7 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      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; +        move_active_slice(this.left_slice_idx, this.right_slice_idx);      }      ///////////////////////////////////////////////////////////////////// @@ -214,17 +485,79 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void select_right() { -        int left = this.slice_count()/2; -        int right = 0; +        move_active_slice(this.right_slice_idx, this.left_slice_idx); +    } -        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()); +    ///////////////////////////////////////////////////////////////////// +    /// Called when the page_up-key is pressed. Selects the next +    /// group of slices. +    ///////////////////////////////////////////////////////////////////// -        this.key_board_control = true; +    public void select_nextpage() { +        if (this.first_slice_idx+this.visible_slice_count < slices.size) { +            //advance one page +            this.first_slice_idx += this.visible_slice_count; +            if (this.first_slice_idx+this.visible_slice_count >= slices.size) { +                this.visible_slice_count= slices.size - this.first_slice_idx; +            } +            this.reset_sclice_anim(); +            this.set_highlighted_slice(-1); +            calc_key_navigation_pos(); +            this.key_board_control = true; + +        } else if (this.first_slice_idx > 0) { +            //go to first page +            this.first_slice_idx= 0; +            this.reset_sclice_anim(); +            //recover the original value +            this.visible_slice_count= this.original_visible_slice_count; +            this.reset_sclice_anim(); +            this.set_highlighted_slice(-1); +            calc_key_navigation_pos(); +            this.key_board_control = true; +        } +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Called when the page_down-key is pressed. Selects the previous +    /// group of slices. +    ///////////////////////////////////////////////////////////////////// + +    public void select_prevpage() { +        if (this.first_slice_idx > 0) { +            //go back one page +            //recover the original value +            this.visible_slice_count= this.original_visible_slice_count; +            this.first_slice_idx -= this.visible_slice_count; +            if (this.first_slice_idx < 0) { +                this.first_slice_idx= 0; +            } +            this.reset_sclice_anim(); +            this.set_highlighted_slice(-1); +            calc_key_navigation_pos(); +            this.key_board_control = true; + +        } else if (this.visible_slice_count < slices.size) { +            //go to last page +            int n= slices.size % this.original_visible_slice_count; +            if (n == 0) +                //all pages have the same number of slices +                this.visible_slice_count= this.original_visible_slice_count; +            else +                //last page has less slices than previous +                this.visible_slice_count= n; +            this.first_slice_idx= slices.size - this.visible_slice_count; +            this.reset_sclice_anim(); +            this.set_highlighted_slice(-1); +            calc_key_navigation_pos(); +            this.key_board_control = true; +        } +    } + +    private void reset_sclice_anim() { +        //reset animation values in all the new visible slices +        for (int i= 0; i < this.visible_slice_count; ++i) +            this.slices[ i+this.first_slice_idx ].reset_anim();      }      ///////////////////////////////////////////////////////////////////// @@ -240,41 +573,58 @@ public class PieRenderer : GLib.Object {      /////////////////////////////////////////////////////////////////////      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); -	        double angle = 0.0; - -	        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) -		                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) { +        if (this.size_w > 0) { +            double distance = sqrt(mouse_x*mouse_x + mouse_y*mouse_y); +            double angle = 0.0; +            int slice_track= 0; + +            if (this.key_board_control) { +                int n= this.active_slice - this.first_slice_idx; +                angle = 2.0*PI*n/(double)this.total_slice_count + this.first_slice_angle; +                slice_track= 1; +            } else { + +                if (distance > 0) { +                    angle = acos(mouse_x/distance); +                    if (mouse_y < 0) +                        angle = 2*PI - angle; +                } -	                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 && distance < Config.global.activation_range) { -	                next_active_slice = (int)(angle*slices.size/(2*PI) + 0.5) % this.slice_count(); -	            } else { -	                next_active_slice = -1; -	            } +                int next_active_slice = this.active_slice; + +                if (distance < Config.global.theme.active_radius +                    && this.quickaction >= this.first_slice_idx +                    && this.quickaction < this.first_slice_idx+this.visible_slice_count) { + +                    next_active_slice = this.quickaction; +                    int n= this.quickaction - this.first_slice_idx; +                    angle = 2.0*PI*n/(double)this.total_slice_count + this.first_slice_angle; + +                } else if (distance > Config.global.theme.active_radius && this.total_slice_count > 0 +                           && distance < this.activation_range) { +                    double a= angle-this.first_slice_angle; +                    if (a < 0) +                        a= a + 2*PI; +                    next_active_slice = (int)(a*this.total_slice_count/(2*PI) + 0.5) % this.total_slice_count; +                    if (next_active_slice >= this.visible_slice_count) +                        next_active_slice = -1; +                    else { +                        next_active_slice = next_active_slice + this.first_slice_idx; +                        slice_track= 1; +                    } +                } else { +                    next_active_slice = -1; +                } -	            this.set_highlighted_slice(next_active_slice); -	        } +                this.set_highlighted_slice(next_active_slice); +            } -            center.draw(frame_time, ctx, angle, distance); +            center.draw(frame_time, ctx, angle, slice_track); -	        foreach (var slice in this.slices) -		        slice.draw(frame_time, ctx, angle, distance); -		} +            for (int i= 0; i < this.visible_slice_count; ++i) { +               this.slices[ i+this.first_slice_idx ].draw(frame_time, ctx, angle, slice_track); +            } +        }      }      ///////////////////////////////////////////////////////////////////// @@ -291,21 +641,215 @@ public class PieRenderer : GLib.Object {      public void set_highlighted_slice(int index) {          if (index != this.active_slice) { -            if (index >= 0 && index < this.slice_count()) +            if (index >= this.first_slice_idx && index < this.first_slice_idx+this.visible_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()) ? +            SliceRenderer? active = (this.active_slice >= 0 && this.active_slice < slices.size) ?                                       this.slices[this.active_slice] : null;              center.set_active_slice(active); -            foreach (var slice in this.slices) -                slice.set_active_slice(active); +            for (int i= 0; i < this.visible_slice_count; ++i) { +               this.slices[ i+this.first_slice_idx ].set_active_slice(active); +            } +        } +    } + +    private void set_show_mode(ShowPieMode show_mode) { +        //The index of the first visible slice +        this.first_slice_idx= 0; +        //Angular position of the first visible slice +        this.first_slice_angle= 0; + +        int mult= 1; +        switch(show_mode) { +            //half pie +            case ShowPieMode.HPIE_LEFT: +                mult= 2; +                this.first_slice_angle= -PI/2; +                break; +            case ShowPieMode.HPIE_RIGHT: +                mult= 2; +                this.first_slice_angle= PI/2; +                break; +            case ShowPieMode.HPIE_TOP: +                mult= 2; +                break; +            case ShowPieMode.HPIE_BOTTOM: +                this.first_slice_angle= PI; +                mult= 2; +                break; + +            //cuarter pie +            case ShowPieMode.CPIE_TOP_LEFT: +                mult= 4; +                break; +            case ShowPieMode.CPIE_TOP_RIGHT: +                this.first_slice_angle= PI/2; +                mult= 4; +                break; +            case ShowPieMode.CPIE_BOT_LEFT: +                this.first_slice_angle= -PI/2; +                mult= 4; +                break; +            case ShowPieMode.CPIE_BOT_RIGHT: +                this.first_slice_angle= PI; +                mult= 4; +                break; + +            default:     //ShowPieMode.FULL_PIE or invalid values +                show_mode= ShowPieMode.FULL_PIE; +                break; +        } +        this.pie_show_mode= show_mode; +        //limit the number of visible slices +        int maxview= this.max_visible_slices / mult; +        //Number of visible slices +        this.visible_slice_count= (int)fmin(slices.size, maxview); +        //Number of slices in full pie (visible or not) +        this.total_slice_count= this.visible_slice_count*mult; +        if (mult > 1 && slices.size > 1) { +            this.total_slice_count -= mult;          } + +        //keep a copy of the original value since page up/down change it +        original_visible_slice_count= visible_slice_count; + +        calc_key_navigation_pos(); +    } + +    private void calc_key_navigation_pos() { +           //calc slices index for keyboard navigation + +        int a= this.first_slice_idx; +        int b= this.first_slice_idx + this.visible_slice_count/4; +        int c= this.first_slice_idx + this.visible_slice_count/2; +        int d= this.first_slice_idx + (this.visible_slice_count*3)/4; +        int e= this.first_slice_idx + this.visible_slice_count -1; +        switch(this.pie_show_mode) { +            //half pie +            case ShowPieMode.HPIE_LEFT: +                this.up_slice_idx=    a; +                this.right_slice_idx= c; +                this.down_slice_idx=  e; +                this.left_slice_idx=  -1;    //no left slice, go up instead +                break; +            case ShowPieMode.HPIE_RIGHT: +                this.down_slice_idx=  a; +                this.left_slice_idx=  c; +                this.up_slice_idx=    e; +                this.right_slice_idx= -1;   //no right slice, go down instead +                break; +            case ShowPieMode.HPIE_TOP: +                this.right_slice_idx= a; +                this.down_slice_idx=  c; +                this.left_slice_idx=  e; +                this.up_slice_idx=    -1;    //no up slice, go left instead +                break; +            case ShowPieMode.HPIE_BOTTOM: +                this.left_slice_idx=  a; +                this.up_slice_idx=    c; +                this.right_slice_idx= e; +                this.down_slice_idx=  -1;   //no down slice, go right instead +                break; + +            //cuarter pie +            case ShowPieMode.CPIE_TOP_LEFT: +                this.right_slice_idx= a; +                this.down_slice_idx=  e; +                this.up_slice_idx=    -1;    //no up slice, go right instead +                this.left_slice_idx=  -1;    //no left slice, go down instead +                break; +            case ShowPieMode.CPIE_TOP_RIGHT: +                this.down_slice_idx=  a; +                this.left_slice_idx=  e; +                this.up_slice_idx=    -1;    //no up slice, go left instead +                this.right_slice_idx= -1;    //no righ slice, go down instead +                break; +            case ShowPieMode.CPIE_BOT_LEFT: +                this.up_slice_idx=    a; +                this.right_slice_idx= e; +                this.down_slice_idx=  -1;    //no down slice, go right instead +                this.left_slice_idx=  -1;    //no left slice, go up instead +                break; +            case ShowPieMode.CPIE_BOT_RIGHT: +                this.left_slice_idx=  a; +                this.up_slice_idx=    e; +                this.down_slice_idx=  -1;    //no down slice, go left instead +                this.right_slice_idx= -1;    //no right slice, go up instead +                break; + +            default:     //ShowPieMode.FULL_PIE or invalid values +                this.right_slice_idx= a; +                this.down_slice_idx=  b; +                this.left_slice_idx=  c; +                this.up_slice_idx=    d; +                break; +        } +    } + + +   ///////////////////////////////////////////////////////////////////// +    /// keyboard navigation helper +    /// move current position one slice towards the given extreme +    ///////////////////////////////////////////////////////////////////// + +    private void move_active_slice(int extreme, int other_extreme ) { +        int pos= this.active_slice; + +        if (pos < 0 || pos == extreme) { +            //no actual position or allready at the extreme +            pos= extreme; //go to the extreme pos + +        } else if (extreme == -1) { +            //the extreme was eaten, just go away from the other_extreme +            if (pos > other_extreme || other_extreme == 0) { +                if (pos < this.visible_slice_count+this.first_slice_idx-1) +                    pos++; +            } else if (pos > this.first_slice_idx) +                pos--; + +        } else if (other_extreme == -1) { +            //the other_extreme was eaten, just get closer to the extreme +            if (pos < extreme) +                pos++; +            else if (pos > extreme) +                pos--; + +        } else if (pos == other_extreme) { +            //both extremes are present +            //jump quickly form one extreme to the other +            pos= extreme; //go to the extreme pos + +        } else { +            //both extremes are present +            //add or substract 1 to position in a circular manner +            if (extreme > other_extreme) { +                if (pos > other_extreme && pos < extreme) +                    //other_extreme < pos < extreme +                    pos= pos+1; +                else +                    pos= pos-1; +            } else { +                if (pos > extreme && pos < other_extreme) +                    //extreme < pos < other_extreme +                    pos= pos-1; +                else +                    pos= pos+1; +            } + +            if (pos < this.first_slice_idx) +                pos= this.visible_slice_count-1+this.first_slice_idx; + +            if (pos >= this.visible_slice_count+this.first_slice_idx) +                pos= this.first_slice_idx; +        } + +        this.set_highlighted_slice(pos); + +        this.key_board_control = true;      }  } diff --git a/src/renderers/pieWindow.vala b/src/renderers/pieWindow.vala index da346dd..4d5d35a 100644..100755 --- a/src/renderers/pieWindow.vala +++ b/src/renderers/pieWindow.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; @@ -45,6 +45,31 @@ public class PieWindow : Gtk.Window {      public Image background { get; private set; default=null; }      ///////////////////////////////////////////////////////////////////// +    /// The background image position and size. +    ///////////////////////////////////////////////////////////////////// + +    private int back_x; +    private int back_y; +    private int back_sz_x; +    private int back_sz_y; + +    ///////////////////////////////////////////////////////////////////// +    /// Some panels moves the window after it was realized. +    /// This value set the maximum allowed panel height or width. +    /// (how many pixels the window could be moved in every direction +    ///  from the screen borders towards the center) +    ///////////////////////////////////////////////////////////////////// + +    private int panel_sz = 64; + +    ///////////////////////////////////////////////////////////////////// +    /// This value set the maximum allowed mouse movement in pixels +    /// from the capture to the show point in every direction. +    ///////////////////////////////////////////////////////////////////// + +    private int mouse_move = 30; + +    /////////////////////////////////////////////////////////////////////      /// The owned renderer.      ///////////////////////////////////////////////////////////////////// @@ -97,11 +122,12 @@ public class PieWindow : Gtk.Window {          this.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK |                          Gdk.EventMask.KEY_RELEASE_MASK |                          Gdk.EventMask.KEY_PRESS_MASK | -                        Gdk.EventMask.POINTER_MOTION_MASK); +                        Gdk.EventMask.POINTER_MOTION_MASK | +                        Gdk.EventMask.SCROLL_MASK );          // activate on left click          this.button_release_event.connect ((e) => { -            if (e.button == 1 || this.renderer.turbo_mode) this.activate_slice(); +            if (e.button == 1 || PieManager.get_is_turbo(this.renderer.id)) this.activate_slice();              return true;          }); @@ -124,7 +150,7 @@ public class PieWindow : Gtk.Window {          // activate on key release if turbo_mode is enabled          this.key_release_event.connect((e) => {              last_key = 0; -            if (this.renderer.turbo_mode) +            if (PieManager.get_is_turbo(this.renderer.id))                  this.activate_slice();              else                  this.handle_key_release(e.keyval); @@ -142,6 +168,15 @@ public class PieWindow : Gtk.Window {              FocusGrabber.grab(this.get_window(), true, true, false);          }); +        this.scroll_event.connect((e) => { +            if (e.direction == Gdk.ScrollDirection.UP) +                this.renderer.select_prevpage(); + +            else if (e.direction == Gdk.ScrollDirection.DOWN) +                this.renderer.select_nextpage(); +            return true; +        }); +          // draw the pie on expose          this.draw.connect(this.draw_window);      } @@ -153,7 +188,7 @@ public class PieWindow : Gtk.Window {      public void load_pie(Pie pie) {          this.renderer.load_pie(pie);          this.set_window_position(pie); -        this.set_size_request(renderer.size, renderer.size); +        this.set_size_request(renderer.size_w, renderer.size_h);      }      ///////////////////////////////////////////////////////////////////// @@ -162,13 +197,56 @@ public class PieWindow : Gtk.Window {      public void open() {          this.realize(); -          // capture the background image if there is no compositing          if (!this.has_compositing) { -            int x, y, width, height; -            this.get_position(out x, out y); -            this.get_size(out width, out height); -            this.background = new Image.capture_screen(x, y, width+1, height+1); +            this.get_position(out this.back_x, out this.back_y); +            this.get_size(out this.back_sz_x, out this.back_sz_y); +            this.back_sz_x++; +            this.back_sz_y++; + +            int screenx= Gdk.Screen.width(); +            int screeny= Gdk.Screen.height(); + +            //allow some window movement from the screen borders +            //(some panels moves the window after it was realized) +            int dx = this.panel_sz - this.back_x; +            if (dx > 0) +                this.back_sz_x += dx; +            dx = this.panel_sz - (screenx - this.back_x - this.back_sz_x +1); +            if (dx > 0) { +                this.back_sz_x += dx; +                this.back_x  -= dx; +            } + +            int dy = this.panel_sz - this.back_y; +            if (dy > 0) +                this.back_sz_y += dy; +            dy = this.panel_sz - (screeny - this.back_y - this.back_sz_y +1); +            if (dy > 0) { +                this.back_sz_y += dy; +                this.back_y  -= dy; +            } + +            //also tolerate some mouse movement +            this.back_x -= this.mouse_move; +            this.back_sz_x += this.mouse_move*2; +            this.back_y -= this.mouse_move; +            this.back_sz_y += this.mouse_move*2; + +            //make sure we don't go outside the screen +            if (this.back_x < 0) { +                this.back_sz_x += this.back_x; +                this.back_x = 0; +            } +            if (this.back_y < 0) { +                this.back_sz_y += this.back_y; +                this.back_y = 0; +            } +            if (this.back_x + this.back_sz_x > screenx) +                this.back_sz_x = screenx - this.back_x; +            if (this.back_y + this.back_sz_y > screeny) +                this.back_sz_y = screeny - this.back_y; +            this.background = new Image.capture_screen(this.back_x, this.back_y, this.back_sz_x, this.back_sz_y);          }          // capture the input focus @@ -179,11 +257,20 @@ public class PieWindow : Gtk.Window {          this.timer.start();          this.queue_draw(); +        bool warp_pointer = PieManager.get_is_warp(this.renderer.id); +          // the main draw loop          GLib.Timeout.add((uint)(1000.0/Config.global.refresh_rate), () => {              if (this.closed)                  return false; +            if (warp_pointer) { +                warp_pointer = false; +                int x, y; +                this.get_center_pos(out x, out y); +                this.set_mouse_position(x, y); +            } +              this.queue_draw();              return this.visible;          }); @@ -194,12 +281,46 @@ public class PieWindow : Gtk.Window {      /////////////////////////////////////////////////////////////////////      public void get_center_pos(out int out_x, out int out_y) { -        int x=0, y=0, width=0, height=0; +        int x=0, y=0; //width=0, height=0;          this.get_position(out x, out y); -        this.get_size(out width, out height); +        out_x = x + renderer.center_x; +        out_y = y + renderer.center_y; +    } -        out_x = x + width/2; -        out_y = y + height/2; +    ///////////////////////////////////////////////////////////////////// +    /// Gets the absolute position of the mouse pointer. +    ///////////////////////////////////////////////////////////////////// + +    private void get_mouse_position(out int mx, out int my) { +        // get the mouse position +        mx = 0; +        my = 0; +        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(device, out mx, out my, out mask); +            } +        } +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Sets the absolute position of the mouse pointer. +    ///////////////////////////////////////////////////////////////////// + +    private void set_mouse_position(int mx, int my) { +        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) { +                device.warp(Gdk.Screen.get_default(), mx, my); +            } +        }      }      ///////////////////////////////////////////////////////////////////// @@ -213,35 +334,34 @@ public class PieWindow : Gtk.Window {              ctx.paint();              ctx.set_operator (Cairo.Operator.OVER);          } else { +            //correct the background position if the window was moved +            //since the background image was captured +            int x, y; +            this.get_position(out x, out y); +            int dx = this.back_x - x; +            int dy = this.back_y - y; +            ctx.save(); +            ctx.translate(dx, dy);              ctx.set_operator (Cairo.Operator.OVER);              ctx.set_source_surface(background.surface, -1, -1);              ctx.paint(); +            ctx.restore();          }          // align the context to the center of the PieWindow -        ctx.translate(this.width_request*0.5, this.height_request*0.5); +        ctx.translate(this.renderer.center_x, this.renderer.center_y);          // get the mouse position -        double mouse_x = 0.0, mouse_y = 0.0; -        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); -            } -        } +        int mouse_x, mouse_y; +        get_mouse_position( out mouse_x, out mouse_y );          // store the frame time          double frame_time = this.timer.elapsed();          this.timer.reset();          // render the Pie -        this.renderer.draw(frame_time, ctx, (int)(mouse_x - this.width_request*0.5), -                                            (int)(mouse_y - this.height_request*0.5)); +        this.renderer.draw(frame_time, ctx, mouse_x - (int)this.renderer.center_x, +                                            mouse_y - (int)this.renderer.center_y);          return true;      } @@ -309,11 +429,15 @@ public class PieWindow : Gtk.Window {      private void handle_key_press(uint key) {          if      (Gdk.keyval_name(key) == "Escape") this.cancel();          else if (Gdk.keyval_name(key) == "Return") this.activate_slice(); -        else if (!this.renderer.turbo_mode) { +        else if (!PieManager.get_is_turbo(this.renderer.id)) {              if (Gdk.keyval_name(key) == "Up") this.renderer.select_up();              else if (Gdk.keyval_name(key) == "Down") this.renderer.select_down();              else if (Gdk.keyval_name(key) == "Left") this.renderer.select_left();              else if (Gdk.keyval_name(key) == "Right") this.renderer.select_right(); +            else if (Gdk.keyval_name(key) == "Page_Down") this.renderer.select_nextpage(); +            else if (Gdk.keyval_name(key) == "Page_Up") this.renderer.select_prevpage(); +            else if (Gdk.keyval_name(key) == "Tab") this.renderer.select_nextpage(); +            else if (Gdk.keyval_name(key) == "ISO_Left_Tab") this.renderer.select_prevpage();              else if (Gdk.keyval_name(key) == "Alt_L") this.renderer.show_hotkeys = true;              else {                  int index = -1; @@ -342,7 +466,7 @@ public class PieWindow : Gtk.Window {      /////////////////////////////////////////////////////////////////////      private void handle_key_release(uint key) { -        if (!this.renderer.turbo_mode) { +        if (!PieManager.get_is_turbo(this.renderer.id)) {              if (Gdk.keyval_name(key) == "Alt_L") this.renderer.show_hotkeys = false;          }      } diff --git a/src/renderers/sliceRenderer.vala b/src/renderers/sliceRenderer.vala index 2ecf7c4..862e2a5 100644 --- a/src/renderers/sliceRenderer.vala +++ b/src/renderers/sliceRenderer.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; @@ -94,7 +94,14 @@ public class SliceRenderer : GLib.Object {      public SliceRenderer(PieRenderer parent) {          this.parent = parent; +        this.reset_anim(); +    } +    ///////////////////////////////////////////////////////////////////// +    /// Put all AnimatedValues in their initial values +    ///////////////////////////////////////////////////////////////////// + +    public void reset_anim() {          this.fade =   new AnimatedValue.linear(0.0, 0.0, Config.global.theme.transition_time);          this.wobble = new AnimatedValue.linear(0.0, 0.0, Config.global.theme.transition_time);          this.alpha =  new AnimatedValue.linear(0.0, 1.0, Config.global.theme.fade_in_time); @@ -147,7 +154,7 @@ public class SliceRenderer : GLib.Object {      }      ///////////////////////////////////////////////////////////////////// -    /// Activaes the Action of this slice. +    /// Activates the Action of this slice.      /////////////////////////////////////////////////////////////////////      public void activate() { @@ -189,7 +196,7 @@ public class SliceRenderer : GLib.Object {      /// Draws all layers of the slice.      ///////////////////////////////////////////////////////////////////// -    public void draw(double frame_time, Cairo.Context ctx, double angle, double distance) { +    public void draw(double frame_time, Cairo.Context ctx, double angle, int slice_track) {          // update the AnimatedValues          this.scale.update(frame_time); @@ -199,16 +206,23 @@ public class SliceRenderer : GLib.Object {          this.fade_rotation.update(frame_time);          this.wobble.update(frame_time); -	    double direction = 2.0 * PI * position/parent.slice_count() + this.fade_rotation.val; -	    double max_scale = 1.0/Config.global.theme.max_zoom; +        double direction = 2.0 * PI * (position-parent.first_slice_idx)/parent.total_slice_count +                            + parent.first_slice_angle + this.fade_rotation.val; +        double max_scale = 1.0/Config.global.theme.max_zoom;          double diff = fabs(angle-direction); -        if (diff > PI) -	        diff = 2 * PI - diff; +        if (diff > 2 * PI) { +            diff = diff - 2 * PI; +        } + +        if (diff > PI) { +            diff = 2 * PI - diff; +        } + -        active = ((parent.active_slice >= 0) && (diff < PI/parent.slice_count())); +        active = ((parent.active_slice >= 0) && (diff < PI/parent.total_slice_count)); -        if (parent.active_slice >= 0) { +        if (slice_track != 0) {              double wobble = Config.global.theme.wobble*diff/PI*(1-diff/PI);              if ((direction < angle && direction > angle - PI) || direction > PI+angle) {                  this.wobble.reset_target(-wobble, Config.global.theme.transition_time*0.5); @@ -228,7 +242,7 @@ public class SliceRenderer : GLib.Object { -        max_scale = (parent.active_slice >= 0 ? max_scale : 1.0/Config.global.theme.max_zoom); +        max_scale = (slice_track != 0 ? max_scale : 1.0/Config.global.theme.max_zoom);          if (fabs(this.scale.end - max_scale) > Config.global.theme.max_zoom*0.005)              this.scale.reset_target(max_scale, Config.global.theme.transition_time); @@ -240,9 +254,9 @@ public class SliceRenderer : GLib.Object {          // increase radius if there are many slices in a pie          if (atan((Config.global.theme.slice_radius+Config.global.theme.slice_gap) -          /(radius/Config.global.theme.max_zoom)) > PI/parent.slice_count()) { +          /(radius/Config.global.theme.max_zoom)) > PI/parent.total_slice_count) {              radius = (Config.global.theme.slice_radius+Config.global.theme.slice_gap) -                     /tan(PI/parent.slice_count())*Config.global.theme.max_zoom; +                     /tan(PI/parent.total_slice_count)*Config.global.theme.max_zoom;          }          // transform the context diff --git a/src/themes/centerLayer.vala b/src/themes/centerLayer.vala index 3469fd0..59f37ed 100644 --- a/src/themes/centerLayer.vala +++ b/src/themes/centerLayer.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This class representing a layer of the center of a pie. Each theme  /// may have plenty of them.  ///////////////////////////////////////////////////////////////////////// @@ -32,77 +32,77 @@ public class CenterLayer : GLib.Object {      /////////////////////////////////////////////////////////////////////      public enum RotationMode {AUTO, TO_MOUSE, TO_ACTIVE} -     +      /////////////////////////////////////////////////////////////////////      /// Information on the contained image.      ///////////////////////////////////////////////////////////////////// -     +      public Image image {get; private set;}      public string image_file; -     +      /////////////////////////////////////////////////////////////////////      /// Properties for the active state of this layer.      ///////////////////////////////////////////////////////////////////// -     +      public double active_scale {get; private set;}      public double active_rotation_speed {get; private set;}      public double active_alpha {get; private set;}      public bool active_colorize {get; private set;}      public RotationMode active_rotation_mode {get; private set;} -     +      /////////////////////////////////////////////////////////////////////      /// Properties for the inactive state of this layer.      ///////////////////////////////////////////////////////////////////// -     +      public double inactive_scale {get; private set;}      public double inactive_rotation_speed {get; private set;}      public double inactive_alpha {get; private set;}      public bool inactive_colorize {get; private set;}      public RotationMode inactive_rotation_mode {get; private set;} -     +      /////////////////////////////////////////////////////////////////////      /// The current rotation of this layer. TODO: Remove this.      ///////////////////////////////////////////////////////////////////// -     +      public double rotation {get; set;} -     +      /////////////////////////////////////////////////////////////////////      /// Helper variable for image loading.      ///////////////////////////////////////////////////////////////////// -     +      private int center_radius; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members of the layer.      ///////////////////////////////////////////////////////////////////// -     -    public CenterLayer(string image_file, int center_radius, double active_scale, double active_rotation_speed,    + +    public CenterLayer(string image_file, int center_radius, double active_scale, double active_rotation_speed,                                      double active_alpha,   bool active_colorize,   RotationMode active_rotation_mode, -                                    double inactive_scale, double inactive_rotation_speed,  +                                    double inactive_scale, double inactive_rotation_speed,                                      double inactive_alpha, bool inactive_colorize, RotationMode inactive_rotation_mode) { -         +          this.image_file = image_file;          this.center_radius = center_radius; -         +          this.active_scale = active_scale;          this.active_rotation_speed = active_rotation_speed;          this.active_alpha = active_alpha;          this.active_colorize = active_colorize;          this.active_rotation_mode = active_rotation_mode; -         +          this.inactive_scale = inactive_scale;          this.inactive_rotation_speed = inactive_rotation_speed;          this.inactive_alpha = inactive_alpha;          this.inactive_colorize = inactive_colorize;          this.inactive_rotation_mode = inactive_rotation_mode; -         +          this.rotation = 0.0;      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads the contained image.      ///////////////////////////////////////////////////////////////////// -     +      public void load_image() {          this.image = new Image.from_file_at_size(image_file, 2*center_radius, 2*center_radius);      } diff --git a/src/themes/sliceLayer.vala b/src/themes/sliceLayer.vala index 3c650c0..17ac3bb 100644 --- a/src/themes/sliceLayer.vala +++ b/src/themes/sliceLayer.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This class representing a layer of a slice of a pie. Each theme may  /// have plenty of them.  ///////////////////////////////////////////////////////////////////////// @@ -26,35 +26,35 @@ public class SliceLayer : GLib.Object {      public enum Type { FILE, ICON, CAPTION }      public enum Visibility { ANY, WITH_CAPTION, WITHOUT_CAPTION } -     +      public Type layer_type { get; private set; }      public Visibility visibility { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Information on the contained image.      ///////////////////////////////////////////////////////////////////// -     +      public Image image {get; set;} -     -     + +      /////////////////////////////////////////////////////////////////////      /// Properties of this layer.      ///////////////////////////////////////////////////////////////////// -     +      public string icon_file {get; private set; default="";}      public bool colorize {get; private set; default=false;}      public int icon_size {get; private set; default=1;} -     +      public string font {get; private set; default="";}      public int width {get; private set; default=0;}      public int height {get; private set; default=0;}      public int position {get; private set; default=0;}      public Color color {get; private set; default=new Color();} -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members of the layer.      ///////////////////////////////////////////////////////////////////// -     +      public SliceLayer.file(string icon_file, int icon_size, bool colorize, Visibility visibility) {          this.layer_type = Type.FILE;          this.icon_file = icon_file; @@ -62,7 +62,7 @@ public class SliceLayer : GLib.Object {          this.icon_size = icon_size;          this.visibility = visibility;      } -     +      public SliceLayer.icon(string icon_file, int icon_size, bool colorize, Visibility visibility) {          this.layer_type = Type.ICON;          this.icon_file = icon_file; @@ -70,7 +70,7 @@ public class SliceLayer : GLib.Object {          this.icon_size = icon_size;          this.visibility = visibility;      } -     +      public SliceLayer.caption(string font, int width, int height, int position, Color color, bool colorize, Visibility visibility) {          this.layer_type = Type.CAPTION;          this.font = font; @@ -81,15 +81,15 @@ public class SliceLayer : GLib.Object {          this.visibility = visibility;          this.colorize = colorize;      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads the contained image.      ///////////////////////////////////////////////////////////////////// -     +      public void load_image() {          this.image = null; -     -        if (this.icon_file == "" && this.layer_type == Type.ICON)  + +        if (this.icon_file == "" && this.layer_type == Type.ICON)              this.image = new Image.empty(this.icon_size, this.icon_size, new Color.from_rgb(1, 1, 1));          else if (this.icon_file != "")              this.image = new Image.from_file_at_size(this.icon_file, this.icon_size, this.icon_size); diff --git a/src/themes/theme.vala b/src/themes/theme.vala index 1956046..e068b9e 100644 --- a/src/themes/theme.vala +++ b/src/themes/theme.vala @@ -1,34 +1,34 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http:www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math;  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A theme of Gnome-Pie. Can be loaded from XML-Files.  /////////////////////////////////////////////////////////////////////////  public class Theme : GLib.Object { -     +      /////////////////////////////////////////////////////////////////////      /// Properties of a theme.      ///////////////////////////////////////////////////////////////////// -     +      public string directory        {get; private set; default="";}      public string name             {get; private set; default="";}      public string description      {get; private set; default="";} @@ -49,6 +49,7 @@ public class Theme : GLib.Object {      public double center_radius    {get; private set; default=90.0;}      public double active_radius    {get; private set; default=45.0;}      public double slice_radius     {get; private set; default=32.0;} +    public double visible_slice_radius {get; private set; default=0.0;}      public double slice_gap        {get; private set; default=14.0;}      public bool   has_slice_captions {get; private set; default=false;}      public bool   caption          {get; private set; default=false;} @@ -58,39 +59,39 @@ public class Theme : GLib.Object {      public double caption_position {get; private set; default=0.0;}      public Color  caption_color    {get; private set; default=new Color();}      public Icon   preview_icon     {get; private set; default=new Icon("gnome-pie", 36);} -     +      public Gee.ArrayList<CenterLayer?> center_layers         {get; private set;}      public Gee.ArrayList<SliceLayer?>  active_slice_layers   {get; private set;}      public Gee.ArrayList<SliceLayer?>  inactive_slice_layers {get; private set;} -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a theme object for a given theme directory. This      /// directory should contain a theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      public Theme(string dir) {          this.center_layers =         new Gee.ArrayList<CenterLayer?>();          this.active_slice_layers =   new Gee.ArrayList<SliceLayer?>();          this.inactive_slice_layers = new Gee.ArrayList<SliceLayer?>(); -         +          this.directory = dir;      } -     +      ///////////////////////////////////////////////////////////////////// -    /// Loads the theme from its directory. Images have to be loaded  +    /// Loads the theme from its directory. Images have to be loaded      /// explicitly.      ///////////////////////////////////////////////////////////////////// -     +      public bool load() {          this.center_layers.clear();          this.active_slice_layers.clear();          this.inactive_slice_layers.clear(); -         +          this.preview_icon = new Icon(this.directory + "/preview.png", 36); -     +          Xml.Parser.init();          string path = this.directory + "/theme.xml"; -         +          Xml.Doc* themeXML = Xml.Parser.parse_file(path);          if (themeXML == null) {              warning("Failed to add theme: \"" + path + "\" not found!"); @@ -103,21 +104,21 @@ public class Theme : GLib.Object {              warning("Failed to add theme: \"theme.xml\" is empty!");              return false;          } -         +          this.parse_root(root); -         +          delete themeXML;          Xml.Parser.cleanup(); -         +          this.radius *= max_zoom; -         +          return true;      } -     +      /////////////////////////////////////////////////////////////////////      /// Loads all images of the theme.      ///////////////////////////////////////////////////////////////////// -     +      public void load_images() {          foreach (var layer in this.center_layers)              layer.load_image(); @@ -126,17 +127,17 @@ public class Theme : GLib.Object {          foreach (var layer in this.inactive_slice_layers)              layer.load_image();      } -     +      /////////////////////////////////////////////////////////////////////      /// The following methods parse specific parts of the theme file.      /// Nothing special here, just some boring code.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_root(Xml.Node* root) {          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 "name":                      name = attr_content; @@ -161,16 +162,16 @@ public class Theme : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <pie> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_pie(Xml.Node* pie) {          for (Xml.Attr* attribute = pie->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                  case "radius":                      radius = double.parse(attr_content) * Config.global.global_scale; @@ -234,16 +235,16 @@ public class Theme : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <center> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_center(Xml.Node* center) {          for (Xml.Attr* attribute = center->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                  case "radius":                      center_radius = double.parse(attr_content) * Config.global.global_scale; @@ -259,7 +260,7 @@ public class Theme : GLib.Object {          for (Xml.Node* node = center->children; node != null; node = node->next) {              if (node->type == Xml.ElementType.ELEMENT_NODE) {                  string element_name = node->name.down(); -                 +                  if (element_name == "center_layer") {                      parse_center_layer(node);                  } else { @@ -268,19 +269,20 @@ public class Theme : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <slices> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_slices(Xml.Node* slices) {          for (Xml.Attr* attribute = slices->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                   case "radius":                      slice_radius = double.parse(attr_content) * Config.global.global_scale; +                    visible_slice_radius = double.parse(attr_content) * Config.global.global_scale;                      break;                  case "mingap":                      slice_gap = double.parse(attr_content) * Config.global.global_scale; @@ -293,7 +295,7 @@ public class Theme : GLib.Object {          for (Xml.Node* node = slices->children; node != null; node = node->next) {              if (node->type == Xml.ElementType.ELEMENT_NODE) {                  string element_name = node->name.down(); -                 +                  if (element_name == "activeslice" || element_name == "inactiveslice") {                      parse_slice_layers(node);                  } else { @@ -302,11 +304,11 @@ public class Theme : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <center_layer> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_center_layer(Xml.Node* layer) {          string file = ""; @@ -320,11 +322,11 @@ public class Theme : GLib.Object {          bool   inactive_colorize = false;          CenterLayer.RotationMode active_rotation_mode = CenterLayer.RotationMode.AUTO;          CenterLayer.RotationMode inactive_rotation_mode = CenterLayer.RotationMode.AUTO; -         +          for (Xml.Attr* attribute = layer->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                  case "file":                      file = attr_content; @@ -342,10 +344,10 @@ public class Theme : GLib.Object {                             break;                          case "turn_to_active":                             active_rotation_mode = CenterLayer.RotationMode.TO_ACTIVE; -                           break;  +                           break;                          case "turn_to_mouse":                             active_rotation_mode = CenterLayer.RotationMode.TO_MOUSE; -                           break;  +                           break;                          default:                             warning("Invalid value \"" + attr_content + "\" for attribute \"" + attr_name + "\" in <center_layer> element!");                             break; @@ -370,10 +372,10 @@ public class Theme : GLib.Object {                             break;                          case "turn_to_active":                             inactive_rotation_mode = CenterLayer.RotationMode.TO_ACTIVE; -                           break;  +                           break;                          case "turn_to_mouse":                             inactive_rotation_mode = CenterLayer.RotationMode.TO_MOUSE; -                           break;  +                           break;                          default:                             warning("Invalid value \"" + attr_content + "\" for attribute \"" + attr_name + "\" in <center_layer> element!");                             break; @@ -392,19 +394,19 @@ public class Theme : GLib.Object {          }          double max_scale = GLib.Math.fmax(active_scale, inactive_scale); -        center_layers.add(new CenterLayer(directory + "/" + file, (int)(center_radius*max_scale), active_scale/max_scale,   active_rotation_speed,   active_alpha,   active_colorize,   active_rotation_mode,  +        center_layers.add(new CenterLayer(directory + "/" + file, (int)(center_radius*max_scale), active_scale/max_scale,   active_rotation_speed,   active_alpha,   active_colorize,   active_rotation_mode,                                                   inactive_scale/max_scale, inactive_rotation_speed, inactive_alpha, inactive_colorize, inactive_rotation_mode));      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <slice_layer> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_slice_layers(Xml.Node* slice) {          for (Xml.Node* layer = slice->children; layer != null; layer = layer->next) {              if (layer->type == Xml.ElementType.ELEMENT_NODE) {                  string element_name = layer->name.down(); -                 +                  if (element_name == "slice_layer") {                      string file = "";                      double scale = 1.0; @@ -417,11 +419,11 @@ public class Theme : GLib.Object {                      int pos_x = 0;                      int pos_y = 0;                      Color slice_caption_color = new Color.from_rgb(1.0f, 1.0f, 1.0f); -                     +                      for (Xml.Attr* attribute = layer->properties; attribute != null; attribute = attribute->next) {                          string attr_name = attribute->name.down();                          string attr_content = attribute->children->content; -                         +                          switch (attr_name) {                              case "file":                                  file = attr_content; @@ -476,11 +478,12 @@ public class Theme : GLib.Object {                                  break;                          }                      } -                     +                      if (file != "")                          file = directory + "/" + file; -                     +                      int size = 2*(int)(slice_radius*scale*max_zoom); +                    this.visible_slice_radius = Math.fmax(slice_radius*scale, this.visible_slice_radius);                      if (slice->name.down() == "activeslice") {                          if (type == SliceLayer.Type.ICON)         active_slice_layers.add(new SliceLayer.icon(file, size, colorize, visibility)); @@ -502,16 +505,16 @@ public class Theme : GLib.Object {              }          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a <caption> element from the theme.xml file.      ///////////////////////////////////////////////////////////////////// -     +      private void parse_caption(Xml.Node* caption) {          for (Xml.Attr* attribute = caption->properties; attribute != null; attribute = attribute->next) {              string attr_name = attribute->name.down();              string attr_content = attribute->children->content; -             +              switch (attr_name) {                  case "font":                      caption_font = attr_content; diff --git a/src/utilities/animatedValue.vala b/src/utilities/animatedValue.vala index 7acc7a7..79be155 100644 --- a/src/utilities/animatedValue.vala +++ b/src/utilities/animatedValue.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////// -namespace GnomePie {	 +namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// A class which interpolates smoothly between to given values.  /// Duration and interpolation mode can be specified.  ///////////////////////////////////////////////////////////////////////// @@ -29,77 +29,77 @@ public class AnimatedValue : GLib.Object {      /////////////////////////////////////////////////////////////////////      public enum Direction { IN, OUT, IN_OUT, OUT_IN } -     +      /////////////////////////////////////////////////////////////////////      /// Type of the interpolation, linear or cubic.      ///////////////////////////////////////////////////////////////////// -     +      private enum Type { LINEAR, CUBIC } -     +      /////////////////////////////////////////////////////////////////////      /// Current value, interpolated.      ///////////////////////////////////////////////////////////////////// -     +      public double val { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Starting value of the interpolation.      ///////////////////////////////////////////////////////////////////// -     +      public double start { get; private set; default=0.0; } -     +      /////////////////////////////////////////////////////////////////////      /// Final value of the interpolation.      ///////////////////////////////////////////////////////////////////// -     -    public double end { get; private set; default=0.0; }  -     + +    public double end { get; private set; default=0.0; } +      /////////////////////////////////////////////////////////////////////      /// The current state. In range 0 .. 1      ///////////////////////////////////////////////////////////////////// -     +      private double state = 0.0; -     +      ///////////////////////////////////////////////////////////////////// -    /// Duration of the interpolation. Should be in the same unit as  +    /// Duration of the interpolation. Should be in the same unit as      /// taken for the update() method.      ///////////////////////////////////////////////////////////////////// -     +      private double duration = 0.0; -     +      /////////////////////////////////////////////////////////////////////      /// The amount of over-shooting of the cubicly interpolated value.      ///////////////////////////////////////////////////////////////////// -     +      private double multiplier = 0.0; -     +      /////////////////////////////////////////////////////////////////////      /// Type of the interpolation, linear or cubic.      ///////////////////////////////////////////////////////////////////// -     +      private Type type = Type.LINEAR; -     +      /////////////////////////////////////////////////////////////////////      /// The direction of the interpolation.      ///////////////////////////////////////////////////////////////////// -     +      private Direction direction = Direction.IN; -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new linearly interpolated value.      ///////////////////////////////////////////////////////////////////// -     +      public AnimatedValue.linear(double start, double end, double duration) {          this.val = start;          this.start = start;          this.end = end;          this.duration = duration;      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates a new cubicly interpolated value.      ///////////////////////////////////////////////////////////////////// -     +      public AnimatedValue.cubic(Direction direction, double start, double end, double duration, double multiplier = 0) {          this.val = start;          this.start = start; @@ -109,17 +109,17 @@ public class AnimatedValue : GLib.Object {          this.type = Type.CUBIC;          this.multiplier = multiplier;      } -     +      /////////////////////////////////////////////////////////////////////      /// Resets the final value of the interpolation to a new value. The      /// current state is taken for the beginning from now.      ///////////////////////////////////////////////////////////////////// -     +      public void reset_target(double end, double duration) {          this.end = end;          this.duration = duration;          this.start = this.val; -         +          if (duration == 0.0) {              this.val = end;              this.state = 1.0; @@ -127,16 +127,16 @@ public class AnimatedValue : GLib.Object {              this.state = 0.0;          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Updates the interpolated value according to it's type.      ///////////////////////////////////////////////////////////////////// -     +      public void update(double time) {          this.state += time/this.duration; -         +          if (this.state < 1) { -         +              switch (this.type) {                  case Type.LINEAR:                      this.val = update_linear(); @@ -158,36 +158,36 @@ public class AnimatedValue : GLib.Object {                  }                  break;              } -             +          } else if (this.val != this.end) {               this.val = this.end; -        }   +        }      }      ///////////////////////////////////////////////////////////////////// -    /// The following equations are based on Robert Penner's easing  -    /// equations. See (http://www.robertpenner.com/easing/) and their  +    /// The following equations are based on Robert Penner's easing +    /// equations. See (http://www.robertpenner.com/easing/) and their      /// adaption by Zeh Fernando, Nate Chatellier and Arthur Debert for      /// the Tweener class. See (http://code.google.com/p/tweener/).      ///////////////////////////////////////////////////////////////////// -     +      private double update_linear(double t = this.state, double s = this.start, double e = this.end) {          return (s + t*(e - s));      } -     +      private double update_ease_in(double t = this.state, double s = this.start, double e = this.end) {          return (s + (t*t*((multiplier+1)*t-multiplier))*(e - s));      } -     +      private double update_ease_out(double t = this.state, double s = this.start, double e = this.end) {          return (s + ((t-1) * (t-1) * ((multiplier+1)*(t-1)+multiplier) + 1) * (e - s));      } -     +      private double update_ease_in_out(double t = this.state, double s = this.start, double e = this.end) {          if (this.state < 0.5) return update_ease_in(t*2, s, e - (e-s)*0.5);          else                  return update_ease_out(t*2-1, s + (e-s)*0.5, e);      } -     +      private double update_ease_out_in(double t = this.state, double s = this.start, double e = this.end) {          if (this.state < 0.5) return update_ease_out(t*2, s, e - (e-s)*0.5);          else                  return update_ease_in(t*2-1, s + (e-s)*0.5, e); diff --git a/src/utilities/bindingManager.vala b/src/utilities/bindingManager.vala index 0c74ece..e90fa74 100644 --- a/src/utilities/bindingManager.vala +++ b/src/utilities/bindingManager.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -98,7 +98,7 @@ public class BindingManager : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void bind(Trigger trigger, string id) { -        if(trigger.key_code != 0) { +        if (trigger.key_code != 0) {              X.Display display = Gdk.X11.get_default_xdisplay();              X.ID xid = Gdk.X11.get_default_root_xwindow(); @@ -116,10 +116,13 @@ public class BindingManager : GLib.Object {              }              Gdk.flush(); -              Keybinding binding = new Keybinding(trigger, id);              bindings.add(binding);              display.flush(); +        } else { +            //no key_code: just add the bindind to the list to save optional trigger parameters +            Keybinding binding = new Keybinding(trigger, id); +            bindings.add(binding);          }      } @@ -128,6 +131,17 @@ public class BindingManager : GLib.Object {      /////////////////////////////////////////////////////////////////////      public void unbind(string id) { +        foreach (var binding in bindings) { +            if (id == binding.id) { +                if (binding.trigger.key_code == 0) { +                    //no key_code: just remove the bindind from the list +                    bindings.remove(binding); +                    return; +                } +                break; +            } +        } +          X.Display display = Gdk.X11.get_default_xdisplay();          X.ID xid = Gdk.X11.get_default_root_xwindow(); @@ -206,14 +220,59 @@ public class BindingManager : GLib.Object {      }      ///////////////////////////////////////////////////////////////////// +    /// Returns whether the pie with the given ID is in warp mode. +    ///////////////////////////////////////////////////////////////////// + +    public bool get_is_warp(string id) { +        foreach (var binding in bindings) { +            if (binding.id == id) { +                return binding.trigger.warp; +            } +        } + +        return false; +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns whether the pie with the given ID is auto shaped +    ///////////////////////////////////////////////////////////////////// + +    public bool get_is_auto_shape(string id) { +        foreach (var binding in bindings) { +            if (binding.id == id) { +                return (binding.trigger.shape == 0); +            } +        } + +        return false; +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns the prefered pie shape number +    ///////////////////////////////////////////////////////////////////// + +    public int get_shape_number(string id) { +        foreach (var binding in bindings) { +            if (binding.id == id) { +                if (binding.trigger.shape == 0) +                    break;  //return default if auto-shaped +                return binding.trigger.shape; //use selected shape +            } +        } + +        return 5;   //default= full pie +    } + + +    /////////////////////////////////////////////////////////////////////      /// Returns the name ID of the Pie bound to the given Trigger.      /// Returns "" if there is nothing bound to this trigger.      /////////////////////////////////////////////////////////////////////      public string get_assigned_id(Trigger trigger) {          foreach (var binding in bindings) { -            var first = binding.trigger.name.replace("[turbo]", "").replace("[delayed]", ""); -            var second = trigger.name.replace("[turbo]", "").replace("[delayed]", ""); +            var first = Trigger.remove_optional(binding.trigger.name); +            var second = Trigger.remove_optional(trigger.name);              if (first == second) {                  return binding.id;              } @@ -276,48 +335,52 @@ public class BindingManager : GLib.Object {      /////////////////////////////////////////////////////////////////////      private void activate_delayed(Keybinding? binding , X.Event event) { -    	// increase event count, so any waiting event will realize that -    	// something happened in the meantime +        // increase event count, so any waiting event will realize that +        // something happened in the meantime          var current_count = ++this.delayed_count;          if (binding == null && this.delayed_event != null) { -        	// if the trigger is released and an event is currently waiting -		    // simulate that the trigger has been pressed without any inter- -		    // ference of Gnome-Pie -       		X.Display display = Gdk.X11.get_default_xdisplay(); +            // if the trigger is released and an event is currently waiting +            // simulate that the trigger has been pressed without any inter- +            // ference of Gnome-Pie +               X.Display display = Gdk.X11.get_default_xdisplay(); -       		// unbind the trigger, else we'll capture that event again ;) -       		unbind(delayed_binding.id); +               // unbind the trigger, else we'll capture that event again ;) +               unbind(delayed_binding.id); -       		if (this.delayed_binding.trigger.with_mouse) { -       			// simulate mouse click -       			X.Test.fake_button_event(display, this.delayed_event.xbutton.button, true, 0); -       			display.flush(); +               if (this.delayed_binding.trigger.with_mouse) { +                   // simulate mouse click +                   X.Test.fake_button_event(display, this.delayed_event.xbutton.button, true, 0); +                   display.flush(); -            	X.Test.fake_button_event(display, this.delayed_event.xbutton.button, false, 0); -            	display.flush(); +                X.Test.fake_button_event(display, this.delayed_event.xbutton.button, false, 0); +                display.flush(); -       		} else { -       			// simulate key press -       			X.Test.fake_key_event(display, this.delayed_event.xkey.keycode, true, 0); -       			display.flush(); +               } else { +                   // simulate key press +                   X.Test.fake_key_event(display, this.delayed_event.xkey.keycode, true, 0); +                   display.flush(); -       			X.Test.fake_key_event(display, this.delayed_event.xkey.keycode, false, 0); -       			display.flush(); -       		} +                   X.Test.fake_key_event(display, this.delayed_event.xkey.keycode, false, 0); +                   display.flush(); +               }              // bind it again              bind(delayed_binding.trigger, delayed_binding.id); + +            this.delayed_binding = null; +            this.delayed_event = null; +          } else if (binding != null) { -        	// if the trigger has been pressed, store it and wait for any interuption -        	// within the next 300 milliseconds +            // if the trigger has been pressed, store it and wait for any interuption +            // within the next 300 milliseconds              this.delayed_event = event;              this.delayed_binding = binding;              Timeout.add(300, () => { -            	// if nothing has been pressed in the meantime +                // if nothing has been pressed in the meantime                  if (current_count == this.delayed_count) { -                	this.delayed_binding = null; +                    this.delayed_binding = null;                      this.delayed_event = null;                      on_press(binding.id);                  } diff --git a/src/utilities/color.vala b/src/utilities/color.vala index bf60e3f..6bb9d06 100644 --- a/src/utilities/color.vala +++ b/src/utilities/color.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  using GLib.Math; @@ -258,10 +258,10 @@ public class Color: GLib.Object {      private void setHSV(float hue, float saturation, float val) {          if(saturation == 0) { -	        r = val; -	        g = val; -	        b = val; -	        return; +            r = val; +            g = val; +            b = val; +            return;          }          hue = fmodf(hue, 360);          hue /= 60; @@ -269,36 +269,36 @@ public class Color: GLib.Object {          float f = hue - i;          switch(i) { -	        case 0: -		        r = val; -		        g = val * (1.0f - saturation * (1.0f - f)); -		        b = val * (1.0f - saturation); -		        break; -	        case 1: -		        r = val * (1.0f - saturation * f); -		        g = val; -		        b = val * (1.0f - saturation); -		        break; -	        case 2: -		        r = val * (1.0f - saturation); -		        g = val; -		        b = val * (1.0f - saturation * (1.0f - f)); -		        break; -	        case 3: -		        r = val * (1.0f - saturation); -		        g = val * (1.0f - saturation * f); -		        b = val; -		        break; -	        case 4: -		        r = val * (1.0f - saturation * (1.0f - f)); -		        g = val * (1.0f - saturation); -		        b = val; -		        break; -	        default: -		        r = val; -		        g = val * (1.0f - saturation); -		        b = val * (1.0f - saturation * f); -		        break; +            case 0: +                r = val; +                g = val * (1.0f - saturation * (1.0f - f)); +                b = val * (1.0f - saturation); +                break; +            case 1: +                r = val * (1.0f - saturation * f); +                g = val; +                b = val * (1.0f - saturation); +                break; +            case 2: +                r = val * (1.0f - saturation); +                g = val; +                b = val * (1.0f - saturation * (1.0f - f)); +                break; +            case 3: +                r = val * (1.0f - saturation); +                g = val * (1.0f - saturation * f); +                b = val; +                break; +            case 4: +                r = val * (1.0f - saturation * (1.0f - f)); +                g = val * (1.0f - saturation); +                b = val; +                break; +            default: +                r = val; +                g = val * (1.0f - saturation); +                b = val * (1.0f - saturation * f); +                break;          }      }  } diff --git a/src/utilities/config.vala b/src/utilities/config.vala index 2ec2788..abb8b23 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { @@ -54,7 +54,8 @@ 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 int  activation_range { get; set; default = 200; } +    public int  max_visible_slices { get; set; default = 24; }      public bool show_indicator { get; set; default = true; }      public bool show_captions { get; set; default = true; }      public bool auto_start { get; set; default = false; } @@ -73,6 +74,7 @@ public class Config : GLib.Object {                  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("max_visible_slices", max_visible_slices.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()); @@ -117,7 +119,11 @@ public class Config : GLib.Object {                              break;                          case "activation_range":                              activation_range = int.parse(attr_content); -                            activation_range.clamp(100, 2000); +                            activation_range.clamp(0, 2000); +                            break; +                        case "max_visible_slices": +                            max_visible_slices = int.parse(attr_content); +                            max_visible_slices.clamp(10, 2000);                              break;                          case "show_indicator":                              show_indicator = bool.parse(attr_content); @@ -166,10 +172,10 @@ public class Config : GLib.Object {              // load global themes              var d = Dir.open(Paths.global_themes);              while ((name = d.read_name()) != null) { -	            var theme = new Theme(Paths.global_themes + "/" + name); +                var theme = new Theme(Paths.global_themes + "/" + name); -	            if (theme.load()) -	            	themes.add(theme); +                if (theme.load()) +                    themes.add(theme);              }              // load local themes diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala index b551def..baa5fed 100644 --- a/src/utilities/focusGrabber.vala +++ b/src/utilities/focusGrabber.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/utilities/key.vala b/src/utilities/key.vala index af6e86a..7cf425f 100644 --- a/src/utilities/key.vala +++ b/src/utilities/key.vala @@ -1,24 +1,24 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     -/// A class which represents a key stroke. It can be used to "press"  +///////////////////////////////////////////////////////////////////////// +/// A class which represents a key stroke. It can be used to "press"  /// the associated keys.  ///////////////////////////////////////////////////////////////////////// @@ -26,7 +26,7 @@ public class Key : GLib.Object {      /////////////////////////////////////////////////////////////////////      /// Some static members, which are often used by this class. -    /////////////////////////////////////////////////////////////////////     +    /////////////////////////////////////////////////////////////////////      private static X.Display display; @@ -40,62 +40,62 @@ public class Key : GLib.Object {      /////////////////////////////////////////////////////////////////////      public string label { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// The accelerator of the Key.      ///////////////////////////////////////////////////////////////////// -     +      public string accelerator { get; private set; } -     +      /////////////////////////////////////////////////////////////////////      /// Keycode and modifiers of this stroke.      ///////////////////////////////////////////////////////////////////// -     +      private int key_code;      private Gdk.ModifierType modifiers; -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members to defaults.      ///////////////////////////////////////////////////////////////////// -     +      public Key() {          this.accelerator = "";          this.modifiers = 0;          this.key_code = 0;          this.label = _("Not bound");      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public Key.from_string(string stroke) {          this.accelerator = stroke; -         +          uint keysym;          Gtk.accelerator_parse(stroke, out keysym, out this.modifiers);          this.key_code = display.keysym_to_keycode(keysym);          this.label = Gtk.accelerator_get_label(keysym, this.modifiers);      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, initializes all members.      ///////////////////////////////////////////////////////////////////// -     +      public Key.from_values(uint keysym, Gdk.ModifierType modifiers) {          this.accelerator = Gtk.accelerator_name(keysym, modifiers);          this.label = Gtk.accelerator_get_label(keysym, modifiers);          this.key_code = display.keysym_to_keycode(keysym);          this.modifiers = modifiers;      } -     +      /////////////////////////////////////////////////////////////////////      /// Initializes static members.      ///////////////////////////////////////////////////////////////////// -     +      static construct {          display = new X.Display(); -     +          shift_code = display.keysym_to_keycode(Gdk.keyval_from_name("Shift_L"));          ctrl_code =  display.keysym_to_keycode(Gdk.keyval_from_name("Control_L"));          alt_code =   display.keysym_to_keycode(Gdk.keyval_from_name("Alt_L")); @@ -113,7 +113,7 @@ public class Key : GLib.Object {          // release them and press the desired ones          press_modifiers(current_modifiers, false);          press_modifiers(this.modifiers, true); -         +          // send events to X          display.flush(); @@ -128,28 +128,28 @@ public class Key : GLib.Object {          // send events to X          display.flush();      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method returning currently hold down modifier keys.      ///////////////////////////////////////////////////////////////////// -     +      private Gdk.ModifierType get_modifiers() {          Gdk.ModifierType modifiers;          Gtk.get_current_event_state(out modifiers);          return modifiers;      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method which 'presses' the desired modifier keys.      ///////////////////////////////////////////////////////////////////// -     +      private void press_modifiers(Gdk.ModifierType modifiers, bool down) {          if ((modifiers & Gdk.ModifierType.CONTROL_MASK) > 0)              X.Test.fake_key_event(display, ctrl_code, down, 0);          if ((modifiers & Gdk.ModifierType.SHIFT_MASK) > 0)              X.Test.fake_key_event(display, shift_code, down, 0); -             +          if ((modifiers & Gdk.ModifierType.MOD1_MASK) > 0)              X.Test.fake_key_event(display, alt_code, down, 0); diff --git a/src/utilities/logger.vala b/src/utilities/logger.vala index 69310fc..7c66615 100644 --- a/src/utilities/logger.vala +++ b/src/utilities/logger.vala @@ -1,26 +1,26 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////   +/////////////////////////////////////////////////////////////////////////  /// A static class which beautifies the messages of the default logger. -/// Some of this code is inspired by plank's written by Robert Dyer.  -/// Thanks a lot for this project!  +/// Some of this code is inspired by plank's written by Robert Dyer. +/// Thanks a lot for this project!  /////////////////////////////////////////////////////////////////////////  public class Logger { @@ -28,53 +28,53 @@ public class Logger {      /////////////////////////////////////////////////////////////////////      /// If these are set to false, the according messages are not shown      ///////////////////////////////////////////////////////////////////// -     -    private static const bool display_debug = true;  -    private static const bool display_warning = true;  -    private static const bool display_error = true;  -    private static const bool display_message = true;  -     + +    private static const bool display_debug = true; +    private static const bool display_warning = true; +    private static const bool display_error = true; +    private static const bool display_message = true; +      /////////////////////////////////////////////////////////////////////      /// If these are set to false, the according messages are not logged      ///////////////////////////////////////////////////////////////////// -     -    private static const bool log_debug = false;  -    private static const bool log_warning = true;  -    private static const bool log_error = true;  -    private static const bool log_message = true;  -     + +    private static const bool log_debug = false; +    private static const bool log_warning = true; +    private static const bool log_error = true; +    private static const bool log_message = true; +      /////////////////////////////////////////////////////////////////////      /// If true, a time stamp is shown in each message.      ///////////////////////////////////////////////////////////////////// -     -    private static const bool display_time = false;  -    private static const bool log_time = true;  -     + +    private static const bool display_time = false; +    private static const bool log_time = true; +      /////////////////////////////////////////////////////////////////////      /// If true, the origin of the message is shown. In form file:line      ///////////////////////////////////////////////////////////////////// -     -    private static const bool display_file = false;  -    private static const bool log_file = false;  -     + +    private static const bool display_file = false; +    private static const bool log_file = false; +      /////////////////////////////////////////////////////////////////////      /// A regex, used to format the standard message.      ///////////////////////////////////////////////////////////////////// -     +      private static Regex regex = null; -     +      /////////////////////////////////////////////////////////////////////      /// Limit log and statistics size to roughly 1 MB.      ///////////////////////////////////////////////////////////////////// -     +      private static const int max_log_length = 1000000; -     +      private static int log_length; -     +      /////////////////////////////////////////////////////////////////////      /// Possible terminal colors.      ///////////////////////////////////////////////////////////////////// -     +      private enum Color {          BLACK,          RED, @@ -85,186 +85,186 @@ public class Logger {          TURQUOISE,          WHITE      } -     +      /////////////////////////////////////////////////////////////////////      /// Creates the regex and binds the handler.      ///////////////////////////////////////////////////////////////////// -     +      public static void init() {          log_length = -1; -     +          try { -			regex = new Regex("""(.*)\.vala(:\d+): (.*)"""); -		} catch {} -		 +            regex = new Regex("""(.*)\.vala(:\d+): (.*)"""); +        } catch {} +          GLib.Log.set_handler(null, GLib.LogLevelFlags.LEVEL_MASK, log_func);      } -     +      /////////////////////////////////////////////////////////////////////      /// Appends a line to the log file      ///////////////////////////////////////////////////////////////////// -     +      private static void write_log_line(string line) {          var log = GLib.FileStream.open(Paths.log, "a"); -             +          if (log != null) { -            if (log_length == -1)  +            if (log_length == -1)                  log_length = (int)log.tell(); -                 +              log.puts(line);              log_length += line.length;          } -         +          if (log_length > max_log_length) {              string content = ""; -             +              try {                  GLib.FileUtils.get_contents(Paths.log, out content); -                int split_index = content.index_of_char('\n', log_length - (int)(max_log_length*0.9));                 +                int split_index = content.index_of_char('\n', log_length - (int)(max_log_length*0.9));                  GLib.FileUtils.set_contents(Paths.log, content.substring(split_index+1)); -                 +                  log_length -= (split_index+1);              } catch (GLib.FileError e) {}          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays a message.      ///////////////////////////////////////////////////////////////////// -     +      private static void message(string message, string message_log) {          if (display_message) {              stdout.printf(set_color(Color.GREEN, false) + "[" + (display_time ? get_time() + " " : "") + "MESSAGE]" + message);          } -         +          if (log_message) {              write_log_line("[" + (log_time ? get_time() + " " : "") + "MESSAGE]" + message_log);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays a Debug message.      ///////////////////////////////////////////////////////////////////// -     +      private static void debug(string message, string message_log) {          if (display_debug) {              stdout.printf(set_color(Color.BLUE, false) + "[" + (display_time ? get_time() + " " : "") + " DEBUG ]" + message);          } -         +          if (log_debug) {              write_log_line("[" + (log_time ? get_time() + " " : "") + " DEBUG ]" + message_log);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays a Warning message.      ///////////////////////////////////////////////////////////////////// -     +      private static void warning(string message, string message_log) {          if (display_warning) {              stdout.printf(set_color(Color.YELLOW, false) + "[" + (display_time ? get_time() + " " : "") + "WARNING]" + message);          } -         +          if (log_warning) {              write_log_line("[" + (log_time ? get_time() + " " : "") + "WARNING]" + message_log);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Displays a Error message.      ///////////////////////////////////////////////////////////////////// -     +      private static void error(string message, string message_log) {          if (display_error) {              stdout.printf(set_color(Color.RED, false) + "[" + (display_time ? get_time() + " " : "") + " ERROR ]" + message);          } -         +          if (log_error) {              write_log_line("[" + (log_time ? get_time() + " " : "") + " ERROR ]" + message_log);          }      } -     +      /////////////////////////////////////////////////////////////////////      /// Helper method which resets the terminal color.      ///////////////////////////////////////////////////////////////////// -     +      private static string reset_color() { -		return "\x001b[0m"; -	} -	 -	///////////////////////////////////////////////////////////////////// -	/// Helper method which sets the terminal color. -	///////////////////////////////////////////////////////////////////// -	 -	private static string set_color(Color color, bool bold) { -	    if (bold) return "\x001b[1;%dm".printf((int)color + 30); -	    else      return "\x001b[0;%dm".printf((int)color + 30); -	} -	 -	///////////////////////////////////////////////////////////////////// -	/// Returns the current time in hh:mm:ss:mmmmmm -	///////////////////////////////////////////////////////////////////// -	 -	private static string get_time() { +        return "\x001b[0m"; +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Helper method which sets the terminal color. +    ///////////////////////////////////////////////////////////////////// + +    private static string set_color(Color color, bool bold) { +        if (bold) return "\x001b[1;%dm".printf((int)color + 30); +        else      return "\x001b[0;%dm".printf((int)color + 30); +    } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns the current time in hh:mm:ss:mmmmmm +    ///////////////////////////////////////////////////////////////////// + +    private static string get_time() {          var now = new DateTime.now_local(); -	    return "%.4d:%.2d:%.2d:%.2d:%.2d:%.2d:%.6d".printf(now.get_year(), now.get_month(), now.get_day_of_month(), now.get_hour(), now.get_minute(), now.get_second(), now.get_microsecond()); -	} -	 -	///////////////////////////////////////////////////////////////////// +        return "%.4d:%.2d:%.2d:%.2d:%.2d:%.2d:%.6d".printf(now.get_year(), now.get_month(), now.get_day_of_month(), now.get_hour(), now.get_minute(), now.get_second(), now.get_microsecond()); +    } + +    /////////////////////////////////////////////////////////////////////      /// Helper method to format the message.      ///////////////////////////////////////////////////////////////////// -	 -	private static string create_message(string message) { -	    if (display_file && regex != null && regex.match(message)) { -			var parts = regex.split(message); -			return " [%s%s]%s %s\n".printf(parts[1], parts[2], reset_color(), parts[3]); -		} else if (regex != null && regex.match(message)) { -		    var parts = regex.split(message); -			return "%s %s\n".printf(reset_color(), parts[3]); -		} else { -		    return reset_color() + " " + message + "\n"; -		} -	} -	 -	///////////////////////////////////////////////////////////////////// + +    private static string create_message(string message) { +        if (display_file && regex != null && regex.match(message)) { +            var parts = regex.split(message); +            return " [%s%s]%s %s\n".printf(parts[1], parts[2], reset_color(), parts[3]); +        } else if (regex != null && regex.match(message)) { +            var parts = regex.split(message); +            return "%s %s\n".printf(reset_color(), parts[3]); +        } else { +            return reset_color() + " " + message + "\n"; +        } +    } + +    /////////////////////////////////////////////////////////////////////      /// Helper method to format the message for logging.      ///////////////////////////////////////////////////////////////////// -	 -	private static string create_log_message(string message) { -	    if (log_file && regex != null && regex.match(message)) { -			var parts = regex.split(message); -			return " [%s%s] %s\n".printf(parts[1], parts[2], parts[3]); -		} else if (regex != null && regex.match(message)) { -		    var parts = regex.split(message); -			return " %s\n".printf(parts[3]); -		} else { -		    return " " + message + "\n"; -		} -	} -	 -	///////////////////////////////////////////////////////////////////// -	/// The handler function. -	///////////////////////////////////////////////////////////////////// -	 -	private static void log_func(string? d, LogLevelFlags flags, string text) { -		switch (flags) { -		    case LogLevelFlags.LEVEL_ERROR: -		    case LogLevelFlags.LEVEL_CRITICAL: -			    error(create_message(text), create_log_message(text)); -			    break; -		    case LogLevelFlags.LEVEL_INFO: -		    case LogLevelFlags.LEVEL_MESSAGE: -			    message(create_message(text), create_log_message(text)); -			    break; -		    case LogLevelFlags.LEVEL_DEBUG: -			    debug(create_message(text), create_log_message(text)); -			    break; -		    case LogLevelFlags.LEVEL_WARNING: -		    default: -			    warning(create_message(text), create_log_message(text)); -			    break; -		} -	} + +    private static string create_log_message(string message) { +        if (log_file && regex != null && regex.match(message)) { +            var parts = regex.split(message); +            return " [%s%s] %s\n".printf(parts[1], parts[2], parts[3]); +        } else if (regex != null && regex.match(message)) { +            var parts = regex.split(message); +            return " %s\n".printf(parts[3]); +        } else { +            return " " + message + "\n"; +        } +    } + +    ///////////////////////////////////////////////////////////////////// +    /// The handler function. +    ///////////////////////////////////////////////////////////////////// + +    private static void log_func(string? d, LogLevelFlags flags, string text) { +        switch (flags) { +            case LogLevelFlags.LEVEL_ERROR: +            case LogLevelFlags.LEVEL_CRITICAL: +                error(create_message(text), create_log_message(text)); +                break; +            case LogLevelFlags.LEVEL_INFO: +            case LogLevelFlags.LEVEL_MESSAGE: +                message(create_message(text), create_log_message(text)); +                break; +            case LogLevelFlags.LEVEL_DEBUG: +                debug(create_message(text), create_log_message(text)); +                break; +            case LogLevelFlags.LEVEL_WARNING: +            default: +                warning(create_message(text), create_log_message(text)); +                break; +        } +    }  }  } diff --git a/src/utilities/paths.vala b/src/utilities/paths.vala index 5b39c45..61111e3 100644 --- a/src/utilities/paths.vala +++ b/src/utilities/paths.vala @@ -1,19 +1,19 @@ -/* -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { diff --git a/src/utilities/trigger.vala b/src/utilities/trigger.vala index 854cbb4..fbd74f8 100644 --- a/src/utilities/trigger.vala +++ b/src/utilities/trigger.vala @@ -1,23 +1,23 @@ -/*  -Copyright (c) 2011 by Simon Schneegans - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program.  If not, see <http://www.gnu.org/licenses/>.  -*/ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +/////////////////////////////////////////////////////////////////////////  namespace GnomePie { -/////////////////////////////////////////////////////////////////////////     +/////////////////////////////////////////////////////////////////////////  /// This class represents a hotkey, used to open pies. It supports any  /// combination of modifier keys with keyboard and mouse buttons.  ///////////////////////////////////////////////////////////////////////// @@ -29,185 +29,253 @@ public class Trigger : GLib.Object {      /////////////////////////////////////////////////////////////////////      public string label { get; private set; default=""; } -     +      /////////////////////////////////////////////////////////////////////      /// Returns a human-readable version of this Trigger. Small      /// identifiers for turbo mode and delayed mode are added.      /////////////////////////////////////////////////////////////////////      public string label_with_specials { get; private set; default=""; } -     +      /////////////////////////////////////////////////////////////////////      /// The Trigger string. Like [delayed]<Control>button3      ///////////////////////////////////////////////////////////////////// -     +      public string name { get; private set; default=""; } -     +      /////////////////////////////////////////////////////////////////////      /// The key code of the hotkey or the button number of the mouse.      ///////////////////////////////////////////////////////////////////// -     +      public int key_code { get; private set; default=0; } -     +      /////////////////////////////////////////////////////////////////////      /// The keysym of the hotkey or the button number of the mouse.      ///////////////////////////////////////////////////////////////////// -     +      public uint key_sym { get; private set; default=0; } -     +      /////////////////////////////////////////////////////////////////////      /// Modifier keys pressed for this hotkey.      ///////////////////////////////////////////////////////////////////// -     +      public Gdk.ModifierType modifiers { get; private set; default=0; } -     +      /////////////////////////////////////////////////////////////////////      /// True if this hotkey involves the mouse.      ///////////////////////////////////////////////////////////////////// -     +      public bool with_mouse { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// True if the pie closes when the trigger hotkey is released.      ///////////////////////////////////////////////////////////////////// -     +      public bool turbo { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// True if the trigger should wait a short delay before being      /// triggered.      ///////////////////////////////////////////////////////////////////// -     +      public bool delayed { get; private set; default=false; } -     +      /////////////////////////////////////////////////////////////////////      /// True if the pie opens in the middle of the screen.      ///////////////////////////////////////////////////////////////////// -     +      public bool centered { get; private set; default=false; } -     + +    ///////////////////////////////////////////////////////////////////// +    /// True if the mouse pointer is warped to the pie's center. +    ///////////////////////////////////////////////////////////////////// + +    public bool warp { get; private set; default=false; } + +    ///////////////////////////////////////////////////////////////////// +    /// Returns the current selected "radio-button" shape: 0= automatic +    /// 5= full pie; 1,3,7,8= quarters; 2,4,6,8=halves +    /// 1 | 4 | 7 +    /// 2 | 5 | 8 +    /// 3 | 6 | 9 +    ///////////////////////////////////////////////////////////////////// + +    public int shape { get; private set; default=5; } +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new, "unbound" Trigger.      ///////////////////////////////////////////////////////////////////// -     +      public Trigger() {          this.set_unbound();      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new Trigger from a given Trigger string. This is      /// in this format: "[option(s)]<modifier(s)>button" where      /// "<modifier>" is something like "<Alt>" or "<Control>", "button"      /// something like "s", "F4" or "button0" and "[option]" is either -    /// "[turbo]", "[centered]" or "["delayed"]". +    /// "[turbo]", "[centered]", "[warp]", "["delayed"]" or "["shape#"]"      ///////////////////////////////////////////////////////////////////// -     +      public Trigger.from_string(string trigger) {          this.parse_string(trigger);      } -     +      /////////////////////////////////////////////////////////////////////      /// C'tor, creates a new Trigger from the key values.      ///////////////////////////////////////////////////////////////////// -     -    public Trigger.from_values(uint key_sym, Gdk.ModifierType modifiers,  + +    public Trigger.from_values(uint key_sym, Gdk.ModifierType modifiers,                                 bool with_mouse, bool turbo, bool delayed, -                               bool centered ) { -         +                               bool centered, bool warp, int shape ) { +          string trigger = (turbo ? "[turbo]" : "")                         + (delayed ? "[delayed]" : "") -                       + (centered ? "[centered]" : ""); -         +                       + (centered ? "[centered]" : "") +                       + (warp ? "[warp]" : "") +                       + (shape!=5 ? "[shape%d]".printf(shape) : ""); +          if (with_mouse) {              trigger += Gtk.accelerator_name(0, modifiers) + "button%u".printf(key_sym);          } else {              trigger += Gtk.accelerator_name(key_sym, modifiers);          } -         +          this.parse_string(trigger);      } -     +      /////////////////////////////////////////////////////////////////////      /// Parses a Trigger string. This is      /// in this format: "[option(s)]<modifier(s)>button" where      /// "<modifier>" is something like "<Alt>" or "<Control>", "button"      /// something like "s", "F4" or "button0" and "[option]" is either -    /// "[turbo]", "[centered]" or "["delayed"]". +    /// "[turbo]", "[centered]", "[warp]", "["delayed"]" or "["shape#"]"      ///////////////////////////////////////////////////////////////////// -     +      public void parse_string(string trigger) {          if (this.is_valid(trigger)) {              // copy string              string check_string = trigger; -         +              this.name = check_string; -             +              this.turbo = check_string.contains("[turbo]");              this.delayed = check_string.contains("[delayed]");              this.centered = check_string.contains("[centered]"); -             +            this.warp = check_string.contains("[warp]"); + +            this.shape= parse_shape( check_string ); +              // remove optional arguments -            check_string = check_string.replace("[turbo]", ""); -            check_string = check_string.replace("[delayed]", ""); -            check_string = check_string.replace("[centered]", ""); -             +            check_string = remove_optional(check_string); +              int button = this.get_mouse_button(check_string);              if (button > 0) {                  this.with_mouse = true;                  this.key_code = button;                  this.key_sym = button; -                 +                  Gtk.accelerator_parse(check_string, null, out this._modifiers);                  this.label = Gtk.accelerator_get_label(0, this.modifiers); -                 +                  string button_text = _("Button %i").printf(this.key_code); -                 +                  if (this.key_code == 1)                      button_text = _("LeftButton");                  else if (this.key_code == 3)                      button_text = _("RightButton");                  else if (this.key_code == 2)                      button_text = _("MiddleButton"); -                 +                  this.label += button_text;              } else { -                this.with_mouse = false; -                 -                var display = new X.Display(); -                 -                uint keysym = 0; -                Gtk.accelerator_parse(check_string, out keysym, out this._modifiers); -                this.key_code = display.keysym_to_keycode(keysym); -                this.key_sym = keysym; -                this.label = Gtk.accelerator_get_label(keysym, this.modifiers); +                //empty triggers are ok now, they carry open options as well +                if (check_string == "") { +                    this.label = _("Not bound"); +                    this.key_code = 0; +                    this.key_sym = 0; +                    this.modifiers = 0; +                } else { +                    this.with_mouse = false; + +                    var display = new X.Display(); + +                    uint keysym = 0; +                    Gtk.accelerator_parse(check_string, out keysym, out this._modifiers); +                    this.key_code = display.keysym_to_keycode(keysym); +                    this.key_sym = keysym; +                    this.label = Gtk.accelerator_get_label(keysym, this.modifiers); +                }              } -             +              this.label_with_specials = GLib.Markup.escape_text(this.label); -             -            if (this.turbo && this.delayed && this.centered) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Turbo") + " | " + _("Delayed") + " | " + _("Centered") + " ]</span></small>"); -            else if (this.turbo && this.centered) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Turbo") + " | " + _("Centered") + " ]</span></small>"); -            else if (this.turbo && this.delayed) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Turbo") + " | " + _("Delayed") + " ]</span></small>"); -            else if (this.centered && this.delayed) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Delayed") + " | " + _("Centered") + " ]</span></small>"); -            else if (this.turbo) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Turbo") + " ]</span></small>"); -            else if (this.delayed) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Delayed") + " ]</span></small>"); -            else if (this.centered) -                this.label_with_specials += ("  <small><span weight='light'>[ " + _("Centered") + " ]</span></small>"); -             + +            string msg= ""; +            if (this.turbo) { +                msg= _("Turbo"); +            } +            if (this.delayed) { +                if (msg == "") +                    msg= _("Delayed"); +                else +                    msg += " | " + _("Delayed"); +            } +            if (this.centered) { +                if (msg == "") +                    msg= _("Centered"); +                else +                    msg += " | " + _("Centered"); +            } +            if (this.warp) { +                if (msg == "") +                    msg= _("Warp"); +                else +                    msg += " | " + _("Warp"); +            } +            if (this.shape == 0) { +                if (msg == "") +                    msg= _("Auto-shaped"); +                else +                    msg += " | " + _("Auto-shaped"); +            } else if (this.shape == 1 || this.shape ==3 || this.shape == 7 || this.shape == 9) { +                if (msg == "") +                    msg= _("Quarter pie"); +                else +                    msg += " | " + _("Quarter pie"); + +            } else if (this.shape == 2 || this.shape == 4 || this.shape == 6 || this.shape == 8) { +                if (msg == "") +                    msg= _("Half pie"); +                else +                    msg += " | " + _("Half pie"); +            } +            if (msg != "") +                this.label_with_specials += ("  <small><span weight='light'>[ " + msg + " ]</span></small>"); +          } else {              this.set_unbound();          }      } -     + +    ///////////////////////////////////////////////////////////////////// +    /// Extract shape number from trigger string +    /// "[0]".."[9]" 0:auto 5:full pie (default) +    /// 1,3,7,9=quarters    2,4,6,8= halves +    ///////////////////////////////////////////////////////////////////// + +    private int parse_shape(string trigger) { +        int rs; +        for( rs= 0; rs < 10; rs++ ) +            if (trigger.contains("[shape%d]".printf(rs) )) +                return rs; +        return 5; //default= full pie +    } +      /////////////////////////////////////////////////////////////////////      /// Resets all member variables to their defaults.      ///////////////////////////////////////////////////////////////////// -     +      private void set_unbound() {          this.label = _("Not bound");          this.label_with_specials = _("Not bound"); @@ -217,53 +285,71 @@ public class Trigger : GLib.Object {          this.modifiers = 0;          this.turbo = false;          this.delayed = false; +        this.centered = false; +        this.warp = false; +        this.shape = 5; //full pie          this.with_mouse = false;      } -     + +    ///////////////////////////////////////////////////////////////////// +    /// Remove optional arguments from the given string +    /// "[turbo]", "[delayed]", "[warp]" "[centered]" and "[shape#]" +    ///////////////////////////////////////////////////////////////////// + +    public static string remove_optional(string trigger) { +        string trg= trigger; +        trg = trg.replace("[turbo]", ""); +        trg = trg.replace("[delayed]", ""); +        trg = trg.replace("[centered]", ""); +        trg = trg.replace("[warp]", ""); +        for (int rs= 0; rs < 10; rs++) +            trg = trg.replace("[shape%d]".printf(rs), ""); +        return trg; +    } +      /////////////////////////////////////////////////////////////////////      /// Returns true, if the trigger string is in a valid format.      ///////////////////////////////////////////////////////////////////// -     +      private bool is_valid(string trigger) { -        // copy string -        string check_string = trigger; -                  // remove optional arguments -        check_string = check_string.replace("[turbo]", ""); -        check_string = check_string.replace("[delayed]", ""); -        check_string = check_string.replace("[centered]", ""); -          +        string check_string = remove_optional(trigger); +          if (this.get_mouse_button(check_string) > 0) {              // it seems to be a valid mouse-trigger so replace button part,              // with something accepted by gtk, and check it with gtk              int button_index = check_string.index_of("button");              check_string = check_string.slice(0, button_index) + "a"; -        }  -         +        } + +        //empty triggers are ok now, they carry open options as well +        if (check_string == "") +            return true; +          // now it shouls be a normal gtk accelerator          uint keysym = 0;          Gdk.ModifierType modifiers = 0;          Gtk.accelerator_parse(check_string, out keysym, out modifiers);          if (keysym == 0)              return false; -         -        return true;  + +        return true;      } -     +      ///////////////////////////////////////////////////////////////////// -    /// Returns the mouse button number of the given trigger string.  +    /// Returns the mouse button number of the given trigger string.      /// Returns -1 if it is not a mouse trigger.      ///////////////////////////////////////////////////////////////////// -     +      private int get_mouse_button(string trigger) {          if (trigger.contains("button")) {              // it seems to be a mouse-trigger so check the button part.              int button_index = trigger.index_of("button"); -            int number = int.parse(trigger.slice(button_index + 6, trigger.length));   -            if (number > 0)       +            int number = int.parse(trigger.slice(button_index + 6, trigger.length)); +            if (number > 0)                  return number;          } -         +          return -1;      }  } | 
