Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/message_center/views/bounded_label.cc

Issue 12757003: Revert 188637 "Added text line limits to collapsed and expanded ..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/message_center/views/bounded_label.h"
6
7 #include <limits>
8
9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "ui/base/text/text_elider.h"
12 #include "ui/gfx/canvas.h"
13
14 namespace message_center {
15
16 BoundedLabel::BoundedLabel(string16 text, size_t max_lines)
17 : views::Label(text, gfx::Font()) {
18 Init(max_lines);
19 }
20
21 BoundedLabel::BoundedLabel(string16 text, gfx::Font font, size_t max_lines)
22 : views::Label(text, font) {
23 Init(max_lines);
24 }
25
26 BoundedLabel::~BoundedLabel() {
27 }
28
29 void BoundedLabel::SetMaxLines(size_t lines) {
30 is_preferred_lines_valid_ = false;
31 is_text_size_valid_ = false;
32 max_lines_ = lines;
33 }
34
35 size_t BoundedLabel::GetMaxLines() {
36 return max_lines_;
37 }
38
39 size_t BoundedLabel::GetPreferredLines() {
40 if (!is_preferred_lines_valid_) {
41 int wrap_width = width() - GetInsets().width();
42 int unlimited_lines = std::numeric_limits<size_t>::max();
43 preferred_lines_ = SplitLines(wrap_width, unlimited_lines).size();
44 is_preferred_lines_valid_ = true;
45 }
46 return preferred_lines_;
47 }
48
49 int BoundedLabel::GetHeightForWidth(int width) {
50 gfx::Insets insets = GetInsets();
51 return GetTextHeightForWidth(width - insets.width()) + insets.height();
52 }
53
54 gfx::Size BoundedLabel::GetTextSize() const {
55 if (!is_text_size_valid_) {
56 text_size_.set_width(width() - GetInsets().width());
57 text_size_.set_height(GetTextHeightForWidth(text_size_.width()));
58 is_text_size_valid_ = true;
59 }
60 return text_size_;
61 }
62
63 void BoundedLabel::OnBoundsChanged(const gfx::Rect& previous_bounds) {
64 is_preferred_lines_valid_ = false;
65 is_text_size_valid_ = false;
66 }
67
68 void BoundedLabel::PaintText(gfx::Canvas* canvas,
69 const string16& paint_text,
70 const gfx::Rect& text_bounds,
71 int flags) {
72 gfx::Insets insets = GetInsets();
73 gfx::Rect bounds(gfx::Point(insets.left(), insets.top()), GetTextSize());
74 string16 text = JoinString(SplitLines(bounds.width(), max_lines_), '\n');
75 views::Label::PaintText(canvas, text, bounds, GetTextFlags());
76 }
77
78 void BoundedLabel::Init(size_t max_lines) {
79 SetMultiLine(true);
80 SetAllowCharacterBreak(true);
81 SetElideBehavior(views::Label::ELIDE_AT_END);
82 max_lines_ = max_lines;
83 is_preferred_lines_valid_ = false;
84 is_text_size_valid_ = false;
85 }
86
87 int BoundedLabel::GetTextFlags() const {
88 int flags = gfx::Canvas::MULTI_LINE | gfx::Canvas::CHARACTER_BREAK;
89
90 // We can't use subpixel rendering if the background is non-opaque.
91 if (SkColorGetA(background_color()) != 0xFF)
92 flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING;
93
94 if (directionality_mode() == AUTO_DETECT_DIRECTIONALITY) {
95 base::i18n::TextDirection direction =
96 base::i18n::GetFirstStrongCharacterDirection(text());
97 if (direction == base::i18n::RIGHT_TO_LEFT)
98 flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY;
99 else
100 flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
101 }
102
103 switch (horizontal_alignment()) {
104 case gfx::ALIGN_LEFT:
105 flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
106 break;
107 case gfx::ALIGN_CENTER:
108 flags |= gfx::Canvas::TEXT_ALIGN_CENTER;
109 break;
110 case gfx::ALIGN_RIGHT:
111 flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
112 break;
113 }
114
115 return flags;
116 }
117
118 int BoundedLabel::GetTextHeightForWidth(int width) const {
119 int height = font().GetHeight();
120 width = std::max(width, 0);
121 string16 text = JoinString(SplitLines(width, max_lines_), '\n');
122 gfx::Canvas::SizeStringInt(text, font(), &width, &height, GetTextFlags());
123 return height;
124 }
125
126 std::vector<string16> BoundedLabel::SplitLines(int width,
127 size_t max_lines) const {
128 // Adjust max_lines so (max_lines + 1) * line_height <= INT_MAX, then use the
129 // adjusted max_lines to get a max_height of (max_lines + 1) * line_height.
130 size_t max_height = std::numeric_limits<int>::max();
131 size_t line_height = std::max(font().GetHeight(), 2); // At least 2 pixels!
132 max_lines = std::min(max_lines, max_height / line_height - 1);
133 max_height = (max_lines + 1) * line_height;
134
135 // Split. Do not use ui::WRAP_LONG_WORDS instead of ui::IGNORE_LONG_WORDS
136 // below as this may cause ui::ElideRectangleText() to go into an infinite
137 // loop for small width values.
138 std::vector<string16> lines;
139 ui::ElideRectangleText(text(), font(), width, max_height,
140 ui::IGNORE_LONG_WORDS, &lines);
141
142 // Elide if necessary.
143 if (lines.size() > max_lines) {
144 // Add an ellipsis to the last line. If this ellipsis makes the last line
145 // too wide, that line will be further elided by the ui::ElideText below,
146 // so for example "ABC" could become "ABC..." here and "AB..." below.
147 string16 last = lines[max_lines - 1] + UTF8ToUTF16(ui::kEllipsis);
148 lines.resize(max_lines - 1);
149 lines.push_back((font().GetStringWidth(last) > width) ?
150 ui::ElideText(last, font(), width, ui::ELIDE_AT_END) :
151 last);
152 }
153
154 return lines;
155 }
156
157 } // namespace message_center
OLDNEW
« no previous file with comments | « ui/message_center/views/bounded_label.h ('k') | ui/message_center/views/bounded_label_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698