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