avatar_menu_button.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
6
7#include "base/command_line.h"
8#include "base/prefs/pref_service.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chrome_notification_types.h"
11#include "chrome/browser/profiles/avatar_menu.h"
12#include "chrome/browser/profiles/profile_avatar_icon_util.h"
13#include "chrome/browser/profiles/profile_metrics.h"
14#include "chrome/browser/ui/browser.h"
15#include "chrome/browser/ui/browser_commands.h"
16#include "chrome/browser/ui/views/frame/browser_view.h"
17#include "chrome/browser/ui/views/profiles/avatar_menu_bubble_view.h"
18#include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
19#include "chrome/common/pref_names.h"
20#include "components/signin/core/common/profile_management_switches.h"
21#include "content/public/browser/notification_service.h"
22#include "ui/gfx/canvas.h"
23#include "ui/views/view_targeter.h"
24#include "ui/views/widget/widget.h"
25
26static inline int Round(double x) {
27  return static_cast<int>(x + 0.5);
28}
29
30// static
31const char AvatarMenuButton::kViewClassName[] = "AvatarMenuButton";
32
33AvatarMenuButton::AvatarMenuButton(Browser* browser, bool disabled)
34    : MenuButton(NULL, base::string16(), this, false),
35      browser_(browser),
36      disabled_(disabled),
37      is_rectangle_(false),
38      old_height_(0),
39      button_on_right_(false) {
40  // In RTL mode, the avatar icon should be looking the opposite direction.
41  EnableCanvasFlippingForRTLUI(true);
42
43  SetEventTargeter(
44      scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
45}
46
47AvatarMenuButton::~AvatarMenuButton() {
48}
49
50const char* AvatarMenuButton::GetClassName() const {
51  return kViewClassName;
52}
53
54void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) {
55  if (!icon_.get())
56    return;
57
58  if (old_height_ != height() || button_icon_.isNull()) {
59    old_height_ = height();
60    button_icon_ = *profiles::GetAvatarIconForTitleBar(
61        *icon_, is_rectangle_, width(), height()).ToImageSkia();
62  }
63
64  // Scale the image to fit the width of the button.
65  int dst_width = std::min(button_icon_.width(), width());
66  // Truncate rather than rounding, so that for odd widths we put the extra
67  // pixel on the left.
68  int dst_x = (width() - dst_width) / 2;
69
70  // Scale the height and maintain aspect ratio. This means that the
71  // icon may not fit in the view. That's ok, we just vertically center it.
72  float scale =
73      static_cast<float>(dst_width) / static_cast<float>(button_icon_.width());
74  // Round here so that we minimize the aspect ratio drift.
75  int dst_height = Round(button_icon_.height() * scale);
76  // Round rather than truncating, so that for odd heights we select an extra
77  // pixel below the image center rather than above.  This is because the
78  // incognito image has shadows at the top that make the apparent center below
79  // the real center.
80  int dst_y = Round((height() - dst_height) / 2.0);
81  canvas->DrawImageInt(button_icon_, 0, 0, button_icon_.width(),
82      button_icon_.height(), dst_x, dst_y, dst_width, dst_height, false);
83}
84
85void AvatarMenuButton::SetAvatarIcon(const gfx::Image& icon,
86                                     bool is_rectangle) {
87  icon_.reset(new gfx::Image(icon));
88  button_icon_ = gfx::ImageSkia();
89  is_rectangle_ = is_rectangle;
90  SchedulePaint();
91}
92
93// views::ViewTargeterDelegate:
94bool AvatarMenuButton::DoesIntersectRect(const views::View* target,
95                                         const gfx::Rect& rect) const {
96  CHECK_EQ(target, this);
97  return !disabled_ &&
98         views::ViewTargeterDelegate::DoesIntersectRect(target, rect);
99}
100
101// views::MenuButtonListener implementation
102void AvatarMenuButton::OnMenuButtonClicked(views::View* source,
103                                           const gfx::Point& point) {
104  if (!disabled_)
105    chrome::ShowAvatarMenu(browser_);
106}
107