OLD | NEW |
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 Loading... |
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 SetDispatchToGestureHandler(internal::RootView* root_view, |
| 92 bool dispatch) { |
| 93 root_view->dispatch_to_gesture_handler_ = dispatch; |
| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 gfx::Point(150, 150), | 220 gfx::Point(150, 150), |
202 ui::EventTimeForNow(), | 221 ui::EventTimeForNow(), |
203 0, | 222 0, |
204 0, 3, | 223 0, 3, |
205 0, 3, | 224 0, 3, |
206 2); | 225 2); |
207 current_target = targeter->FindTargetForEvent(root_view, &scroll); | 226 current_target = targeter->FindTargetForEvent(root_view, &scroll); |
208 EXPECT_EQ(content, static_cast<View*>(current_target)); | 227 EXPECT_EQ(content, static_cast<View*>(current_target)); |
209 } | 228 } |
210 | 229 |
| 230 // Convenience to make constructing a GestureEvent simpler. |
| 231 class GestureEventForTest : public ui::GestureEvent { |
| 232 public: |
| 233 GestureEventForTest(ui::EventType type, int x, int y) |
| 234 : GestureEvent(x, |
| 235 y, |
| 236 0, |
| 237 base::TimeDelta(), |
| 238 ui::GestureEventDetails(type, 0.0f, 0.0f)) {} |
| 239 |
| 240 GestureEventForTest(ui::GestureEventDetails details, int x, int y) |
| 241 : GestureEvent(x, y, 0, base::TimeDelta(), details) {} |
| 242 }; |
| 243 |
| 244 // Verifies that the the functions ViewTargeter::FindTargetForEvent() |
| 245 // and ViewTargeter::FindNextBestTarget() are implemented correctly |
| 246 // for gesture events. |
| 247 TEST_F(ViewTargeterTest, ViewTargeterForGestureEvents) { |
| 248 Widget widget; |
| 249 Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP); |
| 250 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 251 init_params.bounds = gfx::Rect(0, 0, 200, 200); |
| 252 widget.Init(init_params); |
| 253 |
| 254 // The coordinates used for SetBounds() are in the parent coordinate space. |
| 255 View* content = new View; |
| 256 content->SetBounds(0, 0, 100, 100); |
| 257 View* child = new View; |
| 258 child->SetBounds(50, 50, 20, 20); |
| 259 View* grandchild = new View; |
| 260 grandchild->SetBounds(0, 0, 5, 5); |
| 261 |
| 262 widget.SetContentsView(content); |
| 263 content->AddChildView(child); |
| 264 child->AddChildView(grandchild); |
| 265 |
| 266 internal::RootView* root_view = |
| 267 static_cast<internal::RootView*>(widget.GetRootView()); |
| 268 ViewTargeter* view_targeter = new ViewTargeter(root_view); |
| 269 ui::EventTargeter* targeter = view_targeter; |
| 270 root_view->SetEventTargeter(make_scoped_ptr(view_targeter)); |
| 271 |
| 272 // Define a GESTURE_TAP and a GESTURE_SCROLL_BEGIN. |
| 273 gfx::Rect bounding_box(gfx::Point(46, 46), gfx::Size(8, 8)); |
| 274 gfx::Point center_point(bounding_box.CenterPoint()); |
| 275 ui::GestureEventDetails details(ui::ET_GESTURE_TAP, 0.0f, 0.0f); |
| 276 details.set_bounding_box(bounding_box); |
| 277 GestureEventForTest tap(details, center_point.x(), center_point.y()); |
| 278 details = ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0.0f, 0.0f); |
| 279 details.set_bounding_box(bounding_box); |
| 280 GestureEventForTest scroll_begin(details, center_point.x(), center_point.y()); |
| 281 |
| 282 // Assume that the view currently handling gestures has been set as |
| 283 // |grandchild| by a previous gesture event. Thus subsequent gesture events |
| 284 // should be initially targeted to |grandchild|, and re-targeting should |
| 285 // be prohibited for all gesture event types except for GESTURE_SCROLL_BEGIN |
| 286 // (which should be re-targeted to the parent of |grandchild|). |
| 287 SetDispatchToGestureHandler(root_view, true); |
| 288 SetGestureHandler(root_view, grandchild); |
| 289 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
| 290 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap)); |
| 291 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); |
| 292 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); |
| 293 |
| 294 // Assume that the view currently handling gestures is still set as |
| 295 // |grandchild|, but this was not done by a previous gesture. Thus we are |
| 296 // in the process of finding the View to which subsequent gestures will be |
| 297 // dispatched, so all gesture events should be re-targeted up the ancestor |
| 298 // chain. |
| 299 SetDispatchToGestureHandler(root_view, false); |
| 300 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap)); |
| 301 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); |
| 302 |
| 303 // Assume that the default gesture handler was set by the previous gesture, |
| 304 // but that this handler is currently NULL. No gesture events should be |
| 305 // re-targeted in this case (regardless of the view that is passed in to |
| 306 // FindNextBestTarget() as the previous target). |
| 307 SetGestureHandler(root_view, NULL); |
| 308 SetDispatchToGestureHandler(root_view, true); |
| 309 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &tap)); |
| 310 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &tap)); |
| 311 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &scroll_begin)); |
| 312 |
| 313 // If no default gesture handler is currently set, targeting should be |
| 314 // performed using the location of the gesture event. |
| 315 SetDispatchToGestureHandler(root_view, false); |
| 316 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
| 317 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); |
| 318 } |
| 319 |
211 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() | 320 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() |
212 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when | 321 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when |
213 // called on views which are derived from ViewTargeterDelegate. | 322 // called on views which are derived from ViewTargeterDelegate. |
214 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can | 323 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can |
215 // be called from the ViewTargeter installed on RootView. | 324 // be called from the ViewTargeter installed on RootView. |
216 TEST_F(ViewTargeterTest, DoesIntersectRect) { | 325 TEST_F(ViewTargeterTest, DoesIntersectRect) { |
217 Widget widget; | 326 Widget widget; |
218 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 327 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
219 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 328 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
220 params.bounds = gfx::Rect(0, 0, 650, 650); | 329 params.bounds = gfx::Rect(0, 0, 650, 650); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); | 446 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); |
338 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); | 447 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); |
339 | 448 |
340 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); | 449 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); |
341 | 450 |
342 widget->CloseNow(); | 451 widget->CloseNow(); |
343 } | 452 } |
344 | 453 |
345 } // namespace test | 454 } // namespace test |
346 } // namespace views | 455 } // namespace views |
OLD | NEW |