Index: chrome/browser/ui/views/avatar_menu_bubble_view.cc |
diff --git a/chrome/browser/ui/views/avatar_menu_bubble_view.cc b/chrome/browser/ui/views/avatar_menu_bubble_view.cc |
deleted file mode 100644 |
index d2a18b2f17c29c76db830761bded73d8f88774d1..0000000000000000000000000000000000000000 |
--- a/chrome/browser/ui/views/avatar_menu_bubble_view.cc |
+++ /dev/null |
@@ -1,813 +0,0 @@ |
-// 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 "chrome/browser/ui/views/avatar_menu_bubble_view.h" |
- |
-#include <algorithm> |
- |
-#include "base/strings/string16.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "chrome/app/chrome_command_ids.h" |
-#include "chrome/browser/browser_process.h" |
-#include "chrome/browser/profiles/avatar_menu.h" |
-#include "chrome/browser/profiles/profile_info_cache.h" |
-#include "chrome/browser/profiles/profile_info_util.h" |
-#include "chrome/browser/profiles/profile_manager.h" |
-#include "chrome/browser/profiles/profile_window.h" |
-#include "chrome/browser/signin/signin_manager_factory.h" |
-#include "chrome/browser/ui/browser.h" |
-#include "chrome/browser/ui/browser_commands.h" |
-#include "chrome/browser/ui/browser_list.h" |
-#include "chrome/browser/ui/browser_window.h" |
-#include "chrome/browser/ui/chrome_pages.h" |
-#include "chrome/common/profile_management_switches.h" |
-#include "chrome/common/url_constants.h" |
-#include "components/signin/core/browser/signin_manager.h" |
-#include "content/public/browser/page_navigator.h" |
-#include "content/public/browser/web_contents.h" |
-#include "grit/generated_resources.h" |
-#include "grit/theme_resources.h" |
-#include "ui/base/l10n/l10n_util.h" |
-#include "ui/base/resource/resource_bundle.h" |
-#include "ui/gfx/canvas.h" |
-#include "ui/gfx/image/canvas_image_source.h" |
-#include "ui/gfx/image/image.h" |
-#include "ui/views/controls/button/custom_button.h" |
-#include "ui/views/controls/button/image_button.h" |
-#include "ui/views/controls/button/label_button.h" |
-#include "ui/views/controls/image_view.h" |
-#include "ui/views/controls/label.h" |
-#include "ui/views/controls/link.h" |
-#include "ui/views/controls/separator.h" |
-#include "ui/views/layout/grid_layout.h" |
-#include "ui/views/layout/layout_constants.h" |
-#include "ui/views/widget/widget.h" |
- |
-namespace { |
- |
-const int kItemHeight = 44; |
-const int kItemMarginY = 4; |
-const int kIconMarginX = 6; |
-const int kSeparatorPaddingY = 5; |
-const int kMaxItemTextWidth = 200; |
-const SkColor kHighlightColor = 0xFFE3EDF6; |
- |
-inline int Round(double x) { |
- return static_cast<int>(x + 0.5); |
-} |
- |
-gfx::Rect GetCenteredAndScaledRect(int src_width, int src_height, |
- int dst_x, int dst_y, |
- int dst_width, int dst_height) { |
- int scaled_width; |
- int scaled_height; |
- if (src_width > src_height) { |
- scaled_width = std::min(src_width, dst_width); |
- float scale = static_cast<float>(scaled_width) / |
- static_cast<float>(src_width); |
- scaled_height = Round(src_height * scale); |
- } else { |
- scaled_height = std::min(src_height, dst_height); |
- float scale = static_cast<float>(scaled_height) / |
- static_cast<float>(src_height); |
- scaled_width = Round(src_width * scale); |
- } |
- int x = dst_x + (dst_width - scaled_width) / 2; |
- int y = dst_y + (dst_height - scaled_height) / 2; |
- return gfx::Rect(x, y, scaled_width, scaled_height); |
-} |
- |
-// BadgeImageSource ----------------------------------------------------------- |
-class BadgeImageSource: public gfx::CanvasImageSource { |
- public: |
- BadgeImageSource(const gfx::ImageSkia& icon, |
- const gfx::Size& icon_size, |
- const gfx::ImageSkia& badge); |
- |
- virtual ~BadgeImageSource(); |
- |
- // Overridden from CanvasImageSource: |
- virtual void Draw(gfx::Canvas* canvas) OVERRIDE; |
- |
- private: |
- gfx::Size ComputeSize(const gfx::ImageSkia& icon, |
- const gfx::Size& size, |
- const gfx::ImageSkia& badge); |
- |
- const gfx::ImageSkia icon_; |
- gfx::Size icon_size_; |
- const gfx::ImageSkia badge_; |
- |
- DISALLOW_COPY_AND_ASSIGN(BadgeImageSource); |
-}; |
- |
-BadgeImageSource::BadgeImageSource(const gfx::ImageSkia& icon, |
- const gfx::Size& icon_size, |
- const gfx::ImageSkia& badge) |
- : gfx::CanvasImageSource(ComputeSize(icon, icon_size, badge), false), |
- icon_(icon), |
- icon_size_(icon_size), |
- badge_(badge) { |
-} |
- |
-BadgeImageSource::~BadgeImageSource() { |
-} |
- |
-void BadgeImageSource::Draw(gfx::Canvas* canvas) { |
- canvas->DrawImageInt(icon_, 0, 0, icon_.width(), icon_.height(), 0, 0, |
- icon_size_.width(), icon_size_.height(), true); |
- canvas->DrawImageInt(badge_, size().width() - badge_.width(), |
- size().height() - badge_.height()); |
-} |
- |
-gfx::Size BadgeImageSource::ComputeSize(const gfx::ImageSkia& icon, |
- const gfx::Size& icon_size, |
- const gfx::ImageSkia& badge) { |
- const float kBadgeOverlapRatioX = 1.0f / 5.0f; |
- int width = icon_size.width() + badge.width() * kBadgeOverlapRatioX; |
- const float kBadgeOverlapRatioY = 1.0f / 3.0f; |
- int height = icon_size.height() + badge.height() * kBadgeOverlapRatioY; |
- return gfx::Size(width, height); |
-} |
- |
-// HighlightDelegate ---------------------------------------------------------- |
- |
-// Delegate to callback when the highlight state of a control changes. |
-class HighlightDelegate { |
- public: |
- virtual ~HighlightDelegate() {} |
- virtual void OnHighlightStateChanged() = 0; |
- virtual void OnFocusStateChanged(bool has_focus) = 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 base::string16& title, |
- HighlightDelegate* delegate); |
- |
- virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; |
- virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; |
- virtual void OnFocus() OVERRIDE; |
- virtual void OnBlur() OVERRIDE; |
- |
- views::CustomButton::ButtonState state() { return state_; } |
- |
- private: |
- HighlightDelegate* delegate_; |
- views::CustomButton::ButtonState state_; |
-}; |
- |
-EditProfileLink::EditProfileLink(const base::string16& title, |
- HighlightDelegate* delegate) |
- : views::Link(title), |
- delegate_(delegate), |
- state_(views::CustomButton::STATE_NORMAL) { |
-} |
- |
-void EditProfileLink::OnMouseEntered(const ui::MouseEvent& event) { |
- views::Link::OnMouseEntered(event); |
- state_ = views::CustomButton::STATE_HOVERED; |
- delegate_->OnHighlightStateChanged(); |
-} |
- |
-void EditProfileLink::OnMouseExited(const ui::MouseEvent& event) { |
- views::Link::OnMouseExited(event); |
- state_ = views::CustomButton::STATE_NORMAL; |
- delegate_->OnHighlightStateChanged(); |
-} |
- |
-void EditProfileLink::OnFocus() { |
- views::Link::OnFocus(); |
- delegate_->OnFocusStateChanged(true); |
-} |
- |
-void EditProfileLink::OnBlur() { |
- views::Link::OnBlur(); |
- state_ = views::CustomButton::STATE_NORMAL; |
- delegate_->OnFocusStateChanged(false); |
-} |
- |
- |
-// ProfileImageView ----------------------------------------------------------- |
- |
-// A custom image view that ignores mouse events so that the parent can receive |
-// them instead. |
-class ProfileImageView : public views::ImageView { |
- public: |
- virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE; |
-}; |
- |
-bool ProfileImageView::HitTestRect(const gfx::Rect& rect) const { |
- return false; |
-} |
- |
-} // namespace |
- |
-// ProfileItemView ------------------------------------------------------------ |
- |
-// Control that shows information about a single profile. |
-class ProfileItemView : public views::CustomButton, |
- public HighlightDelegate { |
- public: |
- ProfileItemView(const AvatarMenu::Item& item, |
- AvatarMenuBubbleView* parent, |
- AvatarMenu* menu); |
- |
- virtual gfx::Size GetPreferredSize() OVERRIDE; |
- virtual void Layout() OVERRIDE; |
- virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; |
- virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; |
- virtual void OnFocus() OVERRIDE; |
- virtual void OnBlur() OVERRIDE; |
- |
- virtual void OnHighlightStateChanged() OVERRIDE; |
- virtual void OnFocusStateChanged(bool has_focus) OVERRIDE; |
- |
- const AvatarMenu::Item& item() const { return item_; } |
- EditProfileLink* edit_link() { return edit_link_; } |
- |
- private: |
- gfx::ImageSkia GetBadgedIcon(const gfx::ImageSkia& icon); |
- |
- bool IsHighlighted(); |
- |
- AvatarMenu::Item item_; |
- AvatarMenuBubbleView* parent_; |
- AvatarMenu* menu_; |
- views::ImageView* image_view_; |
- views::Label* name_label_; |
- views::Label* sync_state_label_; |
- EditProfileLink* edit_link_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ProfileItemView); |
-}; |
- |
-ProfileItemView::ProfileItemView(const AvatarMenu::Item& item, |
- AvatarMenuBubbleView* parent, |
- AvatarMenu* menu) |
- : views::CustomButton(parent), |
- item_(item), |
- parent_(parent), |
- menu_(menu) { |
- set_notify_enter_exit_on_child(true); |
- |
- image_view_ = new ProfileImageView(); |
- gfx::ImageSkia profile_icon = *item_.icon.ToImageSkia(); |
- if (item_.active || item_.signin_required) |
- image_view_->SetImage(GetBadgedIcon(profile_icon)); |
- else |
- image_view_->SetImage(profile_icon); |
- AddChildView(image_view_); |
- |
- // Add a label to show the profile name. |
- ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
- name_label_ = new views::Label(item_.name, |
- rb->GetFontList(item_.active ? |
- ui::ResourceBundle::BoldFont : |
- ui::ResourceBundle::BaseFont)); |
- name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- AddChildView(name_label_); |
- |
- // Add a label to show the sync state. |
- sync_state_label_ = new views::Label(item_.sync_state); |
- if (item_.signed_in) |
- sync_state_label_->SetElideBehavior(views::Label::ELIDE_AS_EMAIL); |
- sync_state_label_->SetFontList( |
- rb->GetFontList(ui::ResourceBundle::SmallFont)); |
- sync_state_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- sync_state_label_->SetEnabled(false); |
- AddChildView(sync_state_label_); |
- |
- // Add an edit profile link. |
- edit_link_ = new EditProfileLink( |
- l10n_util::GetStringUTF16(IDS_PROFILES_EDIT_PROFILE_LINK), this); |
- edit_link_->set_listener(parent); |
- edit_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- AddChildView(edit_link_); |
- |
- OnHighlightStateChanged(); |
-} |
- |
-gfx::Size ProfileItemView::GetPreferredSize() { |
- int text_width = std::max(name_label_->GetPreferredSize().width(), |
- sync_state_label_->GetPreferredSize().width()); |
- text_width = std::max(edit_link_->GetPreferredSize().width(), text_width); |
- text_width = std::min(kMaxItemTextWidth, text_width); |
- return gfx::Size(profiles::kAvatarIconWidth + kIconMarginX + text_width, |
- kItemHeight); |
-} |
- |
-void ProfileItemView::Layout() { |
- // Profile icon. |
- gfx::Rect icon_rect; |
- if (item_.active) { |
- // If this is the active item then the icon is already scaled and so |
- // just use the preferred size. |
- icon_rect.set_size(image_view_->GetPreferredSize()); |
- icon_rect.set_y((height() - icon_rect.height()) / 2); |
- } else { |
- const gfx::ImageSkia& icon = image_view_->GetImage(); |
- icon_rect = GetCenteredAndScaledRect(icon.width(), icon.height(), 0, 0, |
- profiles::kAvatarIconWidth, height()); |
- } |
- image_view_->SetBoundsRect(icon_rect); |
- |
- int label_x = profiles::kAvatarIconWidth + kIconMarginX; |
- int max_label_width = std::max(width() - label_x, 0); |
- 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)); |
- |
- 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()); |
- |
- 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()); |
-} |
- |
-void ProfileItemView::OnMouseEntered(const ui::MouseEvent& event) { |
- views::CustomButton::OnMouseEntered(event); |
- OnHighlightStateChanged(); |
-} |
- |
-void ProfileItemView::OnMouseExited(const ui::MouseEvent& event) { |
- views::CustomButton::OnMouseExited(event); |
- OnHighlightStateChanged(); |
-} |
- |
-void ProfileItemView::OnFocus() { |
- views::CustomButton::OnFocus(); |
- OnFocusStateChanged(true); |
-} |
- |
-void ProfileItemView::OnBlur() { |
- views::CustomButton::OnBlur(); |
- OnFocusStateChanged(false); |
-} |
- |
-void ProfileItemView::OnHighlightStateChanged() { |
- const SkColor color = IsHighlighted() ? kHighlightColor : parent_->color(); |
- set_background(views::Background::CreateSolidBackground(color)); |
- name_label_->SetBackgroundColor(color); |
- sync_state_label_->SetBackgroundColor(color); |
- edit_link_->SetBackgroundColor(color); |
- |
- bool show_edit = IsHighlighted() && item_.active && |
- menu_->ShouldShowEditProfileLink(); |
- sync_state_label_->SetVisible(!show_edit); |
- edit_link_->SetVisible(show_edit); |
- SchedulePaint(); |
-} |
- |
-void ProfileItemView::OnFocusStateChanged(bool has_focus) { |
- if (!has_focus && state() != views::CustomButton::STATE_DISABLED) |
- SetState(views::CustomButton::STATE_NORMAL); |
- OnHighlightStateChanged(); |
-} |
- |
-// static |
-gfx::ImageSkia ProfileItemView::GetBadgedIcon(const gfx::ImageSkia& icon) { |
- ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); |
- const gfx::ImageSkia* badge = NULL; |
- |
- if (item_.active) |
- badge = rb->GetImageSkiaNamed(IDR_PROFILE_SELECTED); |
- else if (item_.signin_required) // TODO(bcwhite): create new icon |
- badge = rb->GetImageSkiaNamed(IDR_OMNIBOX_HTTPS_VALID); |
- else |
- NOTREACHED(); // function should only be called if one of above is true |
- |
- gfx::Size icon_size = GetCenteredAndScaledRect(icon.width(), icon.height(), |
- 0, 0, profiles::kAvatarIconWidth, kItemHeight).size(); |
- gfx::CanvasImageSource* source = |
- new BadgeImageSource(icon, icon_size, *badge); |
- // ImageSkia takes ownership of |source|. |
- return gfx::ImageSkia(source, source->size()); |
-} |
- |
-bool ProfileItemView::IsHighlighted() { |
- return state() == views::CustomButton::STATE_PRESSED || |
- state() == views::CustomButton::STATE_HOVERED || |
- edit_link_->state() == views::CustomButton::STATE_PRESSED || |
- edit_link_->state() == views::CustomButton::STATE_HOVERED || |
- HasFocus() || |
- edit_link_->HasFocus(); |
-} |
- |
- |
-// ActionButtonView ----------------------------------------------------------- |
- |
-// A custom view that manages the "action" buttons at the bottom of the list |
-// of profiles. |
-class ActionButtonView : public views::View { |
- public: |
- ActionButtonView(views::ButtonListener* listener, Profile* profile); |
- |
- private: |
- views::LabelButton* manage_button_; |
- views::LabelButton* signout_button_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ActionButtonView); |
-}; |
- |
- |
-ActionButtonView::ActionButtonView(views::ButtonListener* listener, |
- Profile* profile) |
- : manage_button_(NULL), |
- signout_button_(NULL) { |
- std::string username; |
- SigninManagerBase* signin = |
- SigninManagerFactory::GetForProfile(profile); |
- if (signin != NULL) |
- username = signin->GetAuthenticatedUsername(); |
- |
- manage_button_ = new views::LabelButton( |
- listener, l10n_util::GetStringUTF16(IDS_PROFILES_MANAGE_PROFILES_BUTTON)); |
- manage_button_->SetStyle(views::Button::STYLE_BUTTON); |
- manage_button_->SetTooltipText( |
- l10n_util::GetStringUTF16(IDS_PROFILES_MANAGE_PROFILES_BUTTON_TIP)); |
- manage_button_->set_tag(IDS_PROFILES_MANAGE_PROFILES_BUTTON); |
- |
- signout_button_ = new views::LabelButton( |
- listener, l10n_util::GetStringUTF16(IDS_PROFILES_PROFILE_SIGNOUT_BUTTON)); |
- signout_button_->SetStyle(views::Button::STYLE_BUTTON); |
- if (username.empty()) { |
- signout_button_->SetTooltipText( |
- l10n_util::GetStringUTF16( |
- IDS_PROFILES_PROFILE_SIGNOUT_BUTTON_TIP_UNAVAILABLE)); |
- signout_button_->SetEnabled(false); |
- } else { |
- signout_button_->SetTooltipText( |
- l10n_util::GetStringFUTF16(IDS_PROFILES_PROFILE_SIGNOUT_BUTTON_TIP, |
- base::UTF8ToUTF16(username))); |
- } |
- signout_button_->set_tag(IDS_PROFILES_PROFILE_SIGNOUT_BUTTON); |
- |
- views::GridLayout* layout = new views::GridLayout(this); |
- views::ColumnSet* columns = layout->AddColumnSet(0); |
- columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, |
- views::GridLayout::USE_PREF, 0, 0); |
- columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1, |
- views::GridLayout::USE_PREF, 0, 0); |
- layout->StartRow(0, 0); |
- layout->AddView(signout_button_); |
- layout->AddView(manage_button_); |
- SetLayoutManager(layout); |
-} |
- |
- |
-// AvatarMenuBubbleView ------------------------------------------------------- |
- |
-// static |
-AvatarMenuBubbleView* AvatarMenuBubbleView::avatar_bubble_ = NULL; |
-bool AvatarMenuBubbleView::close_on_deactivate_for_testing_ = true; |
- |
-// static |
-void AvatarMenuBubbleView::ShowBubble( |
- views::View* anchor_view, |
- views::BubbleBorder::Arrow arrow, |
- views::BubbleBorder::BubbleAlignment border_alignment, |
- const gfx::Rect& anchor_rect, |
- Browser* browser) { |
- if (IsShowing()) |
- return; |
- |
- DCHECK(chrome::IsCommandEnabled(browser, IDC_SHOW_AVATAR_MENU)); |
- avatar_bubble_ = new AvatarMenuBubbleView( |
- anchor_view, arrow, anchor_rect, browser); |
- views::BubbleDelegateView::CreateBubble(avatar_bubble_); |
- avatar_bubble_->set_close_on_deactivate(close_on_deactivate_for_testing_); |
- avatar_bubble_->SetBackgroundColors(); |
- avatar_bubble_->SetAlignment(border_alignment); |
- avatar_bubble_->GetWidget()->Show(); |
-} |
- |
-// static |
-bool AvatarMenuBubbleView::IsShowing() { |
- return avatar_bubble_ != NULL; |
-} |
- |
-// static |
-void AvatarMenuBubbleView::Hide() { |
- if (IsShowing()) |
- avatar_bubble_->GetWidget()->Close(); |
-} |
- |
-AvatarMenuBubbleView::AvatarMenuBubbleView( |
- views::View* anchor_view, |
- views::BubbleBorder::Arrow arrow, |
- const gfx::Rect& anchor_rect, |
- Browser* browser) |
- : BubbleDelegateView(anchor_view, arrow), |
- anchor_rect_(anchor_rect), |
- browser_(browser), |
- separator_(NULL), |
- buttons_view_(NULL), |
- managed_user_info_(NULL), |
- separator_switch_users_(NULL), |
- expanded_(false) { |
- avatar_menu_.reset(new AvatarMenu( |
- &g_browser_process->profile_manager()->GetProfileInfoCache(), |
- this, |
- browser_)); |
- avatar_menu_->RebuildMenu(); |
-} |
- |
-AvatarMenuBubbleView::~AvatarMenuBubbleView() { |
-} |
- |
-gfx::Size AvatarMenuBubbleView::GetPreferredSize() { |
- const int kBubbleViewMinWidth = 175; |
- gfx::Size preferred_size(kBubbleViewMinWidth, 0); |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- gfx::Size size = item_views_[i]->GetPreferredSize(); |
- preferred_size.Enlarge(0, size.height() + kItemMarginY); |
- preferred_size.SetToMax(size); |
- } |
- |
- if (buttons_view_) { |
- preferred_size.Enlarge( |
- 0, kSeparatorPaddingY * 2 + separator_->GetPreferredSize().height()); |
- |
- gfx::Size buttons_size = buttons_view_->GetPreferredSize(); |
- preferred_size.Enlarge(0, buttons_size.height()); |
- preferred_size.SetToMax(buttons_size); |
- } |
- |
- |
- if (managed_user_info_) { |
- // First handle the switch profile link because it can still affect the |
- // preferred width. |
- gfx::Size size = switch_profile_link_->GetPreferredSize(); |
- preferred_size.Enlarge(0, size.height()); |
- preferred_size.SetToMax(size); |
- |
- // Add the height of the two separators. |
- preferred_size.Enlarge( |
- 0, |
- kSeparatorPaddingY * 4 + separator_->GetPreferredSize().height() * 2); |
- } |
- |
- const int kBubbleViewMaxWidth = 800; |
- preferred_size.SetToMin( |
- gfx::Size(kBubbleViewMaxWidth, preferred_size.height())); |
- |
- // We have to do this after the final width is calculated, since the label |
- // will wrap based on the width. |
- if (managed_user_info_) { |
- int remaining_width = |
- preferred_size.width() - icon_view_->GetPreferredSize().width() - |
- views::kRelatedControlSmallHorizontalSpacing; |
- preferred_size.Enlarge( |
- 0, |
- managed_user_info_->GetHeightForWidth(remaining_width) + kItemMarginY); |
- } |
- |
- return preferred_size; |
-} |
- |
-void AvatarMenuBubbleView::Layout() { |
- int y = 0; |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- views::CustomButton* item_view = item_views_[i]; |
- int item_height = item_view->GetPreferredSize().height(); |
- int item_width = width(); |
- item_view->SetBounds(0, y, item_width, item_height); |
- y += item_height + kItemMarginY; |
- } |
- |
- int separator_height; |
- if (buttons_view_ || managed_user_info_) { |
- separator_height = separator_->GetPreferredSize().height(); |
- y += kSeparatorPaddingY; |
- separator_->SetBounds(0, y, width(), separator_height); |
- y += kSeparatorPaddingY + separator_height; |
- } |
- |
- if (buttons_view_) { |
- buttons_view_->SetBounds(0, y, |
- width(), buttons_view_->GetPreferredSize().height()); |
- } else if (managed_user_info_) { |
- gfx::Size icon_size = icon_view_->GetPreferredSize(); |
- gfx::Rect icon_bounds(0, y, icon_size.width(), icon_size.height()); |
- icon_view_->SetBoundsRect(icon_bounds); |
- int info_width = width() - icon_bounds.right() - |
- views::kRelatedControlSmallHorizontalSpacing; |
- int height = managed_user_info_->GetHeightForWidth(info_width); |
- managed_user_info_->SetBounds( |
- icon_bounds.right() + views::kRelatedControlSmallHorizontalSpacing, |
- y, info_width, height); |
- y += height + kItemMarginY + kSeparatorPaddingY; |
- separator_switch_users_->SetBounds(0, y, width(), separator_height); |
- y += separator_height + kSeparatorPaddingY; |
- int link_height = switch_profile_link_->GetPreferredSize().height(); |
- switch_profile_link_->SetBounds(0, y, width(), link_height); |
- } |
-} |
- |
-bool AvatarMenuBubbleView::AcceleratorPressed( |
- const ui::Accelerator& accelerator) { |
- if (accelerator.key_code() != ui::VKEY_DOWN && |
- accelerator.key_code() != ui::VKEY_UP) |
- return BubbleDelegateView::AcceleratorPressed(accelerator); |
- |
- if (item_views_.empty()) |
- return true; |
- |
- // Find the currently focused item. Note that if there is no focused item, the |
- // code below correctly handles a |focus_index| of -1. |
- int focus_index = -1; |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- if (item_views_[i]->HasFocus()) { |
- focus_index = i; |
- break; |
- } |
- } |
- |
- // Moved the focus up or down by 1. |
- if (accelerator.key_code() == ui::VKEY_DOWN) |
- focus_index = (focus_index + 1) % item_views_.size(); |
- else |
- focus_index = ((focus_index > 0) ? focus_index : item_views_.size()) - 1; |
- item_views_[focus_index]->RequestFocus(); |
- |
- return true; |
-} |
- |
-void AvatarMenuBubbleView::ButtonPressed(views::Button* sender, |
- const ui::Event& event) { |
- if (sender->tag() == IDS_PROFILES_MANAGE_PROFILES_BUTTON) { |
- std::string subpage = chrome::kSearchUsersSubPage; |
- chrome::ShowSettingsSubPage(browser_, subpage); |
- return; |
- } else if (sender->tag() == IDS_PROFILES_PROFILE_SIGNOUT_BUTTON) { |
- profiles::LockProfile(browser_->profile()); |
- return; |
- } |
- |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- ProfileItemView* item_view = item_views_[i]; |
- if (sender == item_view) { |
- // Clicking on the active profile shouldn't do anything. |
- if (!item_view->item().active) { |
- avatar_menu_->SwitchToProfile( |
- i, ui::DispositionFromEventFlags(event.flags()) == NEW_WINDOW, |
- ProfileMetrics::SWITCH_PROFILE_ICON); |
- } |
- break; |
- } |
- } |
-} |
- |
-void AvatarMenuBubbleView::LinkClicked(views::Link* source, int event_flags) { |
- if (source == buttons_view_) { |
- avatar_menu_->AddNewProfile(ProfileMetrics::ADD_NEW_USER_ICON); |
- return; |
- } |
- if (source == switch_profile_link_) { |
- expanded_ = true; |
- OnAvatarMenuChanged(avatar_menu_.get()); |
- return; |
- } |
- |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- ProfileItemView* item_view = item_views_[i]; |
- if (source == item_view->edit_link()) { |
- avatar_menu_->EditProfile(i); |
- return; |
- } |
- } |
-} |
- |
-gfx::Rect AvatarMenuBubbleView::GetAnchorRect() { |
- return anchor_rect_; |
-} |
- |
-void AvatarMenuBubbleView::Init() { |
- // Build the menu for the first time. |
- OnAvatarMenuChanged(avatar_menu_.get()); |
- AddAccelerator(ui::Accelerator(ui::VKEY_DOWN, ui::EF_NONE)); |
- AddAccelerator(ui::Accelerator(ui::VKEY_UP, ui::EF_NONE)); |
-} |
- |
-void AvatarMenuBubbleView::WindowClosing() { |
- DCHECK_EQ(avatar_bubble_, this); |
- avatar_bubble_ = NULL; |
-} |
- |
-void AvatarMenuBubbleView::InitMenuContents( |
- AvatarMenu* avatar_menu) { |
- for (size_t i = 0; i < avatar_menu->GetNumberOfItems(); ++i) { |
- const AvatarMenu::Item& item = avatar_menu->GetItemAt(i); |
- ProfileItemView* item_view = new ProfileItemView(item, |
- this, |
- avatar_menu_.get()); |
- item_view->SetAccessibleName(l10n_util::GetStringFUTF16( |
- IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name)); |
- item_view->SetFocusable(true); |
- AddChildView(item_view); |
- item_views_.push_back(item_view); |
- } |
- |
- if (switches::IsNewProfileManagement()) { |
- separator_ = new views::Separator(views::Separator::HORIZONTAL); |
- AddChildView(separator_); |
- buttons_view_ = new ActionButtonView(this, browser_->profile()); |
- AddChildView(buttons_view_); |
- } else if (avatar_menu_->ShouldShowAddNewProfileLink()) { |
- views::Link* add_profile_link = new views::Link( |
- l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK)); |
- add_profile_link->set_listener(this); |
- add_profile_link->SetHorizontalAlignment(gfx::ALIGN_CENTER); |
- add_profile_link->SetBackgroundColor(color()); |
- separator_ = new views::Separator(views::Separator::HORIZONTAL); |
- AddChildView(separator_); |
- buttons_view_ = add_profile_link; |
- AddChildView(buttons_view_); |
- } |
-} |
- |
-void AvatarMenuBubbleView::InitManagedUserContents( |
- AvatarMenu* avatar_menu) { |
- // Show the profile of the managed user. |
- size_t active_index = avatar_menu->GetActiveProfileIndex(); |
- const AvatarMenu::Item& item = |
- avatar_menu->GetItemAt(active_index); |
- ProfileItemView* item_view = new ProfileItemView(item, |
- this, |
- avatar_menu_.get()); |
- item_view->SetAccessibleName(l10n_util::GetStringFUTF16( |
- IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name)); |
- item_views_.push_back(item_view); |
- AddChildView(item_view); |
- separator_ = new views::Separator(views::Separator::HORIZONTAL); |
- AddChildView(separator_); |
- |
- // Add information about managed users. |
- managed_user_info_ = |
- new views::Label(avatar_menu_->GetManagedUserInformation(), |
- ui::ResourceBundle::GetSharedInstance().GetFontList( |
- ui::ResourceBundle::SmallFont)); |
- managed_user_info_->SetMultiLine(true); |
- managed_user_info_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- managed_user_info_->SetBackgroundColor(color()); |
- AddChildView(managed_user_info_); |
- |
- // Add the managed user icon. |
- icon_view_ = new views::ImageView(); |
- icon_view_->SetImage(avatar_menu_->GetManagedUserIcon().ToImageSkia()); |
- AddChildView(icon_view_); |
- |
- // Add a link for switching profiles. |
- separator_switch_users_ = new views::Separator(views::Separator::HORIZONTAL); |
- AddChildView(separator_switch_users_); |
- switch_profile_link_ = new views::Link( |
- l10n_util::GetStringUTF16(IDS_PROFILES_SWITCH_PROFILE_LINK)); |
- switch_profile_link_->set_listener(this); |
- switch_profile_link_->SetHorizontalAlignment(gfx::ALIGN_CENTER); |
- switch_profile_link_->SetBackgroundColor(color()); |
- AddChildView(switch_profile_link_); |
-} |
- |
-void AvatarMenuBubbleView::OnAvatarMenuChanged( |
- AvatarMenu* avatar_menu) { |
- // Unset all our child view references and call RemoveAllChildViews() which |
- // will actually delete them. |
- buttons_view_ = NULL; |
- managed_user_info_ = NULL; |
- item_views_.clear(); |
- RemoveAllChildViews(true); |
- |
- if (avatar_menu_->GetManagedUserInformation().empty() || expanded_) |
- InitMenuContents(avatar_menu); |
- else |
- InitManagedUserContents(avatar_menu); |
- |
- // If the bubble has already been shown then resize and reposition the bubble. |
- Layout(); |
- if (GetBubbleFrameView()) |
- SizeToContents(); |
-} |
- |
-void AvatarMenuBubbleView::SetBackgroundColors() { |
- for (size_t i = 0; i < item_views_.size(); ++i) { |
- item_views_[i]->OnHighlightStateChanged(); |
- } |
-} |