summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authoroshima <oshima@chromium.org>2015-02-23 08:38:08 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-23 16:38:35 +0000
commit3e0cc51a03d65bf057742ac0f1f5e0c8b633bda5 (patch)
tree221d4ab735aa13c8b666eac34bbc384f2bf922a8 /ui
parente5938a2d887bd71f1cf0df76d5d72e0a6318f888 (diff)
downloadchromium_src-3e0cc51a03d65bf057742ac0f1f5e0c8b633bda5.zip
chromium_src-3e0cc51a03d65bf057742ac0f1f5e0c8b633bda5.tar.gz
chromium_src-3e0cc51a03d65bf057742ac0f1f5e0c8b633bda5.tar.bz2
Use RenderText directly to draw tooltip to imporove format and performance.
This replaces the old CL (https://codereview.chromium.org/340543004/). This runs faster and doesn't require the label caching CL. (for the example in 370226, this is 20x faster on arm. ~60ms total vs ~3ms total) I'll look into switching to label once I get the performance data with label after label caching is enabled. This depends on two CLs 1) https://codereview.chromium.org/916423002/ Tooltip Cleanup 2) https://codereview.chromium.org/915383003/ RTL format problem. but this can be reviewed independently. BUG=370226,451853 Review URL: https://codereview.chromium.org/924433002 Cr-Commit-Position: refs/heads/master@{#317590}
Diffstat (limited to 'ui')
-rw-r--r--ui/views/corewm/DEPS2
-rw-r--r--ui/views/corewm/tooltip_aura.cc163
-rw-r--r--ui/views/corewm/tooltip_aura.h19
-rw-r--r--ui/views/corewm/tooltip_aura_unittest.cc131
-rw-r--r--ui/views/corewm/tooltip_controller.cc2
-rw-r--r--ui/views/views.gyp1
6 files changed, 75 insertions, 243 deletions
diff --git a/ui/views/corewm/DEPS b/ui/views/corewm/DEPS
index a2d52d6..c50f694 100644
--- a/ui/views/corewm/DEPS
+++ b/ui/views/corewm/DEPS
@@ -16,6 +16,7 @@ specific_include_rules = {
"+ui/views/background.h",
"+ui/views/border.h",
"+ui/views/widget/widget.h",
+ "+ui/views/view.h",
],
"desktop_capture_controller_unittest.cc": [
@@ -38,7 +39,6 @@ specific_include_rules = {
],
"tooltip_aura.h": [
- "+ui/views/controls/label.h",
"+ui/views/widget/widget_observer.h",
],
diff --git a/ui/views/corewm/tooltip_aura.cc b/ui/views/corewm/tooltip_aura.cc
index 3e98cf16..c0d3691 100644
--- a/ui/views/corewm/tooltip_aura.cc
+++ b/ui/views/corewm/tooltip_aura.cc
@@ -5,14 +5,18 @@
#include "ui/views/corewm/tooltip_aura.h"
#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/render_text.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
+#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace {
@@ -21,8 +25,6 @@ namespace {
// be wrapped.
const int kTooltipMaxWidthPixels = 400;
-const size_t kMaxLines = 10;
-
// FIXME: get cursor offset from actual cursor size.
const int kCursorOffsetX = 10;
const int kCursorOffsetY = 15;
@@ -47,16 +49,68 @@ views::Widget* CreateTooltipWidget(aura::Window* tooltip_window) {
namespace views {
namespace corewm {
+// TODO(oshima): Consider to use views::Label.
+class TooltipAura::TooltipView : public views::View {
+ public:
+ TooltipView()
+ : render_text_(gfx::RenderText::CreateInstance()),
+ max_width_(0) {
+ set_owned_by_client();
+ render_text_->SetMultiline(true);
+ ResetDisplayRect();
+ }
+
+ ~TooltipView() override {}
+
+ // views:View:
+ void OnPaint(gfx::Canvas* canvas) override {
+ OnPaintBackground(canvas);
+ render_text_->SetDisplayRect(gfx::Rect(size()));
+ render_text_->Draw(canvas);
+ OnPaintBorder(canvas);
+ }
+
+ gfx::Size GetPreferredSize() const override {
+ return render_text_->GetStringSize();
+ }
+
+ const char* GetClassName() const override {
+ return "TooltipView";
+ }
+
+ void SetText(const base::string16& text) {
+ render_text_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
+ render_text_->SetText(text);
+ }
+
+ void SetForegroundColor(SkColor color) {
+ render_text_->SetColor(color);
+ }
+
+ void SetMaxWidth(int width) {
+ max_width_ = width;
+ ResetDisplayRect();
+ }
+
+ private:
+ void ResetDisplayRect() {
+ render_text_->SetDisplayRect(gfx::Rect(0, 0, max_width_, 100000));
+ }
+
+ scoped_ptr<gfx::RenderText> render_text_;
+ int max_width_;
+
+ DISALLOW_COPY_AND_ASSIGN(TooltipView);
+};
+
TooltipAura::TooltipAura()
- : widget_(NULL),
+ : tooltip_view_(new TooltipView),
+ widget_(NULL),
tooltip_window_(NULL) {
- label_.set_owned_by_client();
- label_.SetMultiLine(true);
- label_.SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
const int kHorizontalPadding = 3;
const int kVerticalPadding = 2;
- label_.SetBorder(Border::CreateEmptyBorder(
+ tooltip_view_->SetBorder(Border::CreateEmptyBorder(
kVerticalPadding, kHorizontalPadding,
kVerticalPadding, kHorizontalPadding));
}
@@ -65,82 +119,6 @@ TooltipAura::~TooltipAura() {
DestroyWidget();
}
-// static
-void TooltipAura::TrimTooltipToFit(const gfx::FontList& font_list,
- int max_width,
- base::string16* text,
- int* width,
- int* line_count) {
- *width = 0;
- *line_count = 0;
-
- // Determine the available width for the tooltip.
- int available_width = std::min(kTooltipMaxWidthPixels, max_width);
-
- std::vector<base::string16> lines;
- base::SplitString(*text, '\n', &lines);
- std::vector<base::string16> result_lines;
-
- // Format each line to fit.
- for (std::vector<base::string16>::iterator l = lines.begin();
- l != lines.end(); ++l) {
- // We break the line at word boundaries, then stuff as many words as we can
- // in the available width to the current line, and move the remaining words
- // to a new line.
- std::vector<base::string16> words;
- base::SplitStringDontTrim(*l, ' ', &words);
- int current_width = 0;
- base::string16 line;
- for (std::vector<base::string16>::iterator w = words.begin();
- w != words.end(); ++w) {
- base::string16 word = *w;
- if (w + 1 != words.end())
- word.push_back(' ');
- int word_width = gfx::GetStringWidth(word, font_list);
- if (current_width + word_width > available_width) {
- // Current width will exceed the available width. Must start a new line.
- if (!line.empty())
- result_lines.push_back(line);
- current_width = 0;
- line.clear();
- }
- current_width += word_width;
- line.append(word);
- }
- result_lines.push_back(line);
- }
-
- // Clamp number of lines to |kMaxLines|.
- if (result_lines.size() > kMaxLines) {
- result_lines.resize(kMaxLines);
- // Add ellipses character to last line.
- result_lines[kMaxLines - 1] = gfx::TruncateString(
- result_lines.back(), result_lines.back().length() - 1, gfx::WORD_BREAK);
- }
- *line_count = result_lines.size();
-
- // Flatten the result.
- base::string16 result;
- for (std::vector<base::string16>::iterator l = result_lines.begin();
- l != result_lines.end(); ++l) {
- if (!result.empty())
- result.push_back('\n');
- int line_width = gfx::GetStringWidth(*l, font_list);
- // Since we only break at word boundaries, it could happen that due to some
- // very long word, line_width is greater than the available_width. In such
- // case, we simply truncate at available_width and add ellipses at the end.
- if (line_width > available_width) {
- *width = available_width;
- result.append(gfx::ElideText(*l, font_list, available_width,
- gfx::ELIDE_TAIL));
- } else {
- *width = std::max(*width, line_width);
- result.append(*l);
- }
- }
- *text = result;
-}
-
void TooltipAura::SetTooltipBounds(const gfx::Point& mouse_pos,
const gfx::Size& tooltip_size) {
gfx::Rect tooltip_rect(mouse_pos, tooltip_size);
@@ -183,30 +161,23 @@ void TooltipAura::SetText(aura::Window* window,
const base::string16& tooltip_text,
const gfx::Point& location) {
tooltip_window_ = window;
- int max_width = 0;
- int line_count = 0;
- base::string16 trimmed_text(tooltip_text);
- TrimTooltipToFit(label_.font_list(), GetMaxWidth(location, window),
- &trimmed_text, &max_width, &line_count);
- label_.SetText(trimmed_text);
+ tooltip_view_->SetMaxWidth(GetMaxWidth(location, window));
+ tooltip_view_->SetText(tooltip_text);
if (!widget_) {
widget_ = CreateTooltipWidget(tooltip_window_);
- widget_->SetContentsView(&label_);
+ widget_->SetContentsView(tooltip_view_.get());
widget_->AddObserver(this);
}
- label_.SizeToFit(max_width + label_.GetInsets().width());
- SetTooltipBounds(location, label_.size());
+ SetTooltipBounds(location, tooltip_view_->GetPreferredSize());
ui::NativeTheme* native_theme = widget_->GetNativeTheme();
- label_.set_background(
+ tooltip_view_->set_background(
views::Background::CreateSolidBackground(
native_theme->GetSystemColor(
ui::NativeTheme::kColorId_TooltipBackground)));
-
- label_.SetAutoColorReadabilityEnabled(false);
- label_.SetEnabledColor(native_theme->GetSystemColor(
+ tooltip_view_->SetForegroundColor(native_theme->GetSystemColor(
ui::NativeTheme::kColorId_TooltipText));
}
diff --git a/ui/views/corewm/tooltip_aura.h b/ui/views/corewm/tooltip_aura.h
index ce92fa2..d1ef448 100644
--- a/ui/views/corewm/tooltip_aura.h
+++ b/ui/views/corewm/tooltip_aura.h
@@ -5,13 +5,14 @@
#ifndef UI_VIEWS_COREWM_TOOLTIP_AURA_H_
#define UI_VIEWS_COREWM_TOOLTIP_AURA_H_
+#include "base/memory/scoped_ptr.h"
#include "ui/gfx/screen_type_delegate.h"
-#include "ui/views/controls/label.h"
#include "ui/views/corewm/tooltip.h"
#include "ui/views/widget/widget_observer.h"
namespace gfx {
class FontList;
+class Size;
} // namespace gfx
namespace views {
@@ -26,17 +27,9 @@ class VIEWS_EXPORT TooltipAura : public Tooltip, public WidgetObserver {
TooltipAura();
~TooltipAura() override;
- // Trims the tooltip to fit in the width |max_width|, setting |text| to the
- // clipped result, |width| to the width (in pixels) of the clipped text
- // and |line_count| to the number of lines of text in the tooltip. |font_list|
- // is used to layout |text|. |max_width| comes from GetMaxWidth().
- static void TrimTooltipToFit(const gfx::FontList& font_list,
- int max_width,
- base::string16* text,
- int* width,
- int* line_count);
-
private:
+ class TooltipView;
+
// Adjusts the bounds given by the arguments to fit inside the desktop
// and applies the adjusted bounds to the label_.
void SetTooltipBounds(const gfx::Point& mouse_pos,
@@ -58,8 +51,8 @@ class VIEWS_EXPORT TooltipAura : public Tooltip, public WidgetObserver {
// WidgetObserver:
void OnWidgetDestroying(Widget* widget) override;
- // The label showing the tooltip.
- Label label_;
+ // The view showing the tooltip.
+ scoped_ptr<TooltipView> tooltip_view_;
// The widget containing the tooltip. May be NULL.
Widget* widget_;
diff --git a/ui/views/corewm/tooltip_aura_unittest.cc b/ui/views/corewm/tooltip_aura_unittest.cc
deleted file mode 100644
index a77db2f..0000000
--- a/ui/views/corewm/tooltip_aura_unittest.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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/corewm/tooltip_aura.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "ui/aura/test/aura_test_base.h"
-#include "ui/gfx/font_list.h"
-#include "ui/gfx/text_elider.h"
-#include "ui/gfx/text_utils.h"
-
-using base::ASCIIToUTF16;
-using base::UTF8ToUTF16;
-
-namespace views {
-namespace corewm {
-
-typedef aura::test::AuraTestBase TooltipAuraTest;
-
-TEST_F(TooltipAuraTest, TrimTooltipToFitTests) {
- const gfx::FontList font_list;
- const int max_width = 4000;
- base::string16 tooltip;
- int width, line_count, expect_lines;
- int max_pixel_width = 400; // copied from constants in tooltip_controller.cc
- int max_lines = 10; // copied from constants in tooltip_controller.cc
- size_t tooltip_len;
-
- // Error in computed size vs. expected size should not be greater than the
- // size of the longest word.
- int error_in_pixel_width = gfx::GetStringWidth(ASCIIToUTF16("tooltip"),
- font_list);
-
- // Long tooltips should wrap to next line
- tooltip.clear();
- width = line_count = -1;
- expect_lines = 3;
- for (; gfx::GetStringWidth(tooltip, font_list) <=
- (expect_lines - 1) * max_pixel_width;)
- tooltip.append(ASCIIToUTF16("This is part of the tooltip"));
- tooltip_len = tooltip.length();
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_NEAR(max_pixel_width, width, error_in_pixel_width);
- EXPECT_EQ(expect_lines, line_count);
- EXPECT_EQ(tooltip_len + expect_lines - 1, tooltip.length());
-
- // More than |max_lines| lines should get truncated at 10 lines.
- tooltip.clear();
- width = line_count = -1;
- expect_lines = 13;
- for (; gfx::GetStringWidth(tooltip, font_list) <=
- (expect_lines - 1) * max_pixel_width;)
- tooltip.append(ASCIIToUTF16("This is part of the tooltip"));
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_NEAR(max_pixel_width, width, error_in_pixel_width);
- EXPECT_EQ(max_lines, line_count);
-
- // Long multi line tooltips should wrap individual lines.
- tooltip.clear();
- width = line_count = -1;
- expect_lines = 4;
- for (; gfx::GetStringWidth(tooltip, font_list) <=
- (expect_lines - 2) * max_pixel_width;)
- tooltip.append(ASCIIToUTF16("This is part of the tooltip"));
- tooltip.insert(tooltip.length() / 2, ASCIIToUTF16("\n"));
- tooltip_len = tooltip.length();
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_NEAR(max_pixel_width, width, error_in_pixel_width);
- EXPECT_EQ(expect_lines, line_count);
- // We may have inserted the line break above near a space which will get
- // trimmed. Hence we may be off by 1 in the final tooltip length calculation.
- EXPECT_NEAR(tooltip_len + expect_lines - 2, tooltip.length(), 1);
-
-#if !defined(OS_WIN)
- // Tooltip with really long word gets elided.
- tooltip.clear();
- width = line_count = -1;
- tooltip = UTF8ToUTF16(std::string('a', max_pixel_width));
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_NEAR(max_pixel_width, width, 5);
- EXPECT_EQ(1, line_count);
- EXPECT_EQ(gfx::ElideText(UTF8ToUTF16(std::string('a', max_pixel_width)),
- font_list, max_pixel_width, gfx::ELIDE_TAIL),
- tooltip);
-#endif
-
- // Normal small tooltip should stay as is.
- tooltip.clear();
- width = line_count = -1;
- tooltip = ASCIIToUTF16("Small Tooltip");
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_EQ(gfx::GetStringWidth(ASCIIToUTF16("Small Tooltip"), font_list),
- width);
- EXPECT_EQ(1, line_count);
- EXPECT_EQ(ASCIIToUTF16("Small Tooltip"), tooltip);
-
- // Normal small multi-line tooltip should stay as is.
- tooltip.clear();
- width = line_count = -1;
- tooltip = ASCIIToUTF16("Multi line\nTooltip");
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- int expected_width = gfx::GetStringWidth(ASCIIToUTF16("Multi line"),
- font_list);
- expected_width = std::max(expected_width,
- gfx::GetStringWidth(ASCIIToUTF16("Tooltip"),
- font_list));
- EXPECT_EQ(expected_width, width);
- EXPECT_EQ(2, line_count);
- EXPECT_EQ(ASCIIToUTF16("Multi line\nTooltip"), tooltip);
-
- // Whitespaces in tooltips are preserved.
- tooltip.clear();
- width = line_count = -1;
- tooltip = ASCIIToUTF16("Small Tool t\tip");
- TooltipAura::TrimTooltipToFit(font_list, max_width, &tooltip, &width,
- &line_count);
- EXPECT_EQ(gfx::GetStringWidth(ASCIIToUTF16("Small Tool t\tip"), font_list),
- width);
- EXPECT_EQ(1, line_count);
- EXPECT_EQ(ASCIIToUTF16("Small Tool t\tip"), tooltip);
-}
-
-} // namespace corewm
-} // namespace views
diff --git a/ui/views/corewm/tooltip_controller.cc b/ui/views/corewm/tooltip_controller.cc
index 8af7199..bb28c54 100644
--- a/ui/views/corewm/tooltip_controller.cc
+++ b/ui/views/corewm/tooltip_controller.cc
@@ -28,7 +28,7 @@ namespace {
const int kTooltipTimeoutMs = 500;
const int kDefaultTooltipShownTimeoutMs = 10000;
-const size_t kMaxTooltipLength = 1024;
+const size_t kMaxTooltipLength = 2048;
// Returns true if |target| is a valid window to get the tooltip from.
// |event_target| is the original target from the event and |target| the window
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index c1a98ba..8b418b6 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -569,7 +569,6 @@
'window/dialog_delegate_unittest.cc',
],
'views_unittests_aura_sources': [
- 'corewm/tooltip_aura_unittest.cc',
'corewm/tooltip_controller_unittest.cc',
'touchui/touch_selection_controller_impl_unittest.cc',
],