From 154fd60d1dc64ebd52d9ca25e22584fa06efa3be Mon Sep 17 00:00:00 2001 From: Tom Beckmann Date: Mon, 6 Aug 2012 23:03:11 +0200 Subject: [PATCH] Implemented zooming support --- CMakeLists.txt | 1 + data/org.pantheon.desktop.gala.gschema.xml | 10 ++ src/Plugin.vala | 10 ++ src/Zooming.vala | 139 +++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 src/Zooming.vala diff --git a/CMakeLists.txt b/CMakeLists.txt index 72b15b52..a0135bbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ vala_precompile(VALA_C src/Settings.vala src/TextShadowEffect.vala src/Utils.vala + src/Zooming.vala src/Widgets/AppIcon.vala src/Widgets/WindowSwitcher.vala src/Widgets/WorkspaceThumb.vala diff --git a/data/org.pantheon.desktop.gala.gschema.xml b/data/org.pantheon.desktop.gala.gschema.xml index e820770c..09d87e64 100644 --- a/data/org.pantheon.desktop.gala.gschema.xml +++ b/data/org.pantheon.desktop.gala.gschema.xml @@ -65,6 +65,16 @@ Shortcut to move to last workspace + + plus', 'KP_Add']]]> + Zoom in + + + + minus', 'KP_Subtract']]]> + Zoom out + + diff --git a/src/Plugin.vala b/src/Plugin.vala index d431c940..d8436c22 100644 --- a/src/Plugin.vala +++ b/src/Plugin.vala @@ -39,6 +39,7 @@ namespace Gala { WindowSwitcher winswitcher; WorkspaceView workspace_view; + Zooming zooming; Window? moving; //place for the window that is being moved over @@ -77,8 +78,11 @@ namespace Gala winswitcher = new WindowSwitcher (this); + zooming = new Zooming (this); + stage.add_child (workspace_view); stage.add_child (winswitcher); + stage.add_child (zooming); /*keybindings*/ @@ -88,6 +92,12 @@ namespace Gala screen.get_display ().add_keybinding ("move-to-workspace-last", BehaviorSettings.get_default ().schema, 0, () => { screen.get_workspace_by_index (screen.n_workspaces - 1).activate (screen.get_display ().get_current_time ()); }); + screen.get_display ().add_keybinding ("zoom-in", BehaviorSettings.get_default ().schema, 0, () => { + zooming.zoom (true); + }); + screen.get_display ().add_keybinding ("zoom-out", BehaviorSettings.get_default ().schema, 0, () => { + zooming.zoom (false); + }); screen.get_display ().overlay_key.connect (() => { try { diff --git a/src/Zooming.vala b/src/Zooming.vala new file mode 100644 index 00000000..4057648b --- /dev/null +++ b/src/Zooming.vala @@ -0,0 +1,139 @@ +// +// Copyright (C) 2012 Tom Beckmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +using Clutter; +using Meta; + +namespace Gala +{ + + public class Zooming : Clutter.Actor + { + + Plugin plugin; + + public Zooming (Plugin _plugin) + { + plugin = _plugin; + var stage = Compositor.get_stage_for_screen (plugin.get_screen ()); + + visible = false; + reactive = true; + + add_constraint (new BindConstraint (stage, BindCoordinate.WIDTH, 0)); + add_constraint (new BindConstraint (stage, BindCoordinate.HEIGHT, 0)); + + } + + public override bool key_press_event (Clutter.KeyEvent event) + { + switch (event.keyval) { + case Key.Escape: + end (); + + return true; + case Key.plus: + case Key.KP_Add: + zoom (true); + + return true; + case Key.KP_Subtract: + case Key.minus: + zoom (false); + + return true; + } + + return false; + } + + public override bool button_release_event (ButtonEvent event) + { + end (); + + return true; + } + + public override void key_focus_out () + { + end (); + } + + public override bool motion_event (Clutter.MotionEvent event) + { + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + wins.scale_center_x = event.x * (1 / (float)scale_x); + wins.scale_center_y = event.y * (1 / (float)scale_x); + + return true; + } + + void end () + { + if (!visible) + return; + + visible = false; + + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + wins.animate (AnimationMode.EASE_OUT_CUBIC, 300, scale_x:1.0, scale_y:1.0).completed.connect (() => { + wins.scale_center_x = 0.0f; + wins.scale_center_y = 0.0f; + }); + plugin.end_modal (); + + plugin.update_input_area (); + } + + public void zoom (bool in) + { + var wins = Compositor.get_window_group_for_screen (plugin.get_screen ()); + + //setup things + if (in && !visible) { + plugin.begin_modal (); + grab_key_focus (); + + int mx, my; + Gdk.Display.get_default ().get_device_manager ().get_client_pointer ().get_position (null, out mx, out my); + wins.scale_center_x = mx; + wins.scale_center_y = my; + + visible = true; + get_parent ().set_child_above_sibling (this, null); + Utils.set_input_area (plugin.get_screen (), InputArea.FULLSCREEN); + } + + if (!visible) + return; + + var new_val = wins.scale_x - ( in ? -0.5 : 0.5); + + //because of the animation, we might stop a bit before 1.0 accidentally + if (new_val <= 1.25) { + end (); + return; + } + if (new_val > 2.5) + new_val = 2.5; + + wins.animate (Clutter.AnimationMode.EASE_OUT_CUBIC, 300, scale_x:new_val, scale_y:new_val); + } + + } + +}