diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-29 02:20:24 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-29 02:20:24 +0000 |
commit | 551f9e686e5153ff7132427e4e34dc4e7907fb70 (patch) | |
tree | 4cc3d97694318578dca28929c2a106577ec167d3 /ash/wm/gestures | |
parent | 58139d1afb191a318c9fd17f0014a0385141368c (diff) | |
download | chromium_src-551f9e686e5153ff7132427e4e34dc4e7907fb70.zip chromium_src-551f9e686e5153ff7132427e4e34dc4e7907fb70.tar.gz chromium_src-551f9e686e5153ff7132427e4e34dc4e7907fb70.tar.bz2 |
ash: Move out the system-pinch handler into a separate location.
This is the first step of tidying up SystemGestureEventFilter. Subsequent patches will
move bezel and long-press functionality into separate files as well.
BUG=none
Review URL: https://chromiumcodereview.appspot.com/10898021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm/gestures')
-rw-r--r-- | ash/wm/gestures/system_pinch_handler.cc | 155 | ||||
-rw-r--r-- | ash/wm/gestures/system_pinch_handler.h | 84 |
2 files changed, 239 insertions, 0 deletions
diff --git a/ash/wm/gestures/system_pinch_handler.cc b/ash/wm/gestures/system_pinch_handler.cc new file mode 100644 index 0000000..ddfd13c --- /dev/null +++ b/ash/wm/gestures/system_pinch_handler.cc @@ -0,0 +1,155 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/gestures/system_pinch_handler.h" + +#include "ash/launcher/launcher.h" +#include "ash/screen_ash.h" +#include "ash/shell.h" +#include "ash/wm/property_util.h" +#include "ash/wm/window_util.h" +#include "ash/wm/workspace/snap_sizer.h" +#include "ui/aura/window.h" +#include "ui/base/events.h" +#include "ui/base/gestures/gesture_types.h" +#include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/rect.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +const double kPinchThresholdForMaximize = 1.5; +const double kPinchThresholdForMinimize = 0.7; + +namespace ash { +namespace internal { + +const int SystemPinchHandler::kSystemGesturePoints = 4; + +SystemPinchHandler::SystemPinchHandler(aura::Window* target) + : target_(target), + phantom_(target), + phantom_state_(PHANTOM_WINDOW_NORMAL), + pinch_factor_(1.) { + widget_ = views::Widget::GetWidgetForNativeWindow(target_); +} + +SystemPinchHandler::~SystemPinchHandler() { +} + +SystemGestureStatus SystemPinchHandler::ProcessGestureEvent( + const ui::GestureEvent& event) { + // The target has changed, somehow. Let's bale. + if (!widget_ || !widget_->widget_delegate()->CanResize()) + return SYSTEM_GESTURE_END; + + switch (event.type()) { + case ui::ET_GESTURE_END: { + if (event.details().touch_points() > kSystemGesturePoints) + break; + + if (phantom_state_ == PHANTOM_WINDOW_MAXIMIZED) { + if (!wm::IsWindowMaximized(target_) && + !wm::IsWindowFullscreen(target_)) + wm::MaximizeWindow(target_); + } else if (phantom_state_ == PHANTOM_WINDOW_MINIMIZED) { + if (wm::IsWindowMaximized(target_) || + wm::IsWindowFullscreen(target_)) { + wm::RestoreWindow(target_); + } else { + wm::MinimizeWindow(target_); + + // NOTE: Minimizing the window will cause this handler to be + // destroyed. So do not access anything from |this| from here. + return SYSTEM_GESTURE_END; + } + } + return SYSTEM_GESTURE_END; + } + + case ui::ET_GESTURE_PINCH_UPDATE: { + // The PINCH_UPDATE events contain incremental scaling updates. + pinch_factor_ *= event.details().scale(); + gfx::Rect bounds = + GetPhantomWindowScreenBounds(target_, event.location()); + if (phantom_state_ != PHANTOM_WINDOW_NORMAL || phantom_.IsShowing()) + phantom_.Show(bounds); + break; + } + + case ui::ET_GESTURE_MULTIFINGER_SWIPE: { + phantom_.Hide(); + pinch_factor_ = 1.0; + phantom_state_ = PHANTOM_WINDOW_NORMAL; + + if (event.details().swipe_left() || event.details().swipe_right()) { + // Snap for left/right swipes. In case the window is + // maximized/fullscreen, then restore the window first so that tiling + // works correctly. + if (wm::IsWindowMaximized(target_) || + wm::IsWindowFullscreen(target_)) + wm::RestoreWindow(target_); + + ui::ScopedLayerAnimationSettings settings( + target_->layer()->GetAnimator()); + SnapSizer sizer(target_, + gfx::Point(), + event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE : + internal::SnapSizer::RIGHT_EDGE, + Shell::GetInstance()->GetGridSize()); + target_->SetBounds(sizer.GetSnapBounds(target_->bounds())); + } else if (event.details().swipe_up()) { + if (!wm::IsWindowMaximized(target_) && + !wm::IsWindowFullscreen(target_)) + wm::MaximizeWindow(target_); + } else if (event.details().swipe_down()) { + wm::MinimizeWindow(target_); + } else { + NOTREACHED() << "Swipe happened without a direction."; + } + break; + } + + default: + break; + } + + return SYSTEM_GESTURE_PROCESSED; +} + +gfx::Rect SystemPinchHandler::GetPhantomWindowScreenBounds( + aura::Window* window, + const gfx::Point& point) { + if (pinch_factor_ > kPinchThresholdForMaximize) { + phantom_state_ = PHANTOM_WINDOW_MAXIMIZED; + return ScreenAsh::ConvertRectToScreen( + target_->parent(), + ScreenAsh::GetMaximizedWindowBoundsInParent(target_)); + } + + if (pinch_factor_ < kPinchThresholdForMinimize) { + if (wm::IsWindowMaximized(window) || wm::IsWindowFullscreen(window)) { + const gfx::Rect* restore = GetRestoreBoundsInScreen(window); + if (restore) { + phantom_state_ = PHANTOM_WINDOW_MINIMIZED; + return *restore; + } + return window->bounds(); + } + + Launcher* launcher = Shell::GetInstance()->launcher(); + gfx::Rect rect = launcher->GetScreenBoundsOfItemIconForWindow(target_); + if (rect.IsEmpty()) + rect = launcher->widget()->GetWindowBoundsInScreen(); + else + rect.Inset(-8, -8); + phantom_state_ = PHANTOM_WINDOW_MINIMIZED; + return rect; + } + + phantom_state_ = PHANTOM_WINDOW_NORMAL; + return window->bounds(); +} + +} // namespace internal +} // namespace ash diff --git a/ash/wm/gestures/system_pinch_handler.h b/ash/wm/gestures/system_pinch_handler.h new file mode 100644 index 0000000..33700ca --- /dev/null +++ b/ash/wm/gestures/system_pinch_handler.h @@ -0,0 +1,84 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_GESTURES_SYSTEM_PINCH_HANDLER_H_ +#define ASH_WM_GESTURES_SYSTEM_PINCH_HANDLER_H_ + +#include "ash/wm/workspace/phantom_window_controller.h" + +namespace aura { +class Window; +} + +namespace gfx { +class Point; +} + +namespace ui { +class GestureEvent; +} + +namespace views { +class Widget; +} + +namespace ash { +namespace internal { + +enum SystemGestureStatus { + SYSTEM_GESTURE_PROCESSED, // The system gesture has been processed. + SYSTEM_GESTURE_IGNORED, // The system gesture was ignored. + SYSTEM_GESTURE_END, // Marks the end of the sytem gesture. +}; + +class SystemPinchHandler { + public: + explicit SystemPinchHandler(aura::Window* target); + virtual ~SystemPinchHandler(); + + // Processes a gesture event. Returns SYSTEM_GESTURE_PROCESSED if the gesture + // event has been processed. Returns SYSTEM_GESTURE_END if the gesture event + // has been processed, and marks the end of the gesture sequence (i.e. the + // handler should receive no more input events). + SystemGestureStatus ProcessGestureEvent(const ui::GestureEvent& event); + + static const int kSystemGesturePoints; + + private: + // Returns the appropriate bounds for the phantom window depending on the + // state of the window, the state of the gesture sequence, and the current + // event location. + gfx::Rect GetPhantomWindowScreenBounds(aura::Window* window, + const gfx::Point& point); + + enum PhantomWindowState { + PHANTOM_WINDOW_NORMAL, + PHANTOM_WINDOW_MAXIMIZED, + PHANTOM_WINDOW_MINIMIZED, + }; + + aura::Window* target_; + views::Widget* widget_; + + // A phantom window is used to provide visual cues for + // pinch-to-resize/maximize/minimize gestures. + PhantomWindowController phantom_; + + // When the phantom window is in minimized or maximized state, moving the + // target window should not move the phantom window. So |phantom_state_| is + // used to track the state of the phantom window. + PhantomWindowState phantom_state_; + + // PINCH_UPDATE events include incremental pinch-amount. But it is necessary + // to keep track of the overall pinch-amount. |pinch_factor_| is used for + // that. + double pinch_factor_; + + DISALLOW_COPY_AND_ASSIGN(SystemPinchHandler); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_WM_GESTURES_SYSTEM_PINCH_HANDLER_H_ |