summaryrefslogtreecommitdiffstats
path: root/ash/wm/gestures
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 02:20:24 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 02:20:24 +0000
commit551f9e686e5153ff7132427e4e34dc4e7907fb70 (patch)
tree4cc3d97694318578dca28929c2a106577ec167d3 /ash/wm/gestures
parent58139d1afb191a318c9fd17f0014a0385141368c (diff)
downloadchromium_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.cc155
-rw-r--r--ash/wm/gestures/system_pinch_handler.h84
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_