Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / wm / gestures / edge_gesture_handler.cc
blob9ba7ff3d0ae310ca7efde0662840d19340addd91
1 // Copyright (c) 2013 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/edge_gesture_handler.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf_layout_manager.h"
9 #include "ash/shelf/shelf_types.h"
10 #include "ash/shelf/shelf_widget.h"
11 #include "ash/shell.h"
12 #include "ui/base/events/event.h"
13 #include "ui/gfx/screen.h"
15 namespace {
16 const int kBottomEdgeGestureThreshold = 10;
17 const int kLeftEdgeGestureThreshold = 10;
18 const int kRightEdgeGestureThreshold = 10;
19 const int kTopEdgeGestureThreshold = 10;
21 // Bit positions of edge start flags
22 enum EdgeStart {
23 EDGE_START_TOP = 0,
24 EDGE_START_LEFT = 1,
25 EDGE_START_RIGHT = 2,
26 EDGE_START_BOTTOM = 3
29 // Helpers for manipulating edge start flags
30 #define CLEAR_FLAGS(FLAGS) (FLAGS = 0)
31 #define SET_FLAG(FLAGS, FLAG_POS) (FLAGS |= 1 << FLAG_POS)
32 #define IS_FLAG_SET(FLAGS, FLAG_POS) (0 != (FLAGS & (1 << FLAG_POS)))
33 #define ANY_FLAGS_SET(FLAGS) (FLAGS != 0)
34 } // namespace
36 namespace ash {
37 namespace internal {
39 EdgeGestureHandler::EdgeGestureHandler() :
40 orientation_(EDGE_SCROLL_ORIENTATION_UNSET) {
41 CLEAR_FLAGS(start_location_);
44 EdgeGestureHandler::~EdgeGestureHandler() {
47 bool EdgeGestureHandler::ProcessGestureEvent(aura::Window* target,
48 const ui::GestureEvent& event) {
49 // TODO(crbug.com/222746): Rewrite this code to ignore events that are for
50 // edges that a bezel is present for instead of hardcoding the layout of edge
51 // v bezel.
52 switch (event.type()) {
53 case ui::ET_GESTURE_SCROLL_BEGIN:
54 return HandleEdgeGestureStart(target, event);
55 case ui::ET_GESTURE_SCROLL_UPDATE:
56 if (ANY_FLAGS_SET(start_location_)) {
57 if (DetermineGestureOrientation(event)) {
58 return HandleEdgeGestureUpdate(target, event);
61 break;
62 case ui::ET_GESTURE_SCROLL_END:
63 case ui::ET_SCROLL_FLING_START:
64 return HandleEdgeGestureEnd(target, event);
65 default:
66 break;
68 return false;
71 bool EdgeGestureHandler::HandleLauncherControl(const ui::GestureEvent& event) {
72 ShelfLayoutManager* shelf =
73 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
74 // If visible then let the shelf handle it as a normal widget.
75 if (shelf->IsVisible())
76 return false;
78 switch (shelf->GetAlignment()) {
79 case SHELF_ALIGNMENT_LEFT:
80 if (IS_FLAG_SET(start_location_, EDGE_START_LEFT))
81 return shelf_handler_.ProcessGestureEvent(event);
82 break;
83 case SHELF_ALIGNMENT_RIGHT:
84 if (IS_FLAG_SET(start_location_, EDGE_START_RIGHT))
85 return shelf_handler_.ProcessGestureEvent(event);
86 break;
87 // Let the BezelGestureHandler handle gestures on the bottom edge of the
88 // screen and there are no implemented gestures for the top edge at the
89 // moment.
90 case SHELF_ALIGNMENT_BOTTOM:
91 case SHELF_ALIGNMENT_TOP:
92 default:
93 break;
95 return false;
98 bool EdgeGestureHandler::HandleEdgeGestureStart(
99 aura::Window* target,
100 const ui::GestureEvent& event) {
101 gfx::Rect screen =
102 Shell::GetScreen()->GetDisplayNearestWindow(target).bounds();
104 orientation_ = EDGE_SCROLL_ORIENTATION_UNSET;
105 if (GestureStartInEdgeArea(screen, event))
106 return HandleLauncherControl(event);
107 return false;
110 bool EdgeGestureHandler::DetermineGestureOrientation(
111 const ui::GestureEvent& event) {
112 if (orientation_ == EDGE_SCROLL_ORIENTATION_UNSET) {
113 if (!event.details().scroll_x() && !event.details().scroll_y())
114 return false;
115 orientation_ = abs(event.details().scroll_y()) >
116 abs(event.details().scroll_x()) ?
117 EDGE_SCROLL_ORIENTATION_VERTICAL : EDGE_SCROLL_ORIENTATION_HORIZONTAL;
119 return true;
122 bool EdgeGestureHandler::HandleEdgeGestureUpdate(
123 aura::Window* target,
124 const ui::GestureEvent& event) {
125 if (IsGestureInLauncherOrientation(event))
126 return HandleLauncherControl(event);
127 return false;
130 bool EdgeGestureHandler::HandleEdgeGestureEnd(aura::Window* target,
131 const ui::GestureEvent& event) {
132 bool ret_val = HandleLauncherControl(event);
133 CLEAR_FLAGS(start_location_);
134 return ret_val;
137 bool EdgeGestureHandler::GestureStartInEdgeArea(
138 const gfx::Rect& screen,
139 const ui::GestureEvent& event) {
140 CLEAR_FLAGS(start_location_);
142 if (abs(event.y() - screen.y()) < kTopEdgeGestureThreshold &&
143 event.y() >= 0)
144 SET_FLAG(start_location_, EDGE_START_TOP);
145 if (abs(event.x() - screen.x()) < kLeftEdgeGestureThreshold &&
146 event.x() >= 0)
147 SET_FLAG(start_location_, EDGE_START_LEFT);
148 if (abs(event.x() - screen.right()) < kRightEdgeGestureThreshold &&
149 event.x() >= 0)
150 SET_FLAG(start_location_, EDGE_START_RIGHT);
151 if (abs(event.y() - screen.bottom()) < kBottomEdgeGestureThreshold &&
152 event.y() >= 0)
153 SET_FLAG(start_location_, EDGE_START_BOTTOM);
154 return ANY_FLAGS_SET(start_location_);
157 bool EdgeGestureHandler::IsGestureInLauncherOrientation(
158 const ui::GestureEvent& event) {
159 EdgeScrollOrientation new_orientation = abs(event.details().scroll_y()) >
160 abs(event.details().scroll_x()) ?
161 EDGE_SCROLL_ORIENTATION_VERTICAL : EDGE_SCROLL_ORIENTATION_HORIZONTAL;
163 if (new_orientation != orientation_)
164 return false;
166 ShelfLayoutManager* shelf =
167 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
168 switch (shelf->GetAlignment()) {
169 case SHELF_ALIGNMENT_BOTTOM:
170 if (orientation_ == EDGE_SCROLL_ORIENTATION_VERTICAL)
171 return true;
172 break;
173 case SHELF_ALIGNMENT_LEFT:
174 if (orientation_ == EDGE_SCROLL_ORIENTATION_HORIZONTAL)
175 return true;
176 break;
177 case SHELF_ALIGNMENT_RIGHT:
178 if (orientation_ == EDGE_SCROLL_ORIENTATION_HORIZONTAL)
179 return true;
180 break;
181 case SHELF_ALIGNMENT_TOP:
182 if (orientation_ == EDGE_SCROLL_ORIENTATION_VERTICAL)
183 return true;
184 break;
185 default:
186 break;
188 return false;
191 } // namespace internal
192 } // namespace ash