#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 views {
class MenuItemView;
class MenuRunner;
}
namespace ash {
namespace clipboard_history_util {
enum class Action;
}
class ClipboardHistory;
class ClipboardHistoryItem;
class ClipboardHistoryItemView;
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;
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);
bool IsRunning() const;
void Cancel(bool will_paste_item);
std::optional<int> GetFirstMenuItemCommand();
std::optional<int> GetSelectedMenuItemCommand() const;
const ClipboardHistoryItem& GetItemFromCommandId(int command_id) const;
size_t GetMenuItemsCount() const;
void SelectMenuItemWithCommandId(int command_id);
void SelectMenuItemHoveredByMouse();
void RemoveMenuItemWithCommandId(int command_id);
void AdvancePseudoFocus(bool reverse);
clipboard_history_util::Action GetActionForCommandId(int command_id) const;
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);
void AdvancePseudoFocusFromSelectedItem(bool reverse);
int CalculateSelectedCommandIdAfterDeletion(int command_id) const;
void RemoveItemView(int command_id);
views::MenuItemView* AppendMenuItem(views::MenuItemView* menu,
ui::MenuModel* model,
size_t index) override;
void OnMenuClosed(views::MenuItemView* menu) override;
std::unique_ptr<MenuModelWithWillCloseCallback> const model_;
std::unique_ptr<views::MenuRunner> menu_runner_;
raw_ptr<views::MenuItemView> root_view_ = nullptr;
base::TimeTicks menu_open_time_;
std::optional<crosapi::mojom::ClipboardHistoryControllerShowSource>
menu_show_source_;
std::map<int, ClipboardHistoryItem> item_snapshots_;
ItemViewsByCommandId item_views_by_command_id_;
const raw_ptr<const ClipboardHistory> clipboard_history_;
int item_deletion_in_progress_count_ = 0;
std::optional<size_t> header_index_;
std::optional<size_t> footer_index_;
std::unique_ptr<ScopedA11yIgnore> scoped_ignore_;
bool run_before_ = false;
base::WeakPtrFactory<ClipboardHistoryMenuModelAdapter> weak_ptr_factory_{
this};
};
}
#endif