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

Unified Diff: chrome/browser/ui/views/avatar_menu_bubble_view.cc

Issue 8221027: Make views::Label and views::Link auto-color themselves to be readable over their background colo... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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: chrome/browser/ui/views/avatar_menu_bubble_view.cc
===================================================================
--- chrome/browser/ui/views/avatar_menu_bubble_view.cc (revision 104959)
+++ chrome/browser/ui/views/avatar_menu_bubble_view.cc (working copy)
@@ -18,7 +18,6 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/canvas_skia.h"
-#include "ui/gfx/color_utils.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "views/controls/button/image_button.h"
@@ -32,8 +31,6 @@
const int kIconWidth = 38;
const int kIconMarginX = 6;
const int kSeparatorPaddingY = 5;
-const SkColor kHighlightBackgroundColor = SkColorSetRGB(0xe3, 0xed, 0xf6);
-const SkColor kLinkColor = SkColorSetRGB(0, 0x79, 0xda);
inline int Round(double x) {
return static_cast<int>(x + 0.5);
@@ -60,6 +57,9 @@
return gfx::Rect(x, y, scaled_width, scaled_height);
}
+
+// HighlightDelegate ----------------------------------------------------------
+
// Delegate to callback when the highlight state of a control changes.
class HighlightDelegate {
public:
@@ -67,30 +67,20 @@
virtual void OnHighlightStateChanged() = 0;
};
+
+// EditProfileLink ------------------------------------------------------------
+
// A custom Link control that forwards highlight state changes. We need to do
// this to make sure that the ProfileItemView looks highlighted even when
// the mouse is over this link.
class EditProfileLink : public views::Link {
public:
explicit EditProfileLink(const string16& title,
- HighlightDelegate* delegate)
- : views::Link(title),
- delegate_(delegate),
- state_(views::CustomButton::BS_NORMAL) {
- }
+ HighlightDelegate* delegate);
- virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE {
- views::Link::OnMouseEntered(event);
- state_ = views::CustomButton::BS_HOT;
- delegate_->OnHighlightStateChanged();
- }
+ virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
+ virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
- virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE {
- views::Link::OnMouseExited(event);
- state_ = views::CustomButton::BS_NORMAL;
- delegate_->OnHighlightStateChanged();
- }
-
views::CustomButton::ButtonState state() { return state_; }
private:
@@ -98,173 +88,210 @@
views::CustomButton::ButtonState state_;
};
+EditProfileLink::EditProfileLink(const string16& title,
+ HighlightDelegate* delegate)
+ : views::Link(title),
+ delegate_(delegate),
+ state_(views::CustomButton::BS_NORMAL) {
+}
+
+void EditProfileLink::OnMouseEntered(const views::MouseEvent& event) {
+ views::Link::OnMouseEntered(event);
+ state_ = views::CustomButton::BS_HOT;
+ delegate_->OnHighlightStateChanged();
+}
+
+void EditProfileLink::OnMouseExited(const views::MouseEvent& event) {
+ views::Link::OnMouseExited(event);
+ state_ = views::CustomButton::BS_NORMAL;
+ delegate_->OnHighlightStateChanged();
+}
+
+
+// ProfileImageView -----------------------------------------------------------
+
// A custom image view that ignores mouse events so that the parent can receive
// them them instead.
class ProfileImageView : public views::ImageView {
public:
- virtual bool HitTest(const gfx::Point& l) const OVERRIDE {
- return false;
- }
+ virtual bool HitTest(const gfx::Point& l) const OVERRIDE;
};
+bool ProfileImageView::HitTest(const gfx::Point& l) const {
+ return false;
+}
+
+
+// ProfileItemView ------------------------------------------------------------
+
// Control that shows information about a single profile.
class ProfileItemView : public views::CustomButton,
public HighlightDelegate {
public:
ProfileItemView(const AvatarMenuModel::Item& item,
views::ButtonListener* switch_profile_listener,
- views::LinkListener* edit_profile_listener)
- : views::CustomButton(switch_profile_listener),
- item_(item) {
- image_view_ = new ProfileImageView();
- SkBitmap profile_icon = item_.icon;
- if (item_.active) {
- SkBitmap badged_icon = GetBadgedIcon(profile_icon);
- image_view_->SetImage(&badged_icon);
- } else {
- image_view_->SetImage(&profile_icon);
- }
- AddChildView(image_view_);
+ views::LinkListener* edit_profile_listener);
- // Add a label to show the profile name.
- name_label_ = new views::Label(item_.name);
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- gfx::Font base_font = rb.GetFont(ResourceBundle::BaseFont);
- int style = item_.active ? gfx::Font::BOLD : 0;
- const int kNameFontDelta = 1;
- name_label_->SetFont(base_font.DeriveFont(kNameFontDelta, style));
- name_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- AddChildView(name_label_);
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void Layout() OVERRIDE;
+ virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
+ virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
- // Add a label to show the sync state.
- sync_state_label_ = new views::Label(item_.sync_state);
- const int kStateFontDelta = -1;
- sync_state_label_->SetFont(base_font.DeriveFont(kStateFontDelta));
- sync_state_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- sync_state_label_->SetEnabled(false);
- AddChildView(sync_state_label_);
+ virtual void OnHighlightStateChanged() OVERRIDE;
- // Add an edit profile link.
- edit_link_ = new EditProfileLink(
- l10n_util::GetStringUTF16(IDS_PROFILES_EDIT_PROFILE_LINK), this);
- edit_link_->set_listener(edit_profile_listener);
- edit_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- edit_link_->MakeReadableOverBackgroundColor(kHighlightBackgroundColor);
- edit_link_->SetNormalColor(
- color_utils::GetReadableColor(kLinkColor, kHighlightBackgroundColor));
- edit_link_->SetHasFocusBorder(true);
- AddChildView(edit_link_);
+ EditProfileLink* edit_link() { return edit_link_; }
+ const AvatarMenuModel::Item& item() { return item_; }
- OnHighlightStateChanged();
- }
+ private:
+ static SkBitmap GetBadgedIcon(const SkBitmap& icon);
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- if (IsHighlighted()) {
- canvas->FillRectInt(kHighlightBackgroundColor, 0, 0,
- width(), height());
- }
- }
+ bool IsHighlighted() const;
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- int width = std::max(name_label_->GetPreferredSize().width(),
- sync_state_label_->GetPreferredSize().width());
- width = std::max(edit_link_->GetPreferredSize().width(),
- width);
- return gfx::Size(kIconWidth + kIconMarginX + width, kItemHeight);
+ EditProfileLink* edit_link_;
+ views::ImageView* image_view_;
+ AvatarMenuModel::Item item_;
+ views::Label* name_label_;
+ views::Label* sync_state_label_;
+};
+
+ProfileItemView::ProfileItemView(const AvatarMenuModel::Item& item,
+ views::ButtonListener* switch_profile_listener,
+ views::LinkListener* edit_profile_listener)
+ : views::CustomButton(switch_profile_listener),
+ item_(item) {
+ image_view_ = new ProfileImageView();
+ SkBitmap profile_icon = item_.icon;
+ if (item_.active) {
+ SkBitmap badged_icon(GetBadgedIcon(profile_icon));
+ image_view_->SetImage(&badged_icon);
+ } else {
+ image_view_->SetImage(&profile_icon);
}
+ AddChildView(image_view_);
- virtual void Layout() OVERRIDE {
- // Profile icon.
- const SkBitmap& icon = image_view_->GetImage();
- gfx::Rect icon_rect = GetCenteredAndScaledRect(
- icon.width(), icon.height(), 0, 0, kIconWidth, height());
- image_view_->SetBoundsRect(icon_rect);
+ // Add a label to show the profile name.
+ name_label_ = new views::Label(item_.name);
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font base_font = rb.GetFont(ResourceBundle::BaseFont);
+ int style = item_.active ? gfx::Font::BOLD : 0;
+ const int kNameFontDelta = 1;
+ name_label_->SetFont(base_font.DeriveFont(kNameFontDelta, style));
+ name_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(name_label_);
- int label_x = icon_rect.right() + kIconMarginX;
- int max_label_width = width() - label_x;
- gfx::Size name_size = name_label_->GetPreferredSize();
- name_size.set_width(std::min(name_size.width(), max_label_width));
- gfx::Size state_size = sync_state_label_->GetPreferredSize();
- state_size.set_width(std::min(state_size.width(), max_label_width));
- gfx::Size edit_size = edit_link_->GetPreferredSize();
- edit_size.set_width(std::min(edit_size.width(), max_label_width));
+ // Add a label to show the sync state.
+ sync_state_label_ = new views::Label(item_.sync_state);
+ const int kStateFontDelta = -1;
+ sync_state_label_->SetFont(base_font.DeriveFont(kStateFontDelta));
+ sync_state_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ sync_state_label_->SetEnabled(false);
+ AddChildView(sync_state_label_);
- const int kNameStatePaddingY = 2;
- int labels_height = name_size.height() + kNameStatePaddingY +
- std::max(state_size.height(), edit_size.height());
- int y = (height() - labels_height) / 2;
- name_label_->SetBounds(label_x, y, name_size.width(), name_size.height());
+ // Add an edit profile link.
+ edit_link_ = new EditProfileLink(
+ l10n_util::GetStringUTF16(IDS_PROFILES_EDIT_PROFILE_LINK), this);
+ edit_link_->set_listener(edit_profile_listener);
+ edit_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ edit_link_->SetEnabledColor(SkColorSetRGB(0xe3, 0xed, 0xf6));
+ edit_link_->SetHasFocusBorder(true);
+ AddChildView(edit_link_);
- int bottom = y + labels_height;
- sync_state_label_->SetBounds(label_x, bottom - state_size.height(),
- state_size.width(), state_size.height());
- // The edit link overlaps the sync state label.
- edit_link_->SetBounds(label_x, bottom - edit_size.height(),
- edit_size.width(), edit_size.height());
- }
+ OnHighlightStateChanged();
+}
- virtual void OnHighlightStateChanged() OVERRIDE {
- bool is_highlighted = IsHighlighted();
- bool show_edit = is_highlighted && item_.active;
- sync_state_label_->SetVisible(!show_edit);
- edit_link_->SetVisible(show_edit);
+gfx::Size ProfileItemView::GetPreferredSize() {
+ int width = std::max(name_label_->GetPreferredSize().width(),
+ sync_state_label_->GetPreferredSize().width());
+ width = std::max(edit_link_->GetPreferredSize().width(), width);
+ return gfx::Size(kIconWidth + kIconMarginX + width, kItemHeight);
+}
- SkColor background_color =
- is_highlighted ? kHighlightBackgroundColor : Bubble::kBackgroundColor;
- name_label_->MakeReadableOverBackgroundColor(background_color);
- sync_state_label_->MakeReadableOverBackgroundColor(background_color);
+void ProfileItemView::Layout() {
+ // Profile icon.
+ const SkBitmap& icon = image_view_->GetImage();
+ gfx::Rect icon_rect = GetCenteredAndScaledRect(
+ icon.width(), icon.height(), 0, 0, kIconWidth, height());
+ image_view_->SetBoundsRect(icon_rect);
- SchedulePaint();
- }
+ int label_x = icon_rect.right() + kIconMarginX;
+ int max_label_width = width() - label_x;
+ gfx::Size name_size = name_label_->GetPreferredSize();
+ name_size.set_width(std::min(name_size.width(), max_label_width));
+ gfx::Size state_size = sync_state_label_->GetPreferredSize();
+ state_size.set_width(std::min(state_size.width(), max_label_width));
+ gfx::Size edit_size = edit_link_->GetPreferredSize();
+ edit_size.set_width(std::min(edit_size.width(), max_label_width));
- virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE {
- views::CustomButton::OnMouseEntered(event);
- OnHighlightStateChanged();
- }
+ const int kNameStatePaddingY = 2;
+ int labels_height = name_size.height() + kNameStatePaddingY +
+ std::max(state_size.height(), edit_size.height());
+ int y = (height() - labels_height) / 2;
+ name_label_->SetBounds(label_x, y, name_size.width(), name_size.height());
- virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE {
- views::CustomButton::OnMouseExited(event);
- OnHighlightStateChanged();
- }
+ int bottom = y + labels_height;
+ sync_state_label_->SetBounds(label_x, bottom - state_size.height(),
+ state_size.width(), state_size.height());
+ // The edit link overlaps the sync state label.
+ edit_link_->SetBounds(label_x, bottom - edit_size.height(),
+ edit_size.width(), edit_size.height());
+}
- EditProfileLink* edit_link() { return edit_link_; }
- const AvatarMenuModel::Item& item() { return item_; }
+void ProfileItemView::OnMouseEntered(const views::MouseEvent& event) {
+ views::CustomButton::OnMouseEntered(event);
+ OnHighlightStateChanged();
+}
- private:
- bool IsHighlighted() {
- return state() == views::CustomButton::BS_PUSHED ||
- state() == views::CustomButton::BS_HOT ||
- edit_link_->state() == views::CustomButton::BS_PUSHED ||
- edit_link_->state() == views::CustomButton::BS_HOT;
- }
+void ProfileItemView::OnMouseExited(const views::MouseEvent& event) {
+ views::CustomButton::OnMouseExited(event);
+ OnHighlightStateChanged();
+}
- SkBitmap GetBadgedIcon(const SkBitmap& icon) {
- gfx::Rect icon_rect = GetCenteredAndScaledRect(
- icon.width(), icon.height(), 0, 0, kIconWidth, kItemHeight);
+void ProfileItemView::OnHighlightStateChanged() {
+ set_background(IsHighlighted() ? views::Background::CreateSolidBackground(
+ SkColorSetRGB(0xe3, 0xed, 0xf6)) : NULL);
+ SkColor background_color = background() ?
+ background()->get_color() : Bubble::kBackgroundColor;
+ name_label_->SetBackgroundColor(background_color);
+ sync_state_label_->SetBackgroundColor(background_color);
+ edit_link_->SetBackgroundColor(background_color);
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- SkBitmap badge = rb.GetImageNamed(IDR_PROFILE_SELECTED);
- const float kBadgeOverlapRatioX = 1.0f / 5.0f;
- int width = icon_rect.width() + badge.width() * kBadgeOverlapRatioX;
- const float kBadgeOverlapRatioY = 1.0f / 3.0f;
- int height = icon_rect.height() + badge.height() * kBadgeOverlapRatioY;
+ bool show_edit = IsHighlighted() && item_.active;
+ sync_state_label_->SetVisible(!show_edit);
+ edit_link_->SetVisible(show_edit);
+ SchedulePaint();
+}
- gfx::CanvasSkia canvas(width, height, false);
- canvas.DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), 0, 0,
- icon_rect.width(), icon_rect.height(), true);
- canvas.DrawBitmapInt(badge, width - badge.width(), height - badge.height());
- return canvas.ExtractBitmap();
- }
+// static
+SkBitmap ProfileItemView::GetBadgedIcon(const SkBitmap& icon) {
+ gfx::Rect icon_rect = GetCenteredAndScaledRect(
+ icon.width(), icon.height(), 0, 0, kIconWidth, kItemHeight);
- EditProfileLink* edit_link_;
- views::ImageView* image_view_;
- AvatarMenuModel::Item item_;
- views::Label* name_label_;
- views::Label* sync_state_label_;
-};
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SkBitmap badge = rb.GetImageNamed(IDR_PROFILE_SELECTED);
+ const float kBadgeOverlapRatioX = 1.0f / 5.0f;
+ int width = icon_rect.width() + badge.width() * kBadgeOverlapRatioX;
+ const float kBadgeOverlapRatioY = 1.0f / 3.0f;
+ int height = icon_rect.height() + badge.height() * kBadgeOverlapRatioY;
+ gfx::CanvasSkia canvas(width, height, false);
+ canvas.DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), 0, 0,
+ icon_rect.width(), icon_rect.height(), true);
+ canvas.DrawBitmapInt(badge, width - badge.width(), height - badge.height());
+ return canvas.ExtractBitmap();
+}
+
+bool ProfileItemView::IsHighlighted() const {
+ return state() == views::CustomButton::BS_PUSHED ||
+ state() == views::CustomButton::BS_HOT ||
+ edit_link_->state() == views::CustomButton::BS_PUSHED ||
+ edit_link_->state() == views::CustomButton::BS_HOT;
+}
+
} // namespace
+
+// AvatarMenuBubbleView -------------------------------------------------------
+
AvatarMenuBubbleView::AvatarMenuBubbleView(Browser* browser)
: add_profile_link_(NULL),
browser_(browser) {
@@ -385,9 +412,8 @@
l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK));
add_profile_link_->set_listener(this);
add_profile_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- add_profile_link_->MakeReadableOverBackgroundColor(Bubble::kBackgroundColor);
- add_profile_link_->SetNormalColor(
- color_utils::GetReadableColor(kLinkColor, Bubble::kBackgroundColor));
+ add_profile_link_->SetBackgroundColor(Bubble::kBackgroundColor);
+ add_profile_link_->SetEnabledColor(SkColorSetRGB(0xe3, 0xed, 0xf6));
AddChildView(add_profile_link_);
PreferredSizeChanged();
« no previous file with comments | « chrome/browser/ui/views/about_chrome_view.cc ('k') | chrome/browser/ui/views/bookmarks/bookmark_bar_instructions_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698