1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/view_targeter.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/event_targeter.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/event_utils.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/path.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/masked_targeter_delegate.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/test/views_test_base.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/view_targeter.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/view_targeter_delegate.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/widget/root_view.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace views {
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A derived class of View used for testing purposes.
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TestingView : public View, public ViewTargeterDelegate {
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestingView() : can_process_events_within_subtree_(true) {}
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~TestingView() {}
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Reset all test state.
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Reset() { can_process_events_within_subtree_ = true; }
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_can_process_events_within_subtree(bool can_process) {
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    can_process_events_within_subtree_ = can_process;
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // A call-through function to ViewTargeterDelegate::DoesIntersectRect().
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool TestDoesIntersectRect(const View* target, const gfx::Rect& rect) const {
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return DoesIntersectRect(target, rect);
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // View:
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual bool CanProcessEventsWithinSubtree() const OVERRIDE {
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return can_process_events_within_subtree_;
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Value to return from CanProcessEventsWithinSubtree().
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool can_process_events_within_subtree_;
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestingView);
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// A derived class of View having a triangular-shaped hit test mask.
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TestMaskedView : public View, public MaskedTargeterDelegate {
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestMaskedView() {}
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~TestMaskedView() {}
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // A call-through function to MaskedTargeterDelegate::DoesIntersectRect().
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool TestDoesIntersectRect(const View* target, const gfx::Rect& rect) const {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return DoesIntersectRect(target, rect);
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // MaskedTargeterDelegate:
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool GetHitTestMask(gfx::Path* mask) const OVERRIDE {
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(mask);
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SkScalar w = SkIntToScalar(width());
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SkScalar h = SkIntToScalar(height());
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Create a triangular mask within the bounds of this View.
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    mask->moveTo(w / 2, 0);
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    mask->lineTo(w, h);
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    mask->lineTo(0, h);
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    mask->close();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(TestMaskedView);
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace test {
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(tdanderson): Clean up this test suite by moving common code/state into
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//                   ViewTargeterTest and overriding SetUp(), TearDown(), etc.
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//                   See crbug.com/355680.
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ViewTargeterTest : public ViewsTestBase {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ViewTargeterTest() {}
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~ViewTargeterTest() {}
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetGestureHandler(internal::RootView* root_view, View* handler) {
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    root_view->gesture_handler_ = handler;
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetGestureHandlerSetBeforeProcessing(internal::RootView* root_view,
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            bool set) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    root_view->gesture_handler_set_before_processing_ = set;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(ViewTargeterTest);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Point tmp(p);
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp);
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tmp;
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::Rect ConvertRectFromWidgetToView(View* view, const gfx::Rect& r) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect tmp(r);
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tmp.set_origin(ConvertPointFromWidgetToView(view, r.origin()));
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return tmp;
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Verifies that the the functions ViewTargeter::FindTargetForEvent()
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// and ViewTargeter::FindNextBestTarget() are implemented correctly
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// for key events.
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) {
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Widget widget;
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Widget::InitParams init_params =
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_POPUP);
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  widget.Init(init_params);
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* content = new View;
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* child = new View;
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* grandchild = new View;
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  widget.SetContentsView(content);
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  content->AddChildView(child);
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  child->AddChildView(grandchild);
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  grandchild->SetFocusable(true);
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  grandchild->RequestFocus();
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  internal::RootView* root_view =
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      static_cast<internal::RootView*>(widget.GetRootView());
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::EventTargeter* targeter = root_view->targeter();
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::KeyEvent key_event('a', ui::VKEY_A, ui::EF_NONE);
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The focused view should be the initial target of the event.
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                                 &key_event);
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(grandchild, static_cast<View*>(current_target));
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verify that FindNextBestTarget() will return the parent view of the
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // argument (and NULL if the argument has no parent view).
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(grandchild, &key_event);
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(child, static_cast<View*>(current_target));
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(child, &key_event);
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(content, static_cast<View*>(current_target));
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(content, &key_event);
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(widget.GetRootView(), static_cast<View*>(current_target));
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(widget.GetRootView(),
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                &key_event);
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(NULL, static_cast<View*>(current_target));
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Verifies that the the functions ViewTargeter::FindTargetForEvent()
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// and ViewTargeter::FindNextBestTarget() are implemented correctly
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// for scroll events.
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(ViewTargeterTest, ViewTargeterForScrollEvents) {
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Widget widget;
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Widget::InitParams init_params =
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_POPUP);
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  widget.Init(init_params);
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The coordinates used for SetBounds() are in the parent coordinate space.
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* content = new View;
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  content->SetBounds(0, 0, 100, 100);
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* child = new View;
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  child->SetBounds(50, 50, 20, 20);
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  View* grandchild = new View;
178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  grandchild->SetBounds(0, 0, 5, 5);
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  widget.SetContentsView(content);
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  content->AddChildView(child);
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  child->AddChildView(grandchild);
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  internal::RootView* root_view =
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      static_cast<internal::RootView*>(widget.GetRootView());
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::EventTargeter* targeter = root_view->targeter();
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The event falls within the bounds of |child| and |content| but not
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // |grandchild|, so |child| should be the initial target for the event.
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         gfx::Point(60, 60),
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         ui::EventTimeForNow(),
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         0,
194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         0, 3,
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         0, 3,
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         2);
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                                 &scroll);
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(child, static_cast<View*>(current_target));
200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verify that FindNextBestTarget() will return the parent view of the
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // argument (and NULL if the argument has no parent view).
203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(child, &scroll);
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(content, static_cast<View*>(current_target));
205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(content, &scroll);
206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(widget.GetRootView(), static_cast<View*>(current_target));
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindNextBestTarget(widget.GetRootView(),
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                &scroll);
209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(NULL, static_cast<View*>(current_target));
210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The event falls outside of the original specified bounds of |content|,
212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // |child|, and |grandchild|. But since |content| is the contents view,
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // and contents views are resized to fill the entire area of the root
214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // view, the event's initial target should still be |content|.
215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scroll = ui::ScrollEvent(ui::ET_SCROLL,
216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           gfx::Point(150, 150),
217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           ui::EventTimeForNow(),
218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           0,
219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           0, 3,
220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           0, 3,
221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           2);
222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_target = targeter->FindTargetForEvent(root_view, &scroll);
223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(content, static_cast<View*>(current_target));
224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Convenience to make constructing a GestureEvent simpler.
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass GestureEventForTest : public ui::GestureEvent {
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest(ui::EventType type, int x, int y)
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : GestureEvent(x,
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     y,
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     0,
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     base::TimeDelta(),
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ui::GestureEventDetails(type)) {}
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest(ui::GestureEventDetails details, int x, int y)
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : GestureEvent(x, y, 0, base::TimeDelta(), details) {}
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Verifies that the the functions ViewTargeter::FindTargetForEvent()
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// and ViewTargeter::FindNextBestTarget() are implemented correctly
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// for gesture events.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ViewTargeterTest, ViewTargeterForGestureEvents) {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Widget widget;
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_params.bounds = gfx::Rect(0, 0, 200, 200);
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  widget.Init(init_params);
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The coordinates used for SetBounds() are in the parent coordinate space.
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* content = new View;
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content->SetBounds(0, 0, 100, 100);
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* child = new View;
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child->SetBounds(50, 50, 20, 20);
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* grandchild = new View;
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  grandchild->SetBounds(0, 0, 5, 5);
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  widget.SetContentsView(content);
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content->AddChildView(child);
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child->AddChildView(grandchild);
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  internal::RootView* root_view =
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<internal::RootView*>(widget.GetRootView());
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::EventTargeter* targeter = root_view->targeter();
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Define some gesture events for testing.
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect bounding_box(gfx::Point(46, 46), gfx::Size(8, 8));
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point center_point(bounding_box.CenterPoint());
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest tap(details, center_point.x(), center_point.y());
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details = ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN);
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest scroll_begin(details, center_point.x(), center_point.y());
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details = ui::GestureEventDetails(ui::ET_GESTURE_END);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest end(details, center_point.x(), center_point.y());
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assume that the view currently handling gestures has been set as
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |grandchild| by a previous gesture event. Thus subsequent TAP and
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // SCROLL_BEGIN events should be initially targeted to |grandchild|, and
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // re-targeting should be prohibited for TAP but permitted for
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // GESTURE_SCROLL_BEGIN (which should be re-targeted to the parent of
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |grandchild|).
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandlerSetBeforeProcessing(root_view, true);
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, grandchild);
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap));
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &tap));
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin));
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin));
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // GESTURE_END events should be targeted to the existing gesture handler,
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // but re-targeting should be prohibited.
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &end));
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &end));
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assume that the view currently handling gestures is still set as
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |grandchild|, but this was not done by a previous gesture. Thus we are
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // in the process of finding the View to which subsequent gestures will be
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // dispatched, so TAP and SCROLL_BEGIN events should be re-targeted up
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the ancestor chain.
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandlerSetBeforeProcessing(root_view, false);
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap));
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &scroll_begin));
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // GESTURE_END events are not permitted to be re-targeted up the ancestor
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // chain; they are only ever targeted in the case where the gesture handler
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // was established by a previous gesture.
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(grandchild, &end));
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assume that the default gesture handler was set by the previous gesture,
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // but that this handler is currently NULL. No gesture events should be
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // re-targeted in this case (regardless of the view that is passed in to
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // FindNextBestTarget() as the previous target).
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, NULL);
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandlerSetBeforeProcessing(root_view, true);
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &tap));
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &tap));
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &scroll_begin));
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(content, &end));
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Reset the locations of the gesture events to be in the root view
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // coordinate space since we are about to call FindTargetForEvent()
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // again (calls to FindTargetForEvent() and FindNextBestTarget()
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // mutate the location of the gesture events to be in the coordinate
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // space of the returned view).
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details = ui::GestureEventDetails(ui::ET_GESTURE_TAP);
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  tap = GestureEventForTest(details, center_point.x(), center_point.y());
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details = ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN);
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scroll_begin =
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GestureEventForTest(details, center_point.x(), center_point.y());
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details = ui::GestureEventDetails(ui::ET_GESTURE_END);
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  end = GestureEventForTest(details, center_point.x(), center_point.y());
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If no default gesture handler is currently set, targeting should be
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // performed using the location of the gesture event for a TAP and a
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // SCROLL_BEGIN.
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandlerSetBeforeProcessing(root_view, false);
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &tap));
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindTargetForEvent(root_view, &scroll_begin));
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If no default gesture handler is currently set, GESTURE_END events
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // should never be targeted or re-targeted to any View.
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindTargetForEvent(root_view, &end));
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(NULL, &end));
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(child, &end));
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that calls to FindTargetForEvent() and FindNextBestTarget() change
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the location of a gesture event to be in the correct coordinate space.
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ViewTargeterTest, GestureEventCoordinateConversion) {
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Widget widget;
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_params.bounds = gfx::Rect(0, 0, 200, 200);
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  widget.Init(init_params);
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The coordinates used for SetBounds() are in the parent coordinate space.
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* content = new View;
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content->SetBounds(0, 0, 100, 100);
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* child = new View;
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child->SetBounds(50, 50, 20, 20);
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* grandchild = new View;
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  grandchild->SetBounds(5, 5, 10, 10);
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  View* great_grandchild = new View;
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  great_grandchild->SetBounds(3, 3, 4, 4);
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  widget.SetContentsView(content);
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content->AddChildView(child);
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child->AddChildView(grandchild);
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  grandchild->AddChildView(great_grandchild);
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  internal::RootView* root_view =
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<internal::RootView*>(widget.GetRootView());
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::EventTargeter* targeter = root_view->targeter();
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Define a GESTURE_TAP event with a bounding box centered at (60, 60)
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // in root view coordinates with width and height of 4.
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect bounding_box(gfx::Point(58, 58), gfx::Size(4, 4));
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point center_point(bounding_box.CenterPoint());
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  details.set_bounding_box(bounding_box);
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GestureEventForTest tap(details, center_point.x(), center_point.y());
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Calculate the location of the gesture in each of the different
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // coordinate spaces.
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point location_in_root(center_point);
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(60, 60), location_in_root);
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point location_in_great_grandchild(
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConvertPointFromWidgetToView(great_grandchild, location_in_root));
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(2, 2), location_in_great_grandchild);
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point location_in_grandchild(
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConvertPointFromWidgetToView(grandchild, location_in_root));
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(5, 5), location_in_grandchild);
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point location_in_child(
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConvertPointFromWidgetToView(child, location_in_root));
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(10, 10), location_in_child);
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Point location_in_content(
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConvertPointFromWidgetToView(content, location_in_root));
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(60, 60), location_in_content);
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify the location of |tap| is in screen coordinates.
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(gfx::Point(60, 60), tap.location());
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The initial target should be |great_grandchild| and the location of
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the event should be changed into the coordinate space of the target.
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(great_grandchild, targeter->FindTargetForEvent(root_view, &tap));
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_great_grandchild, tap.location());
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, great_grandchild);
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The next target should be |grandchild| and the location of
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the event should be changed into the coordinate space of the target.
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(grandchild, targeter->FindNextBestTarget(great_grandchild, &tap));
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_grandchild, tap.location());
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, grandchild);
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The next target should be |child| and the location of
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the event should be changed into the coordinate space of the target.
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(child, targeter->FindNextBestTarget(grandchild, &tap));
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_child, tap.location());
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, child);
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The next target should be |content| and the location of
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the event should be changed into the coordinate space of the target.
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(content, targeter->FindNextBestTarget(child, &tap));
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_content, tap.location());
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, content);
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The next target should be |root_view| and the location of
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the event should be changed into the coordinate space of the target.
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(widget.GetRootView(), targeter->FindNextBestTarget(content, &tap));
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_root, tap.location());
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetGestureHandler(root_view, widget.GetRootView());
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The next target should be NULL and the location of the event should
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // remain unchanged.
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(NULL, targeter->FindNextBestTarget(widget.GetRootView(), &tap));
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(location_in_root, tap.location());
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Tests that the functions ViewTargeterDelegate::DoesIntersectRect()
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// and MaskedTargeterDelegate::DoesIntersectRect() work as intended when
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// called on views which are derived from ViewTargeterDelegate.
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Also verifies that ViewTargeterDelegate::DoesIntersectRect() can
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// be called from the ViewTargeter installed on RootView.
449116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ViewTargeterTest, DoesIntersectRect) {
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Widget widget;
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 650, 650);
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  widget.Init(params);
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  internal::RootView* root_view =
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      static_cast<internal::RootView*>(widget.GetRootView());
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ViewTargeter* view_targeter = root_view->targeter();
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The coordinates used for SetBounds() are in the parent coordinate space.
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestingView v2;
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestMaskedView v1, v3;
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v1.SetBounds(0, 0, 200, 200);
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v2.SetBounds(300, 0, 300, 300);
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v3.SetBounds(0, 0, 100, 100);
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->AddChildView(&v1);
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->AddChildView(&v2);
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v2.AddChildView(&v3);
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The coordinates used below are in the local coordinate space of the
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // view that is passed in as an argument.
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Hit tests against |v1|, which has a hit test mask.
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v1.TestDoesIntersectRect(&v1, gfx::Rect(0, 0, 200, 200)));
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v1.TestDoesIntersectRect(&v1, gfx::Rect(-10, -10, 110, 12)));
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v1.TestDoesIntersectRect(&v1, gfx::Rect(112, 142, 1, 1)));
477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v1.TestDoesIntersectRect(&v1, gfx::Rect(0, 0, 20, 20)));
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v1.TestDoesIntersectRect(&v1, gfx::Rect(-10, -10, 90, 12)));
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v1.TestDoesIntersectRect(&v1, gfx::Rect(150, 49, 1, 1)));
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Hit tests against |v2|, which does not have a hit test mask.
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v2.TestDoesIntersectRect(&v2, gfx::Rect(0, 0, 200, 200)));
483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v2.TestDoesIntersectRect(&v2, gfx::Rect(-10, 250, 60, 60)));
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v2.TestDoesIntersectRect(&v2, gfx::Rect(250, 250, 1, 1)));
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v2.TestDoesIntersectRect(&v2, gfx::Rect(-10, 250, 7, 7)));
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v2.TestDoesIntersectRect(&v2, gfx::Rect(-1, -1, 1, 1)));
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Hit tests against |v3|, which has a hit test mask and is a child of |v2|.
489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v3.TestDoesIntersectRect(&v3, gfx::Rect(0, 0, 50, 50)));
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(v3.TestDoesIntersectRect(&v3, gfx::Rect(90, 90, 1, 1)));
491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v3.TestDoesIntersectRect(&v3, gfx::Rect(10, 125, 50, 50)));
492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v3.TestDoesIntersectRect(&v3, gfx::Rect(110, 110, 1, 1)));
493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Verify that hit-testing is performed correctly when using the
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // call-through function ViewTargeter::DoesIntersectRect().
496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(view_targeter->DoesIntersectRect(root_view,
497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                               gfx::Rect(0, 0, 50, 50)));
498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(view_targeter->DoesIntersectRect(root_view,
499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                gfx::Rect(-20, -20, 10, 10)));
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Tests that calls made directly on the hit-testing methods in View
503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// (HitTestPoint(), HitTestRect(), etc.) return the correct values.
504116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ViewTargeterTest, HitTestCallsOnView) {
505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The coordinates in this test are in the coordinate space of the root view.
506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Widget* widget = new Widget;
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  widget->Init(params);
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  View* root_view = widget->GetRootView();
510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |v1| has no hit test mask. No ViewTargeter is installed on |v1|, which
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // means that View::HitTestRect() will call into the targeter installed on
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the root view instead when we hit test against |v1|.
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect v1_bounds = gfx::Rect(0, 0, 100, 100);
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestingView* v1 = new TestingView();
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v1->SetBoundsRect(v1_bounds);
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->AddChildView(v1);
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |v2| has a triangular hit test mask. Install a ViewTargeter on |v2| which
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // will be called into by View::HitTestRect().
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect v2_bounds = gfx::Rect(105, 0, 100, 100);
523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestMaskedView* v2 = new TestMaskedView();
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v2->SetBoundsRect(v2_bounds);
525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  root_view->AddChildView(v2);
526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ViewTargeter* view_targeter = new ViewTargeter(v2);
527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v2->SetEventTargeter(make_scoped_ptr(view_targeter));
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Point v1_centerpoint = v1_bounds.CenterPoint();
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Point v2_centerpoint = v2_bounds.CenterPoint();
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Point v1_origin = v1_bounds.origin();
532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Point v2_origin = v2_bounds.origin();
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect r1(10, 10, 110, 15);
534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect r2(106, 1, 98, 98);
535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect r3(0, 0, 300, 300);
536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gfx::Rect r4(115, 342, 200, 10);
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Test calls into View::HitTestPoint().
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      v1->HitTestPoint(ConvertPointFromWidgetToView(v1, v1_centerpoint)));
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      v2->HitTestPoint(ConvertPointFromWidgetToView(v2, v2_centerpoint)));
543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(v1->HitTestPoint(ConvertPointFromWidgetToView(v1, v1_origin)));
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(v2->HitTestPoint(ConvertPointFromWidgetToView(v2, v2_origin)));
546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Test calls into View::HitTestRect().
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r1)));
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r1)));
550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r2)));
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r2)));
553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r3)));
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r3)));
556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(v1->HitTestRect(ConvertRectFromWidgetToView(v1, r4)));
5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(v2->HitTestRect(ConvertRectFromWidgetToView(v2, r4)));
559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Test calls into View::GetEventHandlerForPoint().
561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_centerpoint));
562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v2, root_view->GetEventHandlerForPoint(v2_centerpoint));
563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v1, root_view->GetEventHandlerForPoint(v1_origin));
565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(root_view, root_view->GetEventHandlerForPoint(v2_origin));
566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Test calls into View::GetTooltipHandlerForPoint().
568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_centerpoint));
569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v2, root_view->GetTooltipHandlerForPoint(v2_centerpoint));
570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(v1, root_view->GetTooltipHandlerForPoint(v1_origin));
572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(root_view, root_view->GetTooltipHandlerForPoint(v2_origin));
573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(v1->GetTooltipHandlerForPoint(v2_origin));
575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  widget->CloseNow();
577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace test
580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace views
581