| // Copyright 2024 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_TOOLBAR_PINNED_ACTION_TOOLBAR_BUTTON_H_ |
| #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_PINNED_ACTION_TOOLBAR_BUTTON_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <type_traits> |
| |
| #include "base/auto_reset.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_layout.h" |
| #include "chrome/browser/ui/views/toolbar/pinned_toolbar_button_status_indicator.h" |
| #include "chrome/browser/ui/views/toolbar/toolbar_button.h" |
| #include "ui/base/metadata/metadata_header_macros.h" |
| #include "ui/views/controls/button/button.h" |
| #include "ui/views/controls/button/label_button.h" |
| |
| class Browser; |
| class PinnedToolbarActionsContainer; |
| |
| class PinnedActionToolbarButton : public ToolbarButton { |
| METADATA_HEADER(PinnedActionToolbarButton, ToolbarButton) |
| |
| public: |
| PinnedActionToolbarButton( |
| Browser* browser, |
| actions::ActionId action_id, |
| base::WeakPtr<PinnedToolbarActionsContainer> container); |
| ~PinnedActionToolbarButton() override; |
| |
| actions::ActionId GetActionId() { return action_id_; } |
| |
| void AddHighlight(); |
| void ResetHighlight(); |
| void SetPinned(bool pinned); |
| bool IsActive(); |
| base::AutoReset<bool> SetNeedsDelayedDestruction( |
| bool needs_delayed_destruction); |
| void SetIconVisibility(bool is_visible); |
| bool NeedsDelayedDestruction() { return needs_delayed_destruction_; } |
| void SetIsPermanent() { permanent_ = true; } |
| void SetIsActionShowingBubble(bool showing_bubble) { |
| is_action_showing_bubble_ = showing_bubble; |
| } |
| void SetShouldShowEphemerallyInToolbar(bool should_show_in_toolbar) { |
| should_show_in_toolbar_ = should_show_in_toolbar; |
| } |
| void SetActionEngaged(bool action_engaged); |
| void UpdateIcon() override; |
| bool ShouldShowEphemerallyInToolbar(); |
| bool IsIconVisible() { return is_icon_visible_; } |
| bool IsPinned() { return pinned_; } |
| bool IsPermanent() { return permanent_; } |
| views::View* GetImageContainerView() { return image_container_view(); } |
| |
| bool ShouldSkipExecutionForTesting() { return skip_execution_; } |
| |
| using views::LabelButton::image_container_view; |
| // View: |
| bool OnKeyPressed(const ui::KeyEvent& event) override; |
| |
| // ToolbarButton: |
| gfx::Size CalculatePreferredSize( |
| const views::SizeBounds& available_size) const override; |
| std::unique_ptr<views::ActionViewInterface> GetActionViewInterface() override; |
| void Layout(PassKey) override; |
| bool OnMousePressed(const ui::MouseEvent& event) override; |
| void OnMouseReleased(const ui::MouseEvent& event) override; |
| |
| void UpdateStatusIndicator(); |
| void HideStatusIndicator(); |
| PinnedToolbarButtonStatusIndicator* GetStatusIndicatorForTesting() { |
| return status_indicator_; |
| } |
| |
| private: |
| void OnAnchorCountChanged(size_t anchor_count); |
| |
| raw_ptr<Browser> browser_; |
| raw_ptr<PinnedToolbarButtonStatusIndicator> status_indicator_; |
| |
| actions::ActionId action_id_; |
| base::CallbackListSubscription action_changed_subscription_; |
| base::CallbackListSubscription action_count_changed_subscription_; |
| // Used to ensure the button remains highlighted while active. |
| std::optional<Button::ScopedAnchorHighlight> anchor_higlight_; |
| bool pinned_ = false; |
| bool needs_delayed_destruction_ = false; |
| bool permanent_ = false; |
| bool is_icon_visible_ = true; |
| bool action_engaged_ = false; |
| // Set when the action is currently showing an associated bubble. |
| bool is_action_showing_bubble_ = false; |
| bool skip_execution_ = false; |
| |
| // Set when something is currently anchored to the button (bubble dialog, |
| // context menu, etc.) |
| bool has_anchor_ = false; |
| |
| // Set when a button should be shown in the toolbar regardless of whether it |
| // is pinned or active. This is used in cases like when the recent download |
| // button should be visible after a download. |
| bool should_show_in_toolbar_ = false; |
| |
| // Track the owning container using a weak pointer, because if this were a raw |
| // pointer, it would point to the wrong type during teardown (as child views |
| // aren't destructed until the `views::View` destructor). |
| base::WeakPtr<PinnedToolbarActionsContainer> container_; |
| }; |
| |
| class PinnedActionToolbarButtonActionViewInterface |
| : public ToolbarButtonActionViewInterface { |
| public: |
| explicit PinnedActionToolbarButtonActionViewInterface( |
| PinnedActionToolbarButton* action_view); |
| ~PinnedActionToolbarButtonActionViewInterface() override = default; |
| |
| // ToolbarButtonActionViewInterface: |
| void ActionItemChangedImpl(actions::ActionItem* action_item) override; |
| void InvokeActionImpl(actions::ActionItem* action_item) override; |
| void OnViewChangedImpl(actions::ActionItem* action_item) override; |
| |
| private: |
| raw_ptr<PinnedActionToolbarButton> action_view_; |
| }; |
| |
| extern const ui::ClassProperty< |
| std::underlying_type_t<PinnedToolbarActionFlexPriority>>* const |
| kToolbarButtonFlexPriorityKey; |
| |
| #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_PINNED_ACTION_TOOLBAR_BUTTON_H_ |