OLD | NEW |
---|---|
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 "ui/views/controls/scroll_view.h" | 5 #include "ui/views/controls/scroll_view.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 #include "ui/views/border.h" | 9 #include "ui/views/border.h" |
10 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h" | |
11 #include "ui/views/controls/scrollbar/native_scroll_bar.h" | |
12 #include "ui/views/controls/scrollbar/native_scroll_bar_views.h" | |
10 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" | 13 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" |
11 #include "ui/views/test/test_views.h" | 14 #include "ui/views/test/test_views.h" |
15 #include "ui/views/test/widget_test.h" | |
12 | 16 |
13 #if defined(OS_MACOSX) | 17 #if defined(OS_MACOSX) |
14 #include "ui/base/test/scoped_preferred_scroller_style_mac.h" | 18 #include "ui/base/test/scoped_preferred_scroller_style_mac.h" |
15 #endif | 19 #endif |
16 | 20 |
21 enum ScrollBarOrientation { HORIZONTAL, VERTICAL }; | |
22 | |
17 namespace views { | 23 namespace views { |
24 namespace test { | |
25 | |
26 class ScrollViewTestApi { | |
27 public: | |
28 explicit ScrollViewTestApi(ScrollView* scroll_view) | |
29 : scroll_view_(scroll_view) {} | |
30 | |
31 BaseScrollBar* GetBaseScrollBar(ScrollBarOrientation orientation) { | |
32 ScrollBar* scroll_bar = orientation == VERTICAL ? scroll_view_->vert_sb_ | |
33 : scroll_view_->horiz_sb_; | |
34 if (scroll_bar->GetClassName() == NativeScrollBar::kViewClassName) { | |
35 return static_cast<NativeScrollBarViews*>( | |
sky
2016/08/01 22:33:35
ick!
tapted
2016/08/02 00:05:08
yeah.. that was an interesting journey. I guess th
| |
36 static_cast<NativeScrollBar*>(scroll_bar)->native_wrapper_); | |
37 } | |
38 return static_cast<BaseScrollBar*>(scroll_bar); | |
39 } | |
40 | |
41 const base::Timer& GetScrollBarTimer(ScrollBarOrientation orientation) { | |
42 return GetBaseScrollBar(orientation)->repeater_.timer_for_testing(); | |
43 } | |
44 | |
45 BaseScrollBarThumb* GetScrollBarThumb(ScrollBarOrientation orientation) { | |
46 return GetBaseScrollBar(orientation)->thumb_; | |
47 } | |
48 | |
49 View* corner_view() { return scroll_view_->corner_view_; } | |
50 | |
51 private: | |
52 ScrollView* scroll_view_; | |
53 | |
54 DISALLOW_COPY_AND_ASSIGN(ScrollViewTestApi); | |
55 }; | |
56 | |
57 } // namespace test | |
18 | 58 |
19 namespace { | 59 namespace { |
20 | 60 |
21 const int kWidth = 100; | 61 const int kWidth = 100; |
22 const int kMinHeight = 50; | 62 const int kMinHeight = 50; |
23 const int kMaxHeight = 100; | 63 const int kMaxHeight = 100; |
24 | 64 |
25 enum ScrollBarOrientation { HORIZONTAL, VERTICAL }; | |
26 | |
27 // View implementation that allows setting the preferred size. | 65 // View implementation that allows setting the preferred size. |
28 class CustomView : public View { | 66 class CustomView : public View { |
29 public: | 67 public: |
30 CustomView() {} | 68 CustomView() {} |
31 | 69 |
32 void SetPreferredSize(const gfx::Size& size) { | 70 void SetPreferredSize(const gfx::Size& size) { |
33 preferred_size_ = size; | 71 preferred_size_ = size; |
34 PreferredSizeChanged(); | 72 PreferredSizeChanged(); |
35 } | 73 } |
36 | 74 |
(...skipping 23 matching lines...) Expand all Loading... | |
60 ? scroll_view.horizontal_scroll_bar() | 98 ? scroll_view.horizontal_scroll_bar() |
61 : scroll_view.vertical_scroll_bar(); | 99 : scroll_view.vertical_scroll_bar(); |
62 if (should_be_visible) { | 100 if (should_be_visible) { |
63 ASSERT_TRUE(scrollbar); | 101 ASSERT_TRUE(scrollbar); |
64 EXPECT_TRUE(scrollbar->visible()); | 102 EXPECT_TRUE(scrollbar->visible()); |
65 } else { | 103 } else { |
66 EXPECT_TRUE(!scrollbar || !scrollbar->visible()); | 104 EXPECT_TRUE(!scrollbar || !scrollbar->visible()); |
67 } | 105 } |
68 } | 106 } |
69 | 107 |
108 ui::MouseEvent TestLeftMouseAt(const gfx::Point& location, ui::EventType type) { | |
109 return ui::MouseEvent(type, location, location, base::TimeTicks(), | |
110 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | |
111 } | |
112 | |
70 } // namespace | 113 } // namespace |
71 | 114 |
115 using test::ScrollViewTestApi; | |
116 | |
117 // Test harness that includes a Widget to help test ui::Event handling. | |
118 class WidgetScrollViewTest : public test::WidgetTest { | |
119 public: | |
120 const int kDefaultHeight = 100; | |
sky
2016/08/01 22:33:35
static on these two?
tapted
2016/08/02 00:05:08
Done.
I'd actually flip-flopped on this a bit. Wh
| |
121 const int kDefaultWidth = 100; | |
122 | |
123 WidgetScrollViewTest() { | |
124 #if defined(OS_MACOSX) | |
125 // Disable scrollbar hiding (i.e. disable overlay scrollbars) by default. | |
126 scroller_style_.reset(new ui::test::ScopedPreferredScrollerStyle(false)); | |
127 #endif | |
128 } | |
129 | |
130 // Adds a ScrollView with a contents view of the given |size| and does layout. | |
131 ScrollView* AddScrollViewWithContentSize(const gfx::Size& contents_size) { | |
132 const gfx::Rect default_bounds(50, 50, kDefaultWidth, kDefaultHeight); | |
133 widget_ = CreateTopLevelFramelessPlatformWidget(); | |
134 | |
135 ScrollView* scroll_view = new ScrollView(); | |
136 View* contents = new View; | |
137 scroll_view->SetContents(contents); | |
138 contents->SetSize(contents_size); | |
139 | |
140 widget_->SetBounds(default_bounds); | |
141 widget_->Show(); | |
142 | |
143 widget_->SetContentsView(scroll_view); | |
144 scroll_view->Layout(); | |
145 return scroll_view; | |
146 } | |
147 | |
148 // testing::Test: | |
149 void TearDown() override { | |
150 if (widget_) | |
151 widget_->CloseNow(); | |
152 WidgetTest::TearDown(); | |
153 } | |
154 | |
155 private: | |
156 Widget* widget_ = nullptr; | |
157 | |
158 #if defined(OS_MACOSX) | |
159 std::unique_ptr<ui::test::ScopedPreferredScrollerStyle> scroller_style_; | |
160 #endif | |
161 | |
162 DISALLOW_COPY_AND_ASSIGN(WidgetScrollViewTest); | |
163 }; | |
164 | |
72 // Verifies the viewport is sized to fit the available space. | 165 // Verifies the viewport is sized to fit the available space. |
73 TEST(ScrollViewTest, ViewportSizedToFit) { | 166 TEST(ScrollViewTest, ViewportSizedToFit) { |
74 ScrollView scroll_view; | 167 ScrollView scroll_view; |
75 View* contents = new View; | 168 View* contents = new View; |
76 scroll_view.SetContents(contents); | 169 scroll_view.SetContents(contents); |
77 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); | 170 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); |
78 scroll_view.Layout(); | 171 scroll_view.Layout(); |
79 EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString()); | 172 EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString()); |
80 } | 173 } |
81 | 174 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 EXPECT_EQ(scroll_view.contents()->size().width(), expected_width); | 522 EXPECT_EQ(scroll_view.contents()->size().width(), expected_width); |
430 EXPECT_EQ(scroll_view.contents()->size().height(), 1000 * expected_width); | 523 EXPECT_EQ(scroll_view.contents()->size().height(), 1000 * expected_width); |
431 EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size()); | 524 EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size()); |
432 } | 525 } |
433 | 526 |
434 TEST(ScrollViewTest, CornerViewVisibility) { | 527 TEST(ScrollViewTest, CornerViewVisibility) { |
435 ScrollView scroll_view; | 528 ScrollView scroll_view; |
436 View* contents = new View; | 529 View* contents = new View; |
437 scroll_view.SetContents(contents); | 530 scroll_view.SetContents(contents); |
438 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); | 531 scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); |
439 View* corner_view = scroll_view.corner_view_; | 532 View* corner_view = ScrollViewTestApi(&scroll_view).corner_view(); |
440 | 533 |
441 // Corner view should be visible when both scrollbars are visible. | 534 // Corner view should be visible when both scrollbars are visible. |
442 contents->SetBounds(0, 0, 200, 200); | 535 contents->SetBounds(0, 0, 200, 200); |
443 scroll_view.Layout(); | 536 scroll_view.Layout(); |
444 EXPECT_EQ(&scroll_view, corner_view->parent()); | 537 EXPECT_EQ(&scroll_view, corner_view->parent()); |
445 EXPECT_TRUE(corner_view->visible()); | 538 EXPECT_TRUE(corner_view->visible()); |
446 | 539 |
447 // Corner view should be aligned to the scrollbars. | 540 // Corner view should be aligned to the scrollbars. |
448 EXPECT_EQ(scroll_view.vertical_scroll_bar()->x(), corner_view->x()); | 541 EXPECT_EQ(scroll_view.vertical_scroll_bar()->x(), corner_view->x()); |
449 EXPECT_EQ(scroll_view.horizontal_scroll_bar()->y(), corner_view->y()); | 542 EXPECT_EQ(scroll_view.horizontal_scroll_bar()->y(), corner_view->y()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 scroller_style_override.reset( | 618 scroller_style_override.reset( |
526 new ui::test::ScopedPreferredScrollerStyle(false)); | 619 new ui::test::ScopedPreferredScrollerStyle(false)); |
527 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width()); | 620 EXPECT_EQ(100 - scroll_view.GetScrollBarWidth(), contents->parent()->width()); |
528 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(), | 621 EXPECT_EQ(100 - scroll_view.GetScrollBarHeight(), |
529 contents->parent()->height()); | 622 contents->parent()->height()); |
530 EXPECT_NE(0, scroll_view.GetScrollBarWidth()); | 623 EXPECT_NE(0, scroll_view.GetScrollBarWidth()); |
531 EXPECT_NE(0, scroll_view.GetScrollBarHeight()); | 624 EXPECT_NE(0, scroll_view.GetScrollBarHeight()); |
532 } | 625 } |
533 #endif | 626 #endif |
534 | 627 |
628 // Test scrolling behavior when clicking on the scroll track. | |
629 TEST_F(WidgetScrollViewTest, ScrollTrackScrolling) { | |
630 // Set up with a vertical scroller. | |
631 ScrollView* scroll_view = | |
632 AddScrollViewWithContentSize(gfx::Size(10, kDefaultHeight * 5)); | |
633 ScrollViewTestApi test_api(scroll_view); | |
634 BaseScrollBar* scroll_bar = test_api.GetBaseScrollBar(VERTICAL); | |
635 View* thumb = test_api.GetScrollBarThumb(VERTICAL); | |
636 | |
637 // Click in the middle of the track, ensuring it's below the thumb. | |
638 const gfx::Point location = scroll_bar->bounds().CenterPoint(); | |
639 EXPECT_GT(location.y(), thumb->bounds().bottom()); | |
640 ui::MouseEvent press(TestLeftMouseAt(location, ui::ET_MOUSE_PRESSED)); | |
641 ui::MouseEvent release(TestLeftMouseAt(location, ui::ET_MOUSE_RELEASED)); | |
642 | |
643 const base::Timer& timer = test_api.GetScrollBarTimer(VERTICAL); | |
644 EXPECT_FALSE(timer.IsRunning()); | |
645 | |
646 EXPECT_EQ(0, scroll_view->GetVisibleRect().y()); | |
647 scroll_bar->OnMouseEvent(&press); | |
648 | |
649 // Clicking the scroll track should scroll one "page". | |
650 EXPECT_EQ(kDefaultHeight, scroll_view->GetVisibleRect().y()); | |
651 | |
652 // While the mouse is pressed, timer should trigger more scroll events. | |
653 EXPECT_TRUE(timer.IsRunning()); | |
654 | |
655 // Upon release timer should stop (and scroll position should remain). | |
656 scroll_bar->OnMouseEvent(&release); | |
657 EXPECT_FALSE(timer.IsRunning()); | |
658 EXPECT_EQ(kDefaultHeight, scroll_view->GetVisibleRect().y()); | |
659 } | |
660 | |
535 } // namespace views | 661 } // namespace views |
OLD | NEW |