Chromium Code Reviews| 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 "ui/views/controls/styled_label.h" | 5 #include "ui/views/controls/styled_label.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 std::unique_ptr<Label> CreateLabelRange( | 35 std::unique_ptr<Label> CreateLabelRange( |
| 36 const base::string16& text, | 36 const base::string16& text, |
| 37 const gfx::FontList& font_list, | 37 const gfx::FontList& font_list, |
| 38 const StyledLabel::RangeStyleInfo& style_info, | 38 const StyledLabel::RangeStyleInfo& style_info, |
| 39 views::LinkListener* link_listener) { | 39 views::LinkListener* link_listener) { |
| 40 std::unique_ptr<Label> result; | 40 std::unique_ptr<Label> result; |
| 41 | 41 |
| 42 if (style_info.is_link) { | 42 if (style_info.is_link) { |
| 43 Link* link = new Link(text); | 43 Link* link = new Link(text); |
| 44 link->set_listener(link_listener); | 44 link->set_listener(link_listener); |
| 45 link->SetUnderline((style_info.font_style & gfx::Font::UNDERLINE) != 0); | 45 |
| 46 // Ignore requests to change the default underline style on Link if that's | |
| 47 // being used for the default focus style. | |
| 48 if (Link::GetDefaultFocusStyle() != Link::FocusStyle::UNDERLINE) | |
| 49 link->SetUnderline((style_info.font_style & gfx::Font::UNDERLINE) != 0); | |
| 50 | |
| 46 result.reset(link); | 51 result.reset(link); |
| 47 } else { | 52 } else { |
| 48 result.reset(new Label(text)); | 53 result.reset(new Label(text)); |
| 49 } | 54 } |
| 50 | 55 |
| 51 if (style_info.color != SK_ColorTRANSPARENT) | 56 if (style_info.color != SK_ColorTRANSPARENT) |
| 52 result->SetEnabledColor(style_info.color); | 57 result->SetEnabledColor(style_info.color); |
| 53 result->SetFontList(font_list); | 58 result->SetFontList(font_list); |
| 54 | 59 |
| 55 if (!style_info.tooltip.empty()) | 60 if (!style_info.tooltip.empty()) |
| 56 result->SetTooltipText(style_info.tooltip); | 61 result->SetTooltipText(style_info.tooltip); |
| 57 if (style_info.font_style != gfx::Font::NORMAL || | 62 if (style_info.font_style != gfx::Font::NORMAL || |
| 58 style_info.weight != gfx::Font::Weight::NORMAL) { | 63 style_info.weight != gfx::Font::Weight::NORMAL) { |
| 59 result->SetFontList(result->font_list().Derive(0, style_info.font_style, | 64 result->SetFontList(result->font_list().Derive(0, style_info.font_style, |
| 60 style_info.weight)); | 65 style_info.weight)); |
| 61 } | 66 } |
| 62 | 67 |
| 63 return result; | 68 return result; |
| 64 } | 69 } |
| 65 | 70 |
| 66 } // namespace | 71 } // namespace |
| 67 | 72 |
| 68 | |
| 69 // StyledLabel::RangeStyleInfo ------------------------------------------------ | 73 // StyledLabel::RangeStyleInfo ------------------------------------------------ |
| 70 | 74 |
| 71 StyledLabel::RangeStyleInfo::RangeStyleInfo() | 75 StyledLabel::RangeStyleInfo::RangeStyleInfo() |
| 72 : font_style(gfx::Font::NORMAL), | 76 : font_style(gfx::Font::NORMAL), |
| 73 weight(gfx::Font::Weight::NORMAL), | 77 weight(gfx::Font::Weight::NORMAL), |
| 74 color(SK_ColorTRANSPARENT), | 78 color(SK_ColorTRANSPARENT), |
| 75 disable_line_wrapping(false), | 79 disable_line_wrapping(false), |
| 76 is_link(false) {} | 80 is_link(false) {} |
| 77 | 81 |
| 78 StyledLabel::RangeStyleInfo::~RangeStyleInfo() {} | 82 StyledLabel::RangeStyleInfo::~RangeStyleInfo() {} |
| 79 | 83 |
| 80 // static | 84 // static |
| 81 StyledLabel::RangeStyleInfo StyledLabel::RangeStyleInfo::CreateForLink() { | 85 StyledLabel::RangeStyleInfo StyledLabel::RangeStyleInfo::CreateForLink() { |
| 82 RangeStyleInfo result; | 86 RangeStyleInfo result; |
| 83 result.disable_line_wrapping = true; | 87 result.disable_line_wrapping = true; |
| 84 result.is_link = true; | 88 result.is_link = true; |
| 89 | |
| 90 // When focus isn't indicated by underline, default to making links underlined | |
| 91 // by default. | |
| 92 if (Link::GetDefaultFocusStyle() != Link::FocusStyle::UNDERLINE) | |
| 93 result.font_style = gfx::Font::UNDERLINE; | |
|
tapted
2017/04/19 12:28:45
Of course.. this will add underlines to some Style
tapted
2017/04/20 11:50:18
After my brute-force refactoring in crrev.com/2833
| |
| 94 | |
| 85 return result; | 95 return result; |
| 86 } | 96 } |
| 87 | 97 |
| 88 | 98 |
| 89 // StyledLabel::StyleRange ---------------------------------------------------- | 99 // StyledLabel::StyleRange ---------------------------------------------------- |
| 90 | 100 |
| 91 bool StyledLabel::StyleRange::operator<( | 101 bool StyledLabel::StyleRange::operator<( |
| 92 const StyledLabel::StyleRange& other) const { | 102 const StyledLabel::StyleRange& other) const { |
| 93 return range.start() < other.range.start(); | 103 return range.start() < other.range.start(); |
| 94 } | 104 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 | 181 |
| 172 SetSize(CalculateAndDoLayout(max_width, true)); | 182 SetSize(CalculateAndDoLayout(max_width, true)); |
| 173 } | 183 } |
| 174 | 184 |
| 175 const char* StyledLabel::GetClassName() const { | 185 const char* StyledLabel::GetClassName() const { |
| 176 return kViewClassName; | 186 return kViewClassName; |
| 177 } | 187 } |
| 178 | 188 |
| 179 gfx::Insets StyledLabel::GetInsets() const { | 189 gfx::Insets StyledLabel::GetInsets() const { |
| 180 gfx::Insets insets = View::GetInsets(); | 190 gfx::Insets insets = View::GetInsets(); |
| 191 if (Link::GetDefaultFocusStyle() != Link::FocusStyle::RING) | |
| 192 return insets; | |
| 181 | 193 |
| 182 // We need a focus border iff we contain a link that will have a focus border. | 194 // We need a focus border iff we contain a link that will have a focus border. |
| 183 // That in turn will be true only if the link is non-empty. | 195 // That in turn will be true only if the link is non-empty. |
| 184 for (StyleRanges::const_iterator i(style_ranges_.begin()); | 196 for (StyleRanges::const_iterator i(style_ranges_.begin()); |
| 185 i != style_ranges_.end(); ++i) { | 197 i != style_ranges_.end(); ++i) { |
| 186 if (i->style_info.is_link && !i->range.is_empty()) { | 198 if (i->style_info.is_link && !i->range.is_empty()) { |
| 187 const gfx::Insets focus_border_padding( | 199 insets += gfx::Insets(Link::kFocusBorderPadding); |
| 188 Label::kFocusBorderPadding, Label::kFocusBorderPadding, | |
| 189 Label::kFocusBorderPadding, Label::kFocusBorderPadding); | |
| 190 insets += focus_border_padding; | |
| 191 break; | 200 break; |
| 192 } | 201 } |
| 193 } | 202 } |
| 194 | 203 |
| 195 return insets; | 204 return insets; |
| 196 } | 205 } |
| 197 | 206 |
| 198 gfx::Size StyledLabel::GetPreferredSize() const { | 207 gfx::Size StyledLabel::GetPreferredSize() const { |
| 199 return calculated_size_; | 208 return calculated_size_; |
| 200 } | 209 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 // This chunk is normal text. | 352 // This chunk is normal text. |
| 344 if (position + chunk.size() > range.start()) | 353 if (position + chunk.size() > range.start()) |
| 345 chunk = chunk.substr(0, range.start() - position); | 354 chunk = chunk.substr(0, range.start() - position); |
| 346 label = CreateLabelRange(chunk, font_list_, default_style_info_, this); | 355 label = CreateLabelRange(chunk, font_list_, default_style_info_, this); |
| 347 } | 356 } |
| 348 | 357 |
| 349 if (displayed_on_background_color_set_) | 358 if (displayed_on_background_color_set_) |
| 350 label->SetBackgroundColor(displayed_on_background_color_); | 359 label->SetBackgroundColor(displayed_on_background_color_); |
| 351 label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_); | 360 label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_); |
| 352 | 361 |
| 353 // Calculate the size of the optional focus border, and overlap by that | |
| 354 // amount. Otherwise, "<a>link</a>," will render as "link ,". | |
| 355 gfx::Insets focus_border_insets(label->GetInsets()); | |
| 356 focus_border_insets -= label->View::GetInsets(); | |
| 357 const gfx::Size view_size = label->GetPreferredSize(); | 362 const gfx::Size view_size = label->GetPreferredSize(); |
| 358 const gfx::Insets insets = GetInsets(); | 363 const gfx::Insets insets = GetInsets(); |
| 359 label->SetBoundsRect(gfx::Rect( | 364 gfx::Point view_origin(insets.left() + x, |
| 360 gfx::Point( | 365 insets.top() + line * line_height); |
| 361 insets.left() + x - focus_border_insets.left(), | 366 if (Link::GetDefaultFocusStyle() == Link::FocusStyle::RING) { |
| 362 insets.top() + line * line_height - focus_border_insets.top()), | 367 // Calculate the size of the optional focus border, and overlap by that |
| 363 view_size)); | 368 // amount. Otherwise, "<a>link</a>," will render as "link ,". |
| 364 x += view_size.width() - focus_border_insets.width(); | 369 gfx::Insets focus_border_insets(label->GetInsets()); |
| 370 focus_border_insets -= label->View::GetInsets(); | |
| 371 view_origin.Offset(-focus_border_insets.left(), | |
| 372 -focus_border_insets.top()); | |
| 373 label->SetBoundsRect(gfx::Rect(view_origin, view_size)); | |
| 374 x += view_size.width() - focus_border_insets.width(); | |
| 375 used_width = std::max(used_width, x); | |
| 376 total_height = | |
| 377 std::max(total_height, label->bounds().bottom() + insets.bottom() - | |
| 378 focus_border_insets.bottom()); | |
| 379 } else { | |
| 380 label->SetBoundsRect(gfx::Rect(view_origin, view_size)); | |
| 381 x += view_size.width(); | |
| 382 total_height = | |
| 383 std::max(total_height, label->bounds().bottom() + insets.bottom()); | |
| 384 } | |
| 365 used_width = std::max(used_width, x); | 385 used_width = std::max(used_width, x); |
| 366 total_height = | 386 |
| 367 std::max(total_height, label->bounds().bottom() + insets.bottom() - | |
| 368 focus_border_insets.bottom()); | |
| 369 if (!dry_run) | 387 if (!dry_run) |
| 370 AddChildView(label.release()); | 388 AddChildView(label.release()); |
| 371 | 389 |
| 372 // If |gfx::ElideRectangleText| returned more than one substring, that | 390 // If |gfx::ElideRectangleText| returned more than one substring, that |
| 373 // means the whole text did not fit into remaining line width, with text | 391 // means the whole text did not fit into remaining line width, with text |
| 374 // after |susbtring[0]| spilling into next line. If whole |substring[0]| | 392 // after |susbtring[0]| spilling into next line. If whole |substring[0]| |
| 375 // was added to the current line (this may not be the case if part of the | 393 // was added to the current line (this may not be the case if part of the |
| 376 // substring has different style), proceed to the next line. | 394 // substring has different style), proceed to the next line. |
| 377 if (substrings.size() > 1 && chunk.size() == substrings[0].size()) { | 395 if (substrings.size() > 1 && chunk.size() == substrings[0].size()) { |
| 378 x = 0; | 396 x = 0; |
| 379 ++line; | 397 ++line; |
| 380 } | 398 } |
| 381 | 399 |
| 382 remaining_string = remaining_string.substr(chunk.size()); | 400 remaining_string = remaining_string.substr(chunk.size()); |
| 383 } | 401 } |
| 384 | 402 |
| 385 DCHECK_LE(used_width, width); | 403 DCHECK_LE(used_width, width); |
| 386 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height); | 404 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height); |
| 387 return calculated_size_; | 405 return calculated_size_; |
| 388 } | 406 } |
| 389 | 407 |
| 390 } // namespace views | 408 } // namespace views |
| OLD | NEW |