Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: ui/views/view_targeter_unittest.cc

Issue 481433006: Support targeting for gestures in ViewTargeter (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments addressed Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/view_targeter.cc ('k') | ui/views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/view_targeter.h" 5 #include "ui/views/view_targeter.h"
6 6
7 #include "ui/events/event_targeter.h" 7 #include "ui/events/event_targeter.h"
8 #include "ui/events/event_utils.h" 8 #include "ui/events/event_utils.h"
9 #include "ui/gfx/path.h" 9 #include "ui/gfx/path.h"
10 #include "ui/views/masked_targeter_delegate.h" 10 #include "ui/views/masked_targeter_delegate.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 mask->lineTo(0, h); 69 mask->lineTo(0, h);
70 mask->close(); 70 mask->close();
71 return true; 71 return true;
72 } 72 }
73 73
74 DISALLOW_COPY_AND_ASSIGN(TestMaskedView); 74 DISALLOW_COPY_AND_ASSIGN(TestMaskedView);
75 }; 75 };
76 76
77 namespace test { 77 namespace test {
78 78
79 typedef ViewsTestBase ViewTargeterTest; 79 // TODO(tdanderson): Clean up this test suite by moving common code/state into
80 // ViewTargeterTest and overriding SetUp(), TearDown(), etc.
81 // See crbug.com/355680.
82 class ViewTargeterTest : public ViewsTestBase {
83 public:
84 ViewTargeterTest() {}
85 virtual ~ViewTargeterTest() {}
86
87 void SetGestureHandler(internal::RootView* root_view, View* handler) {
88 root_view->gesture_handler_ = handler;
89 }
90
91 void SetAllowGestureEventRetargeting(internal::RootView* root_view,
92 bool allow) {
93 root_view->allow_gesture_event_retargeting_ = allow;
94 }
95
96 private:
97 DISALLOW_COPY_AND_ASSIGN(ViewTargeterTest);
98 };
80 99
81 namespace { 100 namespace {
82 101
83 gfx::Point ConvertPointToView(View* view, const gfx::Point& p) { 102 gfx::Point ConvertPointToView(View* view, const gfx::Point& p) {
84 gfx::Point tmp(p); 103 gfx::Point tmp(p);
85 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp); 104 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp);
86 return tmp; 105 return tmp;
87 } 106 }
88 107
89 gfx::Rect ConvertRectToView(View* view, const gfx::Rect& r) { 108 gfx::Rect ConvertRectToView(View* view, const gfx::Rect& r) {
(...skipping 20 matching lines...) Expand all
110 129
111 widget.SetContentsView(content); 130 widget.SetContentsView(content);
112 content->AddChildView(child); 131 content->AddChildView(child);
113 child->AddChildView(grandchild); 132 child->AddChildView(grandchild);
114 133
115 grandchild->SetFocusable(true); 134 grandchild->SetFocusable(true);
116 grandchild->RequestFocus(); 135 grandchild->RequestFocus();
117 136
118 internal::RootView* root_view = 137 internal::RootView* root_view =
119 static_cast<internal::RootView*>(widget.GetRootView()); 138 static_cast<internal::RootView*>(widget.GetRootView());
120 ViewTargeter* view_targeter = new ViewTargeter(root_view); 139 ui::EventTargeter* targeter = root_view->targeter();
121 ui::EventTargeter* targeter = view_targeter;
122 root_view->SetEventTargeter(make_scoped_ptr(view_targeter));
123 140
124 ui::KeyEvent key_event('a', ui::VKEY_A, ui::EF_NONE); 141 ui::KeyEvent key_event('a', ui::VKEY_A, ui::EF_NONE);
125 142
126 // The focused view should be the initial target of the event. 143 // The focused view should be the initial target of the event.
127 ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view, 144 ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
128 &key_event); 145 &key_event);
129 EXPECT_EQ(grandchild, static_cast<View*>(current_target)); 146 EXPECT_EQ(grandchild, static_cast<View*>(current_target));
130 147
131 // Verify that FindNextBestTarget() will return the parent view of the 148 // Verify that FindNextBestTarget() will return the parent view of the
132 // argument (and NULL if the argument has no parent view). 149 // argument (and NULL if the argument has no parent view).
(...skipping 26 matching lines...) Expand all
159 child->SetBounds(50, 50, 20, 20); 176 child->SetBounds(50, 50, 20, 20);
160 View* grandchild = new View; 177 View* grandchild = new View;
161 grandchild->SetBounds(0, 0, 5, 5); 178 grandchild->SetBounds(0, 0, 5, 5);
162 179
163 widget.SetContentsView(content); 180 widget.SetContentsView(content);
164 content->AddChildView(child); 181 content->AddChildView(child);
165 child->AddChildView(grandchild); 182 child->AddChildView(grandchild);
166 183
167 internal::RootView* root_view = 184 internal::RootView* root_view =
168 static_cast<internal::RootView*>(widget.GetRootView()); 185 static_cast<internal::RootView*>(widget.GetRootView());
169 ViewTargeter* view_targeter = new ViewTargeter(root_view); 186 ui::EventTargeter* targeter = root_view->targeter();
170 ui::EventTargeter* targeter = view_targeter;
171 root_view->SetEventTargeter(make_scoped_ptr(view_targeter));
172 187
173 // The event falls within the bounds of |child| and |content| but not 188 // The event falls within the bounds of |child| and |content| but not
174 // |grandchild|, so |child| should be the initial target for the event. 189 // |grandchild|, so |child| should be the initial target for the event.
175 ui::ScrollEvent scroll(ui::ET_SCROLL, 190 ui::ScrollEvent scroll(ui::ET_SCROLL,
176 gfx::Point(60, 60), 191 gfx::Point(60, 60),
177 ui::EventTimeForNow(), 192 ui::EventTimeForNow(),
178 0, 193 0,
179 0, 3, 194 0, 3,
180 0, 3, 195 0, 3,
181 2); 196 2);
(...skipping 19 matching lines...) Expand all
201 gfx::Point(150, 150), 216 gfx::Point(150, 150),
202 ui::EventTimeForNow(), 217 ui::EventTimeForNow(),
203 0, 218 0,
204 0, 3, 219 0, 3,
205 0, 3, 220 0, 3,
206 2); 221 2);
207 current_target = targeter->FindTargetForEvent(root_view, &scroll); 222 current_target = targeter->FindTargetForEvent(root_view, &scroll);
208 EXPECT_EQ(content, static_cast<View*>(current_target)); 223 EXPECT_EQ(content, static_cast<View*>(current_target));
209 } 224 }
210 225
226 // Convenience to make constructing a GestureEvent simpler.
227 class GestureEventForTest : public ui::GestureEvent {
228 public:
229 GestureEventForTest(ui::EventType type, int x, int y)
230 : GestureEvent(x,
231 y,
232 0,
233 base::TimeDelta(),
234 ui::GestureEventDetails(type, 0.0f, 0.0f)) {}
235
236 GestureEventForTest(ui::GestureEventDetails details, int x, int y)
237 : GestureEvent(x, y, 0, base::TimeDelta(), details) {}
238 };
239
240 // Verifies that the the functions ViewTargeter::FindTargetForEvent()
241 // and ViewTargeter::FindNextBestTarget() are implemented correctly
242 // for gesture events.
243 TEST_F(ViewTargeterTest, ViewTargeterForGestureEvents) {
244 Widget widget;
245 Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
246 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
247 init_params.bounds = gfx::Rect(0, 0, 200, 200);
248 widget.Init(init_params);
249
250 // The coordinates used for SetBounds() are in the parent coordinate space.
251 View* content = new View;
252 content->SetBounds(0, 0, 100, 100);
253 View* child = new View;
254 child->SetBounds(50, 50, 20, 20);
255 View* grandchild = new View;
256 grandchild->SetBounds(0, 0, 5, 5);
257
258 widget.SetContentsView(content);
259 content->AddChildView(child);
260 child->AddChildView(grandchild);
261
262 internal::RootView* root_view =
263 static_cast<internal::RootView*>(widget.GetRootView());
264 ui::EventTargeter* targeter = root_view->targeter();
265
266 // Define a GESTURE_TAP and a GESTURE_SCROLL_BEGIN.
267 gfx::Rect bounding_box(gfx::Point(46, 46), gfx::Size(8, 8));
268 gfx::Point center_point(bounding_box.CenterPoint());
269 ui::GestureEventDetails details(ui::ET_GESTURE_TAP, 0.0f, 0.0f);
270 details.set_bounding_box(bounding_box);
271 GestureEventForTest tap(details, center_point.x(), center_point.y());
272 details = ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0.0f, 0.0f);
273 details.set_bounding_box(bounding_box);
274 GestureEventForTest scroll_begin(details, center_point.x(), center_point.y());
275
276 // Assume that the view currently handling gestures has been set as
277 // |grandchild| by a previous gesture event. Thus subsequent gesture events
278 // should be initially targeted to |grandchild|, and re-targeting should
279 // be prohibited for all gesture event types except for GESTURE_SCROLL_BEGIN
280 // (which should be re-targeted to the parent of |grandchild|).
281 SetAllowGestureEventRetargeting(root_view, false);
282 SetGestureHandler(root_view, grandchild);
283 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap));
284 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap));
285 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin));
286 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin));
287
288 // Assume that the view currently handling gestures is still set as
289 // |grandchild|, but this was not done by a previous gesture. Thus we are
290 // in the process of finding the View to which subsequent gestures will be
291 // dispatched, so all gesture events should be re-targeted up the ancestor
292 // chain.
293 SetAllowGestureEventRetargeting(root_view, true);
294 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap));
295 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin));
296
297 // Assume that the default gesture handler was set by the previous gesture,
298 // but that this handler is currently NULL. No gesture events should be
299 // re-targeted in this case (regardless of the view that is passed in to
300 // FindNextBestTarget() as the previous target).
301 SetGestureHandler(root_view, NULL);
302 SetAllowGestureEventRetargeting(root_view, false);
303 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &tap));
304 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &tap));
305 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &scroll_begin));
306
307 // If no default gesture handler is currently set, targeting should be
308 // performed using the location of the gesture event.
309 SetAllowGestureEventRetargeting(root_view, true);
310 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap));
311 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin));
312 }
313
211 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() 314 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect()
212 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when 315 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when
213 // called on views which are derived from ViewTargeterDelegate. 316 // called on views which are derived from ViewTargeterDelegate.
214 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can 317 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can
215 // be called from the ViewTargeter installed on RootView. 318 // be called from the ViewTargeter installed on RootView.
216 TEST_F(ViewTargeterTest, DoesIntersectRect) { 319 TEST_F(ViewTargeterTest, DoesIntersectRect) {
217 Widget widget; 320 Widget widget;
218 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 321 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
219 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 322 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
220 params.bounds = gfx::Rect(0, 0, 650, 650); 323 params.bounds = gfx::Rect(0, 0, 650, 650);
221 widget.Init(params); 324 widget.Init(params);
222 325
223 internal::RootView* root_view = 326 internal::RootView* root_view =
224 static_cast<internal::RootView*>(widget.GetRootView()); 327 static_cast<internal::RootView*>(widget.GetRootView());
225 ViewTargeter* view_targeter = new ViewTargeter(root_view); 328 ViewTargeter* view_targeter = root_view->targeter();
226 root_view->SetEventTargeter(make_scoped_ptr(view_targeter));
227 329
228 // The coordinates used for SetBounds() are in the parent coordinate space. 330 // The coordinates used for SetBounds() are in the parent coordinate space.
229 TestingView v2; 331 TestingView v2;
230 TestMaskedView v1, v3; 332 TestMaskedView v1, v3;
231 v1.SetBounds(0, 0, 200, 200); 333 v1.SetBounds(0, 0, 200, 200);
232 v2.SetBounds(300, 0, 300, 300); 334 v2.SetBounds(300, 0, 300, 300);
233 v3.SetBounds(0, 0, 100, 100); 335 v3.SetBounds(0, 0, 100, 100);
234 root_view->AddChildView(&v1); 336 root_view->AddChildView(&v1);
235 root_view->AddChildView(&v2); 337 root_view->AddChildView(&v2);
236 v2.AddChildView(&v3); 338 v2.AddChildView(&v3);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); 439 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin));
338 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); 440 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin));
339 441
340 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); 442 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin));
341 443
342 widget->CloseNow(); 444 widget->CloseNow();
343 } 445 }
344 446
345 } // namespace test 447 } // namespace test
346 } // namespace views 448 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/view_targeter.cc ('k') | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698