diff options
Diffstat (limited to 'src/renderers/pieWindow.vala')
-rwxr-xr-x[-rw-r--r--] | src/renderers/pieWindow.vala | 216 |
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; } } |