1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
#include "components/sessions/core/session_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_icon_image.h"
#include "ui/views/controls/label.h"
class Browser;
namespace content {
class WebContents;
}
namespace views {
class Button;
class ImageButton;
} // namespace views
// View used to display the zoom percentage when it has changed.
class ZoomBubbleView : public LocationBarBubbleDelegateView,
public ImmersiveModeController::Observer,
public extensions::IconImage::Observer {
METADATA_HEADER(ZoomBubbleView, LocationBarBubbleDelegateView)
public:
ZoomBubbleView(const ZoomBubbleView&) = delete;
ZoomBubbleView& operator=(const ZoomBubbleView&) = delete;
// Shows the bubble and automatically closes it after a short time period if
// |reason| is AUTOMATIC.
static void ShowBubble(content::WebContents* web_contents,
DisplayReason reason);
// If the bubble is being shown for the given |web_contents|, refreshes it.
static bool RefreshBubbleIfShowing(const content::WebContents* web_contents);
// Closes the showing bubble (if one exists).
static void CloseCurrentBubble();
// Returns the zoom bubble if the zoom bubble is showing. Returns NULL
// otherwise.
static ZoomBubbleView* GetZoomBubble();
// Refreshes the bubble by changing the zoom percentage appropriately and
// resetting the timer if necessary.
void Refresh();
private:
FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, ImmersiveFullscreen);
FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest,
BubbleSuppressingExtensionRefreshesExistingBubble);
FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, FocusPreventsClose);
FRIEND_TEST_ALL_PREFIXES(ZoomBubbleImmersiveDisabledBrowserTest,
AnchorPositionsInFullscreen);
// Returns true if we can reuse the existing bubble for the given
// |web_contents|.
static bool CanRefresh(const content::WebContents* web_contents);
// Stores information about the extension that initiated the zoom change, if
// any.
struct ZoomBubbleExtensionInfo {
ZoomBubbleExtensionInfo();
~ZoomBubbleExtensionInfo();
// The unique id of the extension, which is used to find the correct
// extension after clicking on the image button in the zoom bubble.
std::string id;
// The name of the extension, which appears in the tooltip of the image
// button in the zoom bubble.
std::string name;
// An image of the extension's icon, which appears in the zoom bubble as an
// image button.
std::unique_ptr<const extensions::IconImage> icon_image;
};
// Constructs ZoomBubbleView. Anchors the bubble to |anchor_view|, which must
// not be nullptr. The bubble will auto-close when |reason| is AUTOMATIC. If
// |immersive_mode_controller_| is present, the bubble will auto-close when
// the top-of-window views are revealed.
ZoomBubbleView(views::View* anchor_view,
content::WebContents* web_contents,
DisplayReason reason,
ImmersiveModeController* immersive_mode_controller);
~ZoomBubbleView() override;
// LocationBarBubbleDelegateView:
std::u16string GetAccessibleWindowTitle() const override;
void OnFocus() override;
void OnBlur() override;
void OnGestureEvent(ui::GestureEvent* event) override;
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
void Init() override;
void WindowClosing() override;
void CloseBubble() override;
// ImmersiveModeController::Observer
void OnImmersiveRevealStarted() override;
void OnImmersiveModeControllerDestroyed() override;
// extensions::IconImage::Observer
void OnExtensionIconImageChanged(extensions::IconImage* /* image */) override;
// Sets information about the extension that initiated the zoom change.
// Calling this method asserts that the extension |extension| did initiate
// the zoom change.
void SetExtensionInfo(const extensions::Extension* extension);
// Updates |label_| with the up to date zoom.
void UpdateZoomPercent();
// Updates visibility of the zoom icon.
void UpdateZoomIconVisibility();
// Starts a timer which will close the bubble if |auto_close_| is true.
void StartTimerIfNecessary();
// Stops the auto-close timer.
void StopTimer();
// Called when any button is pressed; does common logic, then runs |closure|.
void ButtonPressed(base::RepeatingClosure closure);
// Called by ButtonPressed() when |image_button_| is pressed.
void ImageButtonPressed();
// Gets the browser for `web_contents()`. May return null.
Browser* GetBrowser() const;
ZoomBubbleExtensionInfo extension_info_;
// Singleton instance of the zoom bubble. The zoom bubble can only be shown on
// the active browser window, so there is no case in which it will be shown
// twice at the same time.
static ZoomBubbleView* zoom_bubble_;
// Timer used to auto close the bubble.
base::OneShotTimer auto_close_timer_;
// Timer duration that is made longer if a user presses + or - buttons.
base::TimeDelta auto_close_duration_;
// Image button in the zoom bubble that will show the |extension_icon_| image
// if an extension initiated the zoom change, and links to that extension at
// "chrome://extensions".
raw_ptr<views::ImageButton> image_button_ = nullptr;
// Label displaying the zoom percentage.
raw_ptr<views::Label> label_ = nullptr;
// Action buttons that can change zoom.
raw_ptr<views::Button> zoom_out_button_ = nullptr;
raw_ptr<views::Button> zoom_in_button_ = nullptr;
raw_ptr<views::Button> reset_button_ = nullptr;
// Whether the currently displayed bubble will automatically close.
bool auto_close_;
// Used to ignore close requests generated automatically in response to
// button presses, since pressing a button in the bubble should not trigger
// closing.
bool ignore_close_bubble_ = false;
// The immersive mode controller for the BrowserView containing
// |web_contents_|.
// Not owned.
raw_ptr<ImmersiveModeController> immersive_mode_controller_;
// The session of the Browser that triggered the bubble. This allows the zoom
// icon to be updated even if the WebContents is destroyed.
const SessionID session_id_;
};
#endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
|