KiCad PCB EDA Suite
conditional_menu.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 CERN
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #ifndef CONDITIONAL_MENU_H
28 #define CONDITIONAL_MENU_H
29 
31 #include <tool/action_menu.h>
32 #include <list>
33 #include <wx/wx.h>
34 
35 class PCB_SELECTION_TOOL;
36 class TOOL_ACTION;
37 class TOOL_INTERACTIVE;
38 
39 
41 {
42 public:
44  static const int ANY_ORDER = -1;
45 
47 
48  ACTION_MENU* create() const override;
49 
58  void AddItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition,
59  int aOrder = ANY_ORDER );
60 
61  void AddItem( int aId, const wxString& aText, const wxString& aTooltip, BITMAP_DEF aIcon,
62  const SELECTION_CONDITION& aCondition, int aOrder = ANY_ORDER );
63 
75  void AddCheckItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition,
76  int aOrder = ANY_ORDER );
77 
78  void AddCheckItem( int aId, const wxString& aText, const wxString& aTooltip, BITMAP_DEF aIcon,
79  const SELECTION_CONDITION& aCondition, int aOrder = ANY_ORDER );
80 
94  void AddMenu( ACTION_MENU* aMenu,
96  int aOrder = ANY_ORDER );
97 
103  void AddSeparator( int aOrder = ANY_ORDER );
104 
108  void Evaluate( SELECTION& aSelection );
109 
115  void Resolve();
116 
117 private:
119  class ENTRY
120  {
121  public:
122  ENTRY( const TOOL_ACTION* aAction, SELECTION_CONDITION aCondition, int aOrder,
123  bool aCheckmark ) :
124  m_type( ACTION ), m_icon(nullptr),
125  m_condition( aCondition ),
126  m_order( aOrder ),
127  m_isCheckmarkEntry( aCheckmark )
128  {
129  m_data.action = aAction;
130  }
131 
132  ENTRY( ACTION_MENU* aMenu, SELECTION_CONDITION aCondition, int aOrder ) :
133  m_type( MENU ), m_icon(nullptr),
134  m_condition( aCondition ),
135  m_order( aOrder ),
136  m_isCheckmarkEntry( false )
137  {
138  m_data.menu = aMenu;
139  }
140 
141  ENTRY( const wxMenuItem& aItem, const BITMAP_OPAQUE* aWxMenuBitmap,
142  SELECTION_CONDITION aCondition, int aOrder, bool aCheckmark ) :
143  m_type( WXITEM ), m_icon( aWxMenuBitmap ),
144  m_condition( aCondition ),
145  m_order( aOrder ),
146  m_isCheckmarkEntry( aCheckmark )
147  {
148  m_data.wxItem = new wxMenuItem( nullptr, aItem.GetId(), aItem.GetItemLabel(),
149  aItem.GetHelp(), aItem.GetKind() );
150  }
151 
152  // Separator
153  ENTRY( SELECTION_CONDITION aCondition, int aOrder ) :
154  m_type( SEPARATOR ), m_icon(nullptr),
155  m_condition( aCondition ),
156  m_order( aOrder ),
157  m_isCheckmarkEntry( false )
158  {
159  }
160 
161  ENTRY( const ENTRY& aEntry );
162 
163  ~ENTRY();
164 
166  enum ENTRY_TYPE {
171  };
172 
173  inline ENTRY_TYPE Type() const
174  {
175  return m_type;
176  }
177 
178  inline const BITMAP_OPAQUE* GetIcon() const
179  {
180  return m_icon;
181  }
182 
183  inline const TOOL_ACTION* Action() const
184  {
185  assert( m_type == ACTION );
186  return m_data.action;
187  }
188 
189  inline ACTION_MENU* Menu() const
190  {
191  assert( m_type == MENU );
192  return m_data.menu;
193  }
194 
195  inline wxMenuItem* wxItem() const
196  {
197  assert( m_type == WXITEM );
198  return m_data.wxItem;
199  }
200 
201  inline bool IsCheckmarkEntry() const
202  {
203  return m_isCheckmarkEntry;
204  }
205 
206  inline const SELECTION_CONDITION& Condition() const
207  {
208  return m_condition;
209  }
210 
211  inline int Order() const
212  {
213  return m_order;
214  }
215 
216  inline void SetOrder( int aOrder )
217  {
218  m_order = aOrder;
219  }
220 
221  private:
224 
225  // This class owns the wxItem object and needs to create, copy and delete it accordingly
226  // But it does not own the action nor menu item
227  union {
230  wxMenuItem* wxItem;
231  } m_data;
232 
235 
237  int m_order;
238 
240  };
241 
243  void addEntry( ENTRY aEntry );
244 
246  std::list<ENTRY> m_entries;
247 };
248 
249 #endif /* CONDITIONAL_MENU_H */
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
PNG memory record (file in memory).
Definition: bitmap_def.h:29
< Helper class to organize menu entries. Inserts the entry, preserving the requested order.
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:45
static const int ANY_ORDER
< Constant to indicate that we do not care about an #ENTRY location in the menu.
const TOOL_ACTION * action
std::list< ENTRY > m_entries
union CONDITIONAL_MENU::ENTRY::@31 m_data
Condition to be fulfilled to show the entry in menu.
void AddCheckItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a checked menu entry to run a TOOL_ACTION on selected items.
SELECTION_CONDITION m_condition
Order number, the higher the number the lower position it takes it is in the menu.
const SELECTION_CONDITION & Condition() const
void SetOrder(int aOrder)
ENTRY(const wxMenuItem &aItem, const BITMAP_OPAQUE *aWxMenuBitmap, SELECTION_CONDITION aCondition, int aOrder, bool aCheckmark)
~ENTRY()
Possible entry types.
void Evaluate(SELECTION &aSelection)
Update the contents of the menu based on the supplied conditions.
ENTRY_TYPE Type() const
std::function< bool(const SELECTION &)> SELECTION_CONDITION
< Functor type that checks a specific condition for selected items.
ENTRY(SELECTION_CONDITION aCondition, int aOrder)
const TOOL_ACTION * Action() const
void Resolve()
Update the initial contents so that wxWidgets doesn't get its knickers tied in a knot over the menu b...
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
wxMenuItem * wxItem() const
const BITMAP_OPAQUE * GetIcon() const
void addEntry(ENTRY aEntry)
List of all menu entries.
Represent a single user action.
Definition: tool_action.h:49
The selection tool: currently supports:
const BITMAP_OPAQUE * m_icon
ACTION_MENU * Menu() const
CONDITIONAL_MENU(TOOL_INTERACTIVE *aTool)
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
ENTRY(const TOOL_ACTION *aAction, SELECTION_CONDITION aCondition, int aOrder, bool aCheckmark)
ENTRY(ACTION_MENU *aMenu, SELECTION_CONDITION aCondition, int aOrder)