Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / wm / gestures / system_pinch_handler.cc
blob39a733beffc65779164a72a0b1d3660c32146da0
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/gestures/system_pinch_handler.h"
7 #include "ash/launcher/launcher.h"
8 #include "ash/screen_ash.h"
9 #include "ash/shelf/shelf_widget.h"
10 #include "ash/shell.h"
11 #include "ash/wm/property_util.h"
12 #include "ash/wm/window_util.h"
13 #include "ash/wm/workspace/snap_sizer.h"
14 #include "ui/aura/window.h"
15 #include "ui/base/events/event_constants.h"
16 #include "ui/base/gestures/gesture_types.h"
17 #include "ui/compositor/scoped_layer_animation_settings.h"
18 #include "ui/gfx/rect.h"
19 #include "ui/views/widget/widget.h"
20 #include "ui/views/widget/widget_delegate.h"
22 const double kPinchThresholdForMaximize = 1.5;
23 const double kPinchThresholdForMinimize = 0.7;
25 namespace ash {
26 namespace internal {
28 const int SystemPinchHandler::kSystemGesturePoints = 4;
30 SystemPinchHandler::SystemPinchHandler(aura::Window* target)
31 : target_(target),
32 phantom_(target),
33 phantom_state_(PHANTOM_WINDOW_NORMAL),
34 pinch_factor_(1.) {
35 widget_ = views::Widget::GetWidgetForNativeWindow(target_);
38 SystemPinchHandler::~SystemPinchHandler() {
41 SystemGestureStatus SystemPinchHandler::ProcessGestureEvent(
42 const ui::GestureEvent& event) {
43 // The target has changed, somehow. Let's bale.
44 if (!widget_ || !widget_->widget_delegate()->CanResize())
45 return SYSTEM_GESTURE_END;
47 switch (event.type()) {
48 case ui::ET_GESTURE_END: {
49 if (event.details().touch_points() > kSystemGesturePoints)
50 break;
52 if (phantom_state_ == PHANTOM_WINDOW_MAXIMIZED) {
53 if (!wm::IsWindowMaximized(target_) &&
54 !wm::IsWindowFullscreen(target_))
55 wm::MaximizeWindow(target_);
56 } else if (phantom_state_ == PHANTOM_WINDOW_MINIMIZED) {
57 if (wm::IsWindowMaximized(target_) ||
58 wm::IsWindowFullscreen(target_)) {
59 wm::RestoreWindow(target_);
60 } else {
61 wm::MinimizeWindow(target_);
63 // NOTE: Minimizing the window will cause this handler to be
64 // destroyed. So do not access anything from |this| from here.
65 return SYSTEM_GESTURE_END;
68 return SYSTEM_GESTURE_END;
71 case ui::ET_GESTURE_PINCH_UPDATE: {
72 // The PINCH_UPDATE events contain incremental scaling updates.
73 pinch_factor_ *= event.details().scale();
74 gfx::Rect bounds =
75 GetPhantomWindowScreenBounds(target_, event.location());
76 if (phantom_state_ != PHANTOM_WINDOW_NORMAL || phantom_.IsShowing())
77 phantom_.Show(bounds);
78 break;
81 case ui::ET_GESTURE_MULTIFINGER_SWIPE: {
82 phantom_.Hide();
83 pinch_factor_ = 1.0;
84 phantom_state_ = PHANTOM_WINDOW_NORMAL;
86 if (event.details().swipe_left() || event.details().swipe_right()) {
87 // Snap for left/right swipes.
88 ui::ScopedLayerAnimationSettings settings(
89 target_->layer()->GetAnimator());
90 internal::SnapSizer::SnapWindow(target_,
91 event.details().swipe_left() ? internal::SnapSizer::LEFT_EDGE :
92 internal::SnapSizer::RIGHT_EDGE);
93 } else if (event.details().swipe_up()) {
94 if (!wm::IsWindowMaximized(target_) &&
95 !wm::IsWindowFullscreen(target_))
96 wm::MaximizeWindow(target_);
97 } else if (event.details().swipe_down()) {
98 wm::MinimizeWindow(target_);
99 } else {
100 NOTREACHED() << "Swipe happened without a direction.";
102 break;
105 default:
106 break;
109 return SYSTEM_GESTURE_PROCESSED;
112 gfx::Rect SystemPinchHandler::GetPhantomWindowScreenBounds(
113 aura::Window* window,
114 const gfx::Point& point) {
115 if (pinch_factor_ > kPinchThresholdForMaximize) {
116 phantom_state_ = PHANTOM_WINDOW_MAXIMIZED;
117 return ScreenAsh::ConvertRectToScreen(
118 target_->parent(),
119 ScreenAsh::GetMaximizedWindowBoundsInParent(target_));
122 if (pinch_factor_ < kPinchThresholdForMinimize) {
123 if (wm::IsWindowMaximized(window) || wm::IsWindowFullscreen(window)) {
124 const gfx::Rect* restore = GetRestoreBoundsInScreen(window);
125 if (restore) {
126 phantom_state_ = PHANTOM_WINDOW_MINIMIZED;
127 return *restore;
129 return window->bounds();
132 Launcher* launcher = Launcher::ForWindow(window);
133 gfx::Rect rect = launcher->GetScreenBoundsOfItemIconForWindow(target_);
134 if (rect.IsEmpty())
135 rect = launcher->shelf_widget()->GetWindowBoundsInScreen();
136 else
137 rect.Inset(-8, -8);
138 phantom_state_ = PHANTOM_WINDOW_MINIMIZED;
139 return rect;
142 phantom_state_ = PHANTOM_WINDOW_NORMAL;
143 return window->bounds();
146 } // namespace internal
147 } // namespace ash