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.
4
5#include "base/strings/utf_string_conversions.h"
6#include "third_party/skia/include/core/SkBitmap.h"
7#include "ui/gfx/canvas.h"
8#include "ui/gfx/font.h"
9#include "ui/gfx/size.h"
10#include "ui/views/controls/button/label_button.h"
11#include "ui/views/test/views_test_base.h"
12
13namespace {
14
15gfx::ImageSkia CreateTestImage(int width, int height) {
16  SkBitmap bitmap;
17  bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
18  bitmap.allocPixels();
19  return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
20}
21
22}  // namespace
23
24namespace views {
25
26typedef ViewsTestBase LabelButtonTest;
27
28TEST_F(LabelButtonTest, Init) {
29  const string16 text(ASCIIToUTF16("abc"));
30  LabelButton button(NULL, text);
31
32  EXPECT_TRUE(button.GetImage(Button::STATE_NORMAL).isNull());
33  EXPECT_TRUE(button.GetImage(Button::STATE_HOVERED).isNull());
34  EXPECT_TRUE(button.GetImage(Button::STATE_PRESSED).isNull());
35  EXPECT_TRUE(button.GetImage(Button::STATE_DISABLED).isNull());
36
37  EXPECT_EQ(text, button.GetText());
38  EXPECT_EQ(gfx::ALIGN_LEFT, button.GetHorizontalAlignment());
39  EXPECT_FALSE(button.is_default());
40  EXPECT_EQ(button.style(), Button::STYLE_TEXTBUTTON);
41  EXPECT_EQ(Button::STATE_NORMAL, button.state());
42
43  EXPECT_EQ(button.image_->parent(), &button);
44  EXPECT_EQ(button.label_->parent(), &button);
45}
46
47TEST_F(LabelButtonTest, Label) {
48  LabelButton button(NULL, string16());
49  EXPECT_TRUE(button.GetText().empty());
50
51  const gfx::Font font;
52  const string16 short_text(ASCIIToUTF16("abcdefghijklm"));
53  const string16 long_text(ASCIIToUTF16("abcdefghijklmnopqrstuvwxyz"));
54  const int short_text_width = gfx::Canvas::GetStringWidth(short_text, font);
55  const int long_text_width = gfx::Canvas::GetStringWidth(long_text, font);
56
57  // The width increases monotonically with string size (it does not shrink).
58  EXPECT_LT(button.GetPreferredSize().width(), short_text_width);
59  button.SetText(short_text);
60  EXPECT_GT(button.GetPreferredSize().height(), font.GetHeight());
61  EXPECT_GT(button.GetPreferredSize().width(), short_text_width);
62  EXPECT_LT(button.GetPreferredSize().width(), long_text_width);
63  button.SetText(long_text);
64  EXPECT_GT(button.GetPreferredSize().width(), long_text_width);
65  button.SetText(short_text);
66  EXPECT_GT(button.GetPreferredSize().width(), long_text_width);
67
68  // Clamp the size to a maximum value.
69  button.set_max_size(gfx::Size(long_text_width, 1));
70  EXPECT_EQ(button.GetPreferredSize(), gfx::Size(long_text_width, 1));
71
72  // Clear the monotonically increasing minimum size.
73  button.set_min_size(gfx::Size());
74  EXPECT_GT(button.GetPreferredSize().width(), short_text_width);
75  EXPECT_LT(button.GetPreferredSize().width(), long_text_width);
76}
77
78TEST_F(LabelButtonTest, Image) {
79  LabelButton button(NULL, string16());
80
81  const int small_size = 50, large_size = 100;
82  const gfx::ImageSkia small_image = CreateTestImage(small_size, small_size);
83  const gfx::ImageSkia large_image = CreateTestImage(large_size, large_size);
84
85  // The width increases monotonically with image size (it does not shrink).
86  EXPECT_LT(button.GetPreferredSize().width(), small_size);
87  EXPECT_LT(button.GetPreferredSize().height(), small_size);
88  button.SetImage(Button::STATE_NORMAL, small_image);
89  EXPECT_GT(button.GetPreferredSize().width(), small_size);
90  EXPECT_GT(button.GetPreferredSize().height(), small_size);
91  EXPECT_LT(button.GetPreferredSize().width(), large_size);
92  EXPECT_LT(button.GetPreferredSize().height(), large_size);
93  button.SetImage(Button::STATE_NORMAL, large_image);
94  EXPECT_GT(button.GetPreferredSize().width(), large_size);
95  EXPECT_GT(button.GetPreferredSize().height(), large_size);
96  button.SetImage(Button::STATE_NORMAL, small_image);
97  EXPECT_GT(button.GetPreferredSize().width(), large_size);
98  EXPECT_GT(button.GetPreferredSize().height(), large_size);
99
100  // Clamp the size to a maximum value.
101  button.set_max_size(gfx::Size(large_size, 1));
102  EXPECT_EQ(button.GetPreferredSize(), gfx::Size(large_size, 1));
103
104  // Clear the monotonically increasing minimum size.
105  button.set_min_size(gfx::Size());
106  EXPECT_GT(button.GetPreferredSize().width(), small_size);
107  EXPECT_LT(button.GetPreferredSize().width(), large_size);
108}
109
110TEST_F(LabelButtonTest, LabelAndImage) {
111  LabelButton button(NULL, string16());
112
113  const gfx::Font font;
114  const string16 text(ASCIIToUTF16("abcdefghijklm"));
115  const int text_width = gfx::Canvas::GetStringWidth(text, font);
116
117  const int image_size = 50;
118  const gfx::ImageSkia image = CreateTestImage(image_size, image_size);
119  ASSERT_LT(font.GetHeight(), image_size);
120
121  // The width increases monotonically with content size (it does not shrink).
122  EXPECT_LT(button.GetPreferredSize().width(), text_width);
123  EXPECT_LT(button.GetPreferredSize().width(), image_size);
124  EXPECT_LT(button.GetPreferredSize().height(), image_size);
125  button.SetText(text);
126  EXPECT_GT(button.GetPreferredSize().width(), text_width);
127  EXPECT_GT(button.GetPreferredSize().height(), font.GetHeight());
128  EXPECT_LT(button.GetPreferredSize().width(), text_width + image_size);
129  EXPECT_LT(button.GetPreferredSize().height(), image_size);
130  button.SetImage(Button::STATE_NORMAL, image);
131  EXPECT_GT(button.GetPreferredSize().width(), text_width + image_size);
132  EXPECT_GT(button.GetPreferredSize().height(), image_size);
133
134  // Layout and ensure the image is left of the label except for ALIGN_RIGHT.
135  // (A proper parent view or layout manager would Layout on its invalidations).
136  button.SetSize(button.GetPreferredSize());
137  button.Layout();
138  EXPECT_EQ(gfx::ALIGN_LEFT, button.GetHorizontalAlignment());
139  EXPECT_LT(button.image_->bounds().right(), button.label_->bounds().x());
140  button.SetHorizontalAlignment(gfx::ALIGN_CENTER);
141  button.Layout();
142  EXPECT_EQ(gfx::ALIGN_CENTER, button.GetHorizontalAlignment());
143  EXPECT_LT(button.image_->bounds().right(), button.label_->bounds().x());
144  button.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
145  button.Layout();
146  EXPECT_EQ(gfx::ALIGN_RIGHT, button.GetHorizontalAlignment());
147  EXPECT_LT(button.label_->bounds().right(), button.image_->bounds().x());
148
149  button.SetText(string16());
150  EXPECT_GT(button.GetPreferredSize().width(), text_width + image_size);
151  EXPECT_GT(button.GetPreferredSize().height(), image_size);
152  button.SetImage(Button::STATE_NORMAL, gfx::ImageSkia());
153  EXPECT_GT(button.GetPreferredSize().width(), text_width + image_size);
154  EXPECT_GT(button.GetPreferredSize().height(), image_size);
155
156  // Clamp the size to a maximum value.
157  button.set_max_size(gfx::Size(image_size, 1));
158  EXPECT_EQ(button.GetPreferredSize(), gfx::Size(image_size, 1));
159
160  // Clear the monotonically increasing minimum size.
161  button.set_min_size(gfx::Size());
162  EXPECT_LT(button.GetPreferredSize().width(), text_width);
163  EXPECT_LT(button.GetPreferredSize().width(), image_size);
164  EXPECT_LT(button.GetPreferredSize().height(), image_size);
165}
166
167TEST_F(LabelButtonTest, Font) {
168  const string16 text(ASCIIToUTF16("abc"));
169  LabelButton button(NULL, text);
170
171  const gfx::Font original_font = button.GetFont();
172  const gfx::Font large_font = original_font.DeriveFont(100);
173  const int original_width = button.GetPreferredSize().width();
174  const int original_height = button.GetPreferredSize().height();
175
176  // The button size increases when the font size is increased.
177  button.SetFont(large_font);
178  EXPECT_GT(button.GetPreferredSize().width(), original_width);
179  EXPECT_GT(button.GetPreferredSize().height(), original_height);
180
181  // The button returns to its original size when the minimal size is cleared
182  // and the original font size is restored.
183  button.set_min_size(gfx::Size());
184  button.SetFont(original_font);
185  EXPECT_EQ(original_width, button.GetPreferredSize().width());
186  EXPECT_EQ(original_height, button.GetPreferredSize().height());
187}
188
189}  // namespace views
190