electron_api_menu.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #ifndef ELECTRON_SHELL_BROWSER_API_ELECTRON_API_MENU_H_
  5. #define ELECTRON_SHELL_BROWSER_API_ELECTRON_API_MENU_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/functional/callback.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "gin/arguments.h"
  11. #include "shell/browser/api/electron_api_base_window.h"
  12. #include "shell/browser/event_emitter_mixin.h"
  13. #include "shell/browser/ui/electron_menu_model.h"
  14. #include "shell/common/gin_helper/constructible.h"
  15. #include "shell/common/gin_helper/pinnable.h"
  16. namespace electron::api {
  17. class Menu : public gin::Wrappable<Menu>,
  18. public gin_helper::EventEmitterMixin<Menu>,
  19. public gin_helper::Constructible<Menu>,
  20. public gin_helper::Pinnable<Menu>,
  21. public ElectronMenuModel::Delegate,
  22. public ElectronMenuModel::Observer {
  23. public:
  24. // gin_helper::Constructible
  25. static gin::Handle<Menu> New(gin::Arguments* args);
  26. static void FillObjectTemplate(v8::Isolate*, v8::Local<v8::ObjectTemplate>);
  27. static const char* GetClassName() { return "Menu"; }
  28. // gin::Wrappable
  29. static gin::WrapperInfo kWrapperInfo;
  30. const char* GetTypeName() override;
  31. #if BUILDFLAG(IS_MAC)
  32. // Set the global menubar.
  33. static void SetApplicationMenu(Menu* menu);
  34. // Fake sending an action from the application menu.
  35. static void SendActionToFirstResponder(const std::string& action);
  36. #endif
  37. ElectronMenuModel* model() const { return model_.get(); }
  38. // disable copy
  39. Menu(const Menu&) = delete;
  40. Menu& operator=(const Menu&) = delete;
  41. protected:
  42. explicit Menu(gin::Arguments* args);
  43. ~Menu() override;
  44. // Returns a new callback which keeps references of the JS wrapper until the
  45. // passed |callback| is called.
  46. base::OnceClosure BindSelfToClosure(base::OnceClosure callback);
  47. // ui::SimpleMenuModel::Delegate:
  48. bool IsCommandIdChecked(int command_id) const override;
  49. bool IsCommandIdEnabled(int command_id) const override;
  50. bool IsCommandIdVisible(int command_id) const override;
  51. bool ShouldCommandIdWorkWhenHidden(int command_id) const override;
  52. bool GetAcceleratorForCommandIdWithParams(
  53. int command_id,
  54. bool use_default_accelerator,
  55. ui::Accelerator* accelerator) const override;
  56. bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
  57. #if BUILDFLAG(IS_MAC)
  58. bool GetSharingItemForCommandId(
  59. int command_id,
  60. ElectronMenuModel::SharingItem* item) const override;
  61. v8::Local<v8::Value> GetUserAcceleratorAt(int command_id) const;
  62. #endif
  63. void ExecuteCommand(int command_id, int event_flags) override;
  64. void OnMenuWillShow(ui::SimpleMenuModel* source) override;
  65. virtual void PopupAt(BaseWindow* window,
  66. int x,
  67. int y,
  68. int positioning_item,
  69. ui::MenuSourceType source_type,
  70. base::OnceClosure callback) = 0;
  71. virtual void ClosePopupAt(int32_t window_id) = 0;
  72. virtual std::u16string GetAcceleratorTextAtForTesting(int index) const;
  73. std::unique_ptr<ElectronMenuModel> model_;
  74. raw_ptr<Menu> parent_ = nullptr;
  75. // Observable:
  76. void OnMenuWillClose() override;
  77. void OnMenuWillShow() override;
  78. private:
  79. void InsertItemAt(int index, int command_id, const std::u16string& label);
  80. void InsertSeparatorAt(int index);
  81. void InsertCheckItemAt(int index,
  82. int command_id,
  83. const std::u16string& label);
  84. void InsertRadioItemAt(int index,
  85. int command_id,
  86. const std::u16string& label,
  87. int group_id);
  88. void InsertSubMenuAt(int index,
  89. int command_id,
  90. const std::u16string& label,
  91. Menu* menu);
  92. void SetIcon(int index, const gfx::Image& image);
  93. void SetSublabel(int index, const std::u16string& sublabel);
  94. void SetToolTip(int index, const std::u16string& toolTip);
  95. void SetRole(int index, const std::u16string& role);
  96. void Clear();
  97. int GetIndexOfCommandId(int command_id) const;
  98. int GetItemCount() const;
  99. int GetCommandIdAt(int index) const;
  100. std::u16string GetLabelAt(int index) const;
  101. std::u16string GetSublabelAt(int index) const;
  102. std::u16string GetToolTipAt(int index) const;
  103. bool IsItemCheckedAt(int index) const;
  104. bool IsEnabledAt(int index) const;
  105. bool IsVisibleAt(int index) const;
  106. bool WorksWhenHiddenAt(int index) const;
  107. };
  108. } // namespace electron::api
  109. namespace gin {
  110. template <>
  111. struct Converter<electron::ElectronMenuModel*> {
  112. static bool FromV8(v8::Isolate* isolate,
  113. v8::Local<v8::Value> val,
  114. electron::ElectronMenuModel** out) {
  115. // null would be transferred to NULL.
  116. if (val->IsNull()) {
  117. *out = nullptr;
  118. return true;
  119. }
  120. electron::api::Menu* menu;
  121. if (!Converter<electron::api::Menu*>::FromV8(isolate, val, &menu))
  122. return false;
  123. *out = menu->model();
  124. return true;
  125. }
  126. };
  127. } // namespace gin
  128. #endif // ELECTRON_SHELL_BROWSER_API_ELECTRON_API_MENU_H_