summaryrefslogtreecommitdiff
path: root/src/renderers/pieWindow.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderers/pieWindow.vala')
-rwxr-xr-x[-rw-r--r--]src/renderers/pieWindow.vala216
1 files changed, 170 insertions, 46 deletions
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;
}
}