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/bubble/bubble_frame_view.h" | 5 #include "ui/views/bubble/bubble_frame_view.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
11 #include "ui/base/test/material_design_controller_test_api.h" | |
11 #include "ui/gfx/geometry/insets.h" | 12 #include "ui/gfx/geometry/insets.h" |
12 #include "ui/gfx/geometry/rect.h" | 13 #include "ui/gfx/geometry/rect.h" |
13 #include "ui/gfx/geometry/size.h" | 14 #include "ui/gfx/geometry/size.h" |
14 #include "ui/views/bubble/bubble_border.h" | 15 #include "ui/views/bubble/bubble_border.h" |
16 #include "ui/views/bubble/bubble_dialog_delegate.h" | |
15 #include "ui/views/controls/button/label_button.h" | 17 #include "ui/views/controls/button/label_button.h" |
16 #include "ui/views/test/test_views.h" | 18 #include "ui/views/test/test_views.h" |
19 #include "ui/views/test/test_views_delegate.h" | |
17 #include "ui/views/test/views_test_base.h" | 20 #include "ui/views/test/views_test_base.h" |
18 #include "ui/views/widget/widget.h" | 21 #include "ui/views/widget/widget.h" |
19 #include "ui/views/widget/widget_delegate.h" | 22 #include "ui/views/widget/widget_delegate.h" |
23 #include "ui/views/window/dialog_delegate.h" | |
20 | 24 |
21 namespace views { | 25 namespace views { |
22 | 26 |
23 typedef ViewsTestBase BubbleFrameViewTest; | 27 class BubbleFrameViewTestViewsDelegate : public TestViewsDelegate { |
28 public: | |
29 BubbleFrameViewTestViewsDelegate() {} | |
30 ~BubbleFrameViewTestViewsDelegate() override {} | |
31 | |
32 // TestViewsDelegate: | |
33 int GetSnappedDialogWidth(int min_width) const override { | |
34 return snapped_width_ ? snapped_width_ : min_width; | |
35 } | |
36 | |
37 void set_snapped_width(int width) { snapped_width_ = width; } | |
38 | |
39 private: | |
40 int snapped_width_ = 0; | |
41 | |
42 DISALLOW_COPY_AND_ASSIGN(BubbleFrameViewTestViewsDelegate); | |
43 }; | |
44 | |
45 class BubbleFrameViewTest : public ViewsTestBase { | |
46 public: | |
47 BubbleFrameViewTest() { | |
48 views_delegate_ = new BubbleFrameViewTestViewsDelegate; | |
49 set_views_delegate(base::WrapUnique(views_delegate_)); | |
50 } | |
51 ~BubbleFrameViewTest() override {} | |
52 | |
53 BubbleFrameViewTestViewsDelegate* views_delegate() { return views_delegate_; } | |
54 | |
55 private: | |
56 BubbleFrameViewTestViewsDelegate* views_delegate_; | |
57 | |
58 DISALLOW_COPY_AND_ASSIGN(BubbleFrameViewTest); | |
59 }; | |
24 | 60 |
25 namespace { | 61 namespace { |
26 | 62 |
27 const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT; | 63 const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT; |
28 const SkColor kColor = SK_ColorRED; | 64 const SkColor kColor = SK_ColorRED; |
29 const int kMargin = 6; | 65 const int kMargin = 6; |
30 const int kMinimumClientWidth = 100; | 66 const int kMinimumClientWidth = 100; |
31 const int kMinimumClientHeight = 200; | 67 const int kMinimumClientHeight = 200; |
32 const int kMaximumClientWidth = 300; | 68 const int kMaximumClientWidth = 300; |
33 const int kMaximumClientHeight = 300; | 69 const int kMaximumClientHeight = 300; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 void SetShouldShowCloseButton(bool should_show_close) { | 102 void SetShouldShowCloseButton(bool should_show_close) { |
67 should_show_close_ = should_show_close; | 103 should_show_close_ = should_show_close; |
68 } | 104 } |
69 | 105 |
70 private: | 106 private: |
71 Widget* widget_; | 107 Widget* widget_; |
72 View* contents_view_ = nullptr; // Owned by |widget_|. | 108 View* contents_view_ = nullptr; // Owned by |widget_|. |
73 bool should_show_close_ = false; | 109 bool should_show_close_ = false; |
74 }; | 110 }; |
75 | 111 |
112 // A subclass of TestBubbleFrameViewWidgetDelegate that is also a | |
113 // DialogDelegate, used to test creation of Bubbles end-to-end, since the width | |
114 // snapping logic for bubbles only applies to bubbles whose widget delegate is a | |
115 // DialogDelegate. | |
116 // | |
117 // Having a multiple-implementation inherited class is perilous, but there does | |
118 // not seem to be an easy way to avoid it. | |
119 class TestBubbleFrameViewDialogDelegate | |
120 : public DialogDelegate, | |
121 public TestBubbleFrameViewWidgetDelegate { | |
tapted
2017/04/06 00:24:44
I don't think we need this - we're not really inte
Peter Kasting
2017/04/06 06:32:16
+1
| |
122 public: | |
123 TestBubbleFrameViewDialogDelegate(Widget* widget) | |
124 : TestBubbleFrameViewWidgetDelegate(widget) {} | |
125 ~TestBubbleFrameViewDialogDelegate() override {} | |
126 | |
127 // These are defined on both parent classes, so they need to be disambiguated | |
128 // thus: | |
129 Widget* GetWidget() override { | |
130 return TestBubbleFrameViewWidgetDelegate::GetWidget(); | |
131 } | |
132 const Widget* GetWidget() const override { | |
133 return TestBubbleFrameViewWidgetDelegate::GetWidget(); | |
134 } | |
135 DialogDelegate* AsDialogDelegate() override { return this; } | |
136 | |
137 private: | |
138 DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameViewDialogDelegate); | |
139 }; | |
140 | |
76 class TestBubbleFrameView : public BubbleFrameView { | 141 class TestBubbleFrameView : public BubbleFrameView { |
77 public: | 142 public: |
78 TestBubbleFrameView(ViewsTestBase* test_base) | 143 TestBubbleFrameView(ViewsTestBase* test_base) |
79 : BubbleFrameView(gfx::Insets(), gfx::Insets(kMargin)), | 144 : BubbleFrameView(gfx::Insets(), gfx::Insets(kMargin)), |
80 test_base_(test_base), | 145 test_base_(test_base), |
81 available_bounds_(gfx::Rect(0, 0, 1000, 1000)) { | 146 available_bounds_(gfx::Rect(0, 0, 1000, 1000)) { |
82 SetBubbleBorder(std::unique_ptr<BubbleBorder>( | 147 SetBubbleBorder(std::unique_ptr<BubbleBorder>( |
83 new BubbleBorder(kArrow, BubbleBorder::NO_SHADOW, kColor))); | 148 new BubbleBorder(kArrow, BubbleBorder::NO_SHADOW, kColor))); |
84 } | 149 } |
85 ~TestBubbleFrameView() override {} | 150 ~TestBubbleFrameView() override {} |
86 | 151 |
87 // View overrides: | 152 // View overrides: |
88 const Widget* GetWidget() const override { | 153 const Widget* GetWidget() const override { |
89 if (!widget_) { | 154 if (!widget_) { |
90 widget_.reset(new Widget); | 155 widget_.reset(new Widget); |
91 widget_delegate_.reset( | 156 widget_delegate_ = MakeWidgetDelegate(widget_.get()); |
92 new TestBubbleFrameViewWidgetDelegate(widget_.get())); | |
93 Widget::InitParams params = | 157 Widget::InitParams params = |
94 test_base_->CreateParams(Widget::InitParams::TYPE_BUBBLE); | 158 test_base_->CreateParams(Widget::InitParams::TYPE_BUBBLE); |
95 params.delegate = widget_delegate_.get(); | 159 params.delegate = widget_delegate_.get(); |
96 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 160 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
97 widget_->Init(params); | 161 widget_->Init(params); |
98 } | 162 } |
99 | 163 |
100 return widget_.get(); | 164 return widget_.get(); |
101 } | 165 } |
102 | 166 |
103 // BubbleFrameView overrides: | 167 // BubbleFrameView overrides: |
104 gfx::Rect GetAvailableScreenBounds(const gfx::Rect& rect) const override { | 168 gfx::Rect GetAvailableScreenBounds(const gfx::Rect& rect) const override { |
105 return available_bounds_; | 169 return available_bounds_; |
106 } | 170 } |
107 | 171 |
108 TestBubbleFrameViewWidgetDelegate* widget_delegate() { | 172 TestBubbleFrameViewWidgetDelegate* widget_delegate() { |
109 return widget_delegate_.get(); | 173 return widget_delegate_.get(); |
110 } | 174 } |
111 | 175 |
176 protected: | |
177 virtual std::unique_ptr<TestBubbleFrameViewWidgetDelegate> MakeWidgetDelegate( | |
178 Widget* widget) const { | |
179 return base::WrapUnique(new TestBubbleFrameViewWidgetDelegate(widget)); | |
Peter Kasting
2017/04/06 06:32:16
Nit: WrapUnique(new -> MakeUnique (2 places)
| |
180 } | |
181 | |
112 private: | 182 private: |
113 ViewsTestBase* test_base_; | 183 ViewsTestBase* test_base_; |
114 | 184 |
115 gfx::Rect available_bounds_; | 185 gfx::Rect available_bounds_; |
116 | 186 |
117 // Widget returned by GetWidget(). Only created if GetWidget() is called. | 187 // Widget returned by GetWidget(). Only created if GetWidget() is called. |
118 mutable std::unique_ptr<TestBubbleFrameViewWidgetDelegate> widget_delegate_; | 188 mutable std::unique_ptr<TestBubbleFrameViewWidgetDelegate> widget_delegate_; |
119 mutable std::unique_ptr<Widget> widget_; | 189 mutable std::unique_ptr<Widget> widget_; |
120 | 190 |
121 DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameView); | 191 DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameView); |
122 }; | 192 }; |
123 | 193 |
194 class TestBubbleFrameDialogView : public TestBubbleFrameView { | |
195 public: | |
196 TestBubbleFrameDialogView(ViewsTestBase* test_base) | |
197 : TestBubbleFrameView(test_base) {} | |
198 | |
199 protected: | |
200 std::unique_ptr<TestBubbleFrameViewWidgetDelegate> MakeWidgetDelegate( | |
201 Widget* widget) const override { | |
202 return base::WrapUnique(new TestBubbleFrameViewDialogDelegate(widget)); | |
203 } | |
204 }; | |
205 | |
124 } // namespace | 206 } // namespace |
125 | 207 |
126 TEST_F(BubbleFrameViewTest, GetBoundsForClientView) { | 208 TEST_F(BubbleFrameViewTest, GetBoundsForClientView) { |
127 TestBubbleFrameView frame(this); | 209 TestBubbleFrameView frame(this); |
128 EXPECT_EQ(kArrow, frame.bubble_border()->arrow()); | 210 EXPECT_EQ(kArrow, frame.bubble_border()->arrow()); |
129 EXPECT_EQ(kColor, frame.bubble_border()->background_color()); | 211 EXPECT_EQ(kColor, frame.bubble_border()->background_color()); |
130 | 212 |
131 int margin_x = frame.content_margins().left(); | 213 int margin_x = frame.content_margins().left(); |
132 int margin_y = frame.content_margins().top(); | 214 int margin_y = frame.content_margins().top(); |
133 gfx::Insets insets = frame.bubble_border()->GetInsets(); | 215 gfx::Insets insets = frame.bubble_border()->GetInsets(); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 #else | 563 #else |
482 maximum_rect.Inset(frame.bubble_border()->GetInsets()); | 564 maximum_rect.Inset(frame.bubble_border()->GetInsets()); |
483 | 565 |
484 // Should ignore the contents view's maximum size and use the preferred size. | 566 // Should ignore the contents view's maximum size and use the preferred size. |
485 gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth, | 567 gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth, |
486 kPreferredClientHeight + kExpectedAdditionalHeight); | 568 kPreferredClientHeight + kExpectedAdditionalHeight); |
487 EXPECT_EQ(expected_size, maximum_rect.size()); | 569 EXPECT_EQ(expected_size, maximum_rect.size()); |
488 #endif | 570 #endif |
489 } | 571 } |
490 | 572 |
573 // This test ensures that BubbleFrameViews are snapped to the width specified by | |
574 // ViewsDelegate::GetSnappedDialogWidth(). | |
575 TEST_F(BubbleFrameViewTest, WidthSnapsToUnit) { | |
576 TestBubbleFrameDialogView frame(this); | |
577 | |
578 // The "border width" here is primarily for the bubble shadow, but also for | |
579 // the edge stroke of the bubble. This width is *not* included in the width | |
580 // snapping, so it needs to be subtracted out. | |
581 int border_width = 10; | |
Peter Kasting
2017/04/06 06:32:16
Nit: This looks like you're matching a shadow/stro
| |
582 | |
583 // Check that changing the snapping unit changes the computed width to be a | |
584 // multiple of the snapping unit. | |
Peter Kasting
2017/04/06 06:32:16
Nit: Technically, the code below tests only that y
| |
585 const int kTestWidth = 500; | |
586 EXPECT_NE(kTestWidth, frame.GetPreferredSize().width() - border_width); | |
Peter Kasting
2017/04/06 06:32:16
Nit: EXPECT_LT?
| |
587 views_delegate()->set_snapped_width(kTestWidth); | |
588 EXPECT_EQ(kTestWidth, frame.GetPreferredSize().width() - border_width); | |
589 } | |
590 | |
491 } // namespace views | 591 } // namespace views |
OLD | NEW |