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