OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/label.h" | 5 #include "ui/views/controls/label.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 #include <vector> | 10 #include <vector> |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 Label::Label(const base::string16& text, const gfx::FontList& font_list) { | 49 Label::Label(const base::string16& text, const gfx::FontList& font_list) { |
50 Init(text, font_list); | 50 Init(text, font_list); |
51 } | 51 } |
52 | 52 |
53 Label::~Label() { | 53 Label::~Label() { |
54 } | 54 } |
55 | 55 |
56 void Label::SetFontList(const gfx::FontList& font_list) { | 56 void Label::SetFontList(const gfx::FontList& font_list) { |
57 is_first_paint_text_ = true; | 57 is_first_paint_text_ = true; |
58 font_list_ = font_list; | 58 font_list_ = font_list; |
59 ResetCachedSize(); | 59 ResetLayoutCache(); |
60 PreferredSizeChanged(); | 60 PreferredSizeChanged(); |
61 SchedulePaint(); | 61 SchedulePaint(); |
62 } | 62 } |
63 | 63 |
64 void Label::SetText(const base::string16& text) { | 64 void Label::SetText(const base::string16& text) { |
65 if (text != text_) | 65 if (text != text_) |
66 SetTextInternal(text); | 66 SetTextInternal(text); |
67 } | 67 } |
68 | 68 |
69 void Label::SetTextInternal(const base::string16& text) { | 69 void Label::SetTextInternal(const base::string16& text) { |
70 is_first_paint_text_ = true; | 70 is_first_paint_text_ = true; |
71 text_ = text; | 71 text_ = text; |
72 | 72 |
73 if (obscured_) { | 73 if (obscured_) { |
74 size_t obscured_text_length = | 74 size_t obscured_text_length = |
75 static_cast<size_t>(gfx::UTF16IndexToOffset(text_, 0, text_.length())); | 75 static_cast<size_t>(gfx::UTF16IndexToOffset(text_, 0, text_.length())); |
76 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); | 76 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); |
77 } else { | 77 } else { |
78 layout_text_ = text_; | 78 layout_text_ = text_; |
79 } | 79 } |
80 | 80 |
81 ResetCachedSize(); | 81 ResetLayoutCache(); |
82 PreferredSizeChanged(); | 82 PreferredSizeChanged(); |
83 SchedulePaint(); | 83 SchedulePaint(); |
84 } | 84 } |
85 | 85 |
86 void Label::SetAutoColorReadabilityEnabled(bool enabled) { | 86 void Label::SetAutoColorReadabilityEnabled(bool enabled) { |
87 is_first_paint_text_ = true; | 87 is_first_paint_text_ = true; |
88 auto_color_readability_ = enabled; | 88 auto_color_readability_ = enabled; |
89 RecalculateColors(); | 89 RecalculateColors(); |
90 } | 90 } |
91 | 91 |
(...skipping 15 matching lines...) Expand all Loading... | |
107 is_first_paint_text_ = true; | 107 is_first_paint_text_ = true; |
108 background_color_ = color; | 108 background_color_ = color; |
109 background_color_set_ = true; | 109 background_color_set_ = true; |
110 RecalculateColors(); | 110 RecalculateColors(); |
111 } | 111 } |
112 | 112 |
113 void Label::SetShadows(const gfx::ShadowValues& shadows) { | 113 void Label::SetShadows(const gfx::ShadowValues& shadows) { |
114 is_first_paint_text_ = true; | 114 is_first_paint_text_ = true; |
115 shadows_ = shadows; | 115 shadows_ = shadows; |
116 text_size_valid_ = false; | 116 text_size_valid_ = false; |
117 cached_draw_params_.reset(); | |
msw
2015/01/07 20:35:56
Maybe just ResetLayoutCache(); here.
ckocagil
2015/01/07 22:55:08
Done.
| |
117 } | 118 } |
118 | 119 |
119 void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) { | 120 void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) { |
120 is_first_paint_text_ = true; | 121 is_first_paint_text_ = true; |
121 subpixel_rendering_enabled_ = subpixel_rendering_enabled; | 122 subpixel_rendering_enabled_ = subpixel_rendering_enabled; |
122 } | 123 } |
123 | 124 |
124 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { | 125 void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { |
125 is_first_paint_text_ = true; | 126 is_first_paint_text_ = true; |
126 // If the UI layout is right-to-left, flip the alignment direction. | 127 // If the UI layout is right-to-left, flip the alignment direction. |
(...skipping 14 matching lines...) Expand all Loading... | |
141 | 142 |
142 const base::i18n::TextDirection dir = | 143 const base::i18n::TextDirection dir = |
143 base::i18n::GetFirstStrongCharacterDirection(layout_text_); | 144 base::i18n::GetFirstStrongCharacterDirection(layout_text_); |
144 return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; | 145 return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; |
145 } | 146 } |
146 | 147 |
147 void Label::SetLineHeight(int height) { | 148 void Label::SetLineHeight(int height) { |
148 is_first_paint_text_ = true; | 149 is_first_paint_text_ = true; |
149 if (height != line_height_) { | 150 if (height != line_height_) { |
150 line_height_ = height; | 151 line_height_ = height; |
151 ResetCachedSize(); | 152 ResetLayoutCache(); |
152 PreferredSizeChanged(); | 153 PreferredSizeChanged(); |
153 SchedulePaint(); | 154 SchedulePaint(); |
154 } | 155 } |
155 } | 156 } |
156 | 157 |
157 void Label::SetMultiLine(bool multi_line) { | 158 void Label::SetMultiLine(bool multi_line) { |
158 is_first_paint_text_ = true; | 159 is_first_paint_text_ = true; |
159 DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL || | 160 DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL || |
160 elide_behavior_ == gfx::NO_ELIDE)); | 161 elide_behavior_ == gfx::NO_ELIDE)); |
161 if (multi_line != multi_line_) { | 162 if (multi_line != multi_line_) { |
162 multi_line_ = multi_line; | 163 multi_line_ = multi_line; |
163 ResetCachedSize(); | 164 ResetLayoutCache(); |
164 PreferredSizeChanged(); | 165 PreferredSizeChanged(); |
165 SchedulePaint(); | 166 SchedulePaint(); |
166 } | 167 } |
167 } | 168 } |
168 | 169 |
169 void Label::SetObscured(bool obscured) { | 170 void Label::SetObscured(bool obscured) { |
170 is_first_paint_text_ = true; | 171 is_first_paint_text_ = true; |
171 if (obscured != obscured_) { | 172 if (obscured != obscured_) { |
172 obscured_ = obscured; | 173 obscured_ = obscured; |
173 SetTextInternal(text_); | 174 SetTextInternal(text_); |
174 } | 175 } |
175 } | 176 } |
176 | 177 |
177 void Label::SetAllowCharacterBreak(bool allow_character_break) { | 178 void Label::SetAllowCharacterBreak(bool allow_character_break) { |
178 is_first_paint_text_ = true; | 179 is_first_paint_text_ = true; |
179 if (allow_character_break != allow_character_break_) { | 180 if (allow_character_break != allow_character_break_) { |
180 allow_character_break_ = allow_character_break; | 181 allow_character_break_ = allow_character_break; |
181 ResetCachedSize(); | 182 ResetLayoutCache(); |
182 PreferredSizeChanged(); | 183 PreferredSizeChanged(); |
183 SchedulePaint(); | 184 SchedulePaint(); |
184 } | 185 } |
185 } | 186 } |
186 | 187 |
187 void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) { | 188 void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) { |
188 is_first_paint_text_ = true; | 189 is_first_paint_text_ = true; |
189 DCHECK(!multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL || | 190 DCHECK(!multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL || |
190 elide_behavior_ == gfx::NO_ELIDE)); | 191 elide_behavior_ == gfx::NO_ELIDE)); |
191 if (elide_behavior != elide_behavior_) { | 192 if (elide_behavior != elide_behavior_) { |
192 elide_behavior_ = elide_behavior; | 193 elide_behavior_ = elide_behavior; |
193 ResetCachedSize(); | 194 ResetLayoutCache(); |
194 PreferredSizeChanged(); | 195 PreferredSizeChanged(); |
195 SchedulePaint(); | 196 SchedulePaint(); |
196 } | 197 } |
197 } | 198 } |
198 | 199 |
199 void Label::SetTooltipText(const base::string16& tooltip_text) { | 200 void Label::SetTooltipText(const base::string16& tooltip_text) { |
200 DCHECK(handles_tooltips_); | 201 DCHECK(handles_tooltips_); |
201 tooltip_text_ = tooltip_text; | 202 tooltip_text_ = tooltip_text; |
202 } | 203 } |
203 | 204 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows_); | 390 const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows_); |
390 text_size_.Enlarge(shadow_margin.width(), shadow_margin.height()); | 391 text_size_.Enlarge(shadow_margin.width(), shadow_margin.height()); |
391 text_size_valid_ = true; | 392 text_size_valid_ = true; |
392 } | 393 } |
393 | 394 |
394 return text_size_; | 395 return text_size_; |
395 } | 396 } |
396 | 397 |
397 void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 398 void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
398 text_size_valid_ &= !multi_line_; | 399 text_size_valid_ &= !multi_line_; |
400 cached_draw_params_.reset(); | |
399 } | 401 } |
400 | 402 |
401 void Label::OnPaint(gfx::Canvas* canvas) { | 403 void Label::OnPaint(gfx::Canvas* canvas) { |
402 OnPaintBackground(canvas); | 404 OnPaintBackground(canvas); |
403 // We skip painting the focus border because it is being handled seperately by | 405 // We skip painting the focus border because it is being handled seperately by |
404 // some subclasses of Label. We do not want View's focus border painting to | 406 // some subclasses of Label. We do not want View's focus border painting to |
405 // interfere with that. | 407 // interfere with that. |
406 OnPaintBorder(canvas); | 408 OnPaintBorder(canvas); |
407 | 409 |
408 base::string16 paint_text; | 410 const DrawStringParams* paint_params = CalculateDrawStringParams(); |
msw
2015/01/07 20:35:56
nit: |draw_params| or just |params|?
ckocagil
2015/01/07 22:55:08
Done, it's |params| now.
| |
409 gfx::Rect text_bounds; | |
410 int flags = 0; | |
411 CalculateDrawStringParams(&paint_text, &text_bounds, &flags); | |
412 if (is_first_paint_text_) { | 411 if (is_first_paint_text_) { |
413 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. | 412 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. |
414 tracked_objects::ScopedTracker tracking_profile( | 413 tracked_objects::ScopedTracker tracking_profile( |
415 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText first")); | 414 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText first")); |
416 | 415 |
417 is_first_paint_text_ = false; | 416 is_first_paint_text_ = false; |
418 PaintText(canvas, paint_text, text_bounds, flags); | 417 PaintText(canvas, paint_params->text, paint_params->bounds, |
418 paint_params->flags); | |
419 } else { | 419 } else { |
420 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. | 420 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. |
421 tracked_objects::ScopedTracker tracking_profile( | 421 tracked_objects::ScopedTracker tracking_profile( |
422 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText not first")); | 422 FROM_HERE_WITH_EXPLICIT_FUNCTION("431326 Label::PaintText not first")); |
423 | 423 |
424 PaintText(canvas, paint_text, text_bounds, flags); | 424 PaintText(canvas, paint_params->text, paint_params->bounds, |
425 paint_params->flags); | |
425 } | 426 } |
426 } | 427 } |
427 | 428 |
428 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 429 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
429 UpdateColorsFromTheme(theme); | 430 UpdateColorsFromTheme(theme); |
430 } | 431 } |
431 | 432 |
432 void Label::Init(const base::string16& text, const gfx::FontList& font_list) { | 433 void Label::Init(const base::string16& text, const gfx::FontList& font_list) { |
433 font_list_ = font_list; | 434 font_list_ = font_list; |
434 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false; | 435 enabled_color_set_ = disabled_color_set_ = background_color_set_ = false; |
435 subpixel_rendering_enabled_ = true; | 436 subpixel_rendering_enabled_ = true; |
436 auto_color_readability_ = true; | 437 auto_color_readability_ = true; |
437 UpdateColorsFromTheme(ui::NativeTheme::instance()); | 438 UpdateColorsFromTheme(ui::NativeTheme::instance()); |
438 horizontal_alignment_ = gfx::ALIGN_CENTER; | 439 horizontal_alignment_ = gfx::ALIGN_CENTER; |
439 line_height_ = 0; | 440 line_height_ = 0; |
440 multi_line_ = false; | 441 multi_line_ = false; |
441 obscured_ = false; | 442 obscured_ = false; |
442 allow_character_break_ = false; | 443 allow_character_break_ = false; |
443 elide_behavior_ = gfx::ELIDE_TAIL; | 444 elide_behavior_ = gfx::ELIDE_TAIL; |
444 handles_tooltips_ = true; | 445 handles_tooltips_ = true; |
445 collapse_when_hidden_ = false; | 446 collapse_when_hidden_ = false; |
446 cached_heights_.resize(kCachedSizeLimit); | 447 cached_heights_.resize(kCachedSizeLimit); |
447 ResetCachedSize(); | 448 ResetLayoutCache(); |
448 is_first_paint_text_ = true; | 449 is_first_paint_text_ = true; |
449 | 450 |
450 SetText(text); | 451 SetText(text); |
451 } | 452 } |
452 | 453 |
453 void Label::RecalculateColors() { | 454 void Label::RecalculateColors() { |
454 actual_enabled_color_ = auto_color_readability_ ? | 455 actual_enabled_color_ = auto_color_readability_ ? |
455 color_utils::GetReadableColor(requested_enabled_color_, | 456 color_utils::GetReadableColor(requested_enabled_color_, |
456 background_color_) : | 457 background_color_) : |
457 requested_enabled_color_; | 458 requested_enabled_color_; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 | 535 |
535 return flags; | 536 return flags; |
536 } | 537 } |
537 | 538 |
538 gfx::Rect Label::GetAvailableRect() const { | 539 gfx::Rect Label::GetAvailableRect() const { |
539 gfx::Rect bounds(size()); | 540 gfx::Rect bounds(size()); |
540 bounds.Inset(GetInsets()); | 541 bounds.Inset(GetInsets()); |
541 return bounds; | 542 return bounds; |
542 } | 543 } |
543 | 544 |
544 void Label::CalculateDrawStringParams(base::string16* paint_text, | 545 const Label::DrawStringParams* Label::CalculateDrawStringParams() const { |
545 gfx::Rect* text_bounds, | 546 if (!cached_draw_params_) { |
546 int* flags) const { | 547 DrawStringParams* paint_params = new DrawStringParams(); |
msw
2015/01/07 20:35:56
Can you just do cached_draw_params_.reset(new Draw
ckocagil
2015/01/07 22:55:08
It's |params| now. |cached_draw_params_| is longer
| |
547 DCHECK(paint_text && text_bounds && flags); | |
548 | 548 |
549 const bool forbid_ellipsis = elide_behavior_ == gfx::NO_ELIDE || | 549 const bool forbid_ellipsis = elide_behavior_ == gfx::NO_ELIDE || |
550 elide_behavior_ == gfx::FADE_TAIL; | 550 elide_behavior_ == gfx::FADE_TAIL; |
msw
2015/01/07 20:35:56
nit: retain relative indent.
ckocagil
2015/01/07 22:55:08
Done.
| |
551 if (multi_line_ || forbid_ellipsis) { | 551 if (multi_line_ || forbid_ellipsis) { |
552 *paint_text = layout_text_; | 552 paint_params->text = layout_text_; |
553 } else { | 553 } |
554 *paint_text = gfx::ElideText(layout_text_, font_list_, | 554 else { |
msw
2015/01/07 20:35:56
nit: else on line above.
ckocagil
2015/01/07 22:55:08
Done.
| |
555 GetAvailableRect().width(), elide_behavior_); | 555 paint_params->text = gfx::ElideText(layout_text_, font_list_, |
556 GetAvailableRect().width(), elide_behavior_); | |
557 } | |
558 | |
559 paint_params->bounds = GetTextBounds(); | |
560 paint_params->flags = ComputeDrawStringFlags(); | |
561 // TODO(msw): Elide multi-line text with ElideRectangleText instead. | |
562 if (!multi_line_ || forbid_ellipsis) | |
563 paint_params->flags |= gfx::Canvas::NO_ELLIPSIS; | |
564 | |
565 cached_draw_params_.reset(paint_params); | |
556 } | 566 } |
557 | 567 |
558 *text_bounds = GetTextBounds(); | 568 return cached_draw_params_.get(); |
559 *flags = ComputeDrawStringFlags(); | |
560 // TODO(msw): Elide multi-line text with ElideRectangleText instead. | |
561 if (!multi_line_ || forbid_ellipsis) | |
562 *flags |= gfx::Canvas::NO_ELLIPSIS; | |
563 } | 569 } |
564 | 570 |
565 void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) { | 571 void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) { |
566 if (!enabled_color_set_) { | 572 if (!enabled_color_set_) { |
567 requested_enabled_color_ = theme->GetSystemColor( | 573 requested_enabled_color_ = theme->GetSystemColor( |
568 ui::NativeTheme::kColorId_LabelEnabledColor); | 574 ui::NativeTheme::kColorId_LabelEnabledColor); |
569 } | 575 } |
570 if (!disabled_color_set_) { | 576 if (!disabled_color_set_) { |
571 requested_disabled_color_ = theme->GetSystemColor( | 577 requested_disabled_color_ = theme->GetSystemColor( |
572 ui::NativeTheme::kColorId_LabelDisabledColor); | 578 ui::NativeTheme::kColorId_LabelDisabledColor); |
573 } | 579 } |
574 if (!background_color_set_) { | 580 if (!background_color_set_) { |
575 background_color_ = theme->GetSystemColor( | 581 background_color_ = theme->GetSystemColor( |
576 ui::NativeTheme::kColorId_LabelBackgroundColor); | 582 ui::NativeTheme::kColorId_LabelBackgroundColor); |
577 } | 583 } |
578 RecalculateColors(); | 584 RecalculateColors(); |
579 } | 585 } |
580 | 586 |
581 void Label::ResetCachedSize() { | 587 void Label::ResetLayoutCache() { |
588 cached_draw_params_.reset(); | |
582 text_size_valid_ = false; | 589 text_size_valid_ = false; |
583 cached_heights_cursor_ = 0; | 590 cached_heights_cursor_ = 0; |
584 for (int i = 0; i < kCachedSizeLimit; ++i) | 591 for (int i = 0; i < kCachedSizeLimit; ++i) |
585 cached_heights_[i] = gfx::Size(); | 592 cached_heights_[i] = gfx::Size(); |
586 } | 593 } |
587 | 594 |
588 bool Label::ShouldShowDefaultTooltip() const { | 595 bool Label::ShouldShowDefaultTooltip() const { |
589 const gfx::Size text_size = GetTextSize(); | 596 const gfx::Size text_size = GetTextSize(); |
590 const gfx::Size size = GetContentsBounds().size(); | 597 const gfx::Size size = GetContentsBounds().size(); |
591 return !obscured() && (text_size.width() > size.width() || | 598 return !obscured() && (text_size.width() > size.width() || |
592 (multi_line_ && text_size.height() > size.height())); | 599 (multi_line_ && text_size.height() > size.height())); |
593 } | 600 } |
594 | 601 |
595 } // namespace views | 602 } // namespace views |
OLD | NEW |