diff options
28 files changed, 271 insertions, 642 deletions
diff --git a/chrome/app/theme/profile_tag_center_aero.png b/chrome/app/theme/profile_tag_center_aero.png Binary files differdeleted file mode 100644 index 407f9ff..0000000 --- a/chrome/app/theme/profile_tag_center_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_center_mask.png b/chrome/app/theme/profile_tag_center_mask.png Binary files differdeleted file mode 100644 index 9f8368b..0000000 --- a/chrome/app/theme/profile_tag_center_mask.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_center_opaque.png b/chrome/app/theme/profile_tag_center_opaque.png Binary files differdeleted file mode 100644 index f4c3149..0000000 --- a/chrome/app/theme/profile_tag_center_opaque.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_inactive_center_aero.png b/chrome/app/theme/profile_tag_inactive_center_aero.png Binary files differdeleted file mode 100644 index 09dd158..0000000 --- a/chrome/app/theme/profile_tag_inactive_center_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_inactive_left_aero.png b/chrome/app/theme/profile_tag_inactive_left_aero.png Binary files differdeleted file mode 100644 index cec460a..0000000 --- a/chrome/app/theme/profile_tag_inactive_left_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_inactive_right_aero.png b/chrome/app/theme/profile_tag_inactive_right_aero.png Binary files differdeleted file mode 100644 index 208def6a..0000000 --- a/chrome/app/theme/profile_tag_inactive_right_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_left_aero.png b/chrome/app/theme/profile_tag_left_aero.png Binary files differdeleted file mode 100644 index 206d081..0000000 --- a/chrome/app/theme/profile_tag_left_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_left_mask.png b/chrome/app/theme/profile_tag_left_mask.png Binary files differdeleted file mode 100644 index fa6a33e..0000000 --- a/chrome/app/theme/profile_tag_left_mask.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_left_opaque.png b/chrome/app/theme/profile_tag_left_opaque.png Binary files differdeleted file mode 100644 index ba6db11..0000000 --- a/chrome/app/theme/profile_tag_left_opaque.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_right_aero.png b/chrome/app/theme/profile_tag_right_aero.png Binary files differdeleted file mode 100644 index 3f26f11..0000000 --- a/chrome/app/theme/profile_tag_right_aero.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_right_mask.png b/chrome/app/theme/profile_tag_right_mask.png Binary files differdeleted file mode 100644 index c94dc28..0000000 --- a/chrome/app/theme/profile_tag_right_mask.png +++ /dev/null diff --git a/chrome/app/theme/profile_tag_right_opaque.png b/chrome/app/theme/profile_tag_right_opaque.png Binary files differdeleted file mode 100644 index c8ac3c0..0000000 --- a/chrome/app/theme/profile_tag_right_opaque.png +++ /dev/null diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 8bdc77c..db56cb4 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -215,18 +215,7 @@ <!-- NOTE: product_logo_*.* files beyond what's listed above are referenced by installer code; don't remove them unless you know what you're doing! --> - <include name="IDR_PROFILE_TAG_CENTER_AERO" file="profile_tag_center_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_LEFT_AERO" file="profile_tag_left_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_RIGHT_AERO" file="profile_tag_right_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_INACTIVE_CENTER_AERO" file="profile_tag_inactive_center_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_INACTIVE_LEFT_AERO" file="profile_tag_inactive_left_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_INACTIVE_RIGHT_AERO" file="profile_tag_inactive_right_aero.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_CENTER_THEMED" file="profile_tag_center_opaque.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_LEFT_THEMED" file="profile_tag_left_opaque.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_RIGHT_THEMED" file="profile_tag_right_opaque.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_CENTER_MASK" file="profile_tag_center_mask.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_LEFT_MASK" file="profile_tag_left_mask.png" type="BINDATA" /> - <include name="IDR_PROFILE_TAG_RIGHT_MASK" file="profile_tag_right_mask.png" type="BINDATA" /> + <include name="IDR_PROFILE_AVATAR_1" file="avatar_cupcake.png" type="BINDATA" /> <include name="IDR_RESTORE_BUTTON_MASK" file="restore_button_mask.png" type="BINDATA" /> <include name="IDR_SAD_FAVICON" file="sadfavicon.png" type="BINDATA" /> <include name="IDR_SAD_TAB" file="sadtab.png" type="BINDATA" /> diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc new file mode 100644 index 0000000..e2585ca --- /dev/null +++ b/chrome/browser/ui/views/avatar_menu_button.cc @@ -0,0 +1,71 @@ +// 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_button.h" + +#include "ui/gfx/canvas_skia.h" +#include "views/controls/menu/menu_model_adapter.h" +#include "views/window/window.h" + +// Menu should display below the image on the frame. This +// offset size depends on whether the frame is in glass or opaque mode. +const int kMenuDisplayOffset = 5; + +static inline int Round(double x) { + return static_cast<int>(floor(x + 0.5)); +} + +AvatarMenuButton::AvatarMenuButton(const std::wstring& text, + ui::MenuModel* menu_model) + : MenuButton(NULL, text, this, false), + menu_model_(menu_model) { + // In RTL mode, the avatar icon should be looking the opposite direction. + EnableCanvasFlippingForRTLUI(true); +} + +AvatarMenuButton::~AvatarMenuButton() {} + +void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { + const SkBitmap& icon = GetImageToPaint(); + if (!icon.isNull()) { + // Scale the image to fit the width of the button. + int src_width = icon.width(); + int src_x = 0; + int dst_width = std::min(src_width, width()); + int dst_x = Round((width() - dst_width) / 2.0); + + // Scale the height and maintain aspect ratio. This means that the + // icon may not fit in the view. That's ok, we just center it vertically. + float scale = + static_cast<float>(dst_width) / static_cast<float>(icon.width()); + int scaled_height = Round(height() / scale); + int src_height = std::min(scaled_height, icon.height()); + int src_y = Round((icon.height() - src_height) / 2.0); + int dst_height = src_height * scale; + int dst_y = Round((height() - dst_height) / 2.0); + + canvas->DrawBitmapInt(icon, src_x, src_y, src_width, src_height, + dst_x, dst_y, dst_width, dst_height, false); + } +} + +gfx::Size AvatarMenuButton::GetPreferredAvatarSize() { + return gfx::Size(38, 31); +} + +// views::ViewMenuDelegate implementation +void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { + if (!menu_model_.get()) + return; + + views::MenuModelAdapter menu_model_adapter(menu_model_.get()); + views::MenuItemView menu(&menu_model_adapter); + menu_model_adapter.BuildMenu(&menu); + + gfx::Point menu_point(pt.x(), pt.y() + kMenuDisplayOffset); + menu.RunMenuAt(source->GetWindow()->GetNativeWindow(), NULL, + gfx::Rect(pt, gfx::Size(0, 0)), + views::MenuItemView::TOPRIGHT, + true); +} diff --git a/chrome/browser/ui/views/avatar_menu_button.h b/chrome/browser/ui/views/avatar_menu_button.h new file mode 100644 index 0000000..1675e59 --- /dev/null +++ b/chrome/browser/ui/views/avatar_menu_button.h @@ -0,0 +1,47 @@ +// 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_BUTTON_H_ +#define CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_BUTTON_H_ +#pragma once + +#include <string> + +#include "base/compiler_specific.h" +#include "ui/base/models/simple_menu_model.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/view_menu_delegate.h" + +namespace gfx { +class Canvas; +} + +// AvatarMenuButton +// +// A button used to show either the incognito avatar or the profile avatar. +// The button can optionally have a menu attached to it. + +class AvatarMenuButton : public views::MenuButton, + public views::ViewMenuDelegate { + public: + // Creates a new button. The object will take ownership of the menu model. + AvatarMenuButton(const std::wstring& text, ui::MenuModel* menu_model); + + virtual ~AvatarMenuButton(); + + // views::MenuButton + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + + static gfx::Size GetPreferredAvatarSize(); + + private: + // views::ViewMenuDelegate + virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE; + + scoped_ptr<ui::MenuModel> menu_model_; + + DISALLOW_COPY_AND_ASSIGN(AvatarMenuButton); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_AVATAR_MENU_BUTTON_H_ diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index a0c2f30..3c4b856 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -464,8 +464,10 @@ bool BrowserView::IsOffTheRecord() const { return browser_->profile()->IsOffTheRecord(); } -bool BrowserView::ShouldShowOffTheRecordAvatar() const { - return IsOffTheRecord() && IsBrowserTypeNormal(); +bool BrowserView::ShouldShowAvatar() const { + return IsBrowserTypeNormal() && + (IsOffTheRecord() || + CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)); } bool BrowserView::AcceleratorPressed(const views::Accelerator& accelerator) { diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index f45afeb..d61522a 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -165,9 +165,8 @@ class BrowserView : public BrowserBubbleHost, // incognito. bool IsOffTheRecord() const; - // Returns true if the non-client view should render the Incognito - // avatar icon if the window is incognito. - virtual bool ShouldShowOffTheRecordAvatar() const; + // Returns true if the non-client view should render an avatar icon. + virtual bool ShouldShowAvatar() const; // Handle the specified |accelerator| being pressed. virtual bool AcceleratorPressed(const views::Accelerator& accelerator); diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc index fb16075..f2e26c9 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc @@ -11,9 +11,9 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/ui/profile_menu_model.h" +#include "chrome/browser/ui/views/avatar_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/profile_menu_button.h" -#include "chrome/browser/ui/views/profile_tag_view.h" #include "chrome/browser/ui/views/tabs/side_tab_strip.h" #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" @@ -46,13 +46,13 @@ const int kNonClientRestoredExtraThickness = 11; // In the window corners, the resize areas don't actually expand bigger, but the // 16 px at the end of the top and bottom edges triggers diagonal resizing. const int kResizeAreaCornerSize = 16; -// The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the +// The avatar ends 2 px above the bottom of the tabstrip (which, given the // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the // user). -const int kOTRBottomSpacing = 2; -// There are 2 px on each side of the OTR avatar (between the frame border and +const int kAvatarBottomSpacing = 2; +// There are 2 px on each side of the avatar (between the frame border and // it on the left, and between it and the tabstrip on the right). -const int kOTRSideSpacing = 2; +const int kAvatarSideSpacing = 2; // The content left/right images have a shadow built into them. const int kContentEdgeShadowThickness = 2; // The top 1 px of the tabstrip is shadow; in maximized mode we push this off @@ -66,12 +66,6 @@ const int kNewTabCaptionRestoredSpacing = 5; // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid // looking too cluttered. const int kNewTabCaptionMaximizedSpacing = 16; -// Y position for profile button inside the frame. -const int kProfileButtonYPosition = 2; -// Y position for profile tag inside the frame. -const int kProfileTagYPosition = 1; -// Offset y position of profile button and tag by this amount when maximized. -const int kProfileElementMaximizedYOffset = 6; } /////////////////////////////////////////////////////////////////////////////// @@ -86,18 +80,29 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, throbber_frame_(0) { if (browser_view_->ShouldShowWindowIcon()) InitThrobberIcons(); - // If multi-profile is enabled set up profile button and login notifications. + + if (browser_view_->ShouldShowAvatar()) { + ui::MenuModel* menu_model = browser_view_->IsOffTheRecord() ? + NULL : new ProfileMenuModel; + // AvatarMenuButton takes ownership of |menu_model|. + avatar_button_.reset(new AvatarMenuButton(std::wstring(), menu_model)); + AddChildView(avatar_button_.get()); + + if (browser_view_->IsOffTheRecord()) { + avatar_button_->SetIcon(browser_view_->GetOTRAvatarIcon()); + } else { + // TODO(sail) Get the avatar icon assigned to this profile. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + avatar_button_->SetIcon(*rb.GetBitmapNamed(IDR_PROFILE_AVATAR_1)); + // TODO(sail) Also need to call SetHoverIcon() and SetPushedIcon(). + } + } + + // If multi-profile is enabled set up login notifications. const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); if (browser_command_line.HasSwitch(switches::kMultiProfiles) && - !browser_view->ShouldShowOffTheRecordAvatar()) { + !browser_view->IsOffTheRecord()) { RegisterLoginNotifications(); - profile_button_.reset(new ProfileMenuButton(std::wstring(), - browser_view_->browser()->profile())); - profile_button_->SetVisible(false); - profile_tag_.reset(new ProfileTagView(frame_, profile_button_.get())); - profile_tag_->SetVisible(false); - AddChildView(profile_tag_.get()); - AddChildView(profile_button_.get()); } } @@ -117,8 +122,8 @@ gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( } int minimize_button_offset = std::min(frame_->GetMinimizeButtonOffset(), width()); - int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? - (otr_avatar_bounds_.right() + kOTRSideSpacing) : + int tabstrip_x = browser_view_->ShouldShowAvatar() ? + (avatar_bounds_.right() + kAvatarSideSpacing) : NonClientBorderThickness(); // In RTL languages, we have moved an avatar icon left by the size of window // controls to prevent it from being rendered over them. So, we use its x @@ -126,15 +131,11 @@ gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( // a tab strip until the left end of this window without considering the size // of window controls in RTL languages. if (base::i18n::IsRTL()) { - if (!browser_view_->ShouldShowOffTheRecordAvatar() && frame_->IsMaximized()) - tabstrip_x += otr_avatar_bounds_.x(); + if (!browser_view_->ShouldShowAvatar() && frame_->IsMaximized()) + tabstrip_x += avatar_bounds_.x(); minimize_button_offset = width(); } - int maximized_spacing = - kNewTabCaptionMaximizedSpacing + - (show_profile_button() && profile_button_->IsVisible() ? - profile_button_->GetPreferredSize().width() + - ProfileMenuButton::kProfileTagHorizontalSpacing : 0); + int maximized_spacing = kNewTabCaptionMaximizedSpacing; int tabstrip_width = minimize_button_offset - tabstrip_x - (frame_->IsMaximized() ? maximized_spacing : kNewTabCaptionRestoredSpacing); @@ -197,6 +198,11 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { if (!browser_view_->IsBrowserTypeNormal() || !bounds().Contains(point)) return HTNOWHERE; + // See if the point is within the avatar menu button. + if (avatar_button_.get() && + avatar_button_->GetMirroredBounds().Contains(point)) + return HTCLIENT; + int frame_component = frame_->client_view()->NonClientHitTest(point); // See if we're in the sysmenu region. We still have to check the tabstrip @@ -210,11 +216,6 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { if (frame_component != HTNOWHERE) return frame_component; - // See if the point is within the profile menu button. - if (show_profile_button() && profile_button_->IsVisible() && - profile_button_->GetMirroredBounds().Contains(point)) - return HTCLIENT; - int frame_border_thickness = FrameBorderThickness(); int window_component = GetHTComponentForFrame(point, frame_border_thickness, nonclient_border_thickness, frame_border_thickness, @@ -232,24 +233,18 @@ void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { return; // Nothing is visible, so don't bother to paint. PaintToolbarBackground(canvas); - if (browser_view_->ShouldShowOffTheRecordAvatar()) - PaintOTRAvatar(canvas); if (!frame_->IsMaximized()) PaintRestoredClientEdge(canvas); } void GlassBrowserFrameView::Layout() { - LayoutOTRAvatar(); + LayoutAvatar(); LayoutClientView(); - LayoutProfileTag(); } bool GlassBrowserFrameView::HitTest(const gfx::Point& l) const { - // The ProfileMenuButton intrudes into the client area when the window is - // maximized. - return (frame_->IsMaximized() && show_profile_button() && - profile_button_->IsVisible() && - profile_button_->GetMirroredBounds().Contains(l)) || + return (avatar_button_.get() && + avatar_button_->GetMirroredBounds().Contains(l)) || !frame_->client_view()->bounds().Contains(l); } @@ -382,27 +377,6 @@ void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { w - (2 * kClientEdgeThickness), kClientEdgeThickness); } -void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { - // In RTL mode, the avatar icon should be looking the opposite direction. - canvas->Save(); - if (base::i18n::IsRTL()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int w = otr_avatar_bounds_.width(); - int h = otr_avatar_bounds_.height(); - canvas->DrawBitmapInt(otr_avatar_icon, 0, - // Bias the rounding to select a region that's lower rather than higher, - // as the shadows at the image top mean the apparent center is below the - // real center. - ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, - otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); - - canvas->Restore(); -} - void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { ui::ThemeProvider* tp = GetThemeProvider(); gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); @@ -453,81 +427,41 @@ void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { client_area_bottom + kClientEdgeThickness - client_area_top); } -void GlassBrowserFrameView::LayoutOTRAvatar() { - int otr_x = NonClientBorderThickness() + kOTRSideSpacing; +void GlassBrowserFrameView::LayoutAvatar() { + int avatar_x = NonClientBorderThickness() + kAvatarSideSpacing; // Move this avatar icon by the size of window controls to prevent it from // being rendered over them in RTL languages. This code also needs to adjust // the width of a tab strip to avoid decreasing this size twice. (See the // comment in GetBoundsForTabStrip().) if (base::i18n::IsRTL()) - otr_x += width() - frame_->GetMinimizeButtonOffset(); + avatar_x += width() - frame_->GetMinimizeButtonOffset(); + + gfx::Size preferred_size = AvatarMenuButton::GetPreferredAvatarSize(); - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int otr_bottom, otr_restored_y; + int avatar_bottom, avatar_restored_y; if (browser_view_->UseVerticalTabs()) { - otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; - otr_restored_y = kFrameShadowThickness; + avatar_bottom = NonClientTopBorderHeight(false, false) - + kAvatarBottomSpacing; + avatar_restored_y = kFrameShadowThickness; } else { - otr_bottom = GetHorizontalTabStripVerticalOffset(false) + - browser_view_->GetTabStripHeight() - kOTRBottomSpacing; - otr_restored_y = otr_bottom - otr_avatar_icon.height(); + avatar_bottom = GetHorizontalTabStripVerticalOffset(false) + + browser_view_->GetTabStripHeight() - kAvatarBottomSpacing; + avatar_restored_y = avatar_bottom - preferred_size.height(); } - int otr_y = frame_->IsMaximized() ? + int avatar_y = frame_->IsMaximized() ? (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : - otr_restored_y; - otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), - browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); + avatar_restored_y; + avatar_bounds_.SetRect(avatar_x, avatar_y, preferred_size.width(), + browser_view_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); + + if (avatar_button_.get()) + avatar_button_->SetBoundsRect(avatar_bounds_); } void GlassBrowserFrameView::LayoutClientView() { client_view_bounds_ = CalculateClientAreaBounds(width(), height()); } -void GlassBrowserFrameView::LayoutProfileTag() { - if (!show_profile_button()) - return; - - string16 profile_name = UTF8ToUTF16(browser_view_->browser()->profile()-> - GetPrefs()->GetString(prefs::kGoogleServicesUsername)); - if (!profile_name.empty()) { - profile_button_->SetText(profile_name); - profile_button_->SetTextShadowColors( - ProfileMenuButton::kDefaultActiveTextShadow, - ProfileMenuButton::kDefaultInactiveTextShadow); - } else { - profile_button_->SetText(l10n_util::GetStringUTF16( - IDS_PROFILES_NOT_SIGNED_IN_MENU)); - profile_button_->SetTextShadowColors( - ProfileMenuButton::kDarkTextShadow, - ProfileMenuButton::kDefaultInactiveTextShadow); - } - - profile_button_->ClearMaxTextSize(); - profile_button_->SetVisible(true); - int x_tag = - // The x position of minimize button in the frame - frame_->GetMinimizeButtonOffset() - - // - the space between the minimize button and the profile button - ProfileMenuButton::kProfileTagHorizontalSpacing - - // - the width of the profile button - profile_button_->GetPreferredSize().width(); - int y_maximized_offset = frame_->IsMaximized() ? - kProfileElementMaximizedYOffset : 0; - profile_button_->SetBounds( - x_tag, - kProfileButtonYPosition + y_maximized_offset, - profile_button_->GetPreferredSize().width(), - profile_button_->GetPreferredSize().height()); - - profile_tag_->SetVisible(true); - profile_tag_->set_is_signed_in(!profile_name.empty()); - profile_tag_->SetBounds( - x_tag, - kProfileTagYPosition + y_maximized_offset, - profile_button_->GetPreferredSize().width(), - ProfileTagView::kProfileTagHeight); -} - gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, int height) const { if (!browser_view_->IsTabStripVisible()) @@ -592,7 +526,7 @@ void GlassBrowserFrameView::Observe(NotificationType type, DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); std::string* name = Details<std::string>(details).ptr(); if (prefs::kGoogleServicesUsername == *name) - LayoutProfileTag(); + LayoutAvatar(); } void GlassBrowserFrameView::RegisterLoginNotifications() { diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.h b/chrome/browser/ui/views/frame/glass_browser_frame_view.h index 26077f0..14ac8a4 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.h @@ -14,9 +14,7 @@ #include "views/window/non_client_view.h" class BrowserView; -class ProfileMenuButton; -class ProfileMenuModel; -class ProfileTagView; +class AvatarMenuButton; class SkBitmap; class GlassBrowserFrameView : public BrowserNonClientFrameView, @@ -66,13 +64,11 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView, // Paint various sub-components of this view. void PaintToolbarBackground(gfx::Canvas* canvas); - void PaintOTRAvatar(gfx::Canvas* canvas); void PaintRestoredClientEdge(gfx::Canvas* canvas); // Layout various sub-components of this view. - void LayoutOTRAvatar(); + void LayoutAvatar(); void LayoutClientView(); - void LayoutProfileTag(); // Returns the bounds of the client area for the specified view size. gfx::Rect CalculateClientAreaBounds(int width, int height) const; @@ -92,11 +88,8 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView, // Receive notifications when the user's Google services user name changes. void RegisterLoginNotifications(); - // Returns true if the ProfileButton has been created. - bool show_profile_button() const { return profile_button_.get() != NULL; } - - // The layout rect of the OTR avatar icon, if visible. - gfx::Rect otr_avatar_bounds_; + // The layout rect of the avatar icon, if visible. + gfx::Rect avatar_bounds_; // The frame that hosts this view. BrowserFrame* frame_; @@ -107,11 +100,9 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView, // The bounds of the ClientView. gfx::Rect client_view_bounds_; - // Menu button that displays user's name and multi-profile menu. - scoped_ptr<ProfileMenuButton> profile_button_; - - // Image tag displayed on frame beneath profile_button_. - scoped_ptr<ProfileTagView> profile_tag_; + // Menu button that displays that either the incognito icon or the profile + // icon. + scoped_ptr<AvatarMenuButton> avatar_button_; // Whether or not the window throbber is currently animating. bool throbber_running_; diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index 356775e..c3bc04b 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc @@ -10,10 +10,10 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/ui/profile_menu_model.h" +#include "chrome/browser/ui/views/avatar_menu_button.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/profile_menu_button.h" -#include "chrome/browser/ui/views/profile_tag_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar_view.h" #include "chrome/common/chrome_switches.h" @@ -74,13 +74,13 @@ const int kIconMinimumSize = 16; const int kIconTitleSpacing = 4; // There is a 5 px gap between the title text and the caption buttons. const int kTitleLogoSpacing = 5; -// The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the +// The avatar ends 2 px above the bottom of the tabstrip (which, given the // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the // user). -const int kOTRBottomSpacing = 2; -// There are 2 px on each side of the OTR avatar (between the frame border and +const int kAvatarBottomSpacing = 2; +// There are 2 px on each side of the avatar (between the frame border and // it on the left, and between it and the tabstrip on the right). -const int kOTRSideSpacing = 2; +const int kAvatarSideSpacing = 2; // The top 1 px of the tabstrip is shadow; in maximized mode we push this off // the top of the screen so the tabs appear flush against the screen edge. const int kTabstripTopShadowThickness = 1; @@ -93,13 +93,11 @@ const int kNewTabCaptionRestoredSpacing = 5; // looking too cluttered. const int kNewTabCaptionMaximizedSpacing = 16; // How far to indent the tabstrip from the left side of the screen when there -// is no OTR icon. +// is no avatar icon. const int kTabStripIndent = 1; // Inset from the top of the toolbar/tabstrip to the shadow. Used only for // vertical tabs. const int kVerticalTabBorderInset = 3; -// Y position for profile tag inside the frame. -const int kProfileTagYPosition = 1; // Converts |bounds| from |src|'s coordinate system to |dst|, and checks if // |pt| is contained within. @@ -200,18 +198,28 @@ OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, window_icon_->Update(); } - // If multi-profile is enabled set up profile button and login notifications. + if (browser_view_->ShouldShowAvatar()) { + ui::MenuModel* menu_model = browser_view_->IsOffTheRecord() ? + NULL : new ProfileMenuModel; + // AvatarMenuButton takes ownership of |menu_model|. + avatar_button_.reset(new AvatarMenuButton(std::wstring(), menu_model)); + AddChildView(avatar_button_.get()); + + if (browser_view_->IsOffTheRecord()) { + avatar_button_->SetIcon(browser_view_->GetOTRAvatarIcon()); + } else { + // TODO(sail) Get the avatar icon assigned to this profile. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + avatar_button_->SetIcon(*rb.GetBitmapNamed(IDR_PROFILE_AVATAR_1)); + // TODO(sail) Also need to call SetHoverIcon() and SetPushedIcon(). + } + } + + // If multi-profile is enabled set up login notifications. const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); if (browser_command_line.HasSwitch(switches::kMultiProfiles) && - !browser_view_->ShouldShowOffTheRecordAvatar()) { + !browser_view->IsOffTheRecord()) { RegisterLoginNotifications(); - profile_button_.reset(new ProfileMenuButton(std::wstring(), - browser_view_->browser()->profile())); - profile_button_->SetVisible(false); - profile_tag_.reset(new ProfileTagView(frame_, profile_button_.get())); - profile_tag_->SetVisible(false); - AddChildView(profile_tag_.get()); - AddChildView(profile_button_.get()); } } @@ -269,15 +277,11 @@ gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( browser_view_->height()); } - int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? - (otr_avatar_bounds_.right() + kOTRSideSpacing) : + int tabstrip_x = browser_view_->ShouldShowAvatar() ? + (avatar_bounds_.right() + kAvatarSideSpacing) : NonClientBorderThickness() + kTabStripIndent; - int maximized_spacing = - kNewTabCaptionMaximizedSpacing + - (show_profile_button() && profile_button_->IsVisible() ? - profile_button_->GetPreferredSize().width() + - ProfileMenuButton::kProfileTagHorizontalSpacing : 0); + int maximized_spacing = kNewTabCaptionMaximizedSpacing; int tabstrip_width = minimize_button_->x() - tabstrip_x - (frame_->IsMaximized() ? maximized_spacing : kNewTabCaptionRestoredSpacing); @@ -340,8 +344,12 @@ int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { if (!bounds().Contains(point)) return HTNOWHERE; - int frame_component = - frame_->client_view()->NonClientHitTest(point); + // See if the point is within the avatar menu button. + if (avatar_button_.get() && + avatar_button_->GetMirroredBounds().Contains(point)) + return HTCLIENT; + + int frame_component = frame_->client_view()->NonClientHitTest(point); // See if we're in the sysmenu region. We still have to check the tabstrip // first so that clicks in a tab don't get treated as sysmenu clicks. @@ -371,11 +379,6 @@ int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { minimize_button_->GetMirroredBounds().Contains(point)) return HTMINBUTTON; - // See if the point is within the profile menu button. - if (show_profile_button() && profile_button_->IsVisible() && - profile_button_->GetMirroredBounds().Contains(point)) - return HTCLIENT; - views::WindowDelegate* delegate = frame_->window_delegate(); if (!delegate) { LOG(WARNING) << "delegate is NULL, returning safe default."; @@ -428,8 +431,6 @@ void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) { if (browser_view_->IsToolbarVisible() || browser_view_->UseCompactNavigationBar()) PaintToolbarBackground(canvas); - if (browser_view_->ShouldShowOffTheRecordAvatar()) - PaintOTRAvatar(canvas); if (!frame_->IsMaximized()) PaintRestoredClientEdge(canvas); } @@ -437,8 +438,7 @@ void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) { void OpaqueBrowserFrameView::Layout() { LayoutWindowControls(); LayoutTitleBar(); - LayoutOTRAvatar(); - LayoutProfileTag(); + LayoutAvatar(); client_view_bounds_ = CalculateClientAreaBounds(width(), height()); } @@ -524,7 +524,7 @@ void OpaqueBrowserFrameView::Observe(NotificationType type, DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); std::string* name = Details<std::string>(details).ptr(); if (prefs::kGoogleServicesUsername == *name) - LayoutProfileTag(); + LayoutAvatar(); } /////////////////////////////////////////////////////////////////////////////// @@ -925,27 +925,6 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { w - (2 * kClientEdgeThickness), kClientEdgeThickness); } -void OpaqueBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { - // In RTL mode, the avatar icon should be looking the opposite direction. - canvas->Save(); - if (base::i18n::IsRTL()) { - canvas->TranslateInt(width(), 0); - canvas->ScaleInt(-1, 1); - } - - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int w = otr_avatar_bounds_.width(); - int h = otr_avatar_bounds_.height(); - canvas->DrawBitmapInt(otr_avatar_icon, 0, - // Bias the rounding to select a region that's lower rather than higher, - // as the shadows at the image top mean the apparent center is below the - // real center. - ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, - otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); - - canvas->Restore(); -} - void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { ui::ThemeProvider* tp = GetThemeProvider(); int client_area_top = frame_->client_view()->y(); @@ -1134,67 +1113,30 @@ void OpaqueBrowserFrameView::LayoutTitleBar() { } } -void OpaqueBrowserFrameView::LayoutOTRAvatar() { - SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); - int otr_bottom, otr_restored_y; +void OpaqueBrowserFrameView::LayoutAvatar() { + // Even though the avatar is used for both incognito and profiles we always + // use the incognito icon to layout the avatar button. + SkBitmap incognito_icon = browser_view_->GetOTRAvatarIcon(); + + int avatar_bottom, avatar_restored_y; if (browser_view_->UseVerticalTabs()) { - otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; - otr_restored_y = kFrameShadowThickness; + avatar_bottom = NonClientTopBorderHeight(false, false) - + kAvatarBottomSpacing; + avatar_restored_y = kFrameShadowThickness; } else { - otr_bottom = GetHorizontalTabStripVerticalOffset(false) + - browser_view_->GetTabStripHeight() - kOTRBottomSpacing; - otr_restored_y = otr_bottom - otr_avatar_icon.height(); + avatar_bottom = GetHorizontalTabStripVerticalOffset(false) + + browser_view_->GetTabStripHeight() - kAvatarBottomSpacing; + avatar_restored_y = avatar_bottom - incognito_icon.height(); } - int otr_y = frame_->IsMaximized() ? + int avatar_y = frame_->IsMaximized() ? (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : - otr_restored_y; - otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing, - otr_y, otr_avatar_icon.width(), - browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); -} + avatar_restored_y; + avatar_bounds_.SetRect(NonClientBorderThickness() + kAvatarSideSpacing, + avatar_y, incognito_icon.width(), + browser_view_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); -void OpaqueBrowserFrameView::LayoutProfileTag() { - if (!show_profile_button()) - return; - - string16 profile_name = UTF8ToUTF16(browser_view_->browser()->profile()-> - GetPrefs()->GetString(prefs::kGoogleServicesUsername)); - if (!profile_name.empty()) { - profile_button_->SetText(UTF16ToWideHack(profile_name)); - } else { - profile_button_->SetText(UTF16ToWideHack(l10n_util::GetStringUTF16( - IDS_PROFILES_NOT_SIGNED_IN_MENU))); - } - profile_button_->SetTextShadowColors(ProfileMenuButton::kDarkTextShadow, - ProfileMenuButton::kDarkTextShadow); - profile_button_->ClearMaxTextSize(); - profile_button_->SetVisible(true); - int x_tag = - // The x position of minimize button in the frame - minimize_button_->x() - - // - the space between the minimize button and the profile button - ProfileMenuButton::kProfileTagHorizontalSpacing - - // - the width of the profile button - profile_button_->GetPreferredSize().width(); - // Adjust for different default font sizes on different Windows platforms. - int y_tag = profile_button_->font().GetHeight() < 14 ? 2 : 0; - int maximized = frame_->IsMaximized(); - profile_button_->SetBounds( - x_tag, - maximized ? 0 : y_tag, - profile_button_->GetPreferredSize().width(), - profile_button_->GetPreferredSize().height()); - - if (!profile_name.empty()) { - profile_tag_->SetVisible(true); - profile_tag_->SetBounds( - x_tag, - maximized ? 0 : kProfileTagYPosition, - profile_button_->GetPreferredSize().width(), - ProfileTagView::kProfileTagHeight); - } else { - profile_tag_->SetVisible(false); - } + if (avatar_button_.get()) + avatar_button_->SetBoundsRect(avatar_bounds_); } gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h index 6e36207b..be06c3d 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h @@ -18,9 +18,7 @@ class BrowserView; namespace gfx { class Font; } -class ProfileMenuButton; -class ProfileMenuModel; -class ProfileTagView; +class AvatarMenuButton; class TabContents; namespace views { class ImageButton; @@ -144,14 +142,12 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView, void PaintMaximizedFrameBorder(gfx::Canvas* canvas); void PaintTitleBar(gfx::Canvas* canvas); void PaintToolbarBackground(gfx::Canvas* canvas); - void PaintOTRAvatar(gfx::Canvas* canvas); void PaintRestoredClientEdge(gfx::Canvas* canvas); // Layout various sub-components of this view. void LayoutWindowControls(); void LayoutTitleBar(); - void LayoutOTRAvatar(); - void LayoutProfileTag(); + void LayoutAvatar(); // Returns the bounds of the client area for the specified view size. gfx::Rect CalculateClientAreaBounds(int width, int height) const; @@ -159,14 +155,11 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView, // Receive notifications when the user's Google services user name changes. void RegisterLoginNotifications(); - // Returns true if the ProfileButton has been created. - bool show_profile_button() const { return profile_button_.get() != NULL; } - // The layout rect of the title, if visible. gfx::Rect title_bounds_; - // The layout rect of the OTR avatar icon, if visible. - gfx::Rect otr_avatar_bounds_; + // The layout rect of the avatar icon, if visible. + gfx::Rect avatar_bounds_; // Window controls. views::ImageButton* minimize_button_; @@ -186,11 +179,9 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView, // The bounds of the ClientView. gfx::Rect client_view_bounds_; - // Menu button that displays user's name and multi-profile menu. - scoped_ptr<ProfileMenuButton> profile_button_; - - // Image tag displayed on frame beneath profile_button_. - scoped_ptr<ProfileTagView> profile_tag_; + // Menu button that displays that either the incognito icon or the profile + // icon. + scoped_ptr<AvatarMenuButton> avatar_button_; // The Google services user name associated with this BrowserView's profile. StringPrefMember username_pref_; diff --git a/chrome/browser/ui/views/profile_menu_button.cc b/chrome/browser/ui/views/profile_menu_button.cc deleted file mode 100644 index 684226f..0000000 --- a/chrome/browser/ui/views/profile_menu_button.cc +++ /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. - -#include "chrome/browser/ui/views/profile_menu_button.h" - -#include "chrome/browser/ui/profile_menu_model.h" -#include "ui/base/text/text_elider.h" -#include "ui/gfx/color_utils.h" -#include "views/controls/button/button.h" -#include "views/controls/menu/menu_item_view.h" -#include "views/controls/menu/menu_model_adapter.h" -#include "views/window/window.h" - -// Menu should display below the profile button tag image on the frame. This -// offset size depends on whether the frame is in glass or opaque mode. -const int kMenuDisplayOffset = 7; - -// TextHover is slightly darker than enabled color, for a subtle hover shift. -const SkColor kTextHover = 0xFFDDDDDD; -const SkColor kTextEnabled = SK_ColorWHITE; -const SkColor kTextHighlighted = SK_ColorWHITE; - -// Horizontal padding beside profile menu button, to center it in the -// underlying tag image. -const int kProfileButtonBorderSpacing = 10; - -// Maximum width for name string in pixels. -const int kMaxTextWidth = 200; - -ProfileMenuButton::ProfileMenuButton(const std::wstring& text, Profile* profile) - : MenuButton(NULL, text, this, true) { - // Turn off hover highlighting and position button in the center of the - // underlying profile tag image. - set_border(views::Border::CreateEmptyBorder( - 0, kProfileButtonBorderSpacing, 0, kProfileButtonBorderSpacing)); - SetHoverColor(kTextHover); - SetEnabledColor(kTextEnabled); - SetHighlightColor(kTextHighlighted); - - profile_menu_model_.reset(new ProfileMenuModel); -} - -ProfileMenuButton::~ProfileMenuButton() {} - -void ProfileMenuButton::SetText(const std::wstring& text) { - MenuButton::SetText(UTF16ToWideHack(ui::ElideText(WideToUTF16Hack(text), - font(), kMaxTextWidth, false))); -} - -// views::ViewMenuDelegate implementation -void ProfileMenuButton::RunMenu(views::View* source, const gfx::Point &pt) { - views::MenuModelAdapter menu_model_adapter(profile_menu_model_.get()); - views::MenuItemView menu(&menu_model_adapter); - menu_model_adapter.BuildMenu(&menu); - - gfx::Point menu_point(pt.x(), pt.y() + kMenuDisplayOffset); - menu.RunMenuAt(source->GetWidget()->GetNativeWindow(), NULL, - gfx::Rect(pt, gfx::Size(0, 0)), - views::MenuItemView::TOPRIGHT, - true); -} diff --git a/chrome/browser/ui/views/profile_menu_button.h b/chrome/browser/ui/views/profile_menu_button.h deleted file mode 100644 index c1389b9..0000000 --- a/chrome/browser/ui/views/profile_menu_button.h +++ /dev/null @@ -1,61 +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_PROFILE_MENU_BUTTON_H_ -#define CHROME_BROWSER_UI_VIEWS_PROFILE_MENU_BUTTON_H_ -#pragma once - -#include <string> - -#include "base/compiler_specific.h" -#include "ui/base/models/simple_menu_model.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/menu/view_menu_delegate.h" - -class Profile; -class ProfileMenuModel; - -namespace gfx { -class Canvas; -} - -namespace ui { -class Accelerator; -} - -// ProfileMenuButton -// -// Shows the button for the multiprofile menu with an image layered -// underneath that displays the profile tag. - -class ProfileMenuButton : public views::MenuButton, - public views::ViewMenuDelegate { - public: - // DefaultActiveTextShadow is a darkened blue color that works with Windows - // default theme background coloring. - static const SkColor kDefaultActiveTextShadow = 0xFF708DB3; - // InactiveTextShadow is a light gray for inactive default themed buttons. - static const SkColor kDefaultInactiveTextShadow = SK_ColorLTGRAY; - // DarkTextShadow is used to shadow names on themed browser frames. - static const SkColor kDarkTextShadow = SK_ColorGRAY; - // Space between window controls and end of profile tag. - static const int kProfileTagHorizontalSpacing = 5; - - ProfileMenuButton(const std::wstring& text, Profile* profile); - - virtual ~ProfileMenuButton(); - - // Override MenuButton to clamp text at kMaxTextWidth. - virtual void SetText(const std::wstring& text) OVERRIDE; - - private: - // Overridden from views::ViewMenuDelegate: - virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE; - - scoped_ptr<ProfileMenuModel> profile_menu_model_; - - DISALLOW_COPY_AND_ASSIGN(ProfileMenuButton); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_PROFILE_MENU_BUTTON_H_ diff --git a/chrome/browser/ui/views/profile_tag_view.cc b/chrome/browser/ui/views/profile_tag_view.cc deleted file mode 100644 index ed96923..0000000 --- a/chrome/browser/ui/views/profile_tag_view.cc +++ /dev/null @@ -1,144 +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/profile_tag_view.h" - -#include "chrome/browser/themes/theme_service.h" -#include "chrome/browser/ui/views/frame/browser_frame.h" -#include "chrome/browser/ui/views/profile_menu_button.h" -#include "grit/theme_resources.h" -#include "ui/base/theme_provider.h" -#include "ui/gfx/canvas_skia.h" -#include "ui/gfx/color_utils.h" -#include "ui/gfx/skbitmap_operations.h" -#include "views/widget/widget.h" - -namespace { -// Colors for primary profile. TODO(mirandac): add colors for multi-profile. -color_utils::HSL hsl_active_shift = { 0.594, 0.5, 0.5 }; -} - -ProfileTagView::ProfileTagView(BrowserFrame* frame, - ProfileMenuButton* profile_menu_button) - : profile_tag_bitmaps_created_(false), - frame_(frame), - profile_menu_button_(profile_menu_button) { -} - -ProfileTagView::~ProfileTagView() { -} - -void ProfileTagView::OnPaint(gfx::Canvas* canvas) { - CreateProfileTagBitmaps(); - - // The tag image consists of a right and left edge, and a center section that - // scales to fit the length of the user's name. We can't just scale the whole - // image, or the left and right edges would be distorted. - int tag_width = profile_menu_button_->GetPreferredSize().width(); - int center_tag_width = tag_width - active_profile_tag_left_.width() - - active_profile_tag_right_.width(); - - bool use_active = GetWidget()->IsActive() && is_signed_in_; - SkBitmap* profile_tag_left = use_active ? &active_profile_tag_left_ : - &inactive_profile_tag_left_; - SkBitmap* profile_tag_center = use_active ? &active_profile_tag_center_ : - &inactive_profile_tag_center_; - SkBitmap* profile_tag_right = use_active ? &active_profile_tag_right_ : - &inactive_profile_tag_right_; - - if (!active_profile_tag_left_background_.empty()) { - canvas->DrawBitmapInt(active_profile_tag_left_background_, 0, 0); - canvas->DrawBitmapInt(active_profile_tag_center_background_, 0, 0, - profile_tag_center->width(), - profile_tag_center->height(), - profile_tag_left->width(), 0, - center_tag_width, - profile_tag_center->height(), true); - canvas->DrawBitmapInt(active_profile_tag_right_background_, - profile_tag_left->width() + center_tag_width, 0); - } - - canvas->DrawBitmapInt(*profile_tag_left, 0, 0); - canvas->DrawBitmapInt(*profile_tag_center, 0, 0, - profile_tag_center->width(), - profile_tag_center->height(), - profile_tag_left->width(), 0, - center_tag_width, - profile_tag_center->height(), true); - canvas->DrawBitmapInt(*profile_tag_right, - profile_tag_left->width() + center_tag_width, 0); -} - -void ProfileTagView::CreateProfileTagBitmaps() { - // Lazily create profile tag bitmaps on first display. - // TODO(mirandac): Cache these per profile, instead of creating every time. - if (profile_tag_bitmaps_created_) - return; - profile_tag_bitmaps_created_ = true; - - ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); - bool aero = theme_provider->ShouldUseNativeFrame(); - SkBitmap* profile_tag_center = aero ? - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_CENTER_AERO) : - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_CENTER_THEMED); - SkBitmap* profile_tag_left = aero ? - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_LEFT_AERO) : - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_LEFT_THEMED); - SkBitmap* profile_tag_right = aero ? - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_RIGHT_AERO) : - theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_RIGHT_THEMED); - inactive_profile_tag_center_ = aero ? - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_INACTIVE_CENTER_AERO) : - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_CENTER_THEMED); - inactive_profile_tag_left_ = aero ? - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_INACTIVE_LEFT_AERO) : - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_LEFT_THEMED); - inactive_profile_tag_right_ = aero ? - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_INACTIVE_RIGHT_AERO) : - *theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_RIGHT_THEMED); - - // Color if we're using the Aero theme; otherwise the tag will be given by - // the window controls background from the theme. - if (theme_provider->ShouldUseNativeFrame()) { - active_profile_tag_center_ = SkBitmapOperations::CreateHSLShiftedBitmap( - *profile_tag_center, hsl_active_shift); - active_profile_tag_left_ = SkBitmapOperations::CreateHSLShiftedBitmap( - *profile_tag_left, hsl_active_shift); - active_profile_tag_right_ = SkBitmapOperations::CreateHSLShiftedBitmap( - *profile_tag_right, hsl_active_shift); - - // No backgrounds used in Aero theme. - active_profile_tag_center_background_.reset(); - active_profile_tag_left_background_.reset(); - active_profile_tag_center_background_.reset(); - } else { - active_profile_tag_center_ = *profile_tag_center; - active_profile_tag_left_ = *profile_tag_left; - active_profile_tag_right_ = *profile_tag_right; - - SkBitmap* background = theme_provider->GetBitmapNamed( - IDR_THEME_WINDOW_CONTROL_BACKGROUND); - if (!background) { - active_profile_tag_center_background_.reset(); - active_profile_tag_left_background_.reset(); - active_profile_tag_center_background_.reset(); - } else { - active_profile_tag_center_background_ = - SkBitmapOperations::CreateButtonBackground( - theme_provider->GetColor(ThemeService::COLOR_BUTTON_BACKGROUND), - *background, - *(theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_CENTER_MASK))); - active_profile_tag_left_background_ = - SkBitmapOperations::CreateButtonBackground( - theme_provider->GetColor(ThemeService::COLOR_BUTTON_BACKGROUND), - *background, - *(theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_LEFT_MASK))); - active_profile_tag_right_background_ = - SkBitmapOperations::CreateButtonBackground( - theme_provider->GetColor(ThemeService::COLOR_BUTTON_BACKGROUND), - *background, - *(theme_provider->GetBitmapNamed(IDR_PROFILE_TAG_RIGHT_MASK))); - } - } -} diff --git a/chrome/browser/ui/views/profile_tag_view.h b/chrome/browser/ui/views/profile_tag_view.h deleted file mode 100644 index 017c775..0000000 --- a/chrome/browser/ui/views/profile_tag_view.h +++ /dev/null @@ -1,68 +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_PROFILE_TAG_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_PROFILE_TAG_VIEW_H_ -#pragma once - -#include "third_party/skia/include/core/SkBitmap.h" -#include "views/view.h" - -class BrowserFrame; -class ProfileMenuButton; - -namespace gfx { -class Canvas; -} - -// ProfileTag -// -// Displays the tinted button image underneath the ProfileMenuButton. - -class ProfileTagView : public views::View { - public: - // Height of profile tag. - static const int kProfileTagHeight = 20; - - ProfileTagView(BrowserFrame* frame, - ProfileMenuButton* profile_menu_button); - virtual ~ProfileTagView(); - - // Paint the profile tag background image on the given canvas. - virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; - - void set_is_signed_in(bool is_signed_in) { is_signed_in_ = is_signed_in; } - - private: - // Create the bitmaps to be displayed on the frame behind the profile button. - void CreateProfileTagBitmaps(); - - // True if the bitmaps to display the profile tag have been created. - bool profile_tag_bitmaps_created_; - - // Bitmaps for the profile tag in active and inactive states. - SkBitmap active_profile_tag_center_; - SkBitmap active_profile_tag_left_; - SkBitmap active_profile_tag_right_; - SkBitmap inactive_profile_tag_center_; - SkBitmap inactive_profile_tag_left_; - SkBitmap inactive_profile_tag_right_; - // Bitmaps used for a themed profile background. - SkBitmap active_profile_tag_center_background_; - SkBitmap active_profile_tag_left_background_; - SkBitmap active_profile_tag_right_background_; - - // True if the user is signed in to a personalized Chrome profile. - bool is_signed_in_; - - // The frame that hosts this view. - BrowserFrame* frame_; - - // The button to be displayed above this view. - ProfileMenuButton* profile_menu_button_; - - DISALLOW_COPY_AND_ASSIGN(ProfileTagView); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_PROFILE_TAG_VIEW_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 965ba81..c906790 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2945,6 +2945,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_button.cc', + 'browser/ui/views/avatar_menu_button.h', 'browser/ui/views/bookmarks/bookmark_bar_instructions_view.cc', 'browser/ui/views/bookmarks/bookmark_bar_instructions_view.h', 'browser/ui/views/bookmarks/bookmark_bar_view.cc', @@ -3175,10 +3177,6 @@ 'browser/ui/views/page_info_bubble_view.h', 'browser/ui/views/pinned_contents_info_bubble.cc', 'browser/ui/views/pinned_contents_info_bubble.h', - 'browser/ui/views/profile_menu_button.cc', - 'browser/ui/views/profile_menu_button.h', - 'browser/ui/views/profile_tag_view.cc', - 'browser/ui/views/profile_tag_view.h', 'browser/ui/views/reload_button.cc', 'browser/ui/views/reload_button.h', 'browser/ui/views/repost_form_warning_view.cc', diff --git a/views/controls/button/text_button.cc b/views/controls/button/text_button.cc index c88af99..9d4cf72 100644 --- a/views/controls/button/text_button.cc +++ b/views/controls/button/text_button.cc @@ -653,13 +653,7 @@ gfx::Size TextButton::GetPreferredSize() { void TextButton::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { TextButtonBase::PaintButton(canvas, mode); - SkBitmap icon = icon_; - if (show_multiple_icon_states_) { - if (has_hover_icon_ && (state() == BS_HOT)) - icon = icon_hover_; - else if (has_pushed_icon_ && (state() == BS_PUSHED)) - icon = icon_pushed_; - } + const SkBitmap& icon = GetImageToPaint(); if (icon.width() > 0) { gfx::Rect text_bounds = GetTextBounds(); @@ -702,14 +696,7 @@ void TextButton::GetExtraParams(gfx::NativeTheme::ExtraParams* params) const { gfx::Rect TextButton::GetTextBounds() const { int extra_width = 0; - SkBitmap icon = icon_; - if (show_multiple_icon_states_) { - if (has_hover_icon_ && (state() == BS_HOT)) - icon = icon_hover_; - else if (has_pushed_icon_ && (state() == BS_PUSHED)) - icon = icon_pushed_; - } - + const SkBitmap& icon = GetImageToPaint(); if (icon.width() > 0) extra_width = icon.width() + (text_.empty() ? 0 : icon_text_spacing_); @@ -727,4 +714,14 @@ gfx::Rect TextButton::GetTextBounds() const { return bounds; } +const SkBitmap& TextButton::GetImageToPaint() const { + if (show_multiple_icon_states_) { + if (has_hover_icon_ && (state() == BS_HOT)) + return icon_hover_; + if (has_pushed_icon_ && (state() == BS_PUSHED)) + return icon_pushed_; + } + return icon_; +} + } // namespace views diff --git a/views/controls/button/text_button.h b/views/controls/button/text_button.h index cebf988..d816120 100644 --- a/views/controls/button/text_button.h +++ b/views/controls/button/text_button.h @@ -353,6 +353,9 @@ class TextButton : public TextButtonBase { protected: SkBitmap icon() const { return icon_; } + // Returns the image to paint. This is invoked from paint. + virtual const SkBitmap& GetImageToPaint() const; + // Overridden from NativeThemeDelegate: virtual gfx::NativeTheme::Part GetThemePart() const OVERRIDE; |