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

Unified Diff: ui/views/controls/rich_label.cc

Issue 12543032: Add views::RichLabel, a class which creates multi-line text with mixed (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 side-by-side diff with in-line comments
Download patch
Index: ui/views/controls/rich_label.cc
diff --git a/ui/views/controls/rich_label.cc b/ui/views/controls/rich_label.cc
new file mode 100644
index 0000000000000000000000000000000000000000..97947c395f644adce22f679b21fa5c78b03a3b0f
--- /dev/null
+++ b/ui/views/controls/rich_label.cc
@@ -0,0 +1,91 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/controls/rich_label.h"
+
+#include <deque>
+
+#include "base/string_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/text/text_elider.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
+
+namespace views {
+
+RichLabel::RichLabel(const std::vector<string16>& text,
+ const std::vector<GURL>& urls)
+ : strings_(text),
+ urls_(urls) {}
+
+RichLabel::~RichLabel() {}
+
+gfx::Size RichLabel::GetPreferredSize() {
+ return gfx::Size(100, 100);
+}
+
+void RichLabel::Layout() {
+ RemoveAllChildViews(true);
+ gfx::Font font =
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
+ gfx::Rect total_bounds(GetLocalBounds());
+ int height = font.GetHeight();
+ int line = 0;
+ int x = 0;
+
+ std::deque<string16> queue(strings_.begin(), strings_.end());
+ int url_index = 0;
+
+ while (!queue.empty()) {
+ string16 string = queue.front();
+ // Don't put whitespace at beginning of line.
+ if (x == 0)
+ TrimWhitespace(string, TRIM_LEADING, &string);
+ queue.pop_front();
+ gfx::Rect bounds = total_bounds;
+ bounds.set_height(2 * height);
+ bounds.set_x(x);
+ bounds.set_width(bounds.width() - x);
+
+ std::vector<string16> substrings;
+ ui::ElideRectangleText(string,
+ font,
+ bounds.width(), bounds.height(),
+ ui::IGNORE_LONG_WORDS,
+ &substrings);
+
+ View* view = NULL;
+ if (urls_[url_index].is_empty())
+ view = new Label(string);
+ else if (substrings.size() == 1)
+ view = new Link(string);
+
+ if (view) {
+ AddChildView(view);
+ view->SetBoundsRect(gfx::Rect(gfx::Point(x, line * height),
+ view->GetPreferredSize()));
+ x += view->bounds().width();
+
+ if (substrings.size() == 1) {
+ // It all fit on one line.
+ url_index++;
+ } else {
+ // Only part of the string fit on this line. Wrap the remainder to a new
+ // line.
+ queue.push_front(string.substr(substrings[0].size()));
+ line++;
+ x = 0;
+ }
+ } else {
+ // There may be a link that's too long to fit on an entire line. Don't get
+ // stuck in a loop; just ignore that link.
+ if (x != 0)
+ queue.push_front(string);
+ x = 0;
+ line++;
+ }
+ }
+}
+
+} // namespace views

Powered by Google App Engine
This is Rietveld 408576698