1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/univ/menu.h
3 // Purpose:     wxMenu and wxMenuBar classes for wxUniversal
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     05.05.01
7 // RCS-ID:      $Id: menu.h,v 1.1 2006/12/02 15:58:58 scara Exp $
8 // Copyright:   (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_UNIV_MENU_H_
13 #define _WX_UNIV_MENU_H_
14 
15 #ifdef __GNUG__
16     #pragma interface "univmenu.h"
17 #endif
18 
19 #if wxUSE_ACCEL
20     #include "wx/accel.h"
21 #endif // wxUSE_ACCEL
22 
23 #include "wx/dynarray.h"
24 
25 // fwd declarations
26 class WXDLLEXPORT wxMenuInfo;
27 WX_DECLARE_OBJARRAY(wxMenuInfo, wxMenuInfoArray);
28 
29 class WXDLLEXPORT wxMenuGeometryInfo;
30 class WXDLLEXPORT wxPopupMenuWindow;
31 class WXDLLEXPORT wxRenderer;
32 
33 // ----------------------------------------------------------------------------
34 // wxMenu
35 // ----------------------------------------------------------------------------
36 
37 class WXDLLEXPORT wxMenu : public wxMenuBase
38 {
39 public:
40     // ctors and dtor
41     wxMenu(const wxString& title, long style = 0)
wxMenuBase(title,style)42         : wxMenuBase(title, style) { Init(); }
43 
wxMenuBase(style)44     wxMenu(long style = 0) : wxMenuBase(style) { Init(); }
45 
46     virtual ~wxMenu();
47 
48     // called by wxMenuItem when an item of this menu changes
49     void RefreshItem(wxMenuItem *item);
50 
51     // does the menu have any items?
IsEmpty()52     bool IsEmpty() const { return !GetMenuItems().GetFirst(); }
53 
54     // show this menu at the given position (in screen coords) and optionally
55     // select its first item
56     void Popup(const wxPoint& pos, const wxSize& size,
57                bool selectFirst = TRUE);
58 
59     // dismiss the menu
60     void Dismiss();
61 
62     // override the base class methods to connect/disconnect event handlers
63     virtual void Attach(wxMenuBarBase *menubar);
64     virtual void Detach();
65 
66     // implementation only from here
67 
68     // do as if this item were clicked, return TRUE if the resulting event was
69     // processed, FALSE otherwise
70     bool ClickItem(wxMenuItem *item);
71 
72     // process the key event, return TRUE if done
73     bool ProcessKeyDown(int key);
74 
75 #if wxUSE_ACCEL
76     // find the item for the given accel and generate an event if found
77     bool ProcessAccelEvent(const wxKeyEvent& event);
78 #endif // wxUSE_ACCEL
79 
80 protected:
81     // implement base class virtuals
82     virtual bool DoAppend(wxMenuItem *item);
83     virtual bool DoInsert(size_t pos, wxMenuItem *item);
84     virtual wxMenuItem *DoRemove(wxMenuItem *item);
85 
86     // common part of DoAppend and DoInsert
87     void OnItemAdded(wxMenuItem *item);
88 
89     // called by wxPopupMenuWindow when the window is hidden
90     void OnDismiss(bool dismissParent);
91 
92     // return true if the menu is currently shown on screen
93     bool IsShown() const;
94 
95     // get the menu geometry info
96     const wxMenuGeometryInfo& GetGeometryInfo() const;
97 
98     // forget old menu geometry info
99     void InvalidateGeometryInfo();
100 
101     // return either the menubar or the invoking window, normally never NULL
102     wxWindow *GetRootWindow() const;
103 
104     // get the renderer we use for drawing: either the one of the menu bar or
105     // the one of the window if we're a popup menu
106     wxRenderer *GetRenderer() const;
107 
108 #if wxUSE_ACCEL
109     // add/remove accel for the given menu item
110     void AddAccelFor(wxMenuItem *item);
111     void RemoveAccelFor(wxMenuItem *item);
112 #endif // wxUSE_ACCEL
113 
114 private:
115     // common part of all ctors
116     void Init();
117 
118     // the exact menu geometry is defined by a struct derived from this one
119     // which is opaque and defined by the renderer
120     wxMenuGeometryInfo *m_geometry;
121 
122     // the menu shown on screen or NULL if not currently shown
123     wxPopupMenuWindow *m_popupMenu;
124 
125 #if wxUSE_ACCEL
126     // the accel table for this menu
127     wxAcceleratorTable m_accelTable;
128 #endif // wxUSE_ACCEL
129 
130     // it calls out OnDismiss()
131     friend class wxPopupMenuWindow;
132     DECLARE_DYNAMIC_CLASS(wxMenu)
133 };
134 
135 // ----------------------------------------------------------------------------
136 // wxMenuBar
137 // ----------------------------------------------------------------------------
138 
139 class WXDLLEXPORT wxMenuBar : public wxMenuBarBase
140 {
141 public:
142     // ctors and dtor
WXUNUSED(style)143     wxMenuBar(long WXUNUSED(style) = 0) { Init(); }
144     virtual ~wxMenuBar();
145 
146     // implement base class virtuals
147     virtual bool Append( wxMenu *menu, const wxString &title );
148     virtual bool Insert(size_t pos, wxMenu *menu, const wxString& title);
149     virtual wxMenu *Replace(size_t pos, wxMenu *menu, const wxString& title);
150     virtual wxMenu *Remove(size_t pos);
151 
152     virtual void EnableTop(size_t pos, bool enable);
153     virtual bool IsEnabledTop(size_t pos) const;
154 
155     virtual void SetLabelTop(size_t pos, const wxString& label);
156     virtual wxString GetLabelTop(size_t pos) const;
157 
158     virtual void Attach(wxFrame *frame);
159     virtual void Detach();
160 
161     // get the next item for the givan accel letter (used by wxFrame), return
162     // -1 if none
163     //
164     // if unique is not NULL, filled with TRUE if there is only one item with
165     // this accel, FALSE if two or more
166     int FindNextItemForAccel(int idxStart,
167                              int keycode,
168                              bool *unique = NULL) const;
169 
170     // called by wxFrame to set focus to or open the given menu
171     void SelectMenu(size_t pos);
172     void PopupMenu(size_t pos);
173 
174 #if wxUSE_ACCEL
175     // find the item for the given accel and generate an event if found
176     bool ProcessAccelEvent(const wxKeyEvent& event);
177 #endif // wxUSE_ACCEL
178 
179     // called by wxMenu when it is dismissed
180     void OnDismissMenu(bool dismissMenuBar = FALSE);
181 
182 protected:
183     // common part of all ctors
184     void Init();
185 
186     // event handlers
187     void OnLeftDown(wxMouseEvent& event);
188     void OnMouseMove(wxMouseEvent& event);
189     void OnKeyDown(wxKeyEvent& event);
190     void OnKillFocus(wxFocusEvent& event);
191 
192     // process the mouse move event, return TRUE if we did, FALSE to continue
193     // processing as usual
194     //
195     // the coordinates are client coordinates of menubar, convert if necessary
196     bool ProcessMouseEvent(const wxPoint& pt);
197 
198     // called when the menu bar loses mouse capture - it is not hidden unlike
199     // menus, but it doesn't have modal status any longer
200     void OnDismiss();
201 
202     // draw the menubar
203     virtual void DoDraw(wxControlRenderer *renderer);
204 
205     // menubar geometry
206     virtual wxSize DoGetBestClientSize() const;
207 
208     // has the menubar been created already?
IsCreated()209     bool IsCreated() const { return m_frameLast != NULL; }
210 
211     // "fast" version of GetMenuCount()
GetCount()212     size_t GetCount() const { return m_menuInfos.GetCount(); }
213 
214     // get the (total) width of the specified menu
215     wxCoord GetItemWidth(size_t pos) const;
216 
217     // get the rect of the item
218     wxRect GetItemRect(size_t pos) const;
219 
220     // get the menu from the given point or -1 if none
221     int GetMenuFromPoint(const wxPoint& pos) const;
222 
223     // refresh the given item
224     void RefreshItem(size_t pos);
225 
226     // refresh all items after this one (including it)
227     void RefreshAllItemsAfter(size_t pos);
228 
229     // hide the currently shown menu and show this one
230     void DoSelectMenu(size_t pos);
231 
232     // popup the currently selected menu
233     void PopupCurrentMenu(bool selectFirst = TRUE);
234 
235     // hide the currently selected menu
236     void DismissMenu();
237 
238     // do we show a menu currently?
IsShowingMenu()239     bool IsShowingMenu() const { return m_menuShown != 0; }
240 
241     // we don't want to have focus except while selecting from menu
242     void GiveAwayFocus();
243 
244     // the array containing extra menu info we need
245     wxMenuInfoArray m_menuInfos;
246 
247     // the current item (only used when menubar has focus)
248     int m_current;
249 
250 private:
251     // the last frame to which we were attached, NULL initially
252     wxFrame *m_frameLast;
253 
254     // the currently shown menu or NULL
255     wxMenu *m_menuShown;
256 
257     // should be showing the menu? this is subtly different from m_menuShown !=
258     // NULL as the menu which should be shown may be disabled in which case we
259     // don't show it - but will do as soon as the focus shifts to another menu
260     bool m_shouldShowMenu;
261 
262     // it calls out ProcessMouseEvent()
263     friend class wxPopupMenuWindow;
264 
265     DECLARE_EVENT_TABLE()
266     DECLARE_DYNAMIC_CLASS(wxMenuBar)
267 };
268 
269 #endif // _WX_UNIV_MENU_H_
270