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

Side by Side Diff: ui/views/controls/styled_label.cc

Issue 843023002: [Smart Lock] Add a private API to show an error bubble anchored to the Smart Lock app window. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update StyledLabel to specify a preferred size Created 5 years, 11 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
OLDNEW
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 <limits>
7 #include <vector> 8 #include <vector>
8 9
9 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
10 #include "ui/gfx/font_list.h" 11 #include "ui/gfx/font_list.h"
11 #include "ui/gfx/text_elider.h" 12 #include "ui/gfx/text_elider.h"
12 #include "ui/native_theme/native_theme.h" 13 #include "ui/native_theme/native_theme.h"
13 #include "ui/views/controls/label.h" 14 #include "ui/views/controls/label.h"
14 #include "ui/views/controls/link.h" 15 #include "ui/views/controls/link.h"
15 #include "ui/views/controls/styled_label_listener.h" 16 #include "ui/views/controls/styled_label_listener.h"
16 17
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 return range.start() < other.range.start(); 90 return range.start() < other.range.start();
90 } 91 }
91 92
92 93
93 // StyledLabel ---------------------------------------------------------------- 94 // StyledLabel ----------------------------------------------------------------
94 95
95 StyledLabel::StyledLabel(const base::string16& text, 96 StyledLabel::StyledLabel(const base::string16& text,
96 StyledLabelListener* listener) 97 StyledLabelListener* listener)
97 : specified_line_height_(0), 98 : specified_line_height_(0),
98 listener_(listener), 99 listener_(listener),
100 width_at_last_size_calculation_(0),
99 width_at_last_layout_(0), 101 width_at_last_layout_(0),
100 displayed_on_background_color_(SkColorSetRGB(0xFF, 0xFF, 0xFF)), 102 displayed_on_background_color_(SkColorSetRGB(0xFF, 0xFF, 0xFF)),
101 displayed_on_background_color_set_(false), 103 displayed_on_background_color_set_(false),
102 auto_color_readability_enabled_(true) { 104 auto_color_readability_enabled_(true) {
103 base::TrimWhitespace(text, base::TRIM_TRAILING, &text_); 105 base::TrimWhitespace(text, base::TRIM_TRAILING, &text_);
104 } 106 }
105 107
106 StyledLabel::~StyledLabel() {} 108 StyledLabel::~StyledLabel() {}
107 109
108 void StyledLabel::SetText(const base::string16& text) { 110 void StyledLabel::SetText(const base::string16& text) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 displayed_on_background_color_ = color; 151 displayed_on_background_color_ = color;
150 displayed_on_background_color_set_ = true; 152 displayed_on_background_color_set_ = true;
151 153
152 for (int i = 0, count = child_count(); i < count; ++i) { 154 for (int i = 0, count = child_count(); i < count; ++i) {
153 DCHECK((child_at(i)->GetClassName() == Label::kViewClassName) || 155 DCHECK((child_at(i)->GetClassName() == Label::kViewClassName) ||
154 (child_at(i)->GetClassName() == Link::kViewClassName)); 156 (child_at(i)->GetClassName() == Link::kViewClassName));
155 static_cast<Label*>(child_at(i))->SetBackgroundColor(color); 157 static_cast<Label*>(child_at(i))->SetBackgroundColor(color);
156 } 158 }
157 } 159 }
158 160
161 void StyledLabel::SizeToFit(int max_width) {
162 if (max_width == 0)
163 max_width = std::numeric_limits<int>::max();
164
165 SetSize(CalculateAndDoLayout(max_width, true));
166 }
167
168
159 gfx::Insets StyledLabel::GetInsets() const { 169 gfx::Insets StyledLabel::GetInsets() const {
160 gfx::Insets insets = View::GetInsets(); 170 gfx::Insets insets = View::GetInsets();
161 171
162 // We need a focus border iff we contain a link that will have a focus border. 172 // We need a focus border iff we contain a link that will have a focus border.
163 // That in turn will be true only if the link is non-empty. 173 // That in turn will be true only if the link is non-empty.
164 for (StyleRanges::const_iterator i(style_ranges_.begin()); 174 for (StyleRanges::const_iterator i(style_ranges_.begin());
165 i != style_ranges_.end(); ++i) { 175 i != style_ranges_.end(); ++i) {
166 if (i->style_info.is_link && !i->range.is_empty()) { 176 if (i->style_info.is_link && !i->range.is_empty()) {
167 const gfx::Insets focus_border_padding( 177 const gfx::Insets focus_border_padding(
168 Label::kFocusBorderPadding, Label::kFocusBorderPadding, 178 Label::kFocusBorderPadding, Label::kFocusBorderPadding,
169 Label::kFocusBorderPadding, Label::kFocusBorderPadding); 179 Label::kFocusBorderPadding, Label::kFocusBorderPadding);
170 insets += focus_border_padding; 180 insets += focus_border_padding;
171 break; 181 break;
172 } 182 }
173 } 183 }
174 184
175 return insets; 185 return insets;
176 } 186 }
177 187
188 gfx::Size StyledLabel::GetPreferredSize() const {
189 return calculated_size_;
190 }
191
178 int StyledLabel::GetHeightForWidth(int w) const { 192 int StyledLabel::GetHeightForWidth(int w) const {
179 // TODO(erg): Munge the const-ness of the style label. CalculateAndDoLayout 193 // TODO(erg): Munge the const-ness of the style label. CalculateAndDoLayout
180 // doesn't actually make any changes to member variables when |dry_run| is 194 // doesn't actually make any changes to member variables when |dry_run| is
181 // set to true. In general, the mutating and non-mutating parts shouldn't 195 // set to true. In general, the mutating and non-mutating parts shouldn't
182 // be in the same codepath. 196 // be in the same codepath.
183 calculated_size_ = 197 return const_cast<StyledLabel*>(this)->CalculateAndDoLayout(w, true).height();
184 const_cast<StyledLabel*>(this)->CalculateAndDoLayout(w, true);
185 return calculated_size_.height();
186 } 198 }
187 199
188 void StyledLabel::Layout() { 200 void StyledLabel::Layout() {
189 calculated_size_ = CalculateAndDoLayout(GetLocalBounds().width(), false); 201 CalculateAndDoLayout(GetLocalBounds().width(), false);
190 width_at_last_layout_ = calculated_size_.width();
191 } 202 }
192 203
193 void StyledLabel::PreferredSizeChanged() { 204 void StyledLabel::PreferredSizeChanged() {
194 calculated_size_ = gfx::Size(); 205 calculated_size_ = gfx::Size();
206 width_at_last_size_calculation_ = 0;
207 width_at_last_layout_ = 0;
195 View::PreferredSizeChanged(); 208 View::PreferredSizeChanged();
196 } 209 }
197 210
198 void StyledLabel::LinkClicked(Link* source, int event_flags) { 211 void StyledLabel::LinkClicked(Link* source, int event_flags) {
199 if (listener_) 212 if (listener_)
200 listener_->StyledLabelLinkClicked(link_targets_[source], event_flags); 213 listener_->StyledLabelLinkClicked(link_targets_[source], event_flags);
201 } 214 }
202 215
203 gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) { 216 gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
217 if (!dry_run)
218 width_at_last_layout_ = width;
219
220 if (width == width_at_last_size_calculation_ &&
221 (dry_run || width == width_at_last_layout_))
222 return calculated_size_;
223
204 width -= GetInsets().width(); 224 width -= GetInsets().width();
205 if (width == calculated_size_.width() &&
206 (dry_run || width_at_last_layout_ == width))
207 return calculated_size_;
208 225
209 if (!dry_run) { 226 if (!dry_run) {
210 RemoveAllChildViews(true); 227 RemoveAllChildViews(true);
211 link_targets_.clear(); 228 link_targets_.clear();
212 } 229 }
213 230
214 if (width <= 0 || text_.empty()) 231 if (width <= 0 || text_.empty())
215 return gfx::Size(); 232 return gfx::Size();
216 233
217 const int line_height = specified_line_height_ > 0 ? specified_line_height_ 234 const int line_height = specified_line_height_ > 0 ? specified_line_height_
218 : CalculateLineHeight(font_list_); 235 : CalculateLineHeight(font_list_);
219 // The index of the line we're on. 236 // The index of the line we're on.
220 int line = 0; 237 int line = 0;
221 // The x position (in pixels) of the line we're on, relative to content 238 // The x position (in pixels) of the line we're on, relative to content
222 // bounds. 239 // bounds.
223 int x = 0; 240 int x = 0;
241 // The width that was actually used. Guaranteed to be no larger than |width|.
242 int used_width = 0;
224 243
225 base::string16 remaining_string = text_; 244 base::string16 remaining_string = text_;
226 StyleRanges::const_iterator current_range = style_ranges_.begin(); 245 StyleRanges::const_iterator current_range = style_ranges_.begin();
227 246
228 // Iterate over the text, creating a bunch of labels and links and laying them 247 // Iterate over the text, creating a bunch of labels and links and laying them
229 // out in the appropriate positions. 248 // out in the appropriate positions.
230 while (!remaining_string.empty()) { 249 while (!remaining_string.empty()) {
231 // Don't put whitespace at beginning of a line with an exception for the 250 // Don't put whitespace at beginning of a line with an exception for the
232 // first line (so the text's leading whitespace is respected). 251 // first line (so the text's leading whitespace is respected).
233 if (x == 0 && line > 0) { 252 if (x == 0 && line > 0) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 const gfx::Size view_size = label->GetPreferredSize(); 338 const gfx::Size view_size = label->GetPreferredSize();
320 if (!dry_run) { 339 if (!dry_run) {
321 label->SetBoundsRect(gfx::Rect( 340 label->SetBoundsRect(gfx::Rect(
322 gfx::Point(GetInsets().left() + x - focus_border_insets.left(), 341 gfx::Point(GetInsets().left() + x - focus_border_insets.left(),
323 GetInsets().top() + line * line_height - 342 GetInsets().top() + line * line_height -
324 focus_border_insets.top()), 343 focus_border_insets.top()),
325 view_size)); 344 view_size));
326 AddChildView(label.release()); 345 AddChildView(label.release());
327 } 346 }
328 x += view_size.width() - focus_border_insets.width(); 347 x += view_size.width() - focus_border_insets.width();
348 used_width = std::max(used_width, x);
329 349
330 remaining_string = remaining_string.substr(chunk.size()); 350 remaining_string = remaining_string.substr(chunk.size());
331 } 351 }
332 352
353 DCHECK_LE(used_width, width);
333 // The user-specified line height only applies to interline spacing, so the 354 // The user-specified line height only applies to interline spacing, so the
334 // final line's height is unaffected. 355 // final line's height is unaffected.
335 int total_height = line * line_height + 356 int total_height = line * line_height +
336 CalculateLineHeight(font_list_) + GetInsets().height(); 357 CalculateLineHeight(font_list_) + GetInsets().height();
337 return gfx::Size(width, total_height); 358 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height);
359 return calculated_size_;
338 } 360 }
339 361
340 } // namespace views 362 } // namespace views
OLDNEW
« ui/views/controls/styled_label.h ('K') | « ui/views/controls/styled_label.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698