diff options
Diffstat (limited to 'src/utilities')
-rw-r--r-- | src/utilities/animatedValue.vala | 116 | ||||
-rw-r--r-- | src/utilities/bindingManager.vala | 153 | ||||
-rw-r--r-- | src/utilities/color.vala | 100 | ||||
-rw-r--r-- | src/utilities/config.vala | 48 | ||||
-rw-r--r-- | src/utilities/focusGrabber.vala | 32 | ||||
-rw-r--r-- | src/utilities/key.vala | 78 | ||||
-rw-r--r-- | src/utilities/logger.vala | 290 | ||||
-rw-r--r-- | src/utilities/paths.vala | 32 | ||||
-rw-r--r-- | src/utilities/trigger.vala | 302 |
9 files changed, 653 insertions, 498 deletions
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; } } |