You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
8.0 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013-2017 CERN
  5. * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  8. * @author Maciej Suminski <maciej.suminski@cern.ch>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #ifndef __CONTEXT_MENU_H
  28. #define __CONTEXT_MENU_H
  29. #include <map>
  30. #include <list>
  31. #include <functional>
  32. #include <wx/menu.h>
  33. #include <wx/textentry.h>
  34. #include <tool/tool_event.h>
  35. class KIFACE_BASE;
  36. class TOOL_INTERACTIVE;
  37. class TOOL_MANAGER;
  38. enum class BITMAPS : unsigned int;
  39. /**
  40. * Defines the structure of a menu based on ACTIONs.
  41. */
  42. class ACTION_MENU : public wxMenu
  43. {
  44. public:
  45. ///< Default constructor
  46. ACTION_MENU( bool isContextMenu, TOOL_INTERACTIVE* aTool = nullptr );
  47. ~ACTION_MENU() override;
  48. ACTION_MENU( const ACTION_MENU& aMenu ) = delete;
  49. ACTION_MENU& operator=( const ACTION_MENU& aMenu ) = delete;
  50. /**
  51. * Set title for the menu. The title is shown as a text label shown on the top of
  52. * the menu.
  53. *
  54. * @param aTitle is the new title.
  55. */
  56. void SetTitle( const wxString& aTitle ) override;
  57. /**
  58. * Decide whether a title for a pop up menu should be displayed.
  59. */
  60. void DisplayTitle( bool aDisplay = true );
  61. /**
  62. * Assign an icon for the entry.
  63. *
  64. * @param aIcon is the icon to be assigned. NULL is used to remove icon.
  65. */
  66. void SetIcon( BITMAPS aIcon );
  67. /**
  68. * Add a wxWidgets-style entry to the menu.
  69. *
  70. * After highlighting/selecting the entry, a wxWidgets event is generated.
  71. */
  72. wxMenuItem* Add( const wxString& aLabel, int aId, BITMAPS aIcon );
  73. wxMenuItem* Add( const wxString& aLabel, const wxString& aToolTip, int aId,
  74. BITMAPS aIcon, bool aIsCheckmarkEntry = false );
  75. /**
  76. * Add an entry to the menu based on the #TOOL_ACTION object.
  77. *
  78. * After selecting the entry, a #TOOL_EVENT command containing name of the action is sent.
  79. *
  80. * @param aAction is the action to be added to menu entry.
  81. * @param aIsCheckmarkEntry is true to indicate a check menu entry, false for normal menu entry
  82. * @param aOverrideLabel is the label to show in the menu (overriding the action's menu text)
  83. * when non-empty
  84. */
  85. wxMenuItem* Add( const TOOL_ACTION& aAction, bool aIsCheckmarkEntry = false,
  86. const wxString& aOverrideLabel = wxEmptyString );
  87. /**
  88. * Add an action menu as a submenu.
  89. *
  90. * The difference between this function and wxMenu::AppendSubMenu() is the capability to
  91. * handle icons.
  92. *
  93. * @param aMenu is the submenu to be added. This should be a new instance (use Clone()) if required
  94. * as the menu is destructed after use.
  95. */
  96. wxMenuItem* Add( ACTION_MENU* aMenu );
  97. /**
  98. * Add a standard close item to the menu with the accelerator key CTRL-W.
  99. *
  100. * Emits the wxID_CLOSE event.
  101. *
  102. * @param aAppname is the application name to append to the tooltip.
  103. */
  104. void AddClose( const wxString& aAppname = "" );
  105. /**
  106. * Add either a standard Quit or Close item to the menu.
  107. *
  108. * If \a aKiface is NULL or in single-instance then quit (wxID_QUIT) is used, otherwise
  109. * close (wxID_CLOSE) is used.
  110. *
  111. * @param aAppname is the application name to append to the tooltip.
  112. */
  113. void AddQuitOrClose( KIFACE_BASE* aKiface, wxString aAppname = "" );
  114. /**
  115. * Remove all the entries from the menu (as well as its title).
  116. *
  117. * It leaves the menu in the initial state.
  118. */
  119. void Clear();
  120. /**
  121. * Returns true if the menu has any enabled items
  122. */
  123. bool HasEnabledItems() const;
  124. /**
  125. * Return the position of selected item.
  126. *
  127. * If the returned value is negative, that means that menu was dismissed.
  128. *
  129. * @return The position of selected item in the action menu.
  130. */
  131. inline int GetSelected() const
  132. {
  133. return m_selected;
  134. }
  135. /**
  136. * Run update handlers for the menu and its submenus.
  137. */
  138. void UpdateAll();
  139. /**
  140. * Used by some menus to just-in-time translate their titles.
  141. */
  142. virtual void UpdateTitle() {}
  143. /**
  144. * Clear the dirty flag on the menu and all descendants.
  145. */
  146. void ClearDirty();
  147. void SetDirty();
  148. /**
  149. * Set a tool that is the creator of the menu.
  150. *
  151. * @param aTool is the tool that created the menu.
  152. */
  153. void SetTool( TOOL_INTERACTIVE* aTool );
  154. /**
  155. * Create a deep, recursive copy of this ACTION_MENU.
  156. */
  157. ACTION_MENU* Clone() const;
  158. void OnMenuEvent( wxMenuEvent& aEvent );
  159. void OnIdle( wxIdleEvent& event );
  160. virtual bool PassHelpTextToHandler() { return false; }
  161. static constexpr bool NORMAL = false;
  162. static constexpr bool CHECK = true;
  163. protected:
  164. ///< Return an instance of this class. It has to be overridden in inheriting classes.
  165. virtual ACTION_MENU* create() const;
  166. ///< Returns an instance of TOOL_MANAGER class.
  167. TOOL_MANAGER* getToolManager() const;
  168. /**
  169. * Update menu state stub.
  170. *
  171. * It is called before a menu is shown, in order to update its state. Here you can tick
  172. * current settings, enable/disable entries, etc.
  173. */
  174. virtual void update()
  175. {
  176. }
  177. /**
  178. * Event handler stub.
  179. *
  180. * It should be used if you want to generate a #TOOL_EVENT from a wxMenuEvent. It will be
  181. * called when a menu entry is clicked.
  182. */
  183. virtual OPT_TOOL_EVENT eventHandler( const wxMenuEvent& )
  184. {
  185. return OPT_TOOL_EVENT();
  186. }
  187. /**
  188. * Copy another menus data to this instance.
  189. *
  190. * Old entries are preserved and ones form aMenu are copied.
  191. */
  192. void copyFrom( const ACTION_MENU& aMenu );
  193. protected:
  194. /**
  195. * Append a copy of wxMenuItem.
  196. */
  197. wxMenuItem* appendCopy( const wxMenuItem* aSource );
  198. ///< Initialize handlers for events.
  199. void setupEvents();
  200. ///< Update hot key settings for TOOL_ACTIONs in this menu.
  201. void updateHotKeys();
  202. ///< Traverse the submenus tree looking for a submenu capable of handling a particular menu
  203. ///< event. In case it is handled, it is returned the aToolEvent parameter.
  204. void runEventHandlers( const wxMenuEvent& aMenuEvent, OPT_TOOL_EVENT& aToolEvent );
  205. ///< Run a function on the menu and all its submenus.
  206. void runOnSubmenus( std::function<void(ACTION_MENU*)> aFunction );
  207. ///< Check if any of submenus contains a TOOL_ACTION with a specific ID.
  208. OPT_TOOL_EVENT findToolAction( int aId );
  209. bool m_isForcedPosition;
  210. wxPoint m_forcedPosition;
  211. bool m_dirty; // Menu requires update before display
  212. bool m_titleDisplayed;
  213. bool m_isContextMenu;
  214. ///< Menu title
  215. wxString m_title;
  216. ///< Optional icon
  217. BITMAPS m_icon;
  218. ///< Stores the id number of selected item.
  219. int m_selected;
  220. ///< Creator of the menu
  221. TOOL_INTERACTIVE* m_tool;
  222. ///< Associates tool actions with menu item IDs. Non-owning.
  223. std::map<int, const TOOL_ACTION*> m_toolActions;
  224. ///< List of submenus.
  225. std::list<ACTION_MENU*> m_submenus;
  226. friend class TOOL_INTERACTIVE;
  227. };
  228. #endif