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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 bool allow) { | 92 bool allow) { |
93 root_view->allow_gesture_event_retargeting_ = allow; | 93 root_view->allow_gesture_event_retargeting_ = allow; |
94 } | 94 } |
95 | 95 |
96 private: | 96 private: |
97 DISALLOW_COPY_AND_ASSIGN(ViewTargeterTest); | 97 DISALLOW_COPY_AND_ASSIGN(ViewTargeterTest); |
98 }; | 98 }; |
99 | 99 |
100 namespace { | 100 namespace { |
101 | 101 |
102 gfx::Point ConvertPointToView(View* view, const gfx::Point& p) { | 102 gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) { |
103 gfx::Point tmp(p); | 103 gfx::Point tmp(p); |
104 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp); | 104 View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp); |
105 return tmp; | 105 return tmp; |
106 } | 106 } |
107 | 107 |
108 gfx::Rect ConvertRectToView(View* view, const gfx::Rect& r) { | 108 gfx::Rect ConvertRectFromWidgetToView(View* view, const gfx::Rect& r) { |
109 gfx::Rect tmp(r); | 109 gfx::Rect tmp(r); |
110 tmp.set_origin(ConvertPointToView(view, r.origin())); | 110 tmp.set_origin(ConvertPointFromWidgetToView(view, r.origin())); |
111 return tmp; | 111 return tmp; |
112 } | 112 } |
113 | 113 |
114 } // namespace | 114 } // namespace |
115 | 115 |
116 // Verifies that the the functions ViewTargeter::FindTargetForEvent() | 116 // Verifies that the the functions ViewTargeter::FindTargetForEvent() |
117 // and ViewTargeter::FindNextBestTarget() are implemented correctly | 117 // and ViewTargeter::FindNextBestTarget() are implemented correctly |
118 // for key events. | 118 // for key events. |
119 TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) { | 119 TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) { |
120 Widget widget; | 120 Widget widget; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 SetAllowGestureEventRetargeting(root_view, false); | 285 SetAllowGestureEventRetargeting(root_view, false); |
286 SetGestureHandler(root_view, grandchild); | 286 SetGestureHandler(root_view, grandchild); |
287 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); | 287 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
288 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap)); | 288 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap)); |
289 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); | 289 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); |
290 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); | 290 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); |
291 | 291 |
292 // GESTURE_END events should be targeted to the existing gesture handler, | 292 // GESTURE_END events should be targeted to the existing gesture handler, |
293 // but re-targeting should be prohibited. | 293 // but re-targeting should be prohibited. |
294 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &end)); | 294 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &end)); |
295 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap)); | 295 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &end)); |
296 | 296 |
297 // Assume that the view currently handling gestures is still set as | 297 // Assume that the view currently handling gestures is still set as |
298 // |grandchild|, but this was not done by a previous gesture. Thus we are | 298 // |grandchild|, but this was not done by a previous gesture. Thus we are |
299 // in the process of finding the View to which subsequent gestures will be | 299 // in the process of finding the View to which subsequent gestures will be |
300 // dispatched, so TAP and SCROLL_BEGIN events should be re-targeted up | 300 // dispatched, so TAP and SCROLL_BEGIN events should be re-targeted up |
301 // the ancestor chain. | 301 // the ancestor chain. |
302 SetAllowGestureEventRetargeting(root_view, true); | 302 SetAllowGestureEventRetargeting(root_view, true); |
303 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap)); | 303 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap)); |
304 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); | 304 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin)); |
305 | 305 |
306 // GESTURE_END events are not permitted to be re-targeted up the ancestor | 306 // GESTURE_END events are not permitted to be re-targeted up the ancestor |
307 // chain; they are only ever targeted in the case where the gesture handler | 307 // chain; they are only ever targeted in the case where the gesture handler |
308 // was established by a previous gesture. | 308 // was established by a previous gesture. |
309 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &end)); | 309 EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &end)); |
310 | 310 |
311 // Assume that the default gesture handler was set by the previous gesture, | 311 // Assume that the default gesture handler was set by the previous gesture, |
312 // but that this handler is currently NULL. No gesture events should be | 312 // but that this handler is currently NULL. No gesture events should be |
313 // re-targeted in this case (regardless of the view that is passed in to | 313 // re-targeted in this case (regardless of the view that is passed in to |
314 // FindNextBestTarget() as the previous target). | 314 // FindNextBestTarget() as the previous target). |
315 SetGestureHandler(root_view, NULL); | 315 SetGestureHandler(root_view, NULL); |
316 SetAllowGestureEventRetargeting(root_view, false); | 316 SetAllowGestureEventRetargeting(root_view, false); |
317 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &tap)); | 317 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &tap)); |
318 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &tap)); | 318 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &tap)); |
319 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &scroll_begin)); | 319 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &scroll_begin)); |
320 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &end)); | 320 EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &end)); |
321 | 321 |
| 322 // Reset the locations of the gesture events to be in the root view |
| 323 // coordinate space since we are about to call FindTargetForEvent() |
| 324 // again (calls to FindTargetForEvent() and FindNextBestTarget() |
| 325 // mutate the location of the gesture events to be in the coordinate |
| 326 // space of the returned view). |
| 327 details = ui::GestureEventDetails(ui::ET_GESTURE_TAP, 0.0f, 0.0f); |
| 328 details.set_bounding_box(bounding_box); |
| 329 tap = GestureEventForTest(details, center_point.x(), center_point.y()); |
| 330 details = ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0.0f, 0.0f); |
| 331 details.set_bounding_box(bounding_box); |
| 332 scroll_begin = |
| 333 GestureEventForTest(details, center_point.x(), center_point.y()); |
| 334 details = ui::GestureEventDetails(ui::ET_GESTURE_END, 0.0f, 0.0f); |
| 335 details.set_bounding_box(bounding_box); |
| 336 end = GestureEventForTest(details, center_point.x(), center_point.y()); |
| 337 |
322 // If no default gesture handler is currently set, targeting should be | 338 // If no default gesture handler is currently set, targeting should be |
323 // performed using the location of the gesture event for a TAP and a | 339 // performed using the location of the gesture event for a TAP and a |
324 // SCROLL_BEGIN. | 340 // SCROLL_BEGIN. |
325 SetAllowGestureEventRetargeting(root_view, true); | 341 SetAllowGestureEventRetargeting(root_view, true); |
326 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); | 342 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
327 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); | 343 EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin)); |
328 | 344 |
329 // If no default gesture handler is currently set, GESTURE_END events | 345 // If no default gesture handler is currently set, GESTURE_END events |
330 // should never be targeted or re-targeted to any View. | 346 // should never be targeted or re-targeted to any View. |
331 EXPECT_EQ(NULL, targeter->FindTargetForEvent(root_view, &end)); | 347 EXPECT_EQ(NULL, targeter->FindTargetForEvent(root_view, &end)); |
332 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &end)); | 348 EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &end)); |
333 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &end)); | 349 EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &end)); |
334 } | 350 } |
335 | 351 |
| 352 // Tests that calls to FindTargetForEvent() and FindNextBestTarget() change |
| 353 // the location of a gesture event to be in the correct coordinate space. |
| 354 TEST_F(ViewTargeterTest, GestureEventCoordinateConversion) { |
| 355 Widget widget; |
| 356 Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP); |
| 357 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 358 init_params.bounds = gfx::Rect(0, 0, 200, 200); |
| 359 widget.Init(init_params); |
| 360 |
| 361 // The coordinates used for SetBounds() are in the parent coordinate space. |
| 362 View* content = new View; |
| 363 content->SetBounds(0, 0, 100, 100); |
| 364 View* child = new View; |
| 365 child->SetBounds(50, 50, 20, 20); |
| 366 View* grandchild = new View; |
| 367 grandchild->SetBounds(5, 5, 10, 10); |
| 368 View* great_grandchild = new View; |
| 369 great_grandchild->SetBounds(3, 3, 4, 4); |
| 370 |
| 371 widget.SetContentsView(content); |
| 372 content->AddChildView(child); |
| 373 child->AddChildView(grandchild); |
| 374 grandchild->AddChildView(great_grandchild); |
| 375 |
| 376 internal::RootView* root_view = |
| 377 static_cast<internal::RootView*>(widget.GetRootView()); |
| 378 ui::EventTargeter* targeter = root_view->targeter(); |
| 379 |
| 380 // Define a GESTURE_TAP event with a bounding box centered at (60, 60) |
| 381 // in root view coordinates with width and height of 4. |
| 382 gfx::Rect bounding_box(gfx::Point(58, 58), gfx::Size(4, 4)); |
| 383 gfx::Point center_point(bounding_box.CenterPoint()); |
| 384 ui::GestureEventDetails details(ui::ET_GESTURE_TAP, 0.0f, 0.0f); |
| 385 details.set_bounding_box(bounding_box); |
| 386 GestureEventForTest tap(details, center_point.x(), center_point.y()); |
| 387 |
| 388 // Calculate the location of the gesture in each of the different |
| 389 // coordinate spaces. |
| 390 gfx::Point location_in_root(center_point); |
| 391 EXPECT_EQ(gfx::Point(60, 60), location_in_root); |
| 392 gfx::Point location_in_great_grandchild( |
| 393 ConvertPointFromWidgetToView(great_grandchild, location_in_root)); |
| 394 EXPECT_EQ(gfx::Point(2, 2), location_in_great_grandchild); |
| 395 gfx::Point location_in_grandchild( |
| 396 ConvertPointFromWidgetToView(grandchild, location_in_root)); |
| 397 EXPECT_EQ(gfx::Point(5, 5), location_in_grandchild); |
| 398 gfx::Point location_in_child( |
| 399 ConvertPointFromWidgetToView(child, location_in_root)); |
| 400 EXPECT_EQ(gfx::Point(10, 10), location_in_child); |
| 401 gfx::Point location_in_content( |
| 402 ConvertPointFromWidgetToView(content, location_in_root)); |
| 403 EXPECT_EQ(gfx::Point(60, 60), location_in_content); |
| 404 |
| 405 // Verify the location of |tap| is in screen coordinates. |
| 406 EXPECT_EQ(gfx::Point(60, 60), tap.location()); |
| 407 |
| 408 // The initial target should be |great_grandchild| and the location of |
| 409 // the event should be changed into the coordinate space of the target. |
| 410 EXPECT_EQ(great_grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
| 411 EXPECT_EQ(location_in_great_grandchild, tap.location()); |
| 412 SetGestureHandler(root_view, great_grandchild); |
| 413 |
| 414 // The next target should be |grandchild| and the location of |
| 415 // the event should be changed into the coordinate space of the target. |
| 416 EXPECT_EQ(grandchild, targeter->FindNextBestTarget(great_grandchild, &tap)); |
| 417 EXPECT_EQ(location_in_grandchild, tap.location()); |
| 418 SetGestureHandler(root_view, grandchild); |
| 419 |
| 420 // The next target should be |child| and the location of |
| 421 // the event should be changed into the coordinate space of the target. |
| 422 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap)); |
| 423 EXPECT_EQ(location_in_child, tap.location()); |
| 424 SetGestureHandler(root_view, child); |
| 425 |
| 426 // The next target should be |content| and the location of |
| 427 // the event should be changed into the coordinate space of the target. |
| 428 EXPECT_EQ(content, targeter->FindNextBestTarget(child, &tap)); |
| 429 EXPECT_EQ(location_in_content, tap.location()); |
| 430 SetGestureHandler(root_view, content); |
| 431 |
| 432 // The next target should be |root_view| and the location of |
| 433 // the event should be changed into the coordinate space of the target. |
| 434 EXPECT_EQ(widget.GetRootView(), targeter->FindNextBestTarget(content, &tap)); |
| 435 EXPECT_EQ(location_in_root, tap.location()); |
| 436 SetGestureHandler(root_view, widget.GetRootView()); |
| 437 |
| 438 // The next target should be NULL and the location of the event should |
| 439 // remain unchanged. |
| 440 EXPECT_EQ(NULL, targeter->FindNextBestTarget(widget.GetRootView(), &tap)); |
| 441 EXPECT_EQ(location_in_root, tap.location()); |
| 442 } |
| 443 |
336 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() | 444 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() |
337 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when | 445 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when |
338 // called on views which are derived from ViewTargeterDelegate. | 446 // called on views which are derived from ViewTargeterDelegate. |
339 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can | 447 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can |
340 // be called from the ViewTargeter installed on RootView. | 448 // be called from the ViewTargeter installed on RootView. |
341 TEST_F(ViewTargeterTest, DoesIntersectRect) { | 449 TEST_F(ViewTargeterTest, DoesIntersectRect) { |
342 Widget widget; | 450 Widget widget; |
343 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 451 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
344 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 452 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
345 params.bounds = gfx::Rect(0, 0, 650, 650); | 453 params.bounds = gfx::Rect(0, 0, 650, 650); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 gfx::Point v1_centerpoint = v1_bounds.CenterPoint(); | 529 gfx::Point v1_centerpoint = v1_bounds.CenterPoint(); |
422 gfx::Point v2_centerpoint = v2_bounds.CenterPoint(); | 530 gfx::Point v2_centerpoint = v2_bounds.CenterPoint(); |
423 gfx::Point v1_origin = v1_bounds.origin(); | 531 gfx::Point v1_origin = v1_bounds.origin(); |
424 gfx::Point v2_origin = v2_bounds.origin(); | 532 gfx::Point v2_origin = v2_bounds.origin(); |
425 gfx::Rect r1(10, 10, 110, 15); | 533 gfx::Rect r1(10, 10, 110, 15); |
426 gfx::Rect r2(106, 1, 98, 98); | 534 gfx::Rect r2(106, 1, 98, 98); |
427 gfx::Rect r3(0, 0, 300, 300); | 535 gfx::Rect r3(0, 0, 300, 300); |
428 gfx::Rect r4(115, 342, 200, 10); | 536 gfx::Rect r4(115, 342, 200, 10); |
429 | 537 |
430 // Test calls into View::HitTestPoint(). | 538 // Test calls into View::HitTestPoint(). |
431 EXPECT_TRUE(v1->HitTestPoint(ConvertPointToView(v1, v1_centerpoint))); | 539 EXPECT_TRUE( |
432 EXPECT_TRUE(v2->HitTestPoint(ConvertPointToView(v2, v2_centerpoint))); | 540 v1->HitTestPoint(ConvertPointFromWidgetToView(v1, v1_centerpoint))); |
| 541 EXPECT_TRUE( |
| 542 v2->HitTestPoint(ConvertPointFromWidgetToView(v2, v2_centerpoint))); |
433 | 543 |
434 EXPECT_TRUE(v1->HitTestPoint(ConvertPointToView(v1, v1_origin))); | 544 EXPECT_TRUE(v1->HitTestPoint(ConvertPointFromWidgetToView(v1, v1_origin))); |
435 EXPECT_FALSE(v2->HitTestPoint(ConvertPointToView(v2, v2_origin))); | 545 EXPECT_FALSE(v2->HitTestPoint(ConvertPointFromWidgetToView(v2, v2_origin))); |
436 | 546 |
437 // Test calls into View::HitTestRect(). | 547 // Test calls into View::HitTestRect(). |
438 EXPECT_TRUE(v1->HitTestRect(ConvertRectToView(v1, r1))); | 548 EXPECT_TRUE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r1))); |
439 EXPECT_FALSE(v2->HitTestRect(ConvertRectToView(v2, r1))); | 549 EXPECT_FALSE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r1))); |
440 | 550 |
441 EXPECT_FALSE(v1->HitTestRect(ConvertRectToView(v1, r2))); | 551 EXPECT_FALSE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r2))); |
442 EXPECT_TRUE(v2->HitTestRect(ConvertRectToView(v2, r2))); | 552 EXPECT_TRUE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r2))); |
443 | 553 |
444 EXPECT_TRUE(v1->HitTestRect(ConvertRectToView(v1, r3))); | 554 EXPECT_TRUE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r3))); |
445 EXPECT_TRUE(v2->HitTestRect(ConvertRectToView(v2, r3))); | 555 EXPECT_TRUE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r3))); |
446 | 556 |
447 EXPECT_FALSE(v1->HitTestRect(ConvertRectToView(v1, r4))); | 557 EXPECT_FALSE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r4))); |
448 EXPECT_FALSE(v2->HitTestRect(ConvertRectToView(v2, r4))); | 558 EXPECT_FALSE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r4))); |
449 | 559 |
450 // Test calls into View::GetEventHandlerForPoint(). | 560 // Test calls into View::GetEventHandlerForPoint(). |
451 EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_centerpoint)); | 561 EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_centerpoint)); |
452 EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint)); | 562 EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint)); |
453 | 563 |
454 EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin)); | 564 EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin)); |
455 EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin)); | 565 EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin)); |
456 | 566 |
457 // Test calls into View::GetTooltipHandlerForPoint(). | 567 // Test calls into View::GetTooltipHandlerForPoint(). |
458 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_centerpoint)); | 568 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_centerpoint)); |
459 EXPECT_EQ(v2, root_view->GetTooltipHandlerForPoint(v2_centerpoint)); | 569 EXPECT_EQ(v2, root_view->GetTooltipHandlerForPoint(v2_centerpoint)); |
460 | 570 |
461 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); | 571 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); |
462 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); | 572 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); |
463 | 573 |
464 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); | 574 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); |
465 | 575 |
466 widget->CloseNow(); | 576 widget->CloseNow(); |
467 } | 577 } |
468 | 578 |
469 } // namespace test | 579 } // namespace test |
470 } // namespace views | 580 } // namespace views |
OLD | NEW |