diff options
Diffstat (limited to 'ash/tooltips')
-rw-r--r-- | ash/tooltips/tooltip_controller.cc | 137 | ||||
-rw-r--r-- | ash/tooltips/tooltip_controller.h | 10 | ||||
-rw-r--r-- | ash/tooltips/tooltip_controller_unittest.cc | 107 |
3 files changed, 45 insertions, 209 deletions
diff --git a/ash/tooltips/tooltip_controller.cc b/ash/tooltips/tooltip_controller.cc index d3efc1f..52049e7 100644 --- a/ash/tooltips/tooltip_controller.cc +++ b/ash/tooltips/tooltip_controller.cc @@ -33,14 +33,6 @@ const SkColor kTooltipBackground = 0xFFFFFFCC; const SkColor kTooltipBorder = 0xFF646450; const int kTooltipBorderWidth = 1; const int kTooltipHorizontalPadding = 3; - -// Max visual tooltip width. If a tooltip is greater than this width, it will -// be wrapped. -const int kTooltipMaxWidthPixels = 400; - -// Maximum number of lines we allow in the tooltip. -const size_t kMaxLines = 10; - // TODO(derat): This padding is needed on Chrome OS devices but seems excessive // when running the same binary on a Linux workstation; presumably there's a // difference in font metrics. Rationalize this. @@ -54,6 +46,9 @@ const int kCursorOffsetY = 15; // Maximum number of characters we allow in a tooltip. const size_t kMaxTooltipLength = 1024; +// Maximum number of lines we allow in the tooltip. +const size_t kMaxLines = 6; + gfx::Font GetDefaultFont() { // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure // out a way to merge. @@ -69,6 +64,48 @@ int GetMaxWidth(int x, int y) { return (monitor_bounds.width() + 1) / 2; } +// Trims the tooltip to fit, setting |text| to the clipped result, +// |max_width| to the width (in pixels) of the clipped text and |line_count| +// to the number of lines of text in the tooltip. |x| and |y| give the +// location of the tooltip in screen coordinates. +void TrimTooltipToFit(string16* text, + int* max_width, + int* line_count, + int x, + int y) { + *max_width = 0; + *line_count = 0; + + // Clamp the tooltip length to kMaxTooltipLength so that we don't + // accidentally DOS the user with a mega tooltip. + if (text->length() > kMaxTooltipLength) + *text = text->substr(0, kMaxTooltipLength); + + // Determine the available width for the tooltip. + int available_width = GetMaxWidth(x, y); + + // Split the string into at most kMaxLines lines. + std::vector<string16> lines; + base::SplitString(*text, '\n', &lines); + if (lines.size() > kMaxLines) + lines.resize(kMaxLines); + *line_count = static_cast<int>(lines.size()); + + // Format each line to fit. + gfx::Font font = GetDefaultFont(); + string16 result; + for (std::vector<string16>::iterator i = lines.begin(); i != lines.end(); + ++i) { + string16 elided_text = + ui::ElideText(*i, font, available_width, ui::ELIDE_AT_END); + *max_width = std::max(*max_width, font.GetStringWidth(elided_text)); + if (!result.empty()) + result.push_back('\n'); + result.append(elided_text); + } + *text = result; +} + // Creates a widget of type TYPE_TOOLTIP views::Widget* CreateTooltip() { views::Widget* widget = new views::Widget; @@ -283,90 +320,6 @@ void TooltipController::OnWindowDestroyed(aura::Window* window) { } } -//////////////////////////////////////////////////////////////////////////////// -// TooltipController private: - -// static -void TooltipController::TrimTooltipToFit(string16* text, - int* max_width, - int* line_count, - int x, - int y) { - *max_width = 0; - *line_count = 0; - - // Clamp the tooltip length to kMaxTooltipLength so that we don't - // accidentally DOS the user with a mega tooltip. - if (text->length() > kMaxTooltipLength) - *text = text->substr(0, kMaxTooltipLength); - - // Determine the available width for the tooltip. - int available_width = std::min(kTooltipMaxWidthPixels, GetMaxWidth(x, y)); - - std::vector<string16> lines; - base::SplitString(*text, '\n', &lines); - std::vector<string16> result_lines; - - // Format each line to fit. - gfx::Font font = GetDefaultFont(); - for (std::vector<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<string16> words; - base::SplitStringDontTrim(*l, ' ', &words); - int current_width = 0; - string16 line; - for (std::vector<string16>::iterator w = words.begin(); w != words.end(); - ++w) { - string16 word = *w; - if (w + 1 != words.end()) - word.push_back(' '); - int word_width = font.GetStringWidth(word); - 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] = ui::TruncateString( - result_lines.back(), result_lines.back().length() - 1); - } - *line_count = result_lines.size(); - - // Flatten the result. - string16 result; - for (std::vector<string16>::iterator l = result_lines.begin(); - l != result_lines.end(); ++l) { - if (!result.empty()) - result.push_back('\n'); - int line_width = font.GetStringWidth(*l); - // 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) { - *max_width = available_width; - result.append(ui::ElideText(*l, font, available_width, ui::ELIDE_AT_END)); - } else { - *max_width = std::max(*max_width, line_width); - result.append(*l); - } - } - *text = result; -} - void TooltipController::TooltipTimerFired() { UpdateIfRequired(); } diff --git a/ash/tooltips/tooltip_controller.h b/ash/tooltips/tooltip_controller.h index 5e9d103..e2b8ed6 100644 --- a/ash/tooltips/tooltip_controller.h +++ b/ash/tooltips/tooltip_controller.h @@ -60,16 +60,6 @@ class ASH_EXPORT TooltipController : public aura::client::TooltipClient, class Tooltip; - // Trims the tooltip to fit, setting |text| to the clipped result, - // |max_width| to the width (in pixels) of the clipped text and |line_count| - // to the number of lines of text in the tooltip. |x| and |y| give the - // location of the tooltip in screen coordinates. - static void TrimTooltipToFit(string16* text, - int* max_width, - int* line_count, - int x, - int y); - void TooltipTimerFired(); // Updates the tooltip if required (if there is any change in the tooltip diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc index d78b02c..f07dfd5 100644 --- a/ash/tooltips/tooltip_controller_unittest.cc +++ b/ash/tooltips/tooltip_controller_unittest.cc @@ -10,9 +10,6 @@ #include "ui/aura/root_window.h" #include "ui/aura/test/event_generator.h" #include "ui/aura/window.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/text/text_elider.h" -#include "ui/gfx/font.h" #include "ui/gfx/point.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -74,11 +71,6 @@ ash::internal::TooltipController* GetController() { aura::client::GetTooltipClient(Shell::GetRootWindow())); } -gfx::Font GetDefaultFont() { - return ui::ResourceBundle::GetSharedInstance().GetFont( - ui::ResourceBundle::BaseFont); -} - } // namespace class TooltipControllerTest : public AshTestBase { @@ -102,15 +94,6 @@ class TooltipControllerTest : public AshTestBase { return GetController()->IsTooltipVisible(); } - void TrimTooltipToFit(string16* text, - int* max_width, - int* line_count, - int x, - int y) { - ash::internal::TooltipController::TrimTooltipToFit(text, max_width, - line_count, x, y); - } - private: DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest); }; @@ -225,95 +208,5 @@ TEST_F(TooltipControllerTest, EnableOrDisableTooltips) { EXPECT_TRUE(IsTooltipVisible()); } -TEST_F(TooltipControllerTest, TrimTooltipToFitTests) { - string16 tooltip; - int max_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 - gfx::Font font = GetDefaultFont(); - 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 = font.GetStringWidth(ASCIIToUTF16("tooltip")); - - // Long tooltips should wrap to next line - tooltip.clear(); - max_width = line_count = -1; - expect_lines = 3; - for (; font.GetStringWidth(tooltip) <= (expect_lines - 1) * max_pixel_width;) - tooltip.append(ASCIIToUTF16("This is part of the tooltip")); - tooltip_len = tooltip.length(); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_NEAR(max_pixel_width, max_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(); - max_width = line_count = -1; - expect_lines = 13; - for (; font.GetStringWidth(tooltip) <= (expect_lines - 1) * max_pixel_width;) - tooltip.append(ASCIIToUTF16("This is part of the tooltip")); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_NEAR(max_pixel_width, max_width, error_in_pixel_width); - EXPECT_EQ(max_lines, line_count); - - // Long multi line tooltips should wrap individual lines. - tooltip.clear(); - max_width = line_count = -1; - expect_lines = 4; - for (; font.GetStringWidth(tooltip) <= (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(); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_NEAR(max_pixel_width, max_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); - - // Tooltip with really long word gets elided. - tooltip.clear(); - max_width = line_count = -1; - tooltip = UTF8ToUTF16(std::string('a', max_pixel_width)); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_NEAR(max_pixel_width, max_width, 5); - EXPECT_EQ(1, line_count); - EXPECT_EQ(ui::ElideText(tooltip, font, max_pixel_width, ui::ELIDE_AT_END), - tooltip); - - // Normal small tooltip should stay as is. - tooltip.clear(); - max_width = line_count = -1; - tooltip = ASCIIToUTF16("Small Tooltip"); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_EQ(font.GetStringWidth(ASCIIToUTF16("Small Tooltip")), max_width); - EXPECT_EQ(1, line_count); - EXPECT_EQ(ASCIIToUTF16("Small Tooltip"), tooltip); - - // Normal small multi-line tooltip should stay as is. - tooltip.clear(); - max_width = line_count = -1; - tooltip = ASCIIToUTF16("Multi line\nTooltip"); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - int expected_width = font.GetStringWidth(ASCIIToUTF16("Multi line")); - expected_width = std::max(expected_width, - font.GetStringWidth(ASCIIToUTF16("Tooltip"))); - EXPECT_EQ(expected_width, max_width); - EXPECT_EQ(2, line_count); - EXPECT_EQ(ASCIIToUTF16("Multi line\nTooltip"), tooltip); - - // Whitespaces in tooltips are preserved. - tooltip.clear(); - max_width = line_count = -1; - tooltip = ASCIIToUTF16("Small Tool t\tip"); - TrimTooltipToFit(&tooltip, &max_width, &line_count, 0, 0); - EXPECT_EQ(font.GetStringWidth(ASCIIToUTF16("Small Tool t\tip")), max_width); - EXPECT_EQ(1, line_count); - EXPECT_EQ(ASCIIToUTF16("Small Tool t\tip"), tooltip); -} - } // namespace test } // namespace ash |