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 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
|
// Copyright 2013 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_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/animation/ink_drop_host.h"
#include "ui/views/controls/image_view.h"
class Browser;
class CommandUpdater;
class PageActionIconLoadingIndicatorView;
class PageActionIconViewObserver;
namespace content {
class WebContents;
}
namespace gfx {
struct VectorIcon;
}
namespace views {
class BubbleDialogDelegate;
}
// Used for histograms, do not reorder.
enum class PageActionCTREvent {
kShown = 0,
kClicked,
kMaxValue = kClicked,
};
// Used for histograms, do not reorder.
enum class PageActionPageEvent {
kPageShown = 0,
kActionShown,
kMultipleActionsShown,
kMaxValue = kMultipleActionsShown,
};
// Represents an inbuilt (as opposed to an extension) page action icon that
// shows a bubble when clicked.
class PageActionIconView : public IconLabelBubbleView {
METADATA_HEADER(PageActionIconView, IconLabelBubbleView)
public:
class Delegate {
public:
// Gets the opacity to use for the ink highlight.
virtual float GetPageActionInkDropVisibleOpacity() const;
virtual content::WebContents* GetWebContentsForPageActionIconView() = 0;
virtual int GetPageActionIconSize() const;
// Returns the size of the insets in which the icon should draw its inkdrop.
virtual gfx::Insets GetPageActionIconInsets(
const PageActionIconView* icon_view) const;
// Delegate should return true if the page action icons should be hidden.
virtual bool ShouldHidePageActionIcons() const;
// Returns whether or not the given page action icon should be hidden.
virtual bool ShouldHidePageActionIcon(PageActionIconView* icon_view) const;
};
PageActionIconView(const PageActionIconView&) = delete;
PageActionIconView& operator=(const PageActionIconView&) = delete;
~PageActionIconView() override;
void AddPageIconViewObserver(PageActionIconViewObserver* observer);
void RemovePageIconViewObserver(PageActionIconViewObserver* observer);
// Updates the color of the icon, this must be set before the icon is drawn.
// TODO(crbug.com/352245808): Color overrides should be moved into the
// IconLabelBubbleView superclass.
void SetIconColor(SkColor icon_color);
SkColor GetIconColor() const;
// Sets the active state of the icon. An active icon will be displayed in a
// "call to action" color.
void SetActive(bool active);
bool GetActive() const;
// Hide the icon on user input in progress and invokes UpdateImpl().
void Update();
// Returns the bubble instance for the icon.
virtual views::BubbleDialogDelegate* GetBubble() const = 0;
// Retrieve the text to be used for a tooltip or accessible name.
// If this string never changes, subclasses should use `SetAccessibleName`
// in the constructor instead of overriding this function.
virtual std::u16string GetTextForTooltipAndAccessibleName() const;
SkColor GetLabelColorForTesting() const;
std::optional<actions::ActionId> action_id() { return action_id_; }
const char* name_for_histograms() const { return name_for_histograms_; }
bool ephemeral() const { return ephemeral_; }
void ExecuteForTesting();
// Creates and updates the loading indicator.
// TODO(crbug.com/40627870): Ideally this should be lazily initialized in
// SetIsLoading(), but local card migration icon has a weird behavior that
// doing so will cause the indicator being invisible. Investigate and fix.
void InstallLoadingIndicatorForTesting();
// IconLabelBubbleView:
void SetVisible(bool visible) override;
PageActionIconLoadingIndicatorView* loading_indicator_for_testing() {
return loading_indicator_;
}
protected:
enum ExecuteSource {
EXECUTE_SOURCE_MOUSE,
EXECUTE_SOURCE_KEYBOARD,
EXECUTE_SOURCE_GESTURE,
};
PageActionIconView(CommandUpdater* command_updater,
int command_id,
IconLabelBubbleView::Delegate* parent_delegate,
Delegate* delegate,
const char* name_for_histograms,
std::optional<actions::ActionId> action_id = std::nullopt,
Browser* browser = nullptr,
bool ephemeral = true,
const gfx::FontList& = gfx::FontList());
// Returns true if a related bubble is showing.
bool IsBubbleShowing() const override;
// Enables or disables the associated command.
// Returns true if the command is enabled.
bool SetCommandEnabled(bool enabled) const;
// Invoked prior to executing the command.
virtual void OnExecuting(ExecuteSource execute_source) = 0;
// Invoked after executing the command.
virtual void DidExecute(ExecuteSource execute_source) {}
// Invoked after the icon is pressed.
virtual void OnPressed(bool activated) {}
// IconLabelBubbleView:
void ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) override;
void OnThemeChanged() override;
bool ShouldShowSeparator() const final;
void NotifyClick(const ui::Event& event) override;
bool IsTriggerableEvent(const ui::Event& event) override;
bool ShouldUpdateInkDropOnClickCanceled() const override;
void UpdateBorder() override;
virtual void UpdateTooltipText();
protected:
// Calls OnExecuting and runs |command_id_| with a valid |command_updater_|.
virtual void ExecuteCommand(ExecuteSource source);
// Gets the given vector icon.
virtual const gfx::VectorIcon& GetVectorIcon() const = 0;
// Provides the badge to be shown on top of the vector icon, if any.
virtual const gfx::VectorIcon& GetVectorIconBadge() const;
// Gives subclasses the opportunity to supply a non-vector icon for the page
// action icon view. If this returns an empty image the implementation will
// fall-back to using the vector icon.
virtual ui::ImageModel GetSizedIconImage(int size) const;
// IconLabelBubbleView:
void OnTouchUiChanged() override;
// Updates the icon image after some state has changed.
virtual void UpdateIconImage();
// Set if the page action icon is in the loading state.
void SetIsLoading(bool is_loading);
// Returns the associated web contents from the delegate.
content::WebContents* GetWebContents() const;
// Delegate accessor for subclasses.
Delegate* delegate() const { return delegate_; }
// Update the icon and sets visibility appropriate for the associated model
// state.
virtual void UpdateImpl() = 0;
Browser* browser() { return browser_; }
private:
void InstallLoadingIndicator();
void OnAXNameChanged(ax::mojom::StringAttribute attribute,
const std::optional<std::string>& name);
// What color to paint the icon with.
SkColor icon_color_ = gfx::kPlaceholderColor;
// The CommandUpdater for the Browser object that owns the location bar.
const raw_ptr<CommandUpdater, DanglingUntriaged> command_updater_;
// Delegate for access to associated state.
const raw_ptr<Delegate> delegate_;
// The command ID executed when the user clicks this icon.
const int command_id_;
// The ID for the associated ActionItem for this icon.
// This should eventually replace the above |command_id_|.
std::optional<actions::ActionId> action_id_;
// String that represents the page action type for metrics purposes.
const char* const name_for_histograms_;
// Should be true if this page action should only sometimes be displayed.
const bool ephemeral_;
// The active node_data. The precise definition of "active" is unique to each
// subclass, but generally indicates that the associated feature is acting on
// the web page.
bool active_ = false;
raw_ptr<Browser> browser_;
// The loading indicator, showing a throbber animation on top of the icon.
raw_ptr<PageActionIconLoadingIndicatorView> loading_indicator_ = nullptr;
base::ObserverList<PageActionIconViewObserver>::UncheckedAndDanglingUntriaged
observer_list_;
base::CallbackListSubscription name_changed_subscription_;
};
#endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
|