diff options
author | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-11 02:39:57 +0000 |
---|---|---|
committer | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-11 02:39:57 +0000 |
commit | cec09ef0ecb8f5e2f2171797d27b7ea1a496ddfb (patch) | |
tree | a3bf5d0c7f3da997c0701c6f318582c00a3abeb9 | |
parent | 465862a036acee434df5d8fa85a462c75f37b8c7 (diff) | |
download | chromium_src-cec09ef0ecb8f5e2f2171797d27b7ea1a496ddfb.zip chromium_src-cec09ef0ecb8f5e2f2171797d27b7ea1a496ddfb.tar.gz chromium_src-cec09ef0ecb8f5e2f2171797d27b7ea1a496ddfb.tar.bz2 |
Revert 96306 - Multi-Profiles: Change avatar menu to bubble view
BUG=
TEST=Ran on views and verified that things looked ok.
Review URL: http://codereview.chromium.org/7566050
TBR=sail@chromium.org
Review URL: http://codereview.chromium.org/7622001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96309 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 9 | ||||
-rw-r--r-- | chrome/app/theme/profile_edit.png | bin | 1209 -> 0 bytes | |||
-rw-r--r-- | chrome/app/theme/profile_edit_hover.png | bin | 1214 -> 0 bytes | |||
-rw-r--r-- | chrome/app/theme/profile_edit_pressed.png | bin | 1217 -> 0 bytes | |||
-rw-r--r-- | chrome/app/theme/profile_selected.png | bin | 1353 -> 0 bytes | |||
-rw-r--r-- | chrome/app/theme/theme_resources.grd | 4 | ||||
-rw-r--r-- | chrome/browser/profiles/avatar_menu_model.cc | 4 | ||||
-rw-r--r-- | chrome/browser/profiles/avatar_menu_model.h | 2 | ||||
-rw-r--r-- | chrome/browser/profiles/avatar_menu_model_observer.h | 4 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu.cc | 199 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu.h | 38 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu_bubble_view.cc | 264 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu_bubble_view.h | 62 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu_button.cc | 20 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 8 |
15 files changed, 251 insertions, 363 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index e1c9dbe..a33be09 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -8375,15 +8375,6 @@ Keep your key file in a safe place. You will need it to create new versions of y New User </message> </if> - <message name="IDS_PROFILES_CREATE_NEW_PROFILE_LINK" desc="Link in the avatar menu bubble view to create a new profile."> - New user - </message> - <message name="IDS_PROFILES_CUSTOMIZE_PROFILE_ACCESSIBLE_NAME" desc="Description of the customize profile button. This is used for accessibility."> - Customize user: <ph name="PROFILE_NAME">$1<ex>First user</ex></ph> - </message> - <message name="IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME" desc="Description of the switch to profile button. This is used for accessibility."> - Switch to user: <ph name="PROFILE_NAME">$1<ex>First user</ex></ph> - </message> <if expr="not pp_ifdef('use_titlecase')"> <message name="IDS_PROFILES_MENU" desc="The title of the profiles submenu in the wrench menu."> Users diff --git a/chrome/app/theme/profile_edit.png b/chrome/app/theme/profile_edit.png Binary files differdeleted file mode 100644 index 6001ba4..0000000 --- a/chrome/app/theme/profile_edit.png +++ /dev/null diff --git a/chrome/app/theme/profile_edit_hover.png b/chrome/app/theme/profile_edit_hover.png Binary files differdeleted file mode 100644 index 20d66d8..0000000 --- a/chrome/app/theme/profile_edit_hover.png +++ /dev/null diff --git a/chrome/app/theme/profile_edit_pressed.png b/chrome/app/theme/profile_edit_pressed.png Binary files differdeleted file mode 100644 index 782f3d5..0000000 --- a/chrome/app/theme/profile_edit_pressed.png +++ /dev/null diff --git a/chrome/app/theme/profile_selected.png b/chrome/app/theme/profile_selected.png Binary files differdeleted file mode 100644 index ca02353..0000000 --- a/chrome/app/theme/profile_selected.png +++ /dev/null diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 8ce14bd..5c3fd0f 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -232,10 +232,6 @@ <include name="IDR_PROFILE_AVATAR_23" file="profile_avatar_margarita.png" type="BINDATA" /> <include name="IDR_PROFILE_AVATAR_24" file="profile_avatar_note.png" type="BINDATA" /> <include name="IDR_PROFILE_AVATAR_25" file="profile_avatar_sun_cloud.png" type="BINDATA" /> - <include name="IDR_PROFILE_EDIT" file="profile_edit.png" type="BINDATA" /> - <include name="IDR_PROFILE_EDIT_HOVER" file="profile_edit_hover.png" type="BINDATA" /> - <include name="IDR_PROFILE_EDIT_PRESSED" file="profile_edit_pressed.png" type="BINDATA" /> - <include name="IDR_PROFILE_SELECTED" file="profile_selected.png" type="BINDATA" /> <include name="IDR_RESTORE_BUTTON_MASK" file="restore_button_mask.png" type="BINDATA" /> <include name="IDR_SAD_TAB" file="sadtab.png" type="BINDATA" /> <include name="IDR_SAFEBROWSING_WARNING" file="safebrowsing_warning.png" type="BINDATA" /> diff --git a/chrome/browser/profiles/avatar_menu_model.cc b/chrome/browser/profiles/avatar_menu_model.cc index 408728d..512c1ce 100644 --- a/chrome/browser/profiles/avatar_menu_model.cc +++ b/chrome/browser/profiles/avatar_menu_model.cc @@ -70,7 +70,7 @@ AvatarMenuModel::Item::Item(size_t model_index, const gfx::Image& icon) AvatarMenuModel::Item::~Item() { } -void AvatarMenuModel::SwitchToProfile(size_t index) { +void AvatarMenuModel::SwichToProfile(size_t index) { const Item& item = GetItemAt(index); FilePath path = profile_info_->GetPathOfProfileAtIndex(item.model_index); @@ -119,7 +119,7 @@ void AvatarMenuModel::RebuildMenu() { items_.push_back(item); } - observer_->OnAvatarMenuModelChanged(this); + observer_->OnAvatarMenuModelChanged(); } void AvatarMenuModel::ClearMenu() { diff --git a/chrome/browser/profiles/avatar_menu_model.h b/chrome/browser/profiles/avatar_menu_model.h index b371f2b..7de6379 100644 --- a/chrome/browser/profiles/avatar_menu_model.h +++ b/chrome/browser/profiles/avatar_menu_model.h @@ -59,7 +59,7 @@ class AvatarMenuModel : public NotificationObserver { // model: // Opens a Browser with the specified profile in response to the user // selecting an item. - void SwitchToProfile(size_t index); + void SwichToProfile(size_t index); // Opens the profile settings in response to clicking the edit button next to // an item. void EditProfile(size_t index); diff --git a/chrome/browser/profiles/avatar_menu_model_observer.h b/chrome/browser/profiles/avatar_menu_model_observer.h index e6586c3..0643622 100644 --- a/chrome/browser/profiles/avatar_menu_model_observer.h +++ b/chrome/browser/profiles/avatar_menu_model_observer.h @@ -5,15 +5,13 @@ #ifndef CHROME_BROWSER_PROFILES_AVATAR_MENU_MODEL_OBSERVER_H_ #define CHROME_BROWSER_PROFILES_AVATAR_MENU_MODEL_OBSERVER_H_ -class AvatarMenuModel; - // Delegate interface for objects that want to be notified when the // AvatarMenuModel changes. class AvatarMenuModelObserver { public: virtual ~AvatarMenuModelObserver() {} - virtual void OnAvatarMenuModelChanged(AvatarMenuModel* avatar_menu_model) = 0; + virtual void OnAvatarMenuModelChanged() = 0; }; #endif // CHROME_BROWSER_PROFILES_AVATAR_MENU_MODEL_OBSERVER_H_ diff --git a/chrome/browser/ui/views/avatar_menu.cc b/chrome/browser/ui/views/avatar_menu.cc new file mode 100644 index 0000000..8fdcb24 --- /dev/null +++ b/chrome/browser/ui/views/avatar_menu.cc @@ -0,0 +1,199 @@ +// Copyright (c) 2011 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.h" + +#include "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_info_cache.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/profile_menu_model.h" +#include "grit/chromium_strings.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/image.h" +#include "views/controls/button/image_button.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/menu_item_view.h" +#include "views/controls/menu/submenu_view.h" +#include "views/widget/widget.h" + +namespace { + +const int kCellWidth = 38; +const int kCellHeight = 31; +const int kCellPaddingX = 5; +const int kCellPaddingY = 5; +const int kGridMaxCol = 3; + +static inline int Round(double x) { + return static_cast<int>(x + 0.5); +} + +// This is an button that scales its image to fit its bounds. +class ScaledImageButton : public views::ImageButton { + public: + explicit ScaledImageButton(views::ButtonListener* listener); + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(ScaledImageButton); +}; + +// A view that displays avatar icons in a grid. +class AvatarIconGridView : public views::View, public views::ButtonListener { + public: + AvatarIconGridView(Profile* profile, views::MenuItemView* menu); + virtual ~AvatarIconGridView(); + + virtual void Layout() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void ButtonPressed(views::Button* sender, + const views::Event& event) OVERRIDE; + + private: + // Sets the profile's avatar icon to the icon at the given index. + void SetAvatarIconToIndex(int icon_index); + + typedef std::map<int, views::View*> IconIndexToButtonMap; + IconIndexToButtonMap icon_index_to_button_map_; + Profile* profile_; + views::MenuItemView* menu_; + + DISALLOW_COPY_AND_ASSIGN(AvatarIconGridView); +}; + +ScaledImageButton::ScaledImageButton(views::ButtonListener* listener) + : views::ImageButton(listener) { +} + +void ScaledImageButton::OnPaint(gfx::Canvas* canvas) { + if (state() == views::CustomButton::BS_HOT) + canvas->FillRectInt(SkColorSetARGB(20, 0, 0, 0), 0, 0, width(), height()); + else if (state() == views::CustomButton::BS_PUSHED) + canvas->FillRectInt(SkColorSetARGB(40, 0, 0, 0), 0, 0, width(), height()); + + const SkBitmap& icon = GetImageToPaint(); + if (icon.isNull()) + return; + + int dst_width; + int dst_height; + if (icon.width() > icon.height()) { + dst_width = std::min(width(), icon.width()); + float scale = static_cast<float>(dst_width) / + static_cast<float>(icon.width()); + dst_height = Round(icon.height() * scale); + } else { + dst_height = std::min(height(), icon.height()); + float scale = static_cast<float>(dst_height) / + static_cast<float>(icon.height()); + dst_width = Round(icon.width() * scale); + } + int dst_x = (width() - dst_width) / 2; + int dst_y = (height() - dst_height) / 2; + canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), + dst_x, dst_y, dst_width, dst_height, false); +} + +AvatarIconGridView::AvatarIconGridView(Profile* profile, + views::MenuItemView* menu) + : profile_(profile), + menu_(menu) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + for (size_t i = 0; i < ProfileInfoCache::GetDefaultAvatarIconCount(); ++i) { + int resource_id = + ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(i); + views::ImageButton* button = new ScaledImageButton(this); + button->SetImage(views::CustomButton::BS_NORMAL, + rb.GetImageNamed(resource_id)); + button->SetAccessibleName( + l10n_util::GetStringFUTF16Int(IDS_NUMBERED_AVATAR_NAME, + static_cast<int>(i + 1))); + AddChildView(button); + icon_index_to_button_map_[i] = button; + } +} + +AvatarIconGridView::~AvatarIconGridView() { +} + +void AvatarIconGridView::Layout() { + for (IconIndexToButtonMap::const_iterator it = + icon_index_to_button_map_.begin(); + it != icon_index_to_button_map_.end(); ++it) { + views::View* view = it->second; + int icon_index = it->first; + int col = icon_index % kGridMaxCol; + int row = icon_index / kGridMaxCol; + int x = col * kCellWidth + col * kCellPaddingX; + int y = row * kCellHeight + row * kCellPaddingY; + view->SetBounds(x, y, kCellWidth, kCellHeight); + } +} + +gfx::Size AvatarIconGridView::GetPreferredSize() { + int cols = kGridMaxCol; + int rows = ProfileInfoCache::GetDefaultAvatarIconCount() / cols; + if (ProfileInfoCache::GetDefaultAvatarIconCount() % cols != 0) + rows++; + return gfx::Size(cols * kCellWidth + (cols - 1) * kCellPaddingX, + rows * kCellHeight + (rows - 1) * kCellPaddingY); +} + +void AvatarIconGridView::ButtonPressed(views::Button* sender, + const views::Event& event) { + for (IconIndexToButtonMap::const_iterator it = + icon_index_to_button_map_.begin(); + it != icon_index_to_button_map_.end(); ++it) { + if (it->second == sender) { + SetAvatarIconToIndex(it->first); + menu_->Cancel(); + return; + } + } + NOTREACHED(); +} + +void AvatarIconGridView::SetAvatarIconToIndex(int icon_index) { + ProfileInfoCache& cache = + g_browser_process->profile_manager()->GetProfileInfoCache(); + size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath()); + cache.SetAvatarIconOfProfileAtIndex(profile_index, icon_index); +} + +} // namespace + +AvatarMenu::AvatarMenu(ui::MenuModel* model, Profile* profile) + : MenuModelAdapter(model), + profile_(profile) { + root_.reset(new views::MenuItemView(this)); + BuildMenu(root_.get()); + views::MenuItemView* item = + root_->GetMenuItemByID(ProfileMenuModel::COMMAND_CHOOSE_AVATAR_ICON); + item->AddChildView(new AvatarIconGridView(profile_, root_.get())); +} + +AvatarMenu::~AvatarMenu() { +} + +void AvatarMenu::RunMenu(views::MenuButton* host) { + // Up the ref count while the menu is displaying. This way if the window is + // deleted while we're running we won't prematurely delete the menu. + // TODO(sky): fix this, the menu should really take ownership of the menu + // (57890). + scoped_refptr<AvatarMenu> dont_delete_while_running(this); + gfx::Point screen_loc; + views::View::ConvertPointToScreen(host, &screen_loc); + gfx::Rect bounds(screen_loc, host->size()); + root_->RunMenuAt(host->GetWidget(), host, bounds, + views::MenuItemView::TOPLEFT, true); +} diff --git a/chrome/browser/ui/views/avatar_menu.h b/chrome/browser/ui/views/avatar_menu.h new file mode 100644 index 0000000..38d4c6a --- /dev/null +++ b/chrome/browser/ui/views/avatar_menu.h @@ -0,0 +1,38 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_H_ +#define CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_H_ +#pragma once + +#include <map> +#include <utility> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "ui/base/models/menu_model.h" +#include "views/controls/menu/menu_model_adapter.h" + +class Profile; + +class AvatarMenu : public base::RefCounted<AvatarMenu>, + public views::MenuModelAdapter { + public: + AvatarMenu(ui::MenuModel* model, Profile* profile); + virtual ~AvatarMenu(); + + // Shows the menu relative to the specified view. + void RunMenu(views::MenuButton* host); + + private: + // The views menu. + scoped_ptr<views::MenuItemView> root_; + + // Profile the menu is being shown for. + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(AvatarMenu); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_H_ 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 1ce7ce3..0000000 --- a/chrome/browser/ui/views/avatar_menu_bubble_view.cc +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2011 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 "base/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/profiles/avatar_menu_model.h" -#include "chrome/browser/profiles/profile_info_cache.h" -#include "chrome/browser/profiles/profile_manager.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/font.h" -#include "ui/gfx/image/image.h" -#include "views/controls/button/image_button.h" - -namespace { - -const int kBubbleViewMinWidth = 175; -const int kBubbleViewMaxWidth = 800; -const int kItemHeight = 32; -const int kItemMarginY = 8; -const int kIconWidth = 38; -const int kIconMarginX = 6; -const int kEditProfileButtonMarginX = 8; - -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); -} - -class ProfileItemView : public views::CustomButton { - public: - ProfileItemView(const AvatarMenuModel::Item& item, - views::ButtonListener* listener) - : views::CustomButton(listener), - item_(item) { - } - - virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - // Draw the profile icon on the left. - SkBitmap profile_icon = item_.icon; - gfx::Rect profile_icon_rect = GetCenteredAndScaledRect( - profile_icon.width(), profile_icon.height(), - 0, 0, kIconWidth, height()); - canvas->DrawBitmapInt(profile_icon, 0, 0, profile_icon.width(), - profile_icon.height(), profile_icon_rect.x(), - profile_icon_rect.y(), profile_icon_rect.width(), - profile_icon_rect.height(), false); - - // If this profile is selected then draw a check mark on the bottom right - // of the profile icon. - if (item_.active) { - SkBitmap check_icon = rb.GetImageNamed(IDR_PROFILE_SELECTED); - int y = profile_icon_rect.bottom() - check_icon.height(); - int x = profile_icon_rect.right() - check_icon.width() + 2; - canvas->DrawBitmapInt(check_icon, 0, 0, check_icon.width(), - check_icon.height(), x, y, check_icon.width(), - check_icon.height(), false); - } - - // Draw the profile name to the right of the profile icon. - int name_x = profile_icon_rect.right() + kIconMarginX; - canvas->DrawStringInt(item_.name, rb.GetFont(ResourceBundle::BaseFont), - GetNameColor(), name_x, 0, width() - name_x, - height()); - } - - virtual gfx::Size GetPreferredSize() OVERRIDE { - gfx::Font font = ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont); - int title_width = font.GetStringWidth(item_.name); - return gfx::Size(kIconWidth + kIconMarginX + title_width, kItemHeight); - } - - private: - SkColor GetNameColor() { - bool normal = state() != views::CustomButton::BS_PUSHED && - state() != views::CustomButton::BS_HOT; - if (item_.active) - return normal ? SkColorSetRGB(30, 30, 30) : SkColorSetRGB(0, 0, 0); - return normal ? SkColorSetRGB(128, 128, 128) : SkColorSetRGB(64, 64, 64); - } - - AvatarMenuModel::Item item_; -}; - -} // namespace - -class EditProfileButton : public views::ImageButton { - public: - EditProfileButton(size_t profile_index, views::ButtonListener* listener) - : views::ImageButton(listener), - profile_index_(profile_index) { - } - - size_t profile_index() { - return profile_index_; - } - - private: - size_t profile_index_; -}; - -AvatarMenuBubbleView::AvatarMenuBubbleView(Browser* browser) - : add_profile_link_(NULL), - browser_(browser), - edit_profile_button_(NULL) { - avatar_menu_model_.reset(new AvatarMenuModel( - &g_browser_process->profile_manager()->GetProfileInfoCache(), - this, browser_)); -} - -AvatarMenuBubbleView::~AvatarMenuBubbleView() { -} - -gfx::Size AvatarMenuBubbleView::GetPreferredSize() { - int max_width = 0; - int total_height = 0; - for (size_t i = 0; i < item_views_.size(); ++i) { - gfx::Size size = item_views_[i]->GetPreferredSize(); - if (i == edit_profile_button_->profile_index()) { - size.set_width(size.width() + - edit_profile_button_->GetPreferredSize().width() + - kEditProfileButtonMarginX); - } - - max_width = std::max(max_width, size.width()); - total_height += size.height() + kItemMarginY; - } - - gfx::Size add_profile_size = add_profile_link_->GetPreferredSize(); - max_width = std::max(max_width, - add_profile_size.width() + kIconWidth + kIconMarginX); - total_height += add_profile_link_->GetPreferredSize().height(); - - int total_width = std::min(std::max(max_width, kBubbleViewMinWidth), - kBubbleViewMaxWidth); - return gfx::Size(total_width, total_height); -} - -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(); - - if (i == edit_profile_button_->profile_index()) { - gfx::Size edit_size = edit_profile_button_->GetPreferredSize(); - edit_profile_button_->SetBounds(width() - edit_size.width(), y, - edit_size.width(), item_height); - item_width -= edit_size.width() + kEditProfileButtonMarginX; - } - - item_view->SetBounds(0, y, item_width, item_height); - y += item_height + kItemMarginY; - } - - add_profile_link_->SetBounds(kIconWidth + kIconMarginX, y, width(), - add_profile_link_->GetPreferredSize().height()); -} - -void AvatarMenuBubbleView::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == edit_profile_button_) { - avatar_menu_model_->EditProfile(edit_profile_button_->profile_index()); - } else { - for (size_t i = 0; i < item_views_.size(); ++i) { - if (sender == item_views_[i]) { - avatar_menu_model_->SwitchToProfile(i); - break; - } - } - } -} - -void AvatarMenuBubbleView::LinkClicked(views::Link* source, int event_flags) { - DCHECK_EQ(source, add_profile_link_); - avatar_menu_model_->AddNewProfile(); -} - -void AvatarMenuBubbleView::BubbleClosing(Bubble* bubble, - bool closed_by_escape) { -} - -bool AvatarMenuBubbleView::CloseOnEscape() { - return true; -} - -bool AvatarMenuBubbleView::FadeInOnShow() { - return false; -} - -void AvatarMenuBubbleView::OnAvatarMenuModelChanged( - AvatarMenuModel* avatar_menu_model) { - // Unset all our child view references and call RemoveAllChildViews() which - // will actually delete them. - add_profile_link_ = NULL; - edit_profile_button_ = NULL; - item_views_.clear(); - RemoveAllChildViews(true); - - for (size_t i = 0; i < avatar_menu_model->GetNumberOfItems(); ++i) { - const AvatarMenuModel::Item& item = avatar_menu_model->GetItemAt(i); - ProfileItemView* item_view = new ProfileItemView(item, this); - item_view->SetAccessibleName(l10n_util::GetStringFUTF16( - IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME, item.name)); - AddChildView(item_view); - item_views_.push_back(item_view); - - if (item.active) { - DCHECK(!edit_profile_button_); - edit_profile_button_ = new EditProfileButton(i, this); - edit_profile_button_->SetAccessibleName(l10n_util::GetStringFUTF16( - IDS_PROFILES_CUSTOMIZE_PROFILE_ACCESSIBLE_NAME, item.name)); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - edit_profile_button_->SetImage(views::CustomButton::BS_NORMAL, - rb.GetImageNamed(IDR_PROFILE_EDIT)); - edit_profile_button_->SetImage(views::CustomButton::BS_HOT, - rb.GetImageNamed(IDR_PROFILE_EDIT_HOVER)); - edit_profile_button_->SetImage(views::CustomButton::BS_PUSHED, - rb.GetImageNamed(IDR_PROFILE_EDIT_PRESSED)); - edit_profile_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); - AddChildView(edit_profile_button_); - } - } - - add_profile_link_ = new views::Link(UTF16ToWide( - l10n_util::GetStringUTF16(IDS_PROFILES_CREATE_NEW_PROFILE_LINK))); - add_profile_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - add_profile_link_->SetNormalColor(SkColorSetRGB(0, 0x79, 0xda)); - AddChildView(add_profile_link_); - - PreferredSizeChanged(); -} diff --git a/chrome/browser/ui/views/avatar_menu_bubble_view.h b/chrome/browser/ui/views/avatar_menu_bubble_view.h deleted file mode 100644 index 752098c..0000000 --- a/chrome/browser/ui/views/avatar_menu_bubble_view.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_BUBBLE_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_BUBBLE_VIEW_H_ -#pragma once - -#include <vector> - -#include "chrome/browser/profiles/avatar_menu_model_observer.h" -#include "chrome/browser/ui/views/bubble/bubble.h" -#include "views/controls/button/custom_button.h" -#include "views/controls/link.h" -#include "views/controls/link_listener.h" - -class AvatarMenuModel; -class Browser; -class EditProfileButton; - -// This bubble view is displayed when the user clicks on the avatar button. -// It displays a list of profiles and allows users to switch between profiles. -class AvatarMenuBubbleView : public views::View, - public views::ButtonListener, - public views::LinkListener, - public BubbleDelegate, - public AvatarMenuModelObserver { - public: - explicit AvatarMenuBubbleView(Browser* browser); - ~AvatarMenuBubbleView(); - - // views::View implementation. - virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual void Layout() OVERRIDE; - - // views::ButtonListener implementation. - virtual void ButtonPressed(views::Button* sender, - const views::Event& event) OVERRIDE; - - // views::LinkListener implementation. - virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; - - // BubbleDelegate implementation. - virtual void BubbleClosing(Bubble* bubble, bool closed_by_escape) OVERRIDE; - virtual bool CloseOnEscape() OVERRIDE; - virtual bool FadeInOnShow() OVERRIDE; - - // AvatarMenuModelObserver implementation. - virtual void OnAvatarMenuModelChanged( - AvatarMenuModel* avatar_menu_model) OVERRIDE; - - private: - views::Link* add_profile_link_; - scoped_ptr<AvatarMenuModel> avatar_menu_model_; - Browser* browser_; - EditProfileButton* edit_profile_button_; - std::vector<views::CustomButton*> item_views_; - - DISALLOW_COPY_AND_ASSIGN(AvatarMenuBubbleView); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_BUBBLE_VIEW_H_ diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc index 7b99ee0..efe86a8 100644 --- a/chrome/browser/ui/views/avatar_menu_button.cc +++ b/chrome/browser/ui/views/avatar_menu_button.cc @@ -6,8 +6,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/profile_menu_model.h" -#include "chrome/browser/ui/views/avatar_menu_bubble_view.h" -#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/avatar_menu.h" #include "ui/gfx/canvas_skia.h" #include "views/widget/widget.h" @@ -63,16 +62,9 @@ void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { if (!has_menu_) return; - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( - browser_->window()->GetNativeHandle()); - - gfx::Point origin; - views::View::ConvertPointToScreen(this, &origin); - gfx::Rect bounds(0, 0, width(), height()); - bounds.set_origin(origin); - - AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_); - // Bubble::Show() takes ownership of the view. - Bubble::Show(browser_view->GetWidget(), bounds, BubbleBorder::TOP_LEFT, - bubble_view, bubble_view); + menu_model_.reset(new ProfileMenuModel(browser_)); + // The avatar menu will automatically delete itself when done. + AvatarMenu* avatar_menu = + new AvatarMenu(menu_model_.get(), browser_->profile()); + avatar_menu->RunMenu(this); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 79d5a3b..0a1db25 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3081,8 +3081,8 @@ 'browser/ui/views/autocomplete/autocomplete_result_view_model.h', 'browser/ui/views/autocomplete/touch_autocomplete_popup_contents_view.cc', 'browser/ui/views/autocomplete/touch_autocomplete_popup_contents_view.h', - 'browser/ui/views/avatar_menu_bubble_view.cc', - 'browser/ui/views/avatar_menu_bubble_view.h', + 'browser/ui/views/avatar_menu.cc', + 'browser/ui/views/avatar_menu.h', 'browser/ui/views/avatar_menu_button.cc', 'browser/ui/views/avatar_menu_button.h', 'browser/ui/views/bookmarks/bookmark_bar_instructions_view.cc', @@ -4342,8 +4342,8 @@ ['include', '^browser/ui/views/autocomplete/autocomplete_result_view_model.h'], ['include', '^browser/ui/views/autocomplete/touch_autocomplete_popup_contents_view.cc'], ['include', '^browser/ui/views/autocomplete/touch_autocomplete_popup_contents_view.h'], - ['include', '^browser/ui/views/avatar_menu_bubble_view.cc'], - ['include', '^browser/ui/views/avatar_menu_bubble_view.h'], + ['include', '^browser/ui/views/avatar_menu.cc'], + ['include', '^browser/ui/views/avatar_menu.h'], ['include', '^browser/ui/views/avatar_menu_button.cc'], ['include', '^browser/ui/views/avatar_menu_button.h'], ['include', '^browser/ui/views/bookmarks/bookmark_bar_instructions_view.cc'], |