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
|
// 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_TOOLBAR_APP_MENU_H_
#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_APP_MENU_H_
#include <map>
#include <memory>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/bookmarks/bookmark_merged_surface_service_observer.h"
#include "chrome/browser/ui/global_error/global_error_observer.h"
#include "chrome/browser/ui/global_error/global_error_service.h"
#include "chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h"
#include "components/saved_tab_groups/public/saved_tab_group.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/views/controls/menu/menu_delegate.h"
class BookmarkMenuDelegate;
class Browser;
namespace views {
class MenuButtonController;
class MenuItemView;
class MenuRunner;
} // namespace views
struct BookmarkParentFolder;
// AppMenu adapts the AppMenuModel to view's menu related classes.
class AppMenu final : public views::MenuDelegate,
public BookmarkMergedSurfaceServiceObserver,
public GlobalErrorObserver {
public:
AppMenu(Browser* browser, ui::MenuModel* model, int run_types);
AppMenu(const AppMenu&) = delete;
AppMenu& operator=(const AppMenu&) = delete;
~AppMenu() override;
// Shows the menu relative to the specified controller's button.
void RunMenu(views::MenuButtonController* host);
// Closes the menu if it is open, otherwise does nothing.
void CloseMenu();
// Whether the menu is currently visible to the user.
bool IsShowing() const;
bool for_drop() const {
return (run_types_ & views::MenuRunner::FOR_DROP) != 0;
}
views::MenuItemView* root_menu_item() { return root_; }
base::WeakPtr<AppMenu> AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
void SetTimerForTesting(base::ElapsedTimer timer);
// views::MenuDelegate:
const gfx::FontList* GetLabelFontList(int command_id) const override;
std::optional<SkColor> GetLabelColor(int command_id) const override;
std::u16string GetTooltipText(int command_id,
const gfx::Point& p) const override;
bool IsTriggerableEvent(views::MenuItemView* menu,
const ui::Event& e) override;
bool GetDropFormats(views::MenuItemView* menu,
int* formats,
std::set<ui::ClipboardFormatType>* format_types) override;
bool AreDropTypesRequired(views::MenuItemView* menu) override;
bool CanDrop(views::MenuItemView* menu,
const ui::OSExchangeData& data) override;
ui::mojom::DragOperation GetDropOperation(views::MenuItemView* item,
const ui::DropTargetEvent& event,
DropPosition* position) override;
views::View::DropCallback GetDropCallback(
views::MenuItemView* menu,
DropPosition position,
const ui::DropTargetEvent& event) override;
bool ShowContextMenu(views::MenuItemView* source,
int command_id,
const gfx::Point& p,
ui::mojom::MenuSourceType source_type) override;
bool CanDrag(views::MenuItemView* menu) override;
void WriteDragData(views::MenuItemView* sender,
ui::OSExchangeData* data) override;
int GetDragOperations(views::MenuItemView* sender) override;
int GetMaxWidthForMenu(views::MenuItemView* menu) override;
bool IsItemChecked(int command_id) const override;
bool IsCommandEnabled(int command_id) const override;
void ExecuteCommand(int command_id, int mouse_event_flags) override;
bool GetAccelerator(int command_id,
ui::Accelerator* accelerator) const override;
void WillShowMenu(views::MenuItemView* menu) override;
void WillHideMenu(views::MenuItemView* menu) override;
bool ShouldCloseOnDragComplete() override;
void OnMenuClosed(views::MenuItemView* menu) override;
bool ShouldExecuteCommandWithoutClosingMenu(int command_id,
const ui::Event& event) override;
bool ShouldTryPositioningBesideAnchor() const override;
// BookmarkMergedSurfaceServiceObserver overrides:
void BookmarkMergedSurfaceServiceLoaded() override;
void BookmarkMergedSurfaceServiceBeingDeleted() override;
void BookmarkNodeAdded(const BookmarkParentFolder& parent,
size_t index) override;
void BookmarkNodesRemoved(
const BookmarkParentFolder& parent,
const base::flat_set<const bookmarks::BookmarkNode*>& nodes) override;
void BookmarkNodeMoved(const BookmarkParentFolder& old_parent,
size_t old_index,
const BookmarkParentFolder& new_parent,
size_t new_index) override;
void BookmarkNodeChanged(const bookmarks::BookmarkNode* node) override;
void BookmarkNodeFaviconChanged(
const bookmarks::BookmarkNode* node) override {}
void BookmarkParentFolderChildrenReordered(
const BookmarkParentFolder& folder) override;
void BookmarkAllUserNodesRemoved() override;
// GlobalErrorObserver:
void OnGlobalErrorsChanged() override;
views::View* GetZoomAppMenuViewForTest();
private:
class CutCopyPasteView;
class RecentTabsMenuModelDelegate;
class ZoomView;
typedef std::pair<ui::MenuModel*, size_t> Entry;
typedef std::map<int, Entry> CommandIDToEntry;
void BookmarkMergedSurfaceServiceChanged();
// Populates |parent| with all the child menus in |model|. Recursively invokes
// |PopulateMenu| for any submenu.
void PopulateMenu(views::MenuItemView* parent, ui::MenuModel* model);
// Adds a new menu item to |parent| at |menu_index| to represent the item in
// |model| at |model_index|:
// - |menu_index|: position in |parent| to add the new item.
// - |model_index|: position in |model| to retrieve information about the
// new menu item.
// The returned item's MenuItemView::GetCommand() is the same as that of
// |model|->GetCommandIdAt(|model_index|).
views::MenuItemView* AddMenuItem(views::MenuItemView* parent,
size_t menu_index,
ui::MenuModel* model,
size_t model_index,
ui::MenuModel::ItemType menu_type);
// Invoked from the cut/copy/paste menus. Cancels the current active menu and
// activates the menu item in |model| at |index|.
void CancelAndEvaluate(ui::ButtonMenuItemModel* model, size_t index);
// Creates the bookmark menu if necessary. Does nothing if already created or
// the bookmark model isn't loaded.
void CreateBookmarkMenu();
// Returns the index of the MenuModel/index pair representing the |command_id|
// in |command_id_to_entry_|.
size_t ModelIndexFromCommandId(int command_id) const;
std::unique_ptr<views::MenuRunner> menu_runner_;
// The views menu. Owned by `menu_runner_`.
raw_ptr<views::MenuItemView> root_ = nullptr;
// Maps from the command ID in model to the model/index pair the item came
// from.
CommandIDToEntry command_id_to_entry_;
// Browser the menu is being shown for.
const raw_ptr<Browser, DanglingUntriaged> browser_;
const raw_ptr<ui::MenuModel> model_;
// |CancelAndEvaluate| sets |selected_menu_model_| and |selected_index_|.
// If |selected_menu_model_| is non-null after the menu completes
// ActivatedAt is invoked. This is done so that ActivatedAt isn't invoked
// while the message loop is nested.
raw_ptr<ui::ButtonMenuItemModel, DanglingUntriaged> selected_menu_model_ =
nullptr;
size_t selected_index_ = 0;
std::vector<base::CallbackListSubscription>
profile_menu_item_selected_subscription_list_;
// Used for managing the bookmark menu items.
std::unique_ptr<BookmarkMenuDelegate> bookmark_menu_delegate_;
// Menu corresponding to IDC_BOOKMARKS_MENU.
raw_ptr<views::MenuItemView, DanglingUntriaged> bookmark_menu_ = nullptr;
// Used for managing the tab group menu items.
std::unique_ptr<tab_groups::STGEverythingMenu> stg_everything_menu_;
// Menu corresponding to IDC_SAVED_TAB_GROUPS_MENU.
raw_ptr<views::MenuItemView> saved_tab_groups_menu_ = nullptr;
// Menu corresponding to IDC_FEEDBACK.
raw_ptr<views::MenuItemView, DanglingUntriaged> feedback_menu_item_ = nullptr;
// Menu corresponding to IDC_TAKE_SCREENSHOT.
raw_ptr<views::MenuItemView, DanglingUntriaged> screenshot_menu_item_ =
nullptr;
// Used for managing "Recent tabs" menu items.
std::unique_ptr<RecentTabsMenuModelDelegate> recent_tabs_menu_model_delegate_;
base::ScopedObservation<GlobalErrorService, GlobalErrorObserver>
global_error_observation_{this};
// The bit mask of views::MenuRunner::RunTypes.
const int run_types_;
// Records the time from when menu opens to when the user selects a menu item.
base::ElapsedTimer menu_opened_timer_;
base::WeakPtrFactory<AppMenu> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_APP_MENU_H_
|