1// Copyright 2013 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#ifndef CHROME_BROWSER_UI_VIEWS_PROFILE_CHOOSER_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_PROFILE_CHOOSER_VIEW_H_
7
8#include <map>
9#include <vector>
10
11#include "chrome/browser/profiles/avatar_menu_model_observer.h"
12#include "ui/views/bubble/bubble_delegate.h"
13#include "ui/views/controls/button/button.h"
14
15namespace gfx {
16class Image;
17}
18
19namespace views {
20class LabelButton;
21}
22
23class AvatarMenuModel;
24class Browser;
25class ProfileItemView;
26
27// This bubble view is displayed when the user clicks on the avatar button.
28// It displays a list of profiles and allows users to switch between profiles.
29class ProfileChooserView : public views::BubbleDelegateView,
30                           public views::ButtonListener,
31                           public AvatarMenuModelObserver {
32 public:
33  // Shows the bubble if one is not already showing.  This allows us to easily
34  // make a button toggle the bubble on and off when clicked: we unconditionally
35  // call this function when the button is clicked and if the bubble isn't
36  // showing it will appear while if it is showing, nothing will happen here and
37  // the existing bubble will auto-close due to focus loss.
38  static void ShowBubble(views::View* anchor_view,
39                         views::BubbleBorder::Arrow arrow,
40                         views::BubbleBorder::BubbleAlignment border_alignment,
41                         const gfx::Rect& anchor_rect,
42                         Browser* browser);
43  static bool IsShowing();
44  static void Hide();
45
46  // We normally close the bubble any time it becomes inactive but this can lead
47  // to flaky tests where unexpected UI events are triggering this behavior.
48  // Tests should call this with "false" for more consistent operation.
49  static void set_close_on_deactivate(bool close) {
50    close_on_deactivate_ = close;
51  }
52
53 private:
54  friend class AvatarMenuButtonTest;
55  FRIEND_TEST_ALL_PREFIXES(AvatarMenuButtonTest, NewSignOut);
56  FRIEND_TEST_ALL_PREFIXES(AvatarMenuButtonTest, LaunchUserManagerScreen);
57
58  typedef std::vector<size_t> Indexes;
59  typedef std::map<views::View*, int> ViewIndexes;
60
61  ProfileChooserView(views::View* anchor_view,
62                     views::BubbleBorder::Arrow arrow,
63                     const gfx::Rect& anchor_rect,
64                     Browser* browser);
65  virtual ~ProfileChooserView();
66
67  // BubbleDelegateView:
68  virtual void Init() OVERRIDE;
69  virtual void WindowClosing() OVERRIDE;
70  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
71  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
72
73  // ButtonListener:
74  virtual void ButtonPressed(views::Button* sender,
75                             const ui::Event& event) OVERRIDE;
76
77  // AvatarMenuModelObserver:
78  virtual void OnAvatarMenuModelChanged(
79      AvatarMenuModel* avatar_menu_model) OVERRIDE;
80
81  static ProfileChooserView* profile_bubble_;
82  static bool close_on_deactivate_;
83
84  views::View* CreateProfileImageView(const gfx::Image& icon, int side);
85  views::View* CreateProfileCardView(size_t avatar_to_show);
86  views::View* CreateCurrentProfileView(size_t avatars_to_show);
87  views::View* CreateOtherProfilesView(const Indexes& avatars_to_show);
88  views::View* CreateOptionsView();
89
90  scoped_ptr<AvatarMenuModel> avatar_menu_model_;
91  Browser* browser_;
92  views::View* current_profile_view_;
93  views::LabelButton* guest_button_view_;
94  views::LabelButton* users_button_view_;
95  ViewIndexes open_other_profile_indexes_map_;
96  views::View* other_profiles_view_;
97  views::View* signout_current_profile_view_;
98
99  DISALLOW_COPY_AND_ASSIGN(ProfileChooserView);
100};
101
102#endif  // CHROME_BROWSER_UI_VIEWS_PROFILE_CHOOSER_VIEW_H_
103