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

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

Issue 1819303002: StyledLabel: Added AddEmbeddedView method. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@applist-deprecation
Patch Set: Created 4 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
« no previous file with comments | « ui/views/controls/styled_label.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <vector> 10 #include <vector>
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 125 }
126 126
127 void StyledLabel::AddStyleRange(const gfx::Range& range, 127 void StyledLabel::AddStyleRange(const gfx::Range& range,
128 const RangeStyleInfo& style_info) { 128 const RangeStyleInfo& style_info) {
129 DCHECK(!range.is_reversed()); 129 DCHECK(!range.is_reversed());
130 DCHECK(!range.is_empty()); 130 DCHECK(!range.is_empty());
131 DCHECK(gfx::Range(0, text_.size()).Contains(range)); 131 DCHECK(gfx::Range(0, text_.size()).Contains(range));
132 132
133 // Insert the new range in sorted order. 133 // Insert the new range in sorted order.
134 StyleRanges new_range; 134 StyleRanges new_range;
135 new_range.push_front(StyleRange(range, style_info)); 135 new_range.push_front(StyleRange(range, style_info, nullptr));
136 style_ranges_.merge(new_range); 136 style_ranges_.merge(new_range);
137 137
138 PreferredSizeChanged(); 138 PreferredSizeChanged();
139 }
140
141 void StyledLabel::AddEmbeddedView(uint32_t position, scoped_ptr<View> view) {
142 DCHECK_LE(position, text_.size());
143 DCHECK(!view->parent());
144
145 // Set the view as owned by the StyledLabel so the Views hierarchy doesn't
146 // clean it up.
147 view->set_owned_by_client();
148
149 // Insert the new range in sorted order.
150 StyleRanges new_range;
151 embedded_views_.push_back(std::move(view));
152 new_range.push_front(StyleRange(gfx::Range(position, position),
153 RangeStyleInfo(),
154 embedded_views_.back().get()));
155 style_ranges_.merge(new_range);
156
157 PreferredSizeChanged();
139 } 158 }
140 159
141 void StyledLabel::SetDefaultStyle(const RangeStyleInfo& style_info) { 160 void StyledLabel::SetDefaultStyle(const RangeStyleInfo& style_info) {
142 default_style_info_ = style_info; 161 default_style_info_ = style_info;
143 PreferredSizeChanged(); 162 PreferredSizeChanged();
144 } 163 }
145 164
146 void StyledLabel::SetLineHeight(int line_height) { 165 void StyledLabel::SetLineHeight(int line_height) {
147 specified_line_height_ = line_height; 166 specified_line_height_ = line_height;
148 PreferredSizeChanged(); 167 PreferredSizeChanged();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 width -= GetInsets().width(); 252 width -= GetInsets().width();
234 253
235 if (!dry_run) { 254 if (!dry_run) {
236 RemoveAllChildViews(true); 255 RemoveAllChildViews(true);
237 link_targets_.clear(); 256 link_targets_.clear();
238 } 257 }
239 258
240 if (width <= 0 || text_.empty()) 259 if (width <= 0 || text_.empty())
241 return gfx::Size(); 260 return gfx::Size();
242 261
243 const int line_height = specified_line_height_ > 0 ? specified_line_height_ 262 const int usual_line_height = specified_line_height_ > 0
244 : CalculateLineHeight(font_list_); 263 ? specified_line_height_
264 : CalculateLineHeight(font_list_);
245 // The index of the line we're on. 265 // The index of the line we're on.
246 int line = 0; 266 int line = 0;
247 // The x position (in pixels) of the line we're on, relative to content 267 // The x, y position (in pixels) of the line we're on, relative to content
248 // bounds. 268 // bounds.
249 int x = 0; 269 int x = 0, y = 0;
250 // The width that was actually used. Guaranteed to be no larger than |width|. 270 // The width that was actually used. Guaranteed to be no larger than |width|.
251 int used_width = 0; 271 int used_width = 0;
272 // The height of the actual current line. Guaranteed to be no smaller than
273 // |usual_line_height|.
274 int line_height = usual_line_height;
252 275
253 base::string16 remaining_string = text_; 276 base::string16 remaining_string = text_;
254 StyleRanges::const_iterator current_range = style_ranges_.begin(); 277 StyleRanges::const_iterator current_range = style_ranges_.begin();
255 278
256 // Iterate over the text, creating a bunch of labels and links and laying them 279 // Iterate over the text, creating a bunch of labels and links and laying them
257 // out in the appropriate positions. 280 // out in the appropriate positions.
258 while (!remaining_string.empty()) { 281 while (!remaining_string.empty()) {
259 // Don't put whitespace at beginning of a line with an exception for the 282 // Don't put whitespace at beginning of a line with an exception for the
260 // first line (so the text's leading whitespace is respected). 283 // first line (so the text's leading whitespace is respected).
261 if (x == 0 && line > 0) { 284 if (x == 0 && line > 0) {
262 base::TrimWhitespace(remaining_string, base::TRIM_LEADING, 285 base::TrimWhitespace(remaining_string, base::TRIM_LEADING,
263 &remaining_string); 286 &remaining_string);
264 } 287 }
265 288
266 gfx::Range range(gfx::Range::InvalidRange()); 289 gfx::Range range(gfx::Range::InvalidRange());
267 if (current_range != style_ranges_.end()) 290 if (current_range != style_ranges_.end())
268 range = current_range->range; 291 range = current_range->range;
269 292
270 const size_t position = text_.size() - remaining_string.size(); 293 const size_t position = text_.size() - remaining_string.size();
271 294
272 const gfx::Rect chunk_bounds(x, 0, width - x, 2 * line_height); 295 const gfx::Rect chunk_bounds(x, 0, width - x, 2 * usual_line_height);
273 std::vector<base::string16> substrings; 296 std::vector<base::string16> substrings;
274 gfx::FontList text_font_list = font_list_; 297 gfx::FontList text_font_list = font_list_;
275 // If the start of the remaining text is inside a styled range, the font 298 // If the start of the remaining text is inside a styled range, the font
276 // style may differ from the base font. The font specified by the range 299 // style may differ from the base font. The font specified by the range
277 // should be used when eliding text. 300 // should be used when eliding text.
278 if (position >= range.start()) { 301 if (position >= range.start()) {
279 text_font_list = text_font_list.DeriveWithStyle( 302 text_font_list = text_font_list.DeriveWithStyle(
280 current_range->style_info.font_style); 303 current_range->style_info.font_style);
281 } 304 }
282 gfx::ElideRectangleText(remaining_string, 305 gfx::ElideRectangleText(remaining_string,
(...skipping 11 matching lines...) Expand all
294 if (x == 0) { 317 if (x == 0) {
295 if (line == 0) { 318 if (line == 0) {
296 base::TrimWhitespace(remaining_string, base::TRIM_LEADING, 319 base::TrimWhitespace(remaining_string, base::TRIM_LEADING,
297 &remaining_string); 320 &remaining_string);
298 continue; 321 continue;
299 } 322 }
300 break; 323 break;
301 } 324 }
302 325
303 x = 0; 326 x = 0;
327 y += line_height;
328 line_height = usual_line_height;
304 line++; 329 line++;
305 continue; 330 continue;
306 } 331 }
307 332
308 base::string16 chunk = substrings[0]; 333 base::string16 chunk = substrings[0];
309 334
335 View* view = current_range->embedded_view;
310 scoped_ptr<Label> label; 336 scoped_ptr<Label> label;
311 if (position >= range.start()) { 337 if (position >= range.start()) {
338 if (view)
339 line_height = std::max(line_height, view->GetPreferredSize().height());
340
312 const RangeStyleInfo& style_info = current_range->style_info; 341 const RangeStyleInfo& style_info = current_range->style_info;
313 342
314 if (style_info.disable_line_wrapping && chunk.size() < range.length() && 343 if (style_info.disable_line_wrapping && chunk.size() < range.length() &&
315 position == range.start() && x != 0) { 344 position == range.start() && x != 0) {
316 // If the chunk should not be wrapped, try to fit it entirely on the 345 // If the chunk should not be wrapped, try to fit it entirely on the
317 // next line. 346 // next line.
318 x = 0; 347 x = 0;
348 y += line_height;
349 line_height = usual_line_height;
319 line++; 350 line++;
320 continue; 351 continue;
321 } 352 }
322 353
323 if (chunk.size() > range.end() - position) 354 if (chunk.size() > range.end() - position)
324 chunk = chunk.substr(0, range.end() - position); 355 chunk = chunk.substr(0, range.end() - position);
325 356
326 label = CreateLabelRange(chunk, font_list_, style_info, this); 357 if (!view) {
358 label = CreateLabelRange(chunk, font_list_, style_info, this);
327 359
328 if (style_info.is_link && !dry_run) 360 if (style_info.is_link && !dry_run)
329 link_targets_[label.get()] = range; 361 link_targets_[label.get()] = range;
362 }
330 363
331 if (position + chunk.size() >= range.end()) 364 if (position + chunk.size() >= range.end())
332 ++current_range; 365 ++current_range;
333 } else { 366 } else {
334 // This chunk is normal text. 367 // This chunk is normal text.
335 if (position + chunk.size() > range.start()) 368 if (position + chunk.size() > range.start())
336 chunk = chunk.substr(0, range.start() - position); 369 chunk = chunk.substr(0, range.start() - position);
337 label = CreateLabelRange(chunk, font_list_, default_style_info_, this); 370 label = CreateLabelRange(chunk, font_list_, default_style_info_, this);
338 } 371 }
339 372
340 if (displayed_on_background_color_set_) 373 if (label) {
341 label->SetBackgroundColor(displayed_on_background_color_); 374 if (displayed_on_background_color_set_)
342 label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_); 375 label->SetBackgroundColor(displayed_on_background_color_);
376 label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_);
377
378 // |view| temporarily owns the pointer to the Label. This will be owned by
379 // the views hierarchy.
380 view = label.release();
381 }
343 382
344 // Calculate the size of the optional focus border, and overlap by that 383 // Calculate the size of the optional focus border, and overlap by that
345 // amount. Otherwise, "<a>link</a>," will render as "link ,". 384 // amount. Otherwise, "<a>link</a>," will render as "link ,".
346 gfx::Insets focus_border_insets(label->GetInsets()); 385 gfx::Insets focus_border_insets(view->GetInsets());
347 focus_border_insets += -label->View::GetInsets(); 386 focus_border_insets += -view->View::GetInsets();
348 const gfx::Size view_size = label->GetPreferredSize(); 387 const gfx::Size view_size = view->GetPreferredSize();
349 if (!dry_run) { 388 if (!dry_run) {
350 label->SetBoundsRect(gfx::Rect( 389 view->SetBoundsRect(gfx::Rect(
351 gfx::Point(GetInsets().left() + x - focus_border_insets.left(), 390 gfx::Point(GetInsets().left() + x - focus_border_insets.left(),
352 GetInsets().top() + line * line_height - 391 GetInsets().top() + y - focus_border_insets.top()),
353 focus_border_insets.top()),
354 view_size)); 392 view_size));
355 AddChildView(label.release()); 393
394 // Ownership: If |view| came from a Label created above, it will be owned
395 // by the views hierarchy from now on. If |view| came from an externally
396 // supplied embedded view, it will continue to be owned by the
397 // |embedded_views_| vector.
398 AddChildView(view);
356 } 399 }
357 x += view_size.width() - focus_border_insets.width(); 400 x += view_size.width() - focus_border_insets.width();
358 used_width = std::max(used_width, x); 401 used_width = std::max(used_width, x);
359 402
360 // If |gfx::ElideRectangleText| returned more than one substring, that 403 // If |gfx::ElideRectangleText| returned more than one substring, that
361 // means the whole text did not fit into remaining line width, with text 404 // means the whole text did not fit into remaining line width, with text
362 // after |susbtring[0]| spilling into next line. If whole |substring[0]| 405 // after |susbtring[0]| spilling into next line. If whole |substring[0]|
363 // was added to the current line (this may not be the case if part of the 406 // was added to the current line (this may not be the case if part of the
364 // substring has different style), proceed to the next line. 407 // substring has different style), proceed to the next line.
365 if (substrings.size() > 1 && chunk.size() == substrings[0].size()) { 408 if (substrings.size() > 1 && chunk.size() == substrings[0].size()) {
366 x = 0; 409 x = 0;
410 y += line_height;
411 line_height = usual_line_height;
367 ++line; 412 ++line;
368 } 413 }
369 414
370 remaining_string = remaining_string.substr(chunk.size()); 415 remaining_string = remaining_string.substr(chunk.size());
371 } 416 }
372 417
373 DCHECK_LE(used_width, width); 418 DCHECK_LE(used_width, width);
374 // The user-specified line height only applies to interline spacing, so the 419 // The user-specified line height only applies to interline spacing, so the
375 // final line's height is unaffected. 420 // final line's height is unaffected.
376 int total_height = line * line_height + 421 // TODO(mgiuca): I think this makes a bad assumption about the final line.
377 CalculateLineHeight(font_list_) + GetInsets().height(); 422 int total_height = y + CalculateLineHeight(font_list_) + GetInsets().height();
378 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height); 423 calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height);
379 return calculated_size_; 424 return calculated_size_;
380 } 425 }
381 426
382 } // namespace views 427 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/styled_label.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698