blob: 5faebc2c5021df7dba88cea5720b761f0c8663f4 [file] [log] [blame]
// 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_