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_view_targeter.h" | 10 #include "ui/views/masked_view_targeter.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 mask->lineTo(w, h); | 31 mask->lineTo(w, h); |
32 mask->lineTo(0, h); | 32 mask->lineTo(0, h); |
33 mask->close(); | 33 mask->close(); |
34 | 34 |
35 return true; | 35 return true; |
36 } | 36 } |
37 | 37 |
38 DISALLOW_COPY_AND_ASSIGN(TestMaskedViewTargeter); | 38 DISALLOW_COPY_AND_ASSIGN(TestMaskedViewTargeter); |
39 }; | 39 }; |
40 | 40 |
| 41 // A derived class of View used for testing purposes. |
| 42 class TestingView : public View { |
| 43 public: |
| 44 TestingView() : can_process_events_within_subtree_(true) {} |
| 45 virtual ~TestingView() {} |
| 46 |
| 47 // Reset all test state. |
| 48 void Reset() { can_process_events_within_subtree_ = true; } |
| 49 |
| 50 void set_can_process_events_within_subtree(bool can_process) { |
| 51 can_process_events_within_subtree_ = can_process; |
| 52 } |
| 53 |
| 54 // View: |
| 55 virtual bool CanProcessEventsWithinSubtree() const OVERRIDE { |
| 56 return can_process_events_within_subtree_; |
| 57 } |
| 58 |
| 59 private: |
| 60 // Value to return from CanProcessEventsWithinSubtree(). |
| 61 bool can_process_events_within_subtree_; |
| 62 |
| 63 DISALLOW_COPY_AND_ASSIGN(TestingView); |
| 64 }; |
| 65 |
41 namespace test { | 66 namespace test { |
42 | 67 |
43 typedef ViewsTestBase ViewTargeterTest; | 68 typedef ViewsTestBase ViewTargeterTest; |
44 | 69 |
45 // Verifies that the the functions ViewTargeter::FindTargetForEvent() | 70 // Verifies that the the functions ViewTargeter::FindTargetForEvent() |
46 // and ViewTargeter::FindNextBestTarget() are implemented correctly | 71 // and ViewTargeter::FindNextBestTarget() are implemented correctly |
47 // for key events. | 72 // for key events. |
48 TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) { | 73 TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) { |
49 Widget widget; | 74 Widget widget; |
50 Widget::InitParams init_params = | 75 Widget::InitParams init_params = |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v1, event)); | 237 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v1, event)); |
213 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v2, event)); | 238 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v2, event)); |
214 v1.ConvertEventToTarget(&v2, &event); | 239 v1.ConvertEventToTarget(&v2, &event); |
215 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event)); | 240 EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event)); |
216 | 241 |
217 // TODO(tdanderson): Move the hit-testing unit tests out of view_unittest | 242 // TODO(tdanderson): Move the hit-testing unit tests out of view_unittest |
218 // and into here. See crbug.com/355425. | 243 // and into here. See crbug.com/355425. |
219 } | 244 } |
220 | 245 |
221 // Tests that FindTargetForEvent() returns the correct target when some | 246 // Tests that FindTargetForEvent() returns the correct target when some |
| 247 // views in the view tree return false when CanProcessEventsWithinSubtree() |
| 248 // is called on them. |
| 249 TEST_F(ViewTargeterTest, CanProcessEventsWithinSubtree) { |
| 250 Widget widget; |
| 251 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
| 252 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 253 params.bounds = gfx::Rect(0, 0, 650, 650); |
| 254 widget.Init(params); |
| 255 |
| 256 ui::EventTargeter* targeter = new ViewTargeter(); |
| 257 internal::RootView* root_view = |
| 258 static_cast<internal::RootView*>(widget.GetRootView()); |
| 259 root_view->SetEventTargeter(make_scoped_ptr(targeter)); |
| 260 |
| 261 // The coordinates used for SetBounds() are in the parent coordinate space. |
| 262 TestingView v1, v2, v3; |
| 263 v1.SetBounds(0, 0, 300, 300); |
| 264 v2.SetBounds(100, 100, 100, 100); |
| 265 v3.SetBounds(0, 0, 10, 10); |
| 266 root_view->AddChildView(&v1); |
| 267 v1.AddChildView(&v2); |
| 268 v2.AddChildView(&v3); |
| 269 |
| 270 // Note that the coordinates used below are in the coordinate space of |
| 271 // the root view. |
| 272 |
| 273 // Define |scroll| to be (105, 105) (in the coordinate space of the root |
| 274 // view). This is located within all of |v1|, |v2|, and |v3|. |
| 275 gfx::Point scroll_point(105, 105); |
| 276 ui::ScrollEvent scroll( |
| 277 ui::ET_SCROLL, scroll_point, ui::EventTimeForNow(), 0, 0, 3, 0, 3, 2); |
| 278 |
| 279 // If CanProcessEventsWithinSubtree() returns true for each view, |
| 280 // |scroll| should be targeted at the deepest view in the hierarchy, |
| 281 // which is |v3|. |
| 282 ui::EventTarget* current_target = |
| 283 targeter->FindTargetForEvent(root_view, &scroll); |
| 284 EXPECT_EQ(&v3, current_target); |
| 285 |
| 286 // If CanProcessEventsWithinSubtree() returns |false| when called |
| 287 // on |v3|, then |v3| cannot be the target of |scroll| (this should |
| 288 // instead be |v2|). Note we need to reset the location of |scroll| |
| 289 // because it may have been mutated by the previous call to |
| 290 // FindTargetForEvent(). |
| 291 scroll.set_location(scroll_point); |
| 292 v3.set_can_process_events_within_subtree(false); |
| 293 current_target = targeter->FindTargetForEvent(root_view, &scroll); |
| 294 EXPECT_EQ(&v2, current_target); |
| 295 |
| 296 // If CanProcessEventsWithinSubtree() returns |false| when called |
| 297 // on |v2|, then neither |v2| nor |v3| can be the target of |scroll| |
| 298 // (this should instead be |v1|). |
| 299 scroll.set_location(scroll_point); |
| 300 v3.Reset(); |
| 301 v2.set_can_process_events_within_subtree(false); |
| 302 current_target = targeter->FindTargetForEvent(root_view, &scroll); |
| 303 EXPECT_EQ(&v1, current_target); |
| 304 |
| 305 // If CanProcessEventsWithinSubtree() returns |false| when called |
| 306 // on |v1|, then none of |v1|, |v2| or |v3| can be the target of |scroll| |
| 307 // (this should instead be the root view itself). |
| 308 scroll.set_location(scroll_point); |
| 309 v2.Reset(); |
| 310 v1.set_can_process_events_within_subtree(false); |
| 311 current_target = targeter->FindTargetForEvent(root_view, &scroll); |
| 312 EXPECT_EQ(root_view, current_target); |
| 313 |
| 314 // TODO(tdanderson): We should also test that targeting works correctly |
| 315 // with gestures. See crbug.com/375822. |
| 316 } |
| 317 |
| 318 // Tests that FindTargetForEvent() returns the correct target when some |
222 // views in the view tree have a MaskedViewTargeter installed, i.e., | 319 // views in the view tree have a MaskedViewTargeter installed, i.e., |
223 // they have a custom-shaped hit test mask. | 320 // they have a custom-shaped hit test mask. |
224 TEST_F(ViewTargeterTest, MaskedViewTargeter) { | 321 TEST_F(ViewTargeterTest, MaskedViewTargeter) { |
225 Widget widget; | 322 Widget widget; |
226 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); | 323 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); |
227 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 324 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
228 params.bounds = gfx::Rect(0, 0, 650, 650); | 325 params.bounds = gfx::Rect(0, 0, 650, 650); |
229 widget.Init(params); | 326 widget.Init(params); |
230 | 327 |
231 ui::EventTargeter* targeter = new ViewTargeter(); | 328 ui::EventTargeter* targeter = new ViewTargeter(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 scroll.set_location(gfx::Point(300, 12)); | 377 scroll.set_location(gfx::Point(300, 12)); |
281 current_target = targeter->FindTargetForEvent(root_view, &scroll); | 378 current_target = targeter->FindTargetForEvent(root_view, &scroll); |
282 EXPECT_EQ(&unmasked_view, static_cast<View*>(current_target)); | 379 EXPECT_EQ(&unmasked_view, static_cast<View*>(current_target)); |
283 | 380 |
284 // TODO(tdanderson): We should also test that targeting of masked views | 381 // TODO(tdanderson): We should also test that targeting of masked views |
285 // works correctly with gestures. See crbug.com/375822. | 382 // works correctly with gestures. See crbug.com/375822. |
286 } | 383 } |
287 | 384 |
288 } // namespace test | 385 } // namespace test |
289 } // namespace views | 386 } // namespace views |
OLD | NEW |