Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Side by Side Diff: ui/views/view_unittest.cc

Issue 404213003: [WIP] Allow scroll events to permanently change the default gesture handler in RootView (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: friend test Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <map> 5 #include <map>
6 6
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/rand_util.h" 8 #include "base/rand_util.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "grit/ui_strings.h" 12 #include "grit/ui_strings.h"
13 #include "ui/base/accelerators/accelerator.h" 13 #include "ui/base/accelerators/accelerator.h"
14 #include "ui/base/clipboard/clipboard.h" 14 #include "ui/base/clipboard/clipboard.h"
15 #include "ui/base/l10n/l10n_util.h" 15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/compositor/compositor.h" 16 #include "ui/compositor/compositor.h"
17 #include "ui/compositor/layer.h" 17 #include "ui/compositor/layer.h"
18 #include "ui/compositor/layer_animator.h" 18 #include "ui/compositor/layer_animator.h"
19 #include "ui/compositor/test/draw_waiter_for_test.h" 19 #include "ui/compositor/test/draw_waiter_for_test.h"
20 #include "ui/events/event.h" 20 #include "ui/events/event.h"
21 #include "ui/events/gestures/gesture_recognizer.h"
22 #include "ui/events/keycodes/keyboard_codes.h" 21 #include "ui/events/keycodes/keyboard_codes.h"
23 #include "ui/gfx/canvas.h" 22 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/path.h" 23 #include "ui/gfx/path.h"
25 #include "ui/gfx/transform.h" 24 #include "ui/gfx/transform.h"
26 #include "ui/views/background.h" 25 #include "ui/views/background.h"
27 #include "ui/views/controls/native/native_view_host.h" 26 #include "ui/views/controls/native/native_view_host.h"
28 #include "ui/views/controls/scroll_view.h" 27 #include "ui/views/controls/scroll_view.h"
29 #include "ui/views/controls/textfield/textfield.h" 28 #include "ui/views/controls/textfield/textfield.h"
30 #include "ui/views/focus/view_storage.h" 29 #include "ui/views/focus/view_storage.h"
31 #include "ui/views/test/views_test_base.h" 30 #include "ui/views/test/views_test_base.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 view->ReorderChildView(view_b, a); 169 view->ReorderChildView(view_b, a);
171 } 170 }
172 171
173 if (!view->layer() && base::RandDouble() < 0.1) 172 if (!view->layer() && base::RandDouble() < 0.1)
174 view->SetPaintToLayer(true); 173 view->SetPaintToLayer(true);
175 174
176 if (base::RandDouble() < 0.1) 175 if (base::RandDouble() < 0.1)
177 view->SetVisible(!view->visible()); 176 view->SetVisible(!view->visible());
178 } 177 }
179 178
180 // Convenience to make constructing a GestureEvent simpler.
181 class GestureEventForTest : public ui::GestureEvent {
182 public:
183 GestureEventForTest(ui::EventType type, int x, int y, int flags)
184 : GestureEvent(x, y, flags, base::TimeDelta(),
185 ui::GestureEventDetails(type, 0.0f, 0.0f)) {
186 }
187
188 private:
189 DISALLOW_COPY_AND_ASSIGN(GestureEventForTest);
190 };
191
192 } // namespace 179 } // namespace
193 180
194 namespace views { 181 namespace views {
195 182
196 typedef ViewsTestBase ViewTest; 183 typedef ViewsTestBase ViewTest;
197 184
198 // A derived class for testing purpose. 185 // A derived class for testing purpose.
199 class TestView : public View { 186 class TestView : public View {
200 public: 187 public:
201 TestView() 188 TestView()
202 : View(), 189 : View(),
203 delete_on_pressed_(false), 190 delete_on_pressed_(false),
204 native_theme_(NULL), 191 native_theme_(NULL),
205 can_process_events_within_subtree_(true) {} 192 can_process_events_within_subtree_(true) {}
206 virtual ~TestView() {} 193 virtual ~TestView() {}
207 194
208 // Reset all test state 195 // Reset all test state
209 void Reset() { 196 void Reset() {
210 did_change_bounds_ = false; 197 did_change_bounds_ = false;
211 last_mouse_event_type_ = 0; 198 last_mouse_event_type_ = 0;
212 location_.SetPoint(0, 0); 199 location_.SetPoint(0, 0);
213 received_mouse_enter_ = false; 200 received_mouse_enter_ = false;
214 received_mouse_exit_ = false; 201 received_mouse_exit_ = false;
215 last_gesture_event_type_ = 0;
216 last_gesture_event_was_handled_ = false;
217 last_clip_.setEmpty(); 202 last_clip_.setEmpty();
218 accelerator_count_map_.clear(); 203 accelerator_count_map_.clear();
219 can_process_events_within_subtree_ = true; 204 can_process_events_within_subtree_ = true;
220 } 205 }
221 206
222 // Exposed as public for testing. 207 // Exposed as public for testing.
223 void DoFocus() { 208 void DoFocus() {
224 views::View::Focus(); 209 views::View::Focus();
225 } 210 }
226 211
(...skipping 11 matching lines...) Expand all
238 return can_process_events_within_subtree_; 223 return can_process_events_within_subtree_;
239 } 224 }
240 225
241 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; 226 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
242 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 227 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
243 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; 228 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
244 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 229 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
245 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 230 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
246 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 231 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
247 232
248 // Ignores GestureEvent by default.
249 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
250
251 virtual void Paint(gfx::Canvas* canvas, const CullSet& cull_set) OVERRIDE; 233 virtual void Paint(gfx::Canvas* canvas, const CullSet& cull_set) OVERRIDE;
252 virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE; 234 virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
253 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; 235 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
254 236
255 virtual void OnNativeThemeChanged(const ui::NativeTheme* native_theme) 237 virtual void OnNativeThemeChanged(const ui::NativeTheme* native_theme)
256 OVERRIDE; 238 OVERRIDE;
257 239
258 // OnBoundsChanged. 240 // OnBoundsChanged.
259 bool did_change_bounds_; 241 bool did_change_bounds_;
260 gfx::Rect new_bounds_; 242 gfx::Rect new_bounds_;
261 243
262 // MouseEvent. 244 // MouseEvent.
263 int last_mouse_event_type_; 245 int last_mouse_event_type_;
264 gfx::Point location_; 246 gfx::Point location_;
265 bool received_mouse_enter_; 247 bool received_mouse_enter_;
266 bool received_mouse_exit_; 248 bool received_mouse_exit_;
267 bool delete_on_pressed_; 249 bool delete_on_pressed_;
268 250
269 // Painting. 251 // Painting.
270 std::vector<gfx::Rect> scheduled_paint_rects_; 252 std::vector<gfx::Rect> scheduled_paint_rects_;
271 253
272 // GestureEvent
273 int last_gesture_event_type_;
274 bool last_gesture_event_was_handled_;
275
276 // Painting. 254 // Painting.
277 SkRect last_clip_; 255 SkRect last_clip_;
278 256
279 // Accelerators. 257 // Accelerators.
280 std::map<ui::Accelerator, int> accelerator_count_map_; 258 std::map<ui::Accelerator, int> accelerator_count_map_;
281 259
282 // Native theme. 260 // Native theme.
283 const ui::NativeTheme* native_theme_; 261 const ui::NativeTheme* native_theme_;
284 262
285 // Value to return from CanProcessEventsWithinSubtree(). 263 // Value to return from CanProcessEventsWithinSubtree().
286 bool can_process_events_within_subtree_; 264 bool can_process_events_within_subtree_;
287 }; 265 };
288 266
289 // A view subclass that consumes all Gesture events for testing purposes.
290 class TestViewConsumeGesture : public TestView {
291 public:
292 TestViewConsumeGesture() : TestView() {}
293 virtual ~TestViewConsumeGesture() {}
294
295 protected:
296 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
297 last_gesture_event_type_ = event->type();
298 location_.SetPoint(event->x(), event->y());
299 event->StopPropagation();
300 }
301
302 private:
303 DISALLOW_COPY_AND_ASSIGN(TestViewConsumeGesture);
304 };
305
306 // A view subclass that ignores all Gesture events.
307 class TestViewIgnoreGesture: public TestView {
308 public:
309 TestViewIgnoreGesture() : TestView() {}
310 virtual ~TestViewIgnoreGesture() {}
311
312 private:
313 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
314 }
315
316 DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreGesture);
317 };
318
319 // A view subclass that ignores all scroll-gesture events, but consume all other
320 // gesture events.
321 class TestViewIgnoreScrollGestures : public TestViewConsumeGesture {
322 public:
323 TestViewIgnoreScrollGestures() {}
324 virtual ~TestViewIgnoreScrollGestures() {}
325
326 private:
327 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
328 if (event->IsScrollGestureEvent())
329 return;
330 TestViewConsumeGesture::OnGestureEvent(event);
331 }
332
333 DISALLOW_COPY_AND_ASSIGN(TestViewIgnoreScrollGestures);
334 };
335
336 //////////////////////////////////////////////////////////////////////////////// 267 ////////////////////////////////////////////////////////////////////////////////
337 // OnBoundsChanged 268 // OnBoundsChanged
338 //////////////////////////////////////////////////////////////////////////////// 269 ////////////////////////////////////////////////////////////////////////////////
339 270
340 void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) { 271 void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
341 did_change_bounds_ = true; 272 did_change_bounds_ = true;
342 new_bounds_ = bounds(); 273 new_bounds_ = bounds();
343 } 274 }
344 275
345 TEST_F(ViewTest, OnBoundsChanged) { 276 TEST_F(ViewTest, OnBoundsChanged) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 gfx::Point point(110, 120); 403 gfx::Point point(110, 120);
473 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point, 404 ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
474 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); 405 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
475 root->OnMousePressed(pressed); 406 root->OnMousePressed(pressed);
476 EXPECT_EQ(0, v1->child_count()); 407 EXPECT_EQ(0, v1->child_count());
477 408
478 widget->CloseNow(); 409 widget->CloseNow();
479 } 410 }
480 411
481 //////////////////////////////////////////////////////////////////////////////// 412 ////////////////////////////////////////////////////////////////////////////////
482 // GestureEvent
483 ////////////////////////////////////////////////////////////////////////////////
484
485 void TestView::OnGestureEvent(ui::GestureEvent* event) {
486 }
487
488 TEST_F(ViewTest, ScrollGestureEvent) {
489 // Views hierarchy for non delivery of GestureEvent.
490 TestView* v1 = new TestViewConsumeGesture();
491 v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
492
493 TestView* v2 = new TestViewIgnoreScrollGestures();
494 v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
495
496 TestView* v3 = new TestViewIgnoreGesture();
497 v3->SetBoundsRect(gfx::Rect(0, 0, 100, 100));
498
499 scoped_ptr<Widget> widget(new Widget());
500 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
501 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
502 params.bounds = gfx::Rect(50, 50, 650, 650);
503 widget->Init(params);
504 internal::RootView* root =
505 static_cast<internal::RootView*>(widget->GetRootView());
506 ui::EventDispatchDetails details;
507
508 root->AddChildView(v1);
509 v1->AddChildView(v2);
510 v2->AddChildView(v3);
511
512 // |v3| completely obscures |v2|, but all the gesture events on |v3| should
513 // reach |v2| because |v3| doesn't process any gesture events. However, since
514 // |v2| does process gesture events, gesture events on |v3| or |v2| should not
515 // reach |v1|.
516
517 v1->Reset();
518 v2->Reset();
519 v3->Reset();
520
521 // Gesture on |v3|
522 GestureEventForTest g1(ui::ET_GESTURE_TAP, 110, 110, 0);
523 details = root->OnEventFromSource(&g1);
524 EXPECT_FALSE(details.dispatcher_destroyed);
525 EXPECT_FALSE(details.target_destroyed);
526
527 EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_);
528 EXPECT_EQ(gfx::Point(10, 10), v2->location_);
529 EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_);
530
531 v2->Reset();
532
533 // Send scroll gestures on |v3|. The gesture should reach |v2|, however,
534 // since it does not process scroll-gesture events, these events should reach
535 // |v1|.
536 GestureEventForTest gscroll_begin(ui::ET_GESTURE_SCROLL_BEGIN, 115, 115, 0);
537 details = root->OnEventFromSource(&gscroll_begin);
538 EXPECT_FALSE(details.dispatcher_destroyed);
539 EXPECT_FALSE(details.target_destroyed);
540
541 EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_);
542 EXPECT_EQ(ui::ET_GESTURE_SCROLL_BEGIN, v1->last_gesture_event_type_);
543 v1->Reset();
544
545 // Send a second tap on |v1|. The event should reach |v2| since it is the
546 // default gesture handler, and not |v1| (even though it is the view under the
547 // point, and is the scroll event handler).
548 GestureEventForTest second_tap(ui::ET_GESTURE_TAP, 70, 70, 0);
549 details = root->OnEventFromSource(&second_tap);
550 EXPECT_FALSE(details.dispatcher_destroyed);
551 EXPECT_FALSE(details.target_destroyed);
552
553 EXPECT_EQ(ui::ET_GESTURE_TAP, v2->last_gesture_event_type_);
554 EXPECT_EQ(ui::ET_UNKNOWN, v1->last_gesture_event_type_);
555 v2->Reset();
556
557 GestureEventForTest gscroll_end(ui::ET_GESTURE_SCROLL_END, 50, 50, 0);
558 details = root->OnEventFromSource(&gscroll_end);
559 EXPECT_FALSE(details.dispatcher_destroyed);
560 EXPECT_FALSE(details.target_destroyed);
561
562 EXPECT_EQ(ui::ET_GESTURE_SCROLL_END, v1->last_gesture_event_type_);
563 v1->Reset();
564
565 // Simulate an up so that RootView is no longer targetting |v3|.
566 GestureEventForTest g1_up(ui::ET_GESTURE_END, 110, 110, 0);
567 details = root->OnEventFromSource(&g1_up);
568 EXPECT_FALSE(details.dispatcher_destroyed);
569 EXPECT_FALSE(details.target_destroyed);
570
571 EXPECT_EQ(ui::ET_GESTURE_END, v2->last_gesture_event_type_);
572
573 v1->Reset();
574 v2->Reset();
575 v3->Reset();
576
577 // Gesture on |v1|
578 GestureEventForTest g2(ui::ET_GESTURE_TAP, 80, 80, 0);
579 details = root->OnEventFromSource(&g2);
580 EXPECT_FALSE(details.dispatcher_destroyed);
581 EXPECT_FALSE(details.target_destroyed);
582
583 EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
584 EXPECT_EQ(gfx::Point(80, 80), v1->location_);
585 EXPECT_EQ(ui::ET_UNKNOWN, v2->last_gesture_event_type_);
586
587 // Send event |g1| again. Even though the coordinates target |v3| it should go
588 // to |v1| as that is the view the touch was initially down on.
589 v1->last_gesture_event_type_ = ui::ET_UNKNOWN;
590 v3->last_gesture_event_type_ = ui::ET_UNKNOWN;
591 details = root->OnEventFromSource(&g1);
592 EXPECT_FALSE(details.dispatcher_destroyed);
593 EXPECT_FALSE(details.target_destroyed);
594
595 EXPECT_EQ(ui::ET_GESTURE_TAP, v1->last_gesture_event_type_);
596 EXPECT_EQ(ui::ET_UNKNOWN, v3->last_gesture_event_type_);
597 EXPECT_EQ("110,110", v1->location_.ToString());
598
599 widget->CloseNow();
600 }
601
602 ////////////////////////////////////////////////////////////////////////////////
603 // Painting 413 // Painting
604 //////////////////////////////////////////////////////////////////////////////// 414 ////////////////////////////////////////////////////////////////////////////////
605 415
606 void TestView::Paint(gfx::Canvas* canvas, const CullSet& cull_set) { 416 void TestView::Paint(gfx::Canvas* canvas, const CullSet& cull_set) {
607 canvas->sk_canvas()->getClipBounds(&last_clip_); 417 canvas->sk_canvas()->getClipBounds(&last_clip_);
608 } 418 }
609 419
610 void TestView::SchedulePaintInRect(const gfx::Rect& rect) { 420 void TestView::SchedulePaintInRect(const gfx::Rect& rect) {
611 scheduled_paint_rects_.push_back(rect); 421 scheduled_paint_rects_.push_back(rect);
612 View::SchedulePaintInRect(rect); 422 View::SchedulePaintInRect(rect);
(...skipping 3212 matching lines...) Expand 10 before | Expand all | Expand 10 after
3825 // notification. 3635 // notification.
3826 TestView* test_view_child_2 = new TestView(); 3636 TestView* test_view_child_2 = new TestView();
3827 test_view->AddChildView(test_view_child_2); 3637 test_view->AddChildView(test_view_child_2);
3828 EXPECT_TRUE(test_view_child_2->native_theme_); 3638 EXPECT_TRUE(test_view_child_2->native_theme_);
3829 EXPECT_EQ(widget->GetNativeTheme(), test_view_child_2->native_theme_); 3639 EXPECT_EQ(widget->GetNativeTheme(), test_view_child_2->native_theme_);
3830 3640
3831 widget->CloseNow(); 3641 widget->CloseNow();
3832 } 3642 }
3833 3643
3834 } // namespace views 3644 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698