new_avatar_button.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright 2014 The Chromium Authors. All rights reserved.
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Use of this source code is governed by a BSD-style license that can be
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// found in the LICENSE file.
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/ui/views/profiles/new_avatar_button.h"
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/win/windows_version.h"
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/browser_process.h"
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/profiles/profile_manager.h"
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/profiles/profiles_state.h"
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/ui/browser.h"
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "grit/theme_resources.h"
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/base/resource/resource_bundle.h"
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/gfx/canvas.h"
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/border.h"
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/controls/button/label_button_border.h"
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/painter.h"
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace {
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverscoped_ptr<views::Border> CreateBorder(const int normal_image_set[],
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                       const int hot_image_set[],
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                       const int pushed_image_set[]) {
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  scoped_ptr<views::LabelButtonBorder> border(
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      new views::LabelButtonBorder(views::Button::STYLE_TEXTBUTTON));
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  border->SetPainter(false, views::Button::STATE_NORMAL,
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      views::Painter::CreateImageGridPainter(normal_image_set));
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  border->SetPainter(false, views::Button::STATE_HOVERED,
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      views::Painter::CreateImageGridPainter(hot_image_set));
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  border->SetPainter(false, views::Button::STATE_PRESSED,
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      views::Painter::CreateImageGridPainter(pushed_image_set));
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  const int kLeftRightInset = 10;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  const int kTopInset = 0;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  const int kBottomInset = 4;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  border->set_insets(gfx::Insets(kTopInset, kLeftRightInset,
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                 kBottomInset, kLeftRightInset));
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  return border.PassAs<views::Border>();
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}  // namespace
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNewAvatarButton::NewAvatarButton(
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    views::ButtonListener* listener,
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    const base::string16& profile_name,
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    AvatarButtonStyle button_style,
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Browser* browser)
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    : MenuButton(listener,
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 profiles::GetAvatarButtonTextForProfile(browser->profile()),
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 NULL,
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 true),
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      browser_(browser) {
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  set_animate_on_state_change(false);
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SetTextColor(views::Button::STATE_NORMAL, SK_ColorWHITE);
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SetTextColor(views::Button::STATE_HOVERED, SK_ColorWHITE);
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SetTextColor(views::Button::STATE_PRESSED, SK_ColorWHITE);
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SetTextShadows(gfx::ShadowValues(10,
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      gfx::ShadowValue(gfx::Point(), 1.0f, SK_ColorDKGRAY)));
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SetTextSubpixelRenderingEnabled(false);
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  if (button_style == THEMED_BUTTON) {
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL);
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER);
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED);
67
68    SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
69    set_menu_marker(
70        rb->GetImageNamed(IDR_AVATAR_THEMED_BUTTON_DROPARROW).ToImageSkia());
71#if defined(OS_WIN)
72  } else if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
73    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_NORMAL);
74    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_HOVER);
75    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_PRESSED);
76
77    SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
78    set_menu_marker(
79        rb->GetImageNamed(IDR_AVATAR_METRO_BUTTON_DROPARROW).ToImageSkia());
80#endif
81  } else {
82    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL);
83    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER);
84    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED);
85
86    SetBorder(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
87    set_menu_marker(
88        rb->GetImageNamed(IDR_AVATAR_GLASS_BUTTON_DROPARROW).ToImageSkia());
89  }
90
91  g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this);
92
93  // Subscribe to authentication error changes so that the avatar button can
94  // update itself.  Note that guest mode profiles won't have a token service.
95  SigninErrorController* error =
96      profiles::GetSigninErrorController(browser_->profile());
97  if (error) {
98    error->AddObserver(this);
99    OnErrorChanged();
100  }
101
102  SchedulePaint();
103}
104
105NewAvatarButton::~NewAvatarButton() {
106  g_browser_process->profile_manager()->
107      GetProfileInfoCache().RemoveObserver(this);
108  SigninErrorController* error =
109      profiles::GetSigninErrorController(browser_->profile());
110  if (error)
111    error->RemoveObserver(this);
112}
113
114void NewAvatarButton::OnProfileAdded(const base::FilePath& profile_path) {
115  UpdateAvatarButtonAndRelayoutParent();
116}
117
118void NewAvatarButton::OnProfileWasRemoved(
119      const base::FilePath& profile_path,
120      const base::string16& profile_name) {
121  UpdateAvatarButtonAndRelayoutParent();
122}
123
124void NewAvatarButton::OnProfileNameChanged(
125      const base::FilePath& profile_path,
126      const base::string16& old_profile_name) {
127  UpdateAvatarButtonAndRelayoutParent();
128}
129
130void NewAvatarButton::OnProfileSupervisedUserIdChanged(
131      const base::FilePath& profile_path) {
132  UpdateAvatarButtonAndRelayoutParent();
133}
134
135void NewAvatarButton::OnErrorChanged() {
136  gfx::ImageSkia icon;
137
138  // If there is an error, show an warning icon.
139  const SigninErrorController* error =
140      profiles::GetSigninErrorController(browser_->profile());
141  if (error && error->HasError()) {
142    icon = *ui::ResourceBundle::GetSharedInstance().GetImageNamed(
143        IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR).ToImageSkia();
144  }
145
146  SetImage(views::Button::STATE_NORMAL, icon);
147  UpdateAvatarButtonAndRelayoutParent();
148}
149
150void NewAvatarButton::UpdateAvatarButtonAndRelayoutParent() {
151  // We want the button to resize if the new text is shorter.
152  SetText(profiles::GetAvatarButtonTextForProfile(browser_->profile()));
153  SetMinSize(gfx::Size());
154  InvalidateLayout();
155
156  // Because the width of the button might have changed, the parent browser
157  // frame needs to recalculate the button bounds and redraw it.
158  if (parent())
159    parent()->Layout();
160}
161