#ifndef UI_MENUS_SIMPLE_MENU_MODEL_H_
#define UI_MENUS_SIMPLE_MENU_MODEL_H_
#include <optional>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/types/pass_key.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/menu_model.h"
namespace user_education {
class NewBadgeController;
}
class ChromeLabsViewController;
namespace ui {
class ButtonMenuItemModel;
class COMPONENT_EXPORT(UI_MENUS) IsNewFeatureAtValue {
public:
IsNewFeatureAtValue() = default;
IsNewFeatureAtValue(base::PassKey<user_education::NewBadgeController>,
bool value)
: ui::IsNewFeatureAtValue(value) {}
IsNewFeatureAtValue(base::PassKey<ChromeLabsViewController>, bool value)
: ui::IsNewFeatureAtValue(value) {}
IsNewFeatureAtValue(const IsNewFeatureAtValue&) = default;
IsNewFeatureAtValue& operator=(const IsNewFeatureAtValue&) = default;
operator bool() const { return value_; }
bool operator!() const { return !value_; }
static IsNewFeatureAtValue create_for_test(bool value) {
IsNewFeatureAtValue result;
result.value_ = value;
return result;
}
private:
explicit IsNewFeatureAtValue(bool value) : value_(value) {}
bool value_ = false;
};
class COMPONENT_EXPORT(UI_MENUS) SimpleMenuModel : public MenuModel {
public:
static constexpr int kDefaultIconSize = 16;
class COMPONENT_EXPORT(UI_MENUS) Delegate : public AcceleratorProvider {
public:
~Delegate() override = default;
virtual bool IsCommandIdChecked(int command_id) const;
virtual bool IsCommandIdEnabled(int command_id) const;
virtual bool IsCommandIdVisible(int command_id) const;
virtual bool IsCommandIdAlerted(int command_id) const;
virtual bool IsElementIdAlerted(ui::ElementIdentifier element_id) const;
virtual bool IsItemForCommandIdDynamic(int command_id) const;
virtual std::u16string GetLabelForCommandId(int command_id) const;
virtual ImageModel GetIconForCommandId(int command_id) const;
virtual void ExecuteCommand(int command_id, int event_flags) = 0;
virtual void OnMenuWillShow(SimpleMenuModel* source);
virtual void MenuClosed(SimpleMenuModel* source);
bool GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) const override;
};
explicit SimpleMenuModel(Delegate* delegate);
SimpleMenuModel(const SimpleMenuModel&) = delete;
SimpleMenuModel& operator=(const SimpleMenuModel&) = delete;
~SimpleMenuModel() override;
void AddItem(int command_id, const std::u16string& label);
void AddItemWithStringId(int command_id, int string_id);
void AddItemWithIcon(int command_id,
const std::u16string& label,
const ui::ImageModel& icon);
void AddItemWithStringIdAndIcon(int command_id,
int string_id,
const ui::ImageModel& icon);
void AddCheckItem(int command_id, const std::u16string& label);
void AddCheckItemWithStringId(int command_id, int string_id);
void AddRadioItem(int command_id, const std::u16string& label, int group_id);
void AddRadioItemWithStringId(int command_id, int string_id, int group_id);
void AddHighlightedItemWithIcon(int command_id,
const std::u16string& label,
const ui::ImageModel& icon);
void AddTitle(const std::u16string& label);
void AddTitleWithStringId(int string_id);
void AddSeparator(MenuSeparatorType separator_type);
void AddButtonItem(int command_id, ButtonMenuItemModel* model);
void AddSubMenu(int command_id,
const std::u16string& label,
MenuModel* model);
void AddSubMenuWithStringId(int command_id, int string_id, MenuModel* model);
void AddSubMenuWithIcon(int command_id,
const std::u16string& label,
MenuModel* model,
const ImageModel& icon);
void AddSubMenuWithStringIdAndIcon(int command_id,
int string_id,
MenuModel* model,
const ui::ImageModel& icon);
void AddActionableSubMenu(int command_id,
const std::u16string& label,
MenuModel* model);
void AddActionableSubmenuWithStringIdAndIcon(int command_id,
int string_id,
MenuModel* model,
const ui::ImageModel& icon);
void InsertItemAt(size_t index, int command_id, const std::u16string& label);
void InsertItemWithStringIdAt(size_t index, int command_id, int string_id);
void InsertCheckItemAt(size_t index,
int command_id,
const std::u16string& label);
void InsertCheckItemWithStringIdAt(size_t index,
int command_id,
int string_id);
void InsertRadioItemAt(size_t index,
int command_id,
const std::u16string& label,
int group_id);
void InsertRadioItemWithStringIdAt(size_t index,
int command_id,
int string_id,
int group_id);
void InsertTitleWithStringIdAt(size_t index, int string_id);
void InsertSeparatorAt(size_t index, MenuSeparatorType separator_type);
void InsertSubMenuAt(size_t index,
int command_id,
const std::u16string& label,
MenuModel* model);
void InsertSubMenuWithStringIdAt(size_t index,
int command_id,
int string_id,
MenuModel* model);
void RemoveItemAt(size_t index);
void SetIcon(size_t index, const ui::ImageModel& icon);
void SetLabel(size_t index, const std::u16string& label);
void SetAcceleratorAt(size_t index, const ui::Accelerator& accelerator);
void SetMinorText(size_t index, const std::u16string& minor_text);
void SetMinorIcon(size_t index, const ui::ImageModel& minor_icon);
void SetEnabledAt(size_t index, bool enabled);
void SetVisibleAt(size_t index, bool visible);
void SetIsNewFeatureAt(size_t index, IsNewFeatureAtValue is_new_feature);
void SetMayHaveMnemonicsAt(size_t index, bool may_have_mnemonics);
void SetAccessibleNameAt(size_t index, std::u16string accessible_name);
void SetElementIdentifierAt(size_t index, ElementIdentifier unique_id);
void SetExecuteCallbackAt(size_t index,
base::RepeatingCallback<void(int)> callback);
void Clear();
std::optional<size_t> GetIndexOfCommandId(int command_id) const;
void SetForceShowAcceleratorForItemAt(size_t index,
bool force_show_accelerator_for_item);
base::WeakPtr<ui::MenuModel> AsWeakPtr() override;
size_t GetItemCount() const override;
ItemType GetTypeAt(size_t index) const override;
ui::MenuSeparatorType GetSeparatorTypeAt(size_t index) const override;
int GetCommandIdAt(size_t index) const override;
std::u16string GetLabelAt(size_t index) const override;
std::u16string GetMinorTextAt(size_t index) const override;
ImageModel GetMinorIconAt(size_t index) const override;
bool IsItemDynamicAt(size_t index) const override;
bool GetAcceleratorAt(size_t index,
ui::Accelerator* accelerator) const override;
bool IsItemCheckedAt(size_t index) const override;
int GetGroupIdAt(size_t index) const override;
ImageModel GetIconAt(size_t index) const override;
ui::ButtonMenuItemModel* GetButtonMenuItemAt(size_t index) const override;
bool IsEnabledAt(size_t index) const override;
bool IsVisibleAt(size_t index) const override;
bool IsAlertedAt(size_t index) const override;
bool IsNewFeatureAt(size_t index) const override;
bool MayHaveMnemonicsAt(size_t index) const override;
std::u16string GetAccessibleNameAt(size_t index) const override;
ElementIdentifier GetElementIdentifierAt(size_t index) const override;
void ActivatedAt(size_t index) override;
void ActivatedAt(size_t index, int event_flags) override;
MenuModel* GetSubmenuModelAt(size_t index) const override;
void MenuWillShow() override;
void MenuWillClose() override;
bool GetForceShowAcceleratorForItemAt(size_t index) const override;
protected:
Delegate* delegate() { return delegate_; }
virtual void MenuItemsChanged();
private:
struct Item {
Item(Item&&);
Item(int command_id, ItemType type, std::u16string label);
Item& operator=(Item&&);
~Item();
int command_id = 0;
ItemType type = TYPE_COMMAND;
std::u16string label;
ui::Accelerator accelerator;
std::u16string minor_text;
ImageModel minor_icon;
ImageModel icon;
int group_id = -1;
raw_ptr<MenuModel, DanglingUntriaged> submenu = nullptr;
raw_ptr<ButtonMenuItemModel, DanglingUntriaged> button_model = nullptr;
MenuSeparatorType separator_type = NORMAL_SEPARATOR;
bool enabled = true;
bool visible = true;
bool is_new_feature = false;
bool may_have_mnemonics = true;
bool force_show_accelerator_for_item = false;
std::u16string accessible_name;
ElementIdentifier unique_id;
base::RepeatingCallback<void(int)> on_execute_callback;
};
using ItemVector = std::vector<Item>;
size_t ValidateItemIndex(size_t index) const;
void AppendItem(Item item);
void InsertItemAtIndex(Item item, size_t index);
void ValidateItem(const Item& item);
void OnMenuClosed();
ItemVector items_;
raw_ptr<Delegate, AcrossTasksDanglingUntriaged> delegate_;
base::WeakPtrFactory<SimpleMenuModel> method_factory_{this};
};
}
#endif