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; } } |