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