1// Copyright (c) 2012 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_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
7
8#include "base/basictypes.h"
9#include "base/timer/timer.h"
10#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
11#include "content/public/browser/notification_observer.h"
12#include "content/public/browser/notification_registrar.h"
13#include "extensions/browser/extension_icon_image.h"
14#include "ui/views/bubble/bubble_delegate.h"
15#include "ui/views/controls/button/button.h"
16#include "ui/views/controls/label.h"
17
18class FullscreenController;
19
20namespace content {
21class NotificationDetails;
22class NotificationSource;
23class WebContents;
24}
25
26namespace views {
27class ImageButton;
28}  // namespace views
29
30// View used to display the zoom percentage when it has changed.
31class ZoomBubbleView : public views::BubbleDelegateView,
32                       public views::ButtonListener,
33                       public content::NotificationObserver,
34                       public ImmersiveModeController::Observer,
35                       public extensions::IconImage::Observer {
36 public:
37  // Shows the bubble and automatically closes it after a short time period if
38  // |auto_close| is true.
39  static void ShowBubble(content::WebContents* web_contents,
40                         bool auto_close);
41
42  // Closes the showing bubble (if one exists).
43  static void CloseBubble();
44
45  // Whether the zoom bubble is currently showing.
46  static bool IsShowing();
47
48  // Returns the zoom bubble if the zoom bubble is showing. Returns NULL
49  // otherwise.
50  static const ZoomBubbleView* GetZoomBubbleForTest();
51
52 private:
53  // Stores information about the extension that initiated the zoom change, if
54  // any.
55  struct ZoomBubbleExtensionInfo {
56    ZoomBubbleExtensionInfo();
57    ~ZoomBubbleExtensionInfo();
58
59    // The unique id of the extension, which is used to find the correct
60    // extension after clicking on the image button in the zoom bubble.
61    std::string id;
62
63    // The name of the extension, which appears in the tooltip of the image
64    // button in the zoom bubble.
65    std::string name;
66
67    // An image of the extension's icon, which appears in the zoom bubble as an
68    // image button.
69    scoped_ptr<const extensions::IconImage> icon_image;
70  };
71
72  ZoomBubbleView(views::View* anchor_view,
73                 content::WebContents* web_contents,
74                 bool auto_close,
75                 ImmersiveModeController* immersive_mode_controller,
76                 FullscreenController* fullscreen_controller);
77  virtual ~ZoomBubbleView();
78
79  // If the bubble is not anchored to a view, places the bubble in the top
80  // right (left in RTL) of the |screen_bounds| that contain |web_contents_|'s
81  // browser window. Because the positioning is based on the size of the
82  // bubble, this must be called after the bubble is created.
83  void AdjustForFullscreen(const gfx::Rect& screen_bounds);
84
85  // Refreshes the bubble by changing the zoom percentage appropriately and
86  // resetting the timer if necessary.
87  void Refresh();
88
89  void Close();
90
91  // Sets information about the extension that initiated the zoom change.
92  // Calling this method asserts that the extension |extension| did initiate
93  // the zoom change.
94  void SetExtensionInfo(const extensions::Extension* extension);
95
96  // Starts a timer which will close the bubble if |auto_close_| is true.
97  void StartTimerIfNecessary();
98
99  // Stops the auto-close timer.
100  void StopTimer();
101
102  // extensions::IconImage::Observer overrides:
103  virtual void OnExtensionIconImageChanged(
104      extensions::IconImage* /* image */) OVERRIDE;
105
106  // views::View methods.
107  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
108  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
109
110  // ui::EventHandler method.
111  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
112
113  // views::ButtonListener method.
114  virtual void ButtonPressed(views::Button* sender,
115                             const ui::Event& event) OVERRIDE;
116
117  // views::BubbleDelegateView method.
118  virtual void Init() OVERRIDE;
119  virtual void WindowClosing() OVERRIDE;
120
121  // content::NotificationObserver method.
122  virtual void Observe(int type,
123                       const content::NotificationSource& source,
124                       const content::NotificationDetails& details) OVERRIDE;
125
126  // ImmersiveModeController::Observer methods.
127  virtual void OnImmersiveRevealStarted() OVERRIDE;
128  virtual void OnImmersiveModeControllerDestroyed() OVERRIDE;
129
130  ZoomBubbleExtensionInfo extension_info_;
131
132  // Singleton instance of the zoom bubble. The zoom bubble can only be shown on
133  // the active browser window, so there is no case in which it will be shown
134  // twice at the same time.
135  static ZoomBubbleView* zoom_bubble_;
136
137  // Timer used to close the bubble when |auto_close_| is true.
138  base::OneShotTimer<ZoomBubbleView> timer_;
139
140  // Image button in the zoom bubble that will show the |extension_icon_| image
141  // if an extension initiated the zoom change, and links to that extension at
142  // "chrome://extensions".
143  views::ImageButton* image_button_;
144
145  // Label displaying the zoom percentage.
146  views::Label* label_;
147
148  // The WebContents for the page whose zoom has changed.
149  content::WebContents* web_contents_;
150
151  // Whether the currently displayed bubble will automatically close.
152  bool auto_close_;
153
154  // The immersive mode controller for the BrowserView containing
155  // |web_contents_|.
156  // Not owned.
157  ImmersiveModeController* immersive_mode_controller_;
158
159  // Used to register for fullscreen change notifications.
160  content::NotificationRegistrar registrar_;
161
162  DISALLOW_COPY_AND_ASSIGN(ZoomBubbleView);
163};
164
165#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
166