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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/controls/styled_label.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/styled_label.cc
diff --git a/ui/views/controls/styled_label.cc b/ui/views/controls/styled_label.cc
index 9c8f720cee179ae03412fa863f526a9638f9f4d1..8bf6706b3238289c4ac0a7fe7212e8a7cdae6f06 100644
--- a/ui/views/controls/styled_label.cc
+++ b/ui/views/controls/styled_label.cc
@@ -132,7 +132,26 @@ void StyledLabel::AddStyleRange(const gfx::Range& range,
// Insert the new range in sorted order.
StyleRanges new_range;
- new_range.push_front(StyleRange(range, style_info));
+ new_range.push_front(StyleRange(range, style_info, nullptr));
+ style_ranges_.merge(new_range);
+
+ PreferredSizeChanged();
+}
+
+void StyledLabel::AddEmbeddedView(uint32_t position, scoped_ptr<View> view) {
+ DCHECK_LE(position, text_.size());
+ DCHECK(!view->parent());
+
+ // Set the view as owned by the StyledLabel so the Views hierarchy doesn't
+ // clean it up.
+ view->set_owned_by_client();
+
+ // Insert the new range in sorted order.
+ StyleRanges new_range;
+ embedded_views_.push_back(std::move(view));
+ new_range.push_front(StyleRange(gfx::Range(position, position),
+ RangeStyleInfo(),
+ embedded_views_.back().get()));
style_ranges_.merge(new_range);
PreferredSizeChanged();
@@ -240,15 +259,19 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
if (width <= 0 || text_.empty())
return gfx::Size();
- const int line_height = specified_line_height_ > 0 ? specified_line_height_
- : CalculateLineHeight(font_list_);
+ const int usual_line_height = specified_line_height_ > 0
+ ? specified_line_height_
+ : CalculateLineHeight(font_list_);
// The index of the line we're on.
int line = 0;
- // The x position (in pixels) of the line we're on, relative to content
+ // The x, y position (in pixels) of the line we're on, relative to content
// bounds.
- int x = 0;
+ int x = 0, y = 0;
// The width that was actually used. Guaranteed to be no larger than |width|.
int used_width = 0;
+ // The height of the actual current line. Guaranteed to be no smaller than
+ // |usual_line_height|.
+ int line_height = usual_line_height;
base::string16 remaining_string = text_;
StyleRanges::const_iterator current_range = style_ranges_.begin();
@@ -269,7 +292,7 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
const size_t position = text_.size() - remaining_string.size();
- const gfx::Rect chunk_bounds(x, 0, width - x, 2 * line_height);
+ const gfx::Rect chunk_bounds(x, 0, width - x, 2 * usual_line_height);
std::vector<base::string16> substrings;
gfx::FontList text_font_list = font_list_;
// If the start of the remaining text is inside a styled range, the font
@@ -301,14 +324,20 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
}
x = 0;
+ y += line_height;
+ line_height = usual_line_height;
line++;
continue;
}
base::string16 chunk = substrings[0];
+ View* view = current_range->embedded_view;
scoped_ptr<Label> label;
if (position >= range.start()) {
+ if (view)
+ line_height = std::max(line_height, view->GetPreferredSize().height());
+
const RangeStyleInfo& style_info = current_range->style_info;
if (style_info.disable_line_wrapping && chunk.size() < range.length() &&
@@ -316,6 +345,8 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
// If the chunk should not be wrapped, try to fit it entirely on the
// next line.
x = 0;
+ y += line_height;
+ line_height = usual_line_height;
line++;
continue;
}
@@ -323,10 +354,12 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
if (chunk.size() > range.end() - position)
chunk = chunk.substr(0, range.end() - position);
- label = CreateLabelRange(chunk, font_list_, style_info, this);
+ if (!view) {
+ label = CreateLabelRange(chunk, font_list_, style_info, this);
- if (style_info.is_link && !dry_run)
- link_targets_[label.get()] = range;
+ if (style_info.is_link && !dry_run)
+ link_targets_[label.get()] = range;
+ }
if (position + chunk.size() >= range.end())
++current_range;
@@ -337,22 +370,32 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
label = CreateLabelRange(chunk, font_list_, default_style_info_, this);
}
- if (displayed_on_background_color_set_)
- label->SetBackgroundColor(displayed_on_background_color_);
- label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_);
+ if (label) {
+ if (displayed_on_background_color_set_)
+ label->SetBackgroundColor(displayed_on_background_color_);
+ label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_);
+
+ // |view| temporarily owns the pointer to the Label. This will be owned by
+ // the views hierarchy.
+ view = label.release();
+ }
// Calculate the size of the optional focus border, and overlap by that
// amount. Otherwise, "<a>link</a>," will render as "link ,".
- gfx::Insets focus_border_insets(label->GetInsets());
- focus_border_insets += -label->View::GetInsets();
- const gfx::Size view_size = label->GetPreferredSize();
+ gfx::Insets focus_border_insets(view->GetInsets());
+ focus_border_insets += -view->View::GetInsets();
+ const gfx::Size view_size = view->GetPreferredSize();
if (!dry_run) {
- label->SetBoundsRect(gfx::Rect(
+ view->SetBoundsRect(gfx::Rect(
gfx::Point(GetInsets().left() + x - focus_border_insets.left(),
- GetInsets().top() + line * line_height -
- focus_border_insets.top()),
+ GetInsets().top() + y - focus_border_insets.top()),
view_size));
- AddChildView(label.release());
+
+ // Ownership: If |view| came from a Label created above, it will be owned
+ // by the views hierarchy from now on. If |view| came from an externally
+ // supplied embedded view, it will continue to be owned by the
+ // |embedded_views_| vector.
+ AddChildView(view);
}
x += view_size.width() - focus_border_insets.width();
used_width = std::max(used_width, x);
@@ -364,6 +407,8 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
// substring has different style), proceed to the next line.
if (substrings.size() > 1 && chunk.size() == substrings[0].size()) {
x = 0;
+ y += line_height;
+ line_height = usual_line_height;
++line;
}
@@ -373,8 +418,8 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
DCHECK_LE(used_width, width);
// The user-specified line height only applies to interline spacing, so the
// final line's height is unaffected.
- int total_height = line * line_height +
- CalculateLineHeight(font_list_) + GetInsets().height();
+ // TODO(mgiuca): I think this makes a bad assumption about the final line.
+ int total_height = y + CalculateLineHeight(font_list_) + GetInsets().height();
calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height);
return calculated_size_;
}
« 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