| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 #include "third_party/skia/include/core/SkColor.h" | 10 #include "third_party/skia/include/core/SkColor.h" |
| 12 #include "ui/views/controls/link.h" | 11 #include "ui/views/controls/link.h" |
| 13 #include "ui/views/controls/styled_label.h" | 12 #include "ui/views/controls/styled_label.h" |
| 14 #include "ui/views/controls/styled_label_listener.h" | 13 #include "ui/views/controls/styled_label_listener.h" |
| 14 #include "ui/views/test/views_test_base.h" |
| 15 | 15 |
| 16 namespace views { | 16 namespace views { |
| 17 | 17 |
| 18 class StyledLabelTest : public testing::Test, public StyledLabelListener { | 18 class StyledLabelTest : public testing::Test, public StyledLabelListener { |
| 19 public: | 19 public: |
| 20 StyledLabelTest() {} | 20 StyledLabelTest() {} |
| 21 virtual ~StyledLabelTest() {} | 21 virtual ~StyledLabelTest() {} |
| 22 | 22 |
| 23 // StyledLabelListener implementation. | 23 // StyledLabelListener implementation. |
| 24 virtual void StyledLabelLinkClicked(const gfx::Range& range, | 24 virtual void StyledLabelLinkClicked(const gfx::Range& range, |
| 25 int event_flags) OVERRIDE {} | 25 int event_flags) OVERRIDE {} |
| 26 | 26 |
| 27 protected: | 27 protected: |
| 28 StyledLabel* styled() { return styled_.get(); } | 28 StyledLabel* styled() { return styled_.get(); } |
| 29 | 29 |
| 30 void InitStyledLabel(const std::string& ascii_text) { | 30 void InitStyledLabel(const std::string& ascii_text) { |
| 31 styled_.reset(new StyledLabel(ASCIIToUTF16(ascii_text), this)); | 31 styled_.reset(new StyledLabel(ASCIIToUTF16(ascii_text), this)); |
| 32 styled_->set_owned_by_client(); |
| 32 } | 33 } |
| 33 | 34 |
| 34 int StyledLabelContentHeightForWidth(int w) { | 35 int StyledLabelContentHeightForWidth(int w) { |
| 35 return styled_->GetHeightForWidth(w) - styled_->GetInsets().height(); | 36 return styled_->GetHeightForWidth(w) - styled_->GetInsets().height(); |
| 36 } | 37 } |
| 37 | 38 |
| 38 private: | 39 private: |
| 39 scoped_ptr<StyledLabel> styled_; | 40 scoped_ptr<StyledLabel> styled_; |
| 40 | 41 |
| 41 DISALLOW_COPY_AND_ASSIGN(StyledLabelTest); | 42 DISALLOW_COPY_AND_ASSIGN(StyledLabelTest); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 106 |
| 106 // Also respect the border. | 107 // Also respect the border. |
| 107 styled()->set_border(Border::CreateEmptyBorder(3, 3, 3, 3)); | 108 styled()->set_border(Border::CreateEmptyBorder(3, 3, 3, 3)); |
| 108 styled()->SetBounds( | 109 styled()->SetBounds( |
| 109 0, | 110 0, |
| 110 0, | 111 0, |
| 111 styled()->GetInsets().width() + label_preferred_size.width(), | 112 styled()->GetInsets().width() + label_preferred_size.width(), |
| 112 styled()->GetInsets().height() + 2 * label_preferred_size.height()); | 113 styled()->GetInsets().height() + 2 * label_preferred_size.height()); |
| 113 styled()->Layout(); | 114 styled()->Layout(); |
| 114 ASSERT_EQ(2, styled()->child_count()); | 115 ASSERT_EQ(2, styled()->child_count()); |
| 115 EXPECT_EQ(3, styled()->child_at(0)->bounds().x()); | 116 EXPECT_EQ(3, styled()->child_at(0)->x()); |
| 116 EXPECT_EQ(3, styled()->child_at(0)->bounds().y()); | 117 EXPECT_EQ(3, styled()->child_at(0)->y()); |
| 117 EXPECT_EQ(styled()->bounds().height() - 3, | 118 EXPECT_EQ(styled()->height() - 3, styled()->child_at(1)->bounds().bottom()); |
| 118 styled()->child_at(1)->bounds().bottom()); | |
| 119 } | 119 } |
| 120 | 120 |
| 121 TEST_F(StyledLabelTest, CreateLinks) { | 121 TEST_F(StyledLabelTest, CreateLinks) { |
| 122 const std::string text("This is a test block of text."); | 122 const std::string text("This is a test block of text."); |
| 123 InitStyledLabel(text); | 123 InitStyledLabel(text); |
| 124 |
| 125 // Without links, there should be no focus border. |
| 126 EXPECT_TRUE(styled()->GetInsets().empty()); |
| 127 |
| 128 // Now let's add some links. |
| 124 styled()->AddStyleRange(gfx::Range(0, 1), | 129 styled()->AddStyleRange(gfx::Range(0, 1), |
| 125 StyledLabel::RangeStyleInfo::CreateForLink()); | 130 StyledLabel::RangeStyleInfo::CreateForLink()); |
| 126 styled()->AddStyleRange(gfx::Range(1, 2), | 131 styled()->AddStyleRange(gfx::Range(1, 2), |
| 127 StyledLabel::RangeStyleInfo::CreateForLink()); | 132 StyledLabel::RangeStyleInfo::CreateForLink()); |
| 128 styled()->AddStyleRange(gfx::Range(10, 11), | 133 styled()->AddStyleRange(gfx::Range(10, 11), |
| 129 StyledLabel::RangeStyleInfo::CreateForLink()); | 134 StyledLabel::RangeStyleInfo::CreateForLink()); |
| 130 styled()->AddStyleRange(gfx::Range(12, 13), | 135 styled()->AddStyleRange(gfx::Range(12, 13), |
| 131 StyledLabel::RangeStyleInfo::CreateForLink()); | 136 StyledLabel::RangeStyleInfo::CreateForLink()); |
| 132 | 137 |
| 138 // Now there should be a focus border because there are non-empty Links. |
| 139 EXPECT_FALSE(styled()->GetInsets().empty()); |
| 140 |
| 141 // Verify layout creates the right number of children. |
| 133 styled()->SetBounds(0, 0, 1000, 1000); | 142 styled()->SetBounds(0, 0, 1000, 1000); |
| 134 styled()->Layout(); | 143 styled()->Layout(); |
| 135 ASSERT_EQ(7, styled()->child_count()); | 144 EXPECT_EQ(7, styled()->child_count()); |
| 136 } | 145 } |
| 137 | 146 |
| 138 TEST_F(StyledLabelTest, DontBreakLinks) { | 147 TEST_F(StyledLabelTest, DontBreakLinks) { |
| 139 const std::string text("This is a test block of text, "); | 148 const std::string text("This is a test block of text, "); |
| 140 const std::string link_text("and this should be a link"); | 149 const std::string link_text("and this should be a link"); |
| 141 InitStyledLabel(text + link_text); | 150 InitStyledLabel(text + link_text); |
| 142 styled()->AddStyleRange( | 151 styled()->AddStyleRange( |
| 143 gfx::Range(text.size(), text.size() + link_text.size()), | 152 gfx::Range(text.size(), text.size() + link_text.size()), |
| 144 StyledLabel::RangeStyleInfo::CreateForLink()); | 153 StyledLabel::RangeStyleInfo::CreateForLink()); |
| 145 | 154 |
| 146 Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2))); | 155 Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2))); |
| 147 gfx::Size label_preferred_size = label.GetPreferredSize(); | 156 gfx::Size label_preferred_size = label.GetPreferredSize(); |
| 148 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); | 157 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); |
| 149 EXPECT_EQ(label_preferred_size.height() * 2, | 158 EXPECT_EQ(label_preferred_size.height() * 2, |
| 150 pref_height - styled()->GetInsets().height()); | 159 pref_height - styled()->GetInsets().height()); |
| 151 | 160 |
| 152 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); | 161 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); |
| 153 styled()->Layout(); | 162 styled()->Layout(); |
| 154 ASSERT_EQ(2, styled()->child_count()); | 163 ASSERT_EQ(2, styled()->child_count()); |
| 155 EXPECT_EQ(0, styled()->child_at(0)->bounds().x()); | 164 // The label has no focus border while the link (and thus overall styled |
| 156 EXPECT_EQ(0, styled()->child_at(1)->bounds().x()); | 165 // label) does, so the label should be inset by the width of the focus border. |
| 166 EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(0)->x()); |
| 167 EXPECT_EQ(0, styled()->child_at(1)->x()); |
| 157 } | 168 } |
| 158 | 169 |
| 159 TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) { | 170 TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) { |
| 160 const std::string text("This is a test block of text, "); | 171 const std::string text("This is a test block of text, "); |
| 161 const std::string unbreakable_text("and this should not be breaked"); | 172 const std::string unbreakable_text("and this should not be broken"); |
| 162 InitStyledLabel(text + unbreakable_text); | 173 InitStyledLabel(text + unbreakable_text); |
| 163 StyledLabel::RangeStyleInfo style_info; | 174 StyledLabel::RangeStyleInfo style_info; |
| 164 style_info.disable_line_wrapping = true; | 175 style_info.disable_line_wrapping = true; |
| 165 styled()->AddStyleRange( | 176 styled()->AddStyleRange( |
| 166 gfx::Range(text.size(), text.size() + unbreakable_text.size()), | 177 gfx::Range(text.size(), text.size() + unbreakable_text.size()), |
| 167 style_info); | 178 style_info); |
| 168 | 179 |
| 169 Label label(ASCIIToUTF16( | 180 Label label(ASCIIToUTF16( |
| 170 text + unbreakable_text.substr(0, unbreakable_text.size() / 2))); | 181 text + unbreakable_text.substr(0, unbreakable_text.size() / 2))); |
| 171 gfx::Size label_preferred_size = label.GetPreferredSize(); | 182 gfx::Size label_preferred_size = label.GetPreferredSize(); |
| 172 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); | 183 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); |
| 173 EXPECT_EQ(label_preferred_size.height() * 2, | 184 EXPECT_EQ(label_preferred_size.height() * 2, |
| 174 pref_height - styled()->GetInsets().height()); | 185 pref_height - styled()->GetInsets().height()); |
| 175 | 186 |
| 176 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); | 187 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); |
| 177 styled()->Layout(); | 188 styled()->Layout(); |
| 178 ASSERT_EQ(2, styled()->child_count()); | 189 ASSERT_EQ(2, styled()->child_count()); |
| 179 EXPECT_EQ(0, styled()->child_at(0)->bounds().x()); | 190 EXPECT_EQ(0, styled()->child_at(0)->x()); |
| 180 EXPECT_EQ(0, styled()->child_at(1)->bounds().x()); | 191 EXPECT_EQ(0, styled()->child_at(1)->x()); |
| 181 } | 192 } |
| 182 | 193 |
| 183 TEST_F(StyledLabelTest, StyledRangeUnderlined) { | 194 TEST_F(StyledLabelTest, StyledRangeUnderlined) { |
| 184 const std::string text("This is a test block of text, "); | 195 const std::string text("This is a test block of text, "); |
| 185 const std::string underlined_text("and this should be undelined"); | 196 const std::string underlined_text("and this should be undelined"); |
| 186 InitStyledLabel(text + underlined_text); | 197 InitStyledLabel(text + underlined_text); |
| 187 StyledLabel::RangeStyleInfo style_info; | 198 StyledLabel::RangeStyleInfo style_info; |
| 188 style_info.font_style = gfx::Font::UNDERLINE; | 199 style_info.font_style = gfx::Font::UNDERLINE; |
| 189 styled()->AddStyleRange( | 200 styled()->AddStyleRange( |
| 190 gfx::Range(text.size(), text.size() + underlined_text.size()), | 201 gfx::Range(text.size(), text.size() + underlined_text.size()), |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // Set the width so |bold_text| doesn't fit on a single line with bold style, | 233 // Set the width so |bold_text| doesn't fit on a single line with bold style, |
| 223 // but does with normal font style. | 234 // but does with normal font style. |
| 224 int styled_width = (normal_label_size.width() + bold_label_size.width()) / 2; | 235 int styled_width = (normal_label_size.width() + bold_label_size.width()) / 2; |
| 225 int pref_height = styled()->GetHeightForWidth(styled_width); | 236 int pref_height = styled()->GetHeightForWidth(styled_width); |
| 226 | 237 |
| 227 // Sanity check that |bold_text| with normal font style would fit on a single | 238 // Sanity check that |bold_text| with normal font style would fit on a single |
| 228 // line in a styled label with width |styled_width|. | 239 // line in a styled label with width |styled_width|. |
| 229 StyledLabel unstyled(ASCIIToUTF16(bold_text), this); | 240 StyledLabel unstyled(ASCIIToUTF16(bold_text), this); |
| 230 unstyled.SetBounds(0, 0, styled_width, pref_height); | 241 unstyled.SetBounds(0, 0, styled_width, pref_height); |
| 231 unstyled.Layout(); | 242 unstyled.Layout(); |
| 232 ASSERT_EQ(1, unstyled.child_count()); | 243 EXPECT_EQ(1, unstyled.child_count()); |
| 233 | 244 |
| 234 styled()->SetBounds(0, 0, styled_width, pref_height); | 245 styled()->SetBounds(0, 0, styled_width, pref_height); |
| 235 styled()->Layout(); | 246 styled()->Layout(); |
| 236 | 247 |
| 237 ASSERT_EQ(3, styled()->child_count()); | 248 ASSERT_EQ(3, styled()->child_count()); |
| 238 | 249 |
| 239 // The bold text should be broken up into two parts. | 250 // The bold text should be broken up into two parts. |
| 240 ASSERT_EQ(std::string(Label::kViewClassName), | 251 ASSERT_EQ(std::string(Label::kViewClassName), |
| 241 styled()->child_at(0)->GetClassName()); | 252 styled()->child_at(0)->GetClassName()); |
| 242 EXPECT_EQ(gfx::Font::BOLD, | 253 EXPECT_EQ(gfx::Font::BOLD, |
| 243 static_cast<Label*>(styled()->child_at(0))->font().GetStyle()); | 254 static_cast<Label*>(styled()->child_at(0))->font().GetStyle()); |
| 244 ASSERT_EQ(std::string(Label::kViewClassName), | 255 ASSERT_EQ(std::string(Label::kViewClassName), |
| 245 styled()->child_at(1)->GetClassName()); | 256 styled()->child_at(1)->GetClassName()); |
| 246 EXPECT_EQ(gfx::Font::BOLD, | 257 EXPECT_EQ(gfx::Font::BOLD, |
| 247 static_cast<Label*>(styled()->child_at(1))->font().GetStyle()); | 258 static_cast<Label*>(styled()->child_at(1))->font().GetStyle()); |
| 248 ASSERT_EQ(std::string(Label::kViewClassName), | 259 ASSERT_EQ(std::string(Label::kViewClassName), |
| 249 styled()->child_at(2)->GetClassName()); | 260 styled()->child_at(2)->GetClassName()); |
| 250 EXPECT_EQ(gfx::Font::NORMAL, | 261 EXPECT_EQ(gfx::Font::NORMAL, |
| 251 static_cast<Label*>(styled()->child_at(2))->font().GetStyle()); | 262 static_cast<Label*>(styled()->child_at(2))->font().GetStyle()); |
| 252 | 263 |
| 253 // The second bold part should start on a new line. | 264 // The second bold part should start on a new line. |
| 254 EXPECT_EQ(0, styled()->child_at(0)->bounds().x()); | 265 EXPECT_EQ(0, styled()->child_at(0)->x()); |
| 255 EXPECT_EQ(0, styled()->child_at(1)->bounds().x()); | 266 EXPECT_EQ(0, styled()->child_at(1)->x()); |
| 256 EXPECT_EQ(styled()->child_at(1)->bounds().right() - 2, | 267 EXPECT_EQ(styled()->child_at(1)->bounds().right(), |
| 257 styled()->child_at(2)->bounds().x()); | 268 styled()->child_at(2)->x()); |
| 258 } | 269 } |
| 259 | 270 |
| 260 TEST_F(StyledLabelTest, Color) { | 271 TEST_F(StyledLabelTest, Color) { |
| 261 const std::string text_red("RED"); | 272 const std::string text_red("RED"); |
| 262 const std::string text_link("link"); | 273 const std::string text_link("link"); |
| 263 const std::string text("word"); | 274 const std::string text("word"); |
| 264 InitStyledLabel(text_red + text_link + text); | 275 InitStyledLabel(text_red + text_link + text); |
| 265 | 276 |
| 266 StyledLabel::RangeStyleInfo style_info_red; | 277 StyledLabel::RangeStyleInfo style_info_red; |
| 267 style_info_red.color = SK_ColorRED; | 278 style_info_red.color = SK_ColorRED; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); | 346 int pref_height = styled()->GetHeightForWidth(label_preferred_size.width()); |
| 336 EXPECT_EQ(label_preferred_size.height() * 3, | 347 EXPECT_EQ(label_preferred_size.height() * 3, |
| 337 pref_height - styled()->GetInsets().height()); | 348 pref_height - styled()->GetInsets().height()); |
| 338 | 349 |
| 339 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); | 350 styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height); |
| 340 styled()->Layout(); | 351 styled()->Layout(); |
| 341 | 352 |
| 342 EXPECT_EQ(label_preferred_size.width(), styled()->width()); | 353 EXPECT_EQ(label_preferred_size.width(), styled()->width()); |
| 343 | 354 |
| 344 ASSERT_EQ(5, styled()->child_count()); | 355 ASSERT_EQ(5, styled()->child_count()); |
| 345 EXPECT_EQ(0, styled()->child_at(0)->bounds().x()); | 356 // The labels have no focus border while the link (and thus overall styled |
| 346 EXPECT_EQ(styled()->child_at(0)->bounds().right() - 2, | 357 // label) does, so the labels should be inset by the width of the focus |
| 347 styled()->child_at(1)->bounds().x()); | 358 // border. |
| 348 EXPECT_EQ(0, styled()->child_at(2)->bounds().x()); | 359 EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(0)->x()); |
| 349 EXPECT_EQ(styled()->child_at(2)->bounds().right() - 2, | 360 EXPECT_EQ(styled()->child_at(0)->bounds().right(), |
| 350 styled()->child_at(3)->bounds().x()); | 361 styled()->child_at(1)->x()); |
| 351 EXPECT_EQ(0, styled()->child_at(4)->bounds().x()); | 362 EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(2)->x()); |
| 363 EXPECT_EQ(styled()->child_at(2)->bounds().right(), |
| 364 styled()->child_at(3)->x()); |
| 365 EXPECT_EQ(0, styled()->child_at(4)->x()); |
| 352 | 366 |
| 353 string16 tooltip; | 367 string16 tooltip; |
| 354 EXPECT_TRUE( | 368 EXPECT_TRUE( |
| 355 styled()->child_at(1)->GetTooltipText(gfx::Point(1, 1), &tooltip)); | 369 styled()->child_at(1)->GetTooltipText(gfx::Point(1, 1), &tooltip)); |
| 356 EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip); | 370 EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip); |
| 357 EXPECT_TRUE( | 371 EXPECT_TRUE( |
| 358 styled()->child_at(2)->GetTooltipText(gfx::Point(1, 1), &tooltip)); | 372 styled()->child_at(2)->GetTooltipText(gfx::Point(1, 1), &tooltip)); |
| 359 EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip); | 373 EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip); |
| 360 } | 374 } |
| 361 | 375 |
| 362 TEST_F(StyledLabelTest, HandleEmptyLayout) { | 376 TEST_F(StyledLabelTest, HandleEmptyLayout) { |
| 363 const std::string text("This is a test block of text, "); | 377 const std::string text("This is a test block of text."); |
| 364 InitStyledLabel(text); | 378 InitStyledLabel(text); |
| 365 styled()->Layout(); | 379 styled()->Layout(); |
| 366 ASSERT_EQ(0, styled()->child_count()); | 380 EXPECT_EQ(0, styled()->child_count()); |
| 367 } | 381 } |
| 368 | 382 |
| 369 } // namespace | 383 } // namespace |
| OLD | NEW |