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 274 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 ConvertPointToView(great_grandchild, location_in_root)); |
| 394 EXPECT_EQ(gfx::Point(2, 2), location_in_great_grandchild); |
| 395 gfx::Point location_in_grandchild( |
| 396 ConvertPointToView(grandchild, location_in_root)); |
| 397 EXPECT_EQ(gfx::Point(5, 5), location_in_grandchild); |
| 398 gfx::Point location_in_child(ConvertPointToView(child, location_in_root)); |
| 399 EXPECT_EQ(gfx::Point(10, 10), location_in_child); |
| 400 gfx::Point location_in_content(ConvertPointToView(content, location_in_root)); |
| 401 EXPECT_EQ(gfx::Point(60, 60), location_in_content); |
| 402 |
| 403 // Verify the location of |tap| is in screen coordinates. |
| 404 EXPECT_EQ(gfx::Point(60, 60), tap.location()); |
| 405 |
| 406 // The initial target should be |great_grandchild| and the location of |
| 407 // the event should be changed into the coordinate space of the target. |
| 408 EXPECT_EQ(great_grandchild, targeter->FindTargetForEvent(root_view, &tap)); |
| 409 EXPECT_EQ(location_in_great_grandchild, tap.location()); |
| 410 SetGestureHandler(root_view, great_grandchild); |
| 411 |
| 412 // The next target should be |grandchild| and the location of |
| 413 // the event should be changed into the coordinate space of the target. |
| 414 EXPECT_EQ(grandchild, targeter->FindNextBestTarget(great_grandchild, &tap)); |
| 415 EXPECT_EQ(location_in_grandchild, tap.location()); |
| 416 SetGestureHandler(root_view, grandchild); |
| 417 |
| 418 // The next target should be |child| and the location of |
| 419 // the event should be changed into the coordinate space of the target. |
| 420 EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap)); |
| 421 EXPECT_EQ(location_in_child, tap.location()); |
| 422 SetGestureHandler(root_view, child); |
| 423 |
| 424 // The next target should be |content| and the location of |
| 425 // the event should be changed into the coordinate space of the target. |
| 426 EXPECT_EQ(content, targeter->FindNextBestTarget(child, &tap)); |
| 427 EXPECT_EQ(location_in_content, tap.location()); |
| 428 SetGestureHandler(root_view, content); |
| 429 |
| 430 // The next target should be |root_view| and the location of |
| 431 // the event should be changed into the coordinate space of the target. |
| 432 EXPECT_EQ(widget.GetRootView(), targeter->FindNextBestTarget(content, &tap)); |
| 433 EXPECT_EQ(location_in_root, tap.location()); |
| 434 SetGestureHandler(root_view, widget.GetRootView()); |
| 435 |
| 436 // The next target should be NULL and the location of the event should |
| 437 // remain unchanged. |
| 438 EXPECT_EQ(NULL, targeter->FindNextBestTarget(widget.GetRootView(), &tap)); |
| 439 EXPECT_EQ(location_in_root, tap.location()); |
| 440 } |
| 441 |
336 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() | 442 // Tests that the functions ViewTargeterDelegate::DoesIntersectRect() |
337 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when | 443 // and MaskedTargeterDelegate::DoesIntersectRect() work as intended when |
338 // called on views which are derived from ViewTargeterDelegate. | 444 // called on views which are derived from ViewTargeterDelegate. |
339 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can | 445 // Also verifies that ViewTargeterDelegate::DoesIntersectRect() can |
340 // be called from the ViewTargeter installed on RootView. | 446 // be called from the ViewTargeter installed on RootView. |
341 TEST_F(ViewTargeterTest, DoesIntersectRect) { | 447 TEST_F(ViewTargeterTest, DoesIntersectRect) { |
342 Widget widget; | 448 Widget widget; |
343 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 449 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
344 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 450 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
345 params.bounds = gfx::Rect(0, 0, 650, 650); | 451 params.bounds = gfx::Rect(0, 0, 650, 650); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); | 567 EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin)); |
462 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); | 568 EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin)); |
463 | 569 |
464 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); | 570 EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin)); |
465 | 571 |
466 widget->CloseNow(); | 572 widget->CloseNow(); |
467 } | 573 } |
468 | 574 |
469 } // namespace test | 575 } // namespace test |
470 } // namespace views | 576 } // namespace views |
OLD | NEW |