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 // When 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, static_cast<View*>(current_target)); | |
sadrul
2014/05/30 21:20:34
I don't think you need the cast here (or elsewhere
tdanderson
2014/05/30 21:41:49
Done.
| |
285 | |
286 // When CanProcessEventsWithinSubtree() returns |false| when called | |
sadrul
2014/05/30 21:20:34
If
tdanderson
2014/05/30 21:41:49
Done.
| |
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, static_cast<View*>(current_target)); | |
295 | |
296 // When 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, static_cast<View*>(current_target)); | |
304 | |
305 // When 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, static_cast<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 |