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
3 // found in the LICENSE file.
5 #include "ui/views/controls/button/label_button.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "third_party/skia/include/core/SkBitmap.h"
9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/font_list.h"
11 #include "ui/gfx/geometry/size.h"
12 #include "ui/gfx/text_utils.h"
13 #include "ui/views/test/views_test_base.h"
15 using base::ASCIIToUTF16
;
19 gfx::ImageSkia
CreateTestImage(int width
, int height
) {
21 bitmap
.allocN32Pixels(width
, height
);
22 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap
);
29 typedef ViewsTestBase LabelButtonTest
;
31 TEST_F(LabelButtonTest
, Init
) {
32 const base::string16
text(ASCIIToUTF16("abc"));
33 LabelButton
button(NULL
, text
);
35 EXPECT_TRUE(button
.GetImage(Button::STATE_NORMAL
).isNull());
36 EXPECT_TRUE(button
.GetImage(Button::STATE_HOVERED
).isNull());
37 EXPECT_TRUE(button
.GetImage(Button::STATE_PRESSED
).isNull());
38 EXPECT_TRUE(button
.GetImage(Button::STATE_DISABLED
).isNull());
40 EXPECT_EQ(text
, button
.GetText());
41 EXPECT_EQ(gfx::ALIGN_LEFT
, button
.GetHorizontalAlignment());
42 EXPECT_FALSE(button
.is_default());
43 EXPECT_EQ(button
.style(), Button::STYLE_TEXTBUTTON
);
44 EXPECT_EQ(Button::STATE_NORMAL
, button
.state());
46 EXPECT_EQ(button
.image_
->parent(), &button
);
47 EXPECT_EQ(button
.label_
->parent(), &button
);
50 TEST_F(LabelButtonTest
, Label
) {
51 LabelButton
button(NULL
, base::string16());
52 EXPECT_TRUE(button
.GetText().empty());
54 const gfx::FontList font_list
;
55 const base::string16
short_text(ASCIIToUTF16("abcdefghijklm"));
56 const base::string16
long_text(ASCIIToUTF16("abcdefghijklmnopqrstuvwxyz"));
57 const int short_text_width
= gfx::GetStringWidth(short_text
, font_list
);
58 const int long_text_width
= gfx::GetStringWidth(long_text
, font_list
);
60 // The width increases monotonically with string size (it does not shrink).
61 EXPECT_LT(button
.GetPreferredSize().width(), short_text_width
);
62 button
.SetText(short_text
);
63 EXPECT_GT(button
.GetPreferredSize().height(), font_list
.GetHeight());
64 EXPECT_GT(button
.GetPreferredSize().width(), short_text_width
);
65 EXPECT_LT(button
.GetPreferredSize().width(), long_text_width
);
66 button
.SetText(long_text
);
67 EXPECT_GT(button
.GetPreferredSize().width(), long_text_width
);
68 button
.SetText(short_text
);
69 EXPECT_GT(button
.GetPreferredSize().width(), long_text_width
);
71 // Clamp the size to a maximum value.
72 button
.SetMaxSize(gfx::Size(long_text_width
, 1));
73 EXPECT_EQ(button
.GetPreferredSize(), gfx::Size(long_text_width
, 1));
75 // Clear the monotonically increasing minimum size.
76 button
.SetMinSize(gfx::Size());
77 EXPECT_GT(button
.GetPreferredSize().width(), short_text_width
);
78 EXPECT_LT(button
.GetPreferredSize().width(), long_text_width
);
81 TEST_F(LabelButtonTest
, Image
) {
82 LabelButton
button(NULL
, base::string16());
84 const int small_size
= 50, large_size
= 100;
85 const gfx::ImageSkia small_image
= CreateTestImage(small_size
, small_size
);
86 const gfx::ImageSkia large_image
= CreateTestImage(large_size
, large_size
);
88 // The width increases monotonically with image size (it does not shrink).
89 EXPECT_LT(button
.GetPreferredSize().width(), small_size
);
90 EXPECT_LT(button
.GetPreferredSize().height(), small_size
);
91 button
.SetImage(Button::STATE_NORMAL
, small_image
);
92 EXPECT_GT(button
.GetPreferredSize().width(), small_size
);
93 EXPECT_GT(button
.GetPreferredSize().height(), small_size
);
94 EXPECT_LT(button
.GetPreferredSize().width(), large_size
);
95 EXPECT_LT(button
.GetPreferredSize().height(), large_size
);
96 button
.SetImage(Button::STATE_NORMAL
, large_image
);
97 EXPECT_GT(button
.GetPreferredSize().width(), large_size
);
98 EXPECT_GT(button
.GetPreferredSize().height(), large_size
);
99 button
.SetImage(Button::STATE_NORMAL
, small_image
);
100 EXPECT_GT(button
.GetPreferredSize().width(), large_size
);
101 EXPECT_GT(button
.GetPreferredSize().height(), large_size
);
103 // Clamp the size to a maximum value.
104 button
.SetMaxSize(gfx::Size(large_size
, 1));
105 EXPECT_EQ(button
.GetPreferredSize(), gfx::Size(large_size
, 1));
107 // Clear the monotonically increasing minimum size.
108 button
.SetMinSize(gfx::Size());
109 EXPECT_GT(button
.GetPreferredSize().width(), small_size
);
110 EXPECT_LT(button
.GetPreferredSize().width(), large_size
);
113 TEST_F(LabelButtonTest
, LabelAndImage
) {
114 LabelButton
button(NULL
, base::string16());
116 const gfx::FontList font_list
;
117 const base::string16
text(ASCIIToUTF16("abcdefghijklm"));
118 const int text_width
= gfx::GetStringWidth(text
, font_list
);
120 const int image_size
= 50;
121 const gfx::ImageSkia image
= CreateTestImage(image_size
, image_size
);
122 ASSERT_LT(font_list
.GetHeight(), image_size
);
124 // The width increases monotonically with content size (it does not shrink).
125 EXPECT_LT(button
.GetPreferredSize().width(), text_width
);
126 EXPECT_LT(button
.GetPreferredSize().width(), image_size
);
127 EXPECT_LT(button
.GetPreferredSize().height(), image_size
);
128 button
.SetText(text
);
129 EXPECT_GT(button
.GetPreferredSize().width(), text_width
);
130 EXPECT_GT(button
.GetPreferredSize().height(), font_list
.GetHeight());
131 EXPECT_LT(button
.GetPreferredSize().width(), text_width
+ image_size
);
132 EXPECT_LT(button
.GetPreferredSize().height(), image_size
);
133 button
.SetImage(Button::STATE_NORMAL
, image
);
134 EXPECT_GT(button
.GetPreferredSize().width(), text_width
+ image_size
);
135 EXPECT_GT(button
.GetPreferredSize().height(), image_size
);
137 // Layout and ensure the image is left of the label except for ALIGN_RIGHT.
138 // (A proper parent view or layout manager would Layout on its invalidations).
139 button
.SetSize(button
.GetPreferredSize());
141 EXPECT_EQ(gfx::ALIGN_LEFT
, button
.GetHorizontalAlignment());
142 EXPECT_LT(button
.image_
->bounds().right(), button
.label_
->bounds().x());
143 button
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
145 EXPECT_EQ(gfx::ALIGN_CENTER
, button
.GetHorizontalAlignment());
146 EXPECT_LT(button
.image_
->bounds().right(), button
.label_
->bounds().x());
147 button
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
149 EXPECT_EQ(gfx::ALIGN_RIGHT
, button
.GetHorizontalAlignment());
150 EXPECT_LT(button
.label_
->bounds().right(), button
.image_
->bounds().x());
152 button
.SetText(base::string16());
153 EXPECT_GT(button
.GetPreferredSize().width(), text_width
+ image_size
);
154 EXPECT_GT(button
.GetPreferredSize().height(), image_size
);
155 button
.SetImage(Button::STATE_NORMAL
, gfx::ImageSkia());
156 EXPECT_GT(button
.GetPreferredSize().width(), text_width
+ image_size
);
157 EXPECT_GT(button
.GetPreferredSize().height(), image_size
);
159 // Clamp the size to a maximum value.
160 button
.SetMaxSize(gfx::Size(image_size
, 1));
161 EXPECT_EQ(button
.GetPreferredSize(), gfx::Size(image_size
, 1));
163 // Clear the monotonically increasing minimum size.
164 button
.SetMinSize(gfx::Size());
165 EXPECT_LT(button
.GetPreferredSize().width(), text_width
);
166 EXPECT_LT(button
.GetPreferredSize().width(), image_size
);
167 EXPECT_LT(button
.GetPreferredSize().height(), image_size
);
170 TEST_F(LabelButtonTest
, FontList
) {
171 const base::string16
text(ASCIIToUTF16("abc"));
172 LabelButton
button(NULL
, text
);
174 const gfx::FontList original_font_list
= button
.GetFontList();
175 const gfx::FontList large_font_list
=
176 original_font_list
.DeriveWithSizeDelta(100);
177 const int original_width
= button
.GetPreferredSize().width();
178 const int original_height
= button
.GetPreferredSize().height();
180 // The button size increases when the font size is increased.
181 button
.SetFontList(large_font_list
);
182 EXPECT_GT(button
.GetPreferredSize().width(), original_width
);
183 EXPECT_GT(button
.GetPreferredSize().height(), original_height
);
185 // The button returns to its original size when the minimal size is cleared
186 // and the original font size is restored.
187 button
.SetMinSize(gfx::Size());
188 button
.SetFontList(original_font_list
);
189 EXPECT_EQ(original_width
, button
.GetPreferredSize().width());
190 EXPECT_EQ(original_height
, button
.GetPreferredSize().height());
193 TEST_F(LabelButtonTest
, ChangeTextSize
) {
194 const base::string16
text(ASCIIToUTF16("abc"));
195 const base::string16
longer_text(ASCIIToUTF16("abcdefghijklm"));
196 LabelButton
button(NULL
, text
);
198 const int original_width
= button
.GetPreferredSize().width();
200 // The button size increases when the text size is increased.
201 button
.SetText(longer_text
);
202 EXPECT_GT(button
.GetPreferredSize().width(), original_width
);
204 // The button returns to its original size when the original text is restored.
205 button
.SetMinSize(gfx::Size());
206 button
.SetText(text
);
207 EXPECT_EQ(original_width
, button
.GetPreferredSize().width());
210 TEST_F(LabelButtonTest
, ChangeLabelImageSpacing
) {
211 LabelButton
button(NULL
, ASCIIToUTF16("abc"));
212 button
.SetImage(Button::STATE_NORMAL
, CreateTestImage(50, 50));
214 const int kOriginalSpacing
= 5;
215 button
.SetImageLabelSpacing(kOriginalSpacing
);
216 const int original_width
= button
.GetPreferredSize().width();
218 // Increasing the spacing between the text and label should increase the size.
219 button
.SetImageLabelSpacing(2 * kOriginalSpacing
);
220 EXPECT_GT(button
.GetPreferredSize().width(), original_width
);
222 // The button shrinks if the original spacing is restored.
223 button
.SetMinSize(gfx::Size());
224 button
.SetImageLabelSpacing(kOriginalSpacing
);
225 EXPECT_EQ(original_width
, button
.GetPreferredSize().width());