1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_MENU_BUBBLE_VIEW_H_
6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#define CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_MENU_BUBBLE_VIEW_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/gtest_prod_util.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/profiles/avatar_menu_observer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class AvatarMenu;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Browser;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProfileItemView;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebContents;
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CustomButton;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ImageView;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class Label;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Link;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Separator;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This bubble view is displayed when the user clicks on the avatar button.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It displays a list of profiles and allows users to switch between profiles.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AvatarMenuBubbleView : public views::BubbleDelegateView,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             public views::ButtonListener,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             public views::LinkListener,
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             public AvatarMenuObserver {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper function to show the bubble and ensure that it doesn't reshow.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normally this bubble is shown when there's a mouse down event on a button.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the bubble is already showing when the user clicks on the button then
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this will cause two things to happen:
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - (1) the button will show a new instance of the bubble
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - (2) the old instance of the bubble will get a deactivate event and
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   close
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // To prevent this reshow this function checks if an instance of the bubble
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is already showing and do nothing. This means that (1) will do nothing
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and (2) will correctly hide the old bubble instance.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void ShowBubble(views::View* anchor_view,
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         views::BubbleBorder::Arrow arrow,
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         views::BubbleBorder::ArrowPaintType arrow_paint_type,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         views::BubbleBorder::BubbleAlignment border_alignment,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const gfx::Rect& anchor_rect,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         Browser* browser);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool IsShowing();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Hide();
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AvatarMenuBubbleView();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View implementation.
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::ButtonListener implementation.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::LinkListener implementation.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BubbleDelegate implementation.
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Rect GetAnchorRect() const OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Init() OVERRIDE;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void WindowClosing() OVERRIDE;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // AvatarMenuObserver implementation.
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual void OnAvatarMenuChanged(
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      AvatarMenu* avatar_menu) OVERRIDE;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  // We normally close the bubble any time it becomes inactive but this can lead
8458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  // to flaky tests where unexpected UI events are triggering this behavior.
8558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  // Tests should call this with "false" for more consistent operation.
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void clear_close_on_deactivate_for_testing() {
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    close_on_deactivate_for_testing_ = false;
8858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
8958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AvatarMenuBubbleView(views::View* anchor_view,
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       views::BubbleBorder::Arrow arrow,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const gfx::Rect& anchor_rect,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       Browser* browser);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the colors on all the |item_views_|. Called after the
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // BubbleDelegateView is created and has loaded the colors from the
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NativeTheme.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetBackgroundColors();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create the menu contents for a normal profile.
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void InitMenuContents(AvatarMenu* avatar_menu);
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Create the supervised user specific contents of the menu.
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void InitSupervisedUserContents(AvatarMenu* avatar_menu);
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_ptr<AvatarMenu> avatar_menu_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect anchor_rect_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser_;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ProfileItemView*> item_views_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Used to separate the link entry in the avatar menu from the other entries.
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  views::Separator* separator_;
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // This will be non-NULL if and only if
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // avatar_menu_->ShouldShowAddNewProfileLink() returns true.  See
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // OnAvatarMenuChanged().
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  views::View* buttons_view_;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // This will be non-NULL if and only if |expanded_| is false and
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // avatar_menu_->GetSupervisedUserInformation() returns a non-empty string.
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // See OnAvatarMenuChanged().
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::Label* supervised_user_info_;
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  views::ImageView* icon_view_;
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  views::Separator* separator_switch_users_;
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  views::Link* switch_profile_link_;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static AvatarMenuBubbleView* avatar_bubble_;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool close_on_deactivate_for_testing_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Is set to true if the supervised user has clicked on Switch Users.
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool expanded_;
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AvatarMenuBubbleView);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_MENU_BUBBLE_VIEW_H_
138