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
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_CLIPBOARD_CLIPBOARD_HISTORY_MENU_MODEL_ADAPTER_H_
#define ASH_CLIPBOARD_CLIPBOARD_HISTORY_MENU_MODEL_ADAPTER_H_
#include <memory>
#include <optional>
#include "ash/ash_export.h"
#include "ash/public/cpp/clipboard_history_controller.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/menus/simple_menu_model.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
namespace gfx {
class Rect;
} // namespace gfx
namespace views {
class MenuItemView;
class MenuRunner;
} // namespace views
namespace ash {
namespace clipboard_history_util {
enum class Action;
} // namespace clipboard_history_util
class ClipboardHistory;
class ClipboardHistoryItem;
class ClipboardHistoryItemView;
// Used to show the clipboard history menu, which holds the last few things
// copied.
class ASH_EXPORT ClipboardHistoryMenuModelAdapter
: public views::MenuModelAdapter {
public:
static std::unique_ptr<ClipboardHistoryMenuModelAdapter> Create(
ui::SimpleMenuModel::Delegate* delegate,
ClipboardHistoryController::OnMenuClosingCallback
on_menu_closing_callback,
base::RepeatingClosure menu_closed_callback,
const ClipboardHistory* clipboard_history);
ClipboardHistoryMenuModelAdapter(const ClipboardHistoryMenuModelAdapter&) =
delete;
ClipboardHistoryMenuModelAdapter& operator=(
const ClipboardHistoryMenuModelAdapter&) = delete;
~ClipboardHistoryMenuModelAdapter() override;
// Shows the menu anchored at `anchor_rect`. `source_type` and `show_source`
// indicate how the menu was triggered. `menu_last_time_shown` and
// `nudge_last_time_shown` indicate when the menu or any nudge was last shown.
void Run(const gfx::Rect& anchor_rect,
ui::mojom::MenuSourceType source_type,
crosapi::mojom::ClipboardHistoryControllerShowSource show_source,
const std::optional<base::Time>& menu_last_time_shown,
const std::optional<base::Time>& nudge_last_time_shown);
// Returns if the menu is currently running.
bool IsRunning() const;
// Hides and cancels the menu. `will_paste_item` indicates whether a clipboard
// history item will be pasted after the menu is closed.
void Cancel(bool will_paste_item);
// Returns the command of the menu's first clipboard history item. This
// differs from `clipboard_history_util::kFirstItemCommandId` when the menu's
// first item has been removed. If the menu is empty, the result is absent.
std::optional<int> GetFirstMenuItemCommand();
// Returns the command of the currently selected menu item. If no menu item is
// currently selected, returns |std::nullopt|.
std::optional<int> GetSelectedMenuItemCommand() const;
// Returns the item mapped by `command_id` in `item_snapshots_`.
const ClipboardHistoryItem& GetItemFromCommandId(int command_id) const;
// Returns the count of menu items.
size_t GetMenuItemsCount() const;
// Selects the menu item specified by `command_id`.
void SelectMenuItemWithCommandId(int command_id);
// Selects the menu item hovered by mouse.
void SelectMenuItemHoveredByMouse();
// Removes the menu item specified by `command_id`.
void RemoveMenuItemWithCommandId(int command_id);
// Advances the pseudo focus (backward if `reverse` is true).
void AdvancePseudoFocus(bool reverse);
// Returns the action to take on the menu item specified by `command_id`.
clipboard_history_util::Action GetActionForCommandId(int command_id) const;
// Returns menu bounds in screen coordinates.
gfx::Rect GetMenuBoundsInScreenForTest() const;
const views::MenuItemView* GetMenuItemViewAtForTest(size_t index) const;
views::MenuItemView* GetMenuItemViewAtForTest(size_t index);
const ui::SimpleMenuModel* GetModelForTest() const;
private:
class MenuModelWithWillCloseCallback;
class ScopedA11yIgnore;
using ItemViewsByCommandId =
std::map<int, raw_ptr<ClipboardHistoryItemView, CtnExperimental>>;
ClipboardHistoryMenuModelAdapter(
std::unique_ptr<MenuModelWithWillCloseCallback> model,
base::RepeatingClosure menu_closed_callback,
const ClipboardHistory* clipboard_history);
// Advances the pseduo focus from the selected history item view (backward if
// `reverse` is true).
void AdvancePseudoFocusFromSelectedItem(bool reverse);
// Returns the command id of the menu item to be selected after the
// menu item specified by `command_id` is deleted.
int CalculateSelectedCommandIdAfterDeletion(int command_id) const;
// Removes the item view specified by `command_id` from the root menu.
void RemoveItemView(int command_id);
// views::MenuModelAdapter:
views::MenuItemView* AppendMenuItem(views::MenuItemView* menu,
ui::MenuModel* model,
size_t index) override;
void OnMenuClosed(views::MenuItemView* menu) override;
// The model which holds the contents of the menu.
std::unique_ptr<MenuModelWithWillCloseCallback> const model_;
// Responsible for showing `root_view_`.
std::unique_ptr<views::MenuRunner> menu_runner_;
// The root MenuItemView which contains all child MenuItemViews. Owned by
// `menu_runner_`.
raw_ptr<views::MenuItemView> root_view_ = nullptr;
// The timestamp taken when the menu is opened. Used in metrics.
base::TimeTicks menu_open_time_;
// The source which opened the menu, absent until the menu is `Run()`.
std::optional<crosapi::mojom::ClipboardHistoryControllerShowSource>
menu_show_source_;
// The mapping between the command ids and items that are copied from
// `clipboard_history_` when the menu is created. It is used to solve the
// possible inconsistency between the menu model data and the clipboard
// history data. For example, a new item is added to `clipboard_history_`
// while the menu is showing.
// It updates synchronously when a item is removed.
std::map<int, ClipboardHistoryItem> item_snapshots_;
// Stores mappings between command ids and history item view pointers.
// It updates synchronously when a item is removed.
ItemViewsByCommandId item_views_by_command_id_;
const raw_ptr<const ClipboardHistory> clipboard_history_;
// Indicates the number of item deletion operations in progress. Note that
// a `ClipboardHistoryItemView` instance is deleted asynchronously.
int item_deletion_in_progress_count_ = 0;
// The index of the clipboard history menu header, if it exists.
std::optional<size_t> header_index_;
// The index of the clipboard history menu footer, if it exists.
std::optional<size_t> footer_index_;
std::unique_ptr<ScopedA11yIgnore> scoped_ignore_;
// Indicates whether `Run()` has been called before.
bool run_before_ = false;
base::WeakPtrFactory<ClipboardHistoryMenuModelAdapter> weak_ptr_factory_{
this};
};
} // namespace ash
#endif // ASH_CLIPBOARD_CLIPBOARD_HISTORY_MENU_MODEL_ADAPTER_H_
|