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
|
// Copyright 2021 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_SIDE_PANEL_SIDE_PANEL_ENTRY_H_
#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_ENTRY_H_
#include <map>
#include <memory>
#include <optional>
#include <string>
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_key.h"
#include "chrome/browser/ui/views/side_panel/side_panel_enums.h"
#include "extensions/common/extension_id.h"
#include "ui/base/class_property.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/view.h"
class SidePanelEntryScope;
class SidePanelEntryObserver;
enum class SidePanelEntryHideReason;
// This class represents an entry inside the side panel. These are owned by
// a SidePanelRegistry (either a per-tab or a per-window registry).
class SidePanelEntry final : public ui::PropertyHandler {
public:
// The default and minimum acceptable side panel content width.
static constexpr int kSidePanelDefaultContentWidth = 360;
using CreateContentCallback =
base::RepeatingCallback<std::unique_ptr<views::View>(
SidePanelEntryScope&)>;
using Id = SidePanelEntryId;
using Key = SidePanelEntryKey;
// If adding a callback to provide a URL to the 'Open in New Tab' button, you
// must also add a relevant entry in actions.xml because a user action is
// logged on button click.
SidePanelEntry(Key key,
CreateContentCallback create_content_callback,
base::RepeatingCallback<GURL()> open_in_new_tab_url_callback,
base::RepeatingCallback<std::unique_ptr<ui::MenuModel>()>
more_info_callback,
base::RepeatingCallback<int()> default_content_width_callback);
// This constructor is primarily used for extensions.Extensions don't have
// `Open in New Tab` functionality. Other side panels can use this if nothing
// custom is needed (we call the other constructor passing
// base::NullCallback()).
SidePanelEntry(Key key,
CreateContentCallback create_content_callback,
base::RepeatingCallback<int()> default_content_width_callback);
SidePanelEntry(const SidePanelEntry&) = delete;
SidePanelEntry& operator=(const SidePanelEntry&) = delete;
~SidePanelEntry() override;
// Creates the content to be shown inside the side panel when this entry is
// shown.
std::unique_ptr<views::View> GetContent();
void CacheView(std::unique_ptr<views::View> view);
void ClearCachedView();
views::View* CachedView() {
return content_view_ ? content_view_.get() : nullptr;
}
// Called when the entry has been shown/hidden in the side panel.
void OnEntryShown();
void OnEntryWillHide(SidePanelEntryHideReason reason);
void OnEntryHidden();
const Key& key() const { return key_; }
void set_last_open_trigger(std::optional<SidePanelOpenTrigger> trigger) {
last_open_trigger_ = trigger;
}
std::optional<SidePanelOpenTrigger> last_open_trigger() const {
return last_open_trigger_;
}
void AddObserver(SidePanelEntryObserver* observer);
void RemoveObserver(SidePanelEntryObserver* observer);
// Gets the 'Open in New Tab' URL. Returns an empty GURL if this function is
// unavailable for the current side panel entry.
GURL GetOpenInNewTabURL() const;
// Gets the menu model for the more info menu if the current side panel entry
// has one, otherwise null.
std::unique_ptr<ui::MenuModel> GetMoreInfoMenuModel() const;
// Returns whether the side panel entry has a defined callback for getting the
// open new tab button URL.
bool SupportsNewTabButton();
// Returns whether the side panel entry has a defined callback for the more
// info button.
bool SupportsMoreInfoButton();
// Resets the `entry_show_triggered_timestamp_` so we don't track metrics
// incorrectly.
void ResetLoadTimestamp();
void set_scope(SidePanelEntryScope* scope) { scope_ = scope; }
base::WeakPtr<SidePanelEntry> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Gets the default content width for this entry, if one is specified.
int GetDefaultContentWidth() const;
// Allows tests to override the default width for an existing entry.
void SetDefaultContentWidthForTesting(int width) {
default_content_width_ = width;
}
private:
const Key key_;
std::unique_ptr<views::View> content_view_;
// Scope of this entry, will outlive the entry and its content.
raw_ptr<SidePanelEntryScope> scope_ = nullptr;
CreateContentCallback create_content_callback_;
// If this returns an empty GURL, the 'Open in New Tab' button is hidden.
base::RepeatingCallback<GURL()> open_in_new_tab_url_callback_;
// If this returns null, the more info button is hidden.
base::RepeatingCallback<std::unique_ptr<ui::MenuModel>()> more_info_callback_;
// When specified sets the default starting width for this entry. However, if
// the user manually changes the size of the side panel that preference is
// used instead (prefs::kSidePanelIdToWidth). If nothing is specified, then
// the default minimum content width of the side panel is used.
base::RepeatingCallback<int()> default_content_width_callback_;
// Timestamp of when the side panel was triggered to be shown.
base::TimeTicks entry_show_triggered_timestamp_;
base::TimeTicks entry_shown_timestamp_;
base::ObserverList<SidePanelEntryObserver> observers_;
// The last trigger that caused this side panel entry to be shown. This is
// used for metrics.
std::optional<SidePanelOpenTrigger> last_open_trigger_;
// The default minimum content width for the side panel that can be overridden
// for testing. This is used if the default_content_width_callback_ is not
// set. However, if the user manually changes the size of the side panel that
// preference is used instead (prefs::kSidePanelIdToWidth).
int default_content_width_ = kSidePanelDefaultContentWidth;
base::WeakPtrFactory<SidePanelEntry> weak_factory_{this};
};
extern const ui::ClassProperty<bool>* const
kShouldShowTitleInSidePanelHeaderKey;
#endif // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_ENTRY_H_
|