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

Unified Diff: ui/views/controls/button/label_button.cc

Issue 329813003: Reland: Use labels to display views tab titles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Call AddChildView(title_) on Tab to prevent leaks. Created 6 years, 6 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/message_center/views/bounded_label.cc ('k') | ui/views/controls/label.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/button/label_button.cc
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index b1fde43644cf76117866a12588de7d19fb4ecca4..af53fadcc645ccb16fbe57cc86b202aa3da5d48f 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -1,438 +1,438 @@
-// Copyright (c) 2012 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/button/label_button.h"
-
-#include "base/logging.h"
-#include "grit/ui_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/animation/throb_animation.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/font_list.h"
-#include "ui/gfx/sys_color_change_listener.h"
-#include "ui/native_theme/native_theme.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/button/label_button_border.h"
-#include "ui/views/painter.h"
-#include "ui/views/window/dialog_delegate.h"
-
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-#include "ui/views/linux_ui/linux_ui.h"
-#endif
-
-namespace {
-
-// The spacing between the icon and text.
-const int kSpacing = 5;
-
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
-// Default text and shadow colors for STYLE_BUTTON.
-const SkColor kStyleButtonTextColor = SK_ColorBLACK;
-const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
-#endif
-
-} // namespace
-
-namespace views {
-
-// static
-const int LabelButton::kHoverAnimationDurationMs = 170;
-
-// static
-const char LabelButton::kViewClassName[] = "LabelButton";
-
-LabelButton::LabelButton(ButtonListener* listener, const base::string16& text)
- : CustomButton(listener),
- image_(new ImageView()),
- label_(new Label()),
- button_state_images_(),
- button_state_colors_(),
- explicitly_set_colors_(),
- is_default_(false),
- style_(STYLE_TEXTBUTTON),
- border_is_themed_border_(true) {
- SetAnimationDuration(kHoverAnimationDurationMs);
- SetText(text);
- SetFontList(gfx::FontList());
-
- AddChildView(image_);
- image_->set_interactive(false);
-
- AddChildView(label_);
- label_->SetAutoColorReadabilityEnabled(false);
- label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
- // Initialize the colors, border, and layout.
- SetStyle(style_);
-
- SetAccessibleName(text);
-}
-
-LabelButton::~LabelButton() {}
-
-const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) {
- if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull())
- return button_state_images_[STATE_NORMAL];
- return button_state_images_[for_state];
-}
-
-void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) {
- button_state_images_[for_state] = image;
- UpdateImage();
-}
-
-const base::string16& LabelButton::GetText() const {
- return label_->text();
-}
-
-void LabelButton::SetText(const base::string16& text) {
- SetAccessibleName(text);
- label_->SetText(text);
-}
-
-void LabelButton::SetTextColor(ButtonState for_state, SkColor color) {
- button_state_colors_[for_state] = color;
- if (for_state == STATE_DISABLED)
- label_->SetDisabledColor(color);
- else if (for_state == state())
- label_->SetEnabledColor(color);
- explicitly_set_colors_[for_state] = true;
-}
-
-bool LabelButton::GetTextMultiLine() const {
- return label_->is_multi_line();
-}
-
-void LabelButton::SetTextMultiLine(bool text_multi_line) {
- label_->SetMultiLine(text_multi_line);
-}
-
-const gfx::FontList& LabelButton::GetFontList() const {
- return label_->font_list();
-}
-
-void LabelButton::SetFontList(const gfx::FontList& font_list) {
- cached_normal_font_list_ = font_list;
- cached_bold_font_list_ = font_list.DeriveWithStyle(
- font_list.GetFontStyle() | gfx::Font::BOLD);
-
- // STYLE_BUTTON uses bold text to indicate default buttons.
- label_->SetFontList(
- style_ == STYLE_BUTTON && is_default_ ?
- cached_bold_font_list_ : cached_normal_font_list_);
-}
-
-void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
- label_->SetElideBehavior(elide_behavior);
-}
-
-gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const {
- return label_->horizontal_alignment();
-}
-
-void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
- label_->SetHorizontalAlignment(alignment);
- InvalidateLayout();
-}
-
-void LabelButton::SetIsDefault(bool is_default) {
- if (is_default == is_default_)
- return;
- is_default_ = is_default;
- ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE);
- is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel);
-
- // STYLE_BUTTON uses bold text to indicate default buttons.
- if (style_ == STYLE_BUTTON) {
- label_->SetFontList(
- is_default ? cached_bold_font_list_ : cached_normal_font_list_);
- }
-}
-
-void LabelButton::SetStyle(ButtonStyle style) {
- style_ = style;
- // Inset the button focus rect from the actual border; roughly match Windows.
- if (style == STYLE_BUTTON) {
- SetFocusPainter(scoped_ptr<Painter>());
- } else {
- SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets(
- gfx::Insets(3, 3, 3, 3)));
- }
- if (style == STYLE_BUTTON) {
- label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- SetFocusable(true);
- }
- if (style == STYLE_BUTTON)
- set_min_size(gfx::Size(70, 33));
-
- OnNativeThemeChanged(GetNativeTheme());
-}
-
-void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
- focus_painter_ = focus_painter.Pass();
-}
-
-gfx::Size LabelButton::GetPreferredSize() const {
- // Use a temporary label copy for sizing to avoid calculation side-effects.
- Label label(GetText(), cached_normal_font_list_);
- label.SetMultiLine(GetTextMultiLine());
-
- if (style() == STYLE_BUTTON) {
- // Some text appears wider when rendered normally than when rendered bold.
- // Accommodate the widest, as buttons may show bold and shouldn't resize.
- const int current_width = label.GetPreferredSize().width();
- label.SetFontList(cached_bold_font_list_);
- if (label.GetPreferredSize().width() < current_width)
- label.SetFontList(cached_normal_font_list_);
- }
-
- // Resize multi-line labels given the current limited available width.
- const gfx::Size image_size(image_->GetPreferredSize());
- const int image_width = image_size.width();
- if (GetTextMultiLine() && (width() > image_width + kSpacing))
- label.SizeToFit(width() - image_width - (image_width > 0 ? kSpacing : 0));
-
- // Calculate the required size.
- gfx::Size size(label.GetPreferredSize());
- if (image_width > 0 && size.width() > 0)
- size.Enlarge(kSpacing, 0);
- size.SetToMax(gfx::Size(0, image_size.height()));
- const gfx::Insets insets(GetInsets());
- size.Enlarge(image_size.width() + insets.width(), insets.height());
-
- // Make the size at least as large as the minimum size needed by the border.
- size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size());
-
- // Increase the minimum size monotonically with the preferred size.
- size.SetToMax(min_size_);
- min_size_ = size;
-
- // Return the largest known size clamped to the maximum size (if valid).
- if (max_size_.width() > 0)
- size.set_width(std::min(max_size_.width(), size.width()));
- if (max_size_.height() > 0)
- size.set_height(std::min(max_size_.height(), size.height()));
- return size;
-}
-
-void LabelButton::Layout() {
- gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment();
- if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER)
- adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ?
- gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
-
- gfx::Rect child_area(GetLocalBounds());
- child_area.Inset(GetInsets());
-
- gfx::Size image_size(image_->GetPreferredSize());
- image_size.SetToMin(child_area.size());
-
- // The label takes any remaining width after sizing the image, unless both
- // views are centered. In that case, using the tighter preferred label width
- // avoids wasted space within the label that would look like awkward padding.
- gfx::Size label_size(child_area.size());
- if (!image_size.IsEmpty() && !label_size.IsEmpty()) {
- label_size.set_width(
- std::max(child_area.width() - image_size.width() - kSpacing, 0));
- if (adjusted_alignment == gfx::ALIGN_CENTER) {
- // Ensure multi-line labels paired with images use their available width.
- if (GetTextMultiLine())
- label_->SizeToFit(label_size.width());
- label_size.set_width(
- std::min(label_size.width(), label_->GetPreferredSize().width()));
- }
- }
-
- gfx::Point image_origin(child_area.origin());
- image_origin.Offset(0, (child_area.height() - image_size.height()) / 2);
- if (adjusted_alignment == gfx::ALIGN_CENTER) {
- const int total_width = image_size.width() + label_size.width() +
- ((image_size.width() > 0 && label_size.width() > 0) ? kSpacing : 0);
- image_origin.Offset((child_area.width() - total_width) / 2, 0);
- } else if (adjusted_alignment == gfx::ALIGN_RIGHT) {
- image_origin.Offset(child_area.width() - image_size.width(), 0);
- }
-
- gfx::Point label_origin(child_area.origin());
- if (!image_size.IsEmpty() &&adjusted_alignment != gfx::ALIGN_RIGHT)
- label_origin.set_x(image_origin.x() + image_size.width() + kSpacing);
-
- image_->SetBoundsRect(gfx::Rect(image_origin, image_size));
- label_->SetBoundsRect(gfx::Rect(label_origin, label_size));
-}
-
-const char* LabelButton::GetClassName() const {
- return kViewClassName;
-}
-
-scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const {
- return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_));
-}
-
-void LabelButton::SetBorder(scoped_ptr<Border> border) {
- border_is_themed_border_ = false;
- View::SetBorder(border.Pass());
-}
-
-void LabelButton::OnPaint(gfx::Canvas* canvas) {
- View::OnPaint(canvas);
- Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
-}
-
-void LabelButton::OnFocus() {
- View::OnFocus();
- // Typically the border renders differently when focused.
- SchedulePaint();
-}
-
-void LabelButton::OnBlur() {
- View::OnBlur();
- // Typically the border renders differently when focused.
- SchedulePaint();
-}
-
-void LabelButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const {
- params->button.checked = false;
- params->button.indeterminate = false;
- params->button.is_default = is_default_;
- params->button.is_focused = HasFocus() && IsAccessibilityFocusable();
- params->button.has_border = false;
- params->button.classic_state = 0;
- params->button.background_color = label_->background_color();
-}
-
-void LabelButton::ResetColorsFromNativeTheme() {
- const ui::NativeTheme* theme = GetNativeTheme();
- SkColor colors[STATE_COUNT] = {
- theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonEnabledColor),
- theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor),
- theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor),
- theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor),
- };
-
- // Certain styles do not change text color when hovered or pressed.
- bool constant_text_color = false;
- // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON.
- if (gfx::IsInvertedColorScheme()) {
- constant_text_color = true;
- colors[STATE_NORMAL] = SK_ColorWHITE;
- label_->SetBackgroundColor(SK_ColorBLACK);
- label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK));
- label_->SetAutoColorReadabilityEnabled(true);
- label_->ClearEmbellishing();
- } else if (style() == STYLE_BUTTON) {
- // TODO(erg): This is disabled on desktop linux because of the binary asset
- // confusion. These details should either be pushed into ui::NativeThemeWin
- // or should be obsoleted by rendering buttons with paint calls instead of
- // with static assets. http://crbug.com/350498
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
- constant_text_color = true;
- colors[STATE_NORMAL] = kStyleButtonTextColor;
- label_->SetBackgroundColor(theme->GetSystemColor(
- ui::NativeTheme::kColorId_ButtonBackgroundColor));
- label_->SetAutoColorReadabilityEnabled(false);
- label_->SetShadowColors(kStyleButtonShadowColor, kStyleButtonShadowColor);
- label_->SetShadowOffset(0, 1);
-#endif
- label_->set_background(NULL);
- } else {
- label_->set_background(NULL);
- }
-
- if (constant_text_color)
- colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL];
-
- for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) {
- if (!explicitly_set_colors_[state]) {
- SetTextColor(static_cast<ButtonState>(state), colors[state]);
- explicitly_set_colors_[state] = false;
- }
- }
-}
-
-void LabelButton::UpdateImage() {
- image_->SetImage(GetImage(state()));
-}
-
-void LabelButton::UpdateThemedBorder() {
- // Don't override borders set by others.
- if (!border_is_themed_border_)
- return;
-
- scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder();
-
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
- views::LinuxUI* linux_ui = views::LinuxUI::instance();
- if (linux_ui) {
- SetBorder(linux_ui->CreateNativeBorder(
- this, label_button_border.PassAs<Border>()));
- } else
-#endif
- {
- SetBorder(label_button_border.PassAs<Border>());
- }
-
- border_is_themed_border_ = true;
-}
-
-void LabelButton::StateChanged() {
- const gfx::Size previous_image_size(image_->GetPreferredSize());
- UpdateImage();
- const SkColor color = button_state_colors_[state()];
- if (state() != STATE_DISABLED && label_->enabled_color() != color)
- label_->SetEnabledColor(color);
- label_->SetEnabled(state() != STATE_DISABLED);
- if (image_->GetPreferredSize() != previous_image_size)
- Layout();
-}
-
-void LabelButton::ChildPreferredSizeChanged(View* child) {
- PreferredSizeChanged();
-}
-
-void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
- ResetColorsFromNativeTheme();
- UpdateThemedBorder();
- // Invalidate the layout to pickup the new insets from the border.
- InvalidateLayout();
-}
-
-ui::NativeTheme::Part LabelButton::GetThemePart() const {
- return ui::NativeTheme::kPushButton;
-}
-
-gfx::Rect LabelButton::GetThemePaintRect() const {
- return GetLocalBounds();
-}
-
-ui::NativeTheme::State LabelButton::GetThemeState(
- ui::NativeTheme::ExtraParams* params) const {
- GetExtraParams(params);
- switch (state()) {
- case STATE_NORMAL: return ui::NativeTheme::kNormal;
- case STATE_HOVERED: return ui::NativeTheme::kHovered;
- case STATE_PRESSED: return ui::NativeTheme::kPressed;
- case STATE_DISABLED: return ui::NativeTheme::kDisabled;
- case STATE_COUNT: NOTREACHED() << "Unknown state: " << state();
- }
- return ui::NativeTheme::kNormal;
-}
-
-const gfx::Animation* LabelButton::GetThemeAnimation() const {
- return hover_animation_.get();
-}
-
-ui::NativeTheme::State LabelButton::GetBackgroundThemeState(
- ui::NativeTheme::ExtraParams* params) const {
- GetExtraParams(params);
- return ui::NativeTheme::kNormal;
-}
-
-ui::NativeTheme::State LabelButton::GetForegroundThemeState(
- ui::NativeTheme::ExtraParams* params) const {
- GetExtraParams(params);
- return ui::NativeTheme::kHovered;
-}
-
-} // namespace views
+// Copyright (c) 2012 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/button/label_button.h"
+
+#include "base/logging.h"
+#include "grit/ui_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/animation/throb_animation.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/font_list.h"
+#include "ui/gfx/sys_color_change_listener.h"
+#include "ui/native_theme/native_theme.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/button/label_button_border.h"
+#include "ui/views/painter.h"
+#include "ui/views/window/dialog_delegate.h"
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#include "ui/views/linux_ui/linux_ui.h"
+#endif
+
+namespace {
+
+// The spacing between the icon and text.
+const int kSpacing = 5;
+
+#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
+// Default text and shadow colors for STYLE_BUTTON.
+const SkColor kStyleButtonTextColor = SK_ColorBLACK;
+const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
+#endif
+
+} // namespace
+
+namespace views {
+
+// static
+const int LabelButton::kHoverAnimationDurationMs = 170;
+
+// static
+const char LabelButton::kViewClassName[] = "LabelButton";
+
+LabelButton::LabelButton(ButtonListener* listener, const base::string16& text)
+ : CustomButton(listener),
+ image_(new ImageView()),
+ label_(new Label()),
+ button_state_images_(),
+ button_state_colors_(),
+ explicitly_set_colors_(),
+ is_default_(false),
+ style_(STYLE_TEXTBUTTON),
+ border_is_themed_border_(true) {
+ SetAnimationDuration(kHoverAnimationDurationMs);
+ SetText(text);
+ SetFontList(gfx::FontList());
+
+ AddChildView(image_);
+ image_->set_interactive(false);
+
+ AddChildView(label_);
+ label_->SetAutoColorReadabilityEnabled(false);
+ label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+ // Initialize the colors, border, and layout.
+ SetStyle(style_);
+
+ SetAccessibleName(text);
+}
+
+LabelButton::~LabelButton() {}
+
+const gfx::ImageSkia& LabelButton::GetImage(ButtonState for_state) {
+ if (for_state != STATE_NORMAL && button_state_images_[for_state].isNull())
+ return button_state_images_[STATE_NORMAL];
+ return button_state_images_[for_state];
+}
+
+void LabelButton::SetImage(ButtonState for_state, const gfx::ImageSkia& image) {
+ button_state_images_[for_state] = image;
+ UpdateImage();
+}
+
+const base::string16& LabelButton::GetText() const {
+ return label_->text();
+}
+
+void LabelButton::SetText(const base::string16& text) {
+ SetAccessibleName(text);
+ label_->SetText(text);
+}
+
+void LabelButton::SetTextColor(ButtonState for_state, SkColor color) {
+ button_state_colors_[for_state] = color;
+ if (for_state == STATE_DISABLED)
+ label_->SetDisabledColor(color);
+ else if (for_state == state())
+ label_->SetEnabledColor(color);
+ explicitly_set_colors_[for_state] = true;
+}
+
+bool LabelButton::GetTextMultiLine() const {
+ return label_->is_multi_line();
+}
+
+void LabelButton::SetTextMultiLine(bool text_multi_line) {
+ label_->SetMultiLine(text_multi_line);
+}
+
+const gfx::FontList& LabelButton::GetFontList() const {
+ return label_->font_list();
+}
+
+void LabelButton::SetFontList(const gfx::FontList& font_list) {
+ cached_normal_font_list_ = font_list;
+ cached_bold_font_list_ = font_list.DeriveWithStyle(
+ font_list.GetFontStyle() | gfx::Font::BOLD);
+
+ // STYLE_BUTTON uses bold text to indicate default buttons.
+ label_->SetFontList(
+ style_ == STYLE_BUTTON && is_default_ ?
+ cached_bold_font_list_ : cached_normal_font_list_);
+}
+
+void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
+ label_->SetElideBehavior(elide_behavior);
+}
+
+gfx::HorizontalAlignment LabelButton::GetHorizontalAlignment() const {
+ return label_->GetHorizontalAlignment();
+}
+
+void LabelButton::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
+ label_->SetHorizontalAlignment(alignment);
+ InvalidateLayout();
+}
+
+void LabelButton::SetIsDefault(bool is_default) {
+ if (is_default == is_default_)
+ return;
+ is_default_ = is_default;
+ ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE);
+ is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel);
+
+ // STYLE_BUTTON uses bold text to indicate default buttons.
+ if (style_ == STYLE_BUTTON) {
+ label_->SetFontList(
+ is_default ? cached_bold_font_list_ : cached_normal_font_list_);
+ }
+}
+
+void LabelButton::SetStyle(ButtonStyle style) {
+ style_ = style;
+ // Inset the button focus rect from the actual border; roughly match Windows.
+ if (style == STYLE_BUTTON) {
+ SetFocusPainter(scoped_ptr<Painter>());
+ } else {
+ SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets(
+ gfx::Insets(3, 3, 3, 3)));
+ }
+ if (style == STYLE_BUTTON) {
+ label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
+ SetFocusable(true);
+ }
+ if (style == STYLE_BUTTON)
+ set_min_size(gfx::Size(70, 33));
+
+ OnNativeThemeChanged(GetNativeTheme());
+}
+
+void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
+ focus_painter_ = focus_painter.Pass();
+}
+
+gfx::Size LabelButton::GetPreferredSize() const {
+ // Use a temporary label copy for sizing to avoid calculation side-effects.
+ Label label(GetText(), cached_normal_font_list_);
+ label.SetMultiLine(GetTextMultiLine());
+
+ if (style() == STYLE_BUTTON) {
+ // Some text appears wider when rendered normally than when rendered bold.
+ // Accommodate the widest, as buttons may show bold and shouldn't resize.
+ const int current_width = label.GetPreferredSize().width();
+ label.SetFontList(cached_bold_font_list_);
+ if (label.GetPreferredSize().width() < current_width)
+ label.SetFontList(cached_normal_font_list_);
+ }
+
+ // Resize multi-line labels given the current limited available width.
+ const gfx::Size image_size(image_->GetPreferredSize());
+ const int image_width = image_size.width();
+ if (GetTextMultiLine() && (width() > image_width + kSpacing))
+ label.SizeToFit(width() - image_width - (image_width > 0 ? kSpacing : 0));
+
+ // Calculate the required size.
+ gfx::Size size(label.GetPreferredSize());
+ if (image_width > 0 && size.width() > 0)
+ size.Enlarge(kSpacing, 0);
+ size.SetToMax(gfx::Size(0, image_size.height()));
+ const gfx::Insets insets(GetInsets());
+ size.Enlarge(image_size.width() + insets.width(), insets.height());
+
+ // Make the size at least as large as the minimum size needed by the border.
+ size.SetToMax(border() ? border()->GetMinimumSize() : gfx::Size());
+
+ // Increase the minimum size monotonically with the preferred size.
+ size.SetToMax(min_size_);
+ min_size_ = size;
+
+ // Return the largest known size clamped to the maximum size (if valid).
+ if (max_size_.width() > 0)
+ size.set_width(std::min(max_size_.width(), size.width()));
+ if (max_size_.height() > 0)
+ size.set_height(std::min(max_size_.height(), size.height()));
+ return size;
+}
+
+void LabelButton::Layout() {
+ gfx::HorizontalAlignment adjusted_alignment = GetHorizontalAlignment();
+ if (base::i18n::IsRTL() && adjusted_alignment != gfx::ALIGN_CENTER)
+ adjusted_alignment = (adjusted_alignment == gfx::ALIGN_LEFT) ?
+ gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
+
+ gfx::Rect child_area(GetLocalBounds());
+ child_area.Inset(GetInsets());
+
+ gfx::Size image_size(image_->GetPreferredSize());
+ image_size.SetToMin(child_area.size());
+
+ // The label takes any remaining width after sizing the image, unless both
+ // views are centered. In that case, using the tighter preferred label width
+ // avoids wasted space within the label that would look like awkward padding.
+ gfx::Size label_size(child_area.size());
+ if (!image_size.IsEmpty() && !label_size.IsEmpty()) {
+ label_size.set_width(
+ std::max(child_area.width() - image_size.width() - kSpacing, 0));
+ if (adjusted_alignment == gfx::ALIGN_CENTER) {
+ // Ensure multi-line labels paired with images use their available width.
+ if (GetTextMultiLine())
+ label_->SizeToFit(label_size.width());
+ label_size.set_width(
+ std::min(label_size.width(), label_->GetPreferredSize().width()));
+ }
+ }
+
+ gfx::Point image_origin(child_area.origin());
+ image_origin.Offset(0, (child_area.height() - image_size.height()) / 2);
+ if (adjusted_alignment == gfx::ALIGN_CENTER) {
+ const int total_width = image_size.width() + label_size.width() +
+ ((image_size.width() > 0 && label_size.width() > 0) ? kSpacing : 0);
+ image_origin.Offset((child_area.width() - total_width) / 2, 0);
+ } else if (adjusted_alignment == gfx::ALIGN_RIGHT) {
+ image_origin.Offset(child_area.width() - image_size.width(), 0);
+ }
+
+ gfx::Point label_origin(child_area.origin());
+ if (!image_size.IsEmpty() &&adjusted_alignment != gfx::ALIGN_RIGHT)
+ label_origin.set_x(image_origin.x() + image_size.width() + kSpacing);
+
+ image_->SetBoundsRect(gfx::Rect(image_origin, image_size));
+ label_->SetBoundsRect(gfx::Rect(label_origin, label_size));
+}
+
+const char* LabelButton::GetClassName() const {
+ return kViewClassName;
+}
+
+scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const {
+ return scoped_ptr<LabelButtonBorder>(new LabelButtonBorder(style_));
+}
+
+void LabelButton::SetBorder(scoped_ptr<Border> border) {
+ border_is_themed_border_ = false;
+ View::SetBorder(border.Pass());
+}
+
+void LabelButton::OnPaint(gfx::Canvas* canvas) {
+ View::OnPaint(canvas);
+ Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
+}
+
+void LabelButton::OnFocus() {
+ View::OnFocus();
+ // Typically the border renders differently when focused.
+ SchedulePaint();
+}
+
+void LabelButton::OnBlur() {
+ View::OnBlur();
+ // Typically the border renders differently when focused.
+ SchedulePaint();
+}
+
+void LabelButton::GetExtraParams(ui::NativeTheme::ExtraParams* params) const {
+ params->button.checked = false;
+ params->button.indeterminate = false;
+ params->button.is_default = is_default_;
+ params->button.is_focused = HasFocus() && IsAccessibilityFocusable();
+ params->button.has_border = false;
+ params->button.classic_state = 0;
+ params->button.background_color = label_->background_color();
+}
+
+void LabelButton::ResetColorsFromNativeTheme() {
+ const ui::NativeTheme* theme = GetNativeTheme();
+ SkColor colors[STATE_COUNT] = {
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonEnabledColor),
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor),
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHoverColor),
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor),
+ };
+
+ // Certain styles do not change text color when hovered or pressed.
+ bool constant_text_color = false;
+ // Use hardcoded colors for inverted color scheme support and STYLE_BUTTON.
+ if (gfx::IsInvertedColorScheme()) {
+ constant_text_color = true;
+ colors[STATE_NORMAL] = SK_ColorWHITE;
+ label_->SetBackgroundColor(SK_ColorBLACK);
+ label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK));
+ label_->SetAutoColorReadabilityEnabled(true);
+ label_->ClearEmbellishing();
+ } else if (style() == STYLE_BUTTON) {
+ // TODO(erg): This is disabled on desktop linux because of the binary asset
+ // confusion. These details should either be pushed into ui::NativeThemeWin
+ // or should be obsoleted by rendering buttons with paint calls instead of
+ // with static assets. http://crbug.com/350498
+#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
+ constant_text_color = true;
+ colors[STATE_NORMAL] = kStyleButtonTextColor;
+ label_->SetBackgroundColor(theme->GetSystemColor(
+ ui::NativeTheme::kColorId_ButtonBackgroundColor));
+ label_->SetAutoColorReadabilityEnabled(false);
+ label_->SetShadowColors(kStyleButtonShadowColor, kStyleButtonShadowColor);
+ label_->SetShadowOffset(0, 1);
+#endif
+ label_->set_background(NULL);
+ } else {
+ label_->set_background(NULL);
+ }
+
+ if (constant_text_color)
+ colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL];
+
+ for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) {
+ if (!explicitly_set_colors_[state]) {
+ SetTextColor(static_cast<ButtonState>(state), colors[state]);
+ explicitly_set_colors_[state] = false;
+ }
+ }
+}
+
+void LabelButton::UpdateImage() {
+ image_->SetImage(GetImage(state()));
+}
+
+void LabelButton::UpdateThemedBorder() {
+ // Don't override borders set by others.
+ if (!border_is_themed_border_)
+ return;
+
+ scoped_ptr<LabelButtonBorder> label_button_border = CreateDefaultBorder();
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ views::LinuxUI* linux_ui = views::LinuxUI::instance();
+ if (linux_ui) {
+ SetBorder(linux_ui->CreateNativeBorder(
+ this, label_button_border.PassAs<Border>()));
+ } else
+#endif
+ {
+ SetBorder(label_button_border.PassAs<Border>());
+ }
+
+ border_is_themed_border_ = true;
+}
+
+void LabelButton::StateChanged() {
+ const gfx::Size previous_image_size(image_->GetPreferredSize());
+ UpdateImage();
+ const SkColor color = button_state_colors_[state()];
+ if (state() != STATE_DISABLED && label_->enabled_color() != color)
+ label_->SetEnabledColor(color);
+ label_->SetEnabled(state() != STATE_DISABLED);
+ if (image_->GetPreferredSize() != previous_image_size)
+ Layout();
+}
+
+void LabelButton::ChildPreferredSizeChanged(View* child) {
+ PreferredSizeChanged();
+}
+
+void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
+ ResetColorsFromNativeTheme();
+ UpdateThemedBorder();
+ // Invalidate the layout to pickup the new insets from the border.
+ InvalidateLayout();
+}
+
+ui::NativeTheme::Part LabelButton::GetThemePart() const {
+ return ui::NativeTheme::kPushButton;
+}
+
+gfx::Rect LabelButton::GetThemePaintRect() const {
+ return GetLocalBounds();
+}
+
+ui::NativeTheme::State LabelButton::GetThemeState(
+ ui::NativeTheme::ExtraParams* params) const {
+ GetExtraParams(params);
+ switch (state()) {
+ case STATE_NORMAL: return ui::NativeTheme::kNormal;
+ case STATE_HOVERED: return ui::NativeTheme::kHovered;
+ case STATE_PRESSED: return ui::NativeTheme::kPressed;
+ case STATE_DISABLED: return ui::NativeTheme::kDisabled;
+ case STATE_COUNT: NOTREACHED() << "Unknown state: " << state();
+ }
+ return ui::NativeTheme::kNormal;
+}
+
+const gfx::Animation* LabelButton::GetThemeAnimation() const {
+ return hover_animation_.get();
+}
+
+ui::NativeTheme::State LabelButton::GetBackgroundThemeState(
+ ui::NativeTheme::ExtraParams* params) const {
+ GetExtraParams(params);
+ return ui::NativeTheme::kNormal;
+}
+
+ui::NativeTheme::State LabelButton::GetForegroundThemeState(
+ ui::NativeTheme::ExtraParams* params) const {
+ GetExtraParams(params);
+ return ui::NativeTheme::kHovered;
+}
+
+} // namespace views
« no previous file with comments | « ui/message_center/views/bounded_label.cc ('k') | ui/views/controls/label.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698