#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_view_state.h"
-#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/insets.h"
void Label::SetTextInternal(const base::string16& text) {
text_ = text;
- if (is_obscured_) {
+ if (obscured_) {
size_t obscured_text_length =
static_cast<size_t>(gfx::UTF16IndexToOffset(text_, 0, text_.length()));
layout_text_.assign(obscured_text_length, kPasswordReplacementChar);
RecalculateColors();
}
+void Label::SetShadows(const gfx::ShadowValues& shadows) {
+ shadows_ = shadows;
+ text_size_valid_ = false;
+}
+
+void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) {
+ subpixel_rendering_enabled_ = subpixel_rendering_enabled;
+}
+
void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
// If the UI layout is right-to-left, flip the alignment direction.
if (base::i18n::IsRTL() &&
return horizontal_alignment_;
const base::i18n::TextDirection dir =
- base::i18n::GetFirstStrongCharacterDirection(layout_text());
+ base::i18n::GetFirstStrongCharacterDirection(layout_text_);
return dir == base::i18n::RIGHT_TO_LEFT ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
}
void Label::SetMultiLine(bool multi_line) {
DCHECK(!multi_line || (elide_behavior_ == gfx::ELIDE_TAIL ||
- elide_behavior_ == gfx::TRUNCATE));
- if (multi_line != is_multi_line_) {
- is_multi_line_ = multi_line;
+ elide_behavior_ == gfx::NO_ELIDE));
+ if (multi_line != multi_line_) {
+ multi_line_ = multi_line;
ResetCachedSize();
PreferredSizeChanged();
SchedulePaint();
}
void Label::SetObscured(bool obscured) {
- if (obscured != is_obscured_) {
- is_obscured_ = obscured;
+ if (obscured != obscured_) {
+ obscured_ = obscured;
SetTextInternal(text_);
}
}
}
void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
- DCHECK(!is_multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL ||
- elide_behavior_ == gfx::TRUNCATE));
+ DCHECK(!multi_line_ || (elide_behavior_ == gfx::ELIDE_TAIL ||
+ elide_behavior_ == gfx::NO_ELIDE));
if (elide_behavior != elide_behavior_) {
elide_behavior_ = elide_behavior;
ResetCachedSize();
}
void Label::SetTooltipText(const base::string16& tooltip_text) {
+ DCHECK(handles_tooltips_);
tooltip_text_ = tooltip_text;
}
+void Label::SetHandlesTooltips(bool enabled) {
+ handles_tooltips_ = enabled;
+}
+
void Label::SizeToFit(int max_width) {
- DCHECK(is_multi_line_);
+ DCHECK(multi_line_);
std::vector<base::string16> lines;
- base::SplitString(layout_text(), '\n', &lines);
+ base::SplitString(layout_text_, '\n', &lines);
int label_width = 0;
for (std::vector<base::string16>::const_iterator iter = lines.begin();
SizeToPreferredSize();
}
+const base::string16& Label::GetLayoutTextForTesting() const {
+ return layout_text_;
+}
+
gfx::Insets Label::GetInsets() const {
gfx::Insets insets = View::GetInsets();
if (focusable()) {
}
int Label::GetHeightForWidth(int w) const {
- if (!is_multi_line_)
+ if (!multi_line_)
return View::GetHeightForWidth(w);
w = std::max(0, w - GetInsets().width());
int h = font_list_.GetHeight();
const int flags = ComputeDrawStringFlags();
gfx::Canvas::SizeStringInt(
- layout_text(), font_list_, &w, &h, line_height_, flags);
+ layout_text_, font_list_, &w, &h, line_height_, flags);
cached_heights_[cached_heights_cursor_] = gfx::Size(cache_width, h);
cached_heights_cursor_ = (cached_heights_cursor_ + 1) % kCachedSizeLimit;
return h + GetInsets().height();
}
View* Label::GetTooltipHandlerForPoint(const gfx::Point& point) {
- // Bail out if the label does not contain the point.
- // Note that HitTestPoint() cannot be used here as it uses
- // Label::HitTestRect() to determine if the point hits the label; and
- // Label::HitTestRect() always fails. Instead, default HitTestRect()
- // implementation should be used.
- if (!View::HitTestRect(gfx::Rect(point, gfx::Size(1, 1))))
+ if (!handles_tooltips_ ||
+ (tooltip_text_.empty() && !ShouldShowDefaultTooltip()))
return NULL;
- if (tooltip_text_.empty() && !ShouldShowDefaultTooltip())
- return NULL;
-
- return this;
+ return HitTestPoint(point) ? this : NULL;
}
bool Label::CanProcessEventsWithinSubtree() const {
return false;
}
+void Label::GetAccessibleState(ui::AXViewState* state) {
+ state->role = ui::AX_ROLE_STATIC_TEXT;
+ state->AddStateFlag(ui::AX_STATE_READ_ONLY);
+ state->name = layout_text_;
+}
+
bool Label::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
- DCHECK(tooltip);
+ if (!handles_tooltips_)
+ return false;
- // If a tooltip has been explicitly set, use it.
if (!tooltip_text_.empty()) {
tooltip->assign(tooltip_text_);
return true;
}
- // Show the full text if the text does not fit.
if (ShouldShowDefaultTooltip()) {
- *tooltip = layout_text();
+ *tooltip = layout_text_;
return true;
}
return false;
}
-void Label::GetAccessibleState(ui::AXViewState* state) {
- state->role = ui::AX_ROLE_STATIC_TEXT;
- state->AddStateFlag(ui::AX_STATE_READ_ONLY);
- state->name = layout_text();
-}
-
void Label::PaintText(gfx::Canvas* canvas,
const base::string16& text,
const gfx::Rect& text_bounds,
// while adding NO_ELLIPSIS to the flags works on Windows for forcing
// SizeStringInt() to calculate the desired width, it doesn't seem to work
// on Linux.
- int w = is_multi_line_ ?
+ int w = multi_line_ ?
GetAvailableRect().width() : std::numeric_limits<int>::max();
int h = font_list_.GetHeight();
// For single-line strings, ignore the available width and calculate how
// wide the text wants to be.
int flags = ComputeDrawStringFlags();
- if (!is_multi_line_)
+ if (!multi_line_)
flags |= gfx::Canvas::NO_ELLIPSIS;
gfx::Canvas::SizeStringInt(
- layout_text(), font_list_, &w, &h, line_height_, flags);
+ layout_text_, font_list_, &w, &h, line_height_, flags);
text_size_.SetSize(w, h);
const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows_);
text_size_.Enlarge(shadow_margin.width(), shadow_margin.height());
}
void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) {
- text_size_valid_ &= !is_multi_line_;
+ text_size_valid_ &= !multi_line_;
}
void Label::OnPaint(gfx::Canvas* canvas) {
UpdateColorsFromTheme(ui::NativeTheme::instance());
horizontal_alignment_ = gfx::ALIGN_CENTER;
line_height_ = 0;
- is_multi_line_ = false;
- is_obscured_ = false;
+ multi_line_ = false;
+ obscured_ = false;
allow_character_break_ = false;
elide_behavior_ = gfx::ELIDE_TAIL;
+ handles_tooltips_ = true;
collapse_when_hidden_ = false;
- directionality_mode_ = gfx::DIRECTIONALITY_FROM_UI;
cached_heights_.resize(kCachedSizeLimit);
ResetCachedSize();
NOTREACHED();
break;
}
+ if (!multi_line_)
+ text_size.set_height(available.height());
+ // Support vertical centering of multi-line labels: http://crbug.com/429595
origin.Offset(0, std::max(0, (available.height() - text_size.height())) / 2);
return gfx::Rect(origin, text_size);
}
if (SkColorGetA(background_color_) != 0xFF || !subpixel_rendering_enabled_)
flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING;
- if (directionality_mode_ == gfx::DIRECTIONALITY_FORCE_LTR) {
- flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
- } else if (directionality_mode_ == gfx::DIRECTIONALITY_FORCE_RTL) {
+ base::i18n::TextDirection direction =
+ base::i18n::GetFirstStrongCharacterDirection(layout_text_);
+ if (direction == base::i18n::RIGHT_TO_LEFT)
flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY;
- } else if (directionality_mode_ == gfx::DIRECTIONALITY_FROM_TEXT) {
- base::i18n::TextDirection direction =
- base::i18n::GetFirstStrongCharacterDirection(layout_text());
- if (direction == base::i18n::RIGHT_TO_LEFT)
- flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY;
- else
- flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
- }
+ else
+ flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
switch (GetHorizontalAlignment()) {
case gfx::ALIGN_LEFT:
break;
}
- if (!is_multi_line_)
+ if (!multi_line_)
return flags;
flags |= gfx::Canvas::MULTI_LINE;
int* flags) const {
DCHECK(paint_text && text_bounds && flags);
- const bool forbid_ellipsis = elide_behavior_ == gfx::TRUNCATE ||
+ const bool forbid_ellipsis = elide_behavior_ == gfx::NO_ELIDE ||
elide_behavior_ == gfx::FADE_TAIL;
- if (is_multi_line_ || forbid_ellipsis) {
- *paint_text = layout_text();
+ if (multi_line_ || forbid_ellipsis) {
+ *paint_text = layout_text_;
} else {
- *paint_text = gfx::ElideText(layout_text(), font_list_,
+ *paint_text = gfx::ElideText(layout_text_, font_list_,
GetAvailableRect().width(), elide_behavior_);
}
*text_bounds = GetTextBounds();
*flags = ComputeDrawStringFlags();
// TODO(msw): Elide multi-line text with ElideRectangleText instead.
- if (!is_multi_line_ || forbid_ellipsis)
+ if (!multi_line_ || forbid_ellipsis)
*flags |= gfx::Canvas::NO_ELLIPSIS;
}
}
bool Label::ShouldShowDefaultTooltip() const {
- return !is_multi_line_ && !is_obscured_ &&
- gfx::GetStringWidth(layout_text(), font_list_) >
- GetAvailableRect().width();
+ const gfx::Size text_size = GetTextSize();
+ const gfx::Size size = GetContentsBounds().size();
+ return !obscured() && (text_size.width() > size.width() ||
+ (multi_line_ && text_size.height() > size.height()));
}
} // namespace views