]> git.saurik.com Git - wxWidgets.git/blob - include/wx/mdi.h
52cbed7da4de1516e65f162f6f081a4ab9dab915
[wxWidgets.git] / include / wx / mdi.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/mdi.h
3 // Purpose: wxMDI base header
4 // Author: Julian Smart (original)
5 // Vadim Zeitlin (base MDI classes refactoring)
6 // Copyright: (c) 1998 Julian Smart
7 // (c) 2008 Vadim Zeitlin
8 // RCS-ID: $Id$
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_MDI_H_BASE_
13 #define _WX_MDI_H_BASE_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_MDI
18
19 #include "wx/frame.h"
20 #include "wx/menu.h"
21
22 // forward declarations
23 class WXDLLIMPEXP_FWD_CORE wxMDIParentFrame;
24 class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame;
25 class WXDLLIMPEXP_FWD_CORE wxMDIClientWindowBase;
26 class WXDLLIMPEXP_FWD_CORE wxMDIClientWindow;
27
28 // ----------------------------------------------------------------------------
29 // wxMDIParentFrameBase: base class for parent frame for MDI children
30 // ----------------------------------------------------------------------------
31
32 class WXDLLIMPEXP_CORE wxMDIParentFrameBase : public wxFrame
33 {
34 public:
35 wxMDIParentFrameBase()
36 {
37 m_clientWindow = NULL;
38 m_currentChild = NULL;
39 #if wxUSE_MENUS
40 m_windowMenu = NULL;
41 #endif // wxUSE_MENUS
42 }
43
44 /*
45 Derived classes should provide ctor and Create() with the following
46 declaration:
47
48 bool Create(wxWindow *parent,
49 wxWindowID winid,
50 const wxString& title,
51 const wxPoint& pos = wxDefaultPosition,
52 const wxSize& size = wxDefaultSize,
53 long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
54 const wxString& name = wxFrameNameStr);
55 */
56
57 #if wxUSE_MENUS
58 virtual ~wxMDIParentFrameBase()
59 {
60 delete m_windowMenu;
61 }
62 #endif // wxUSE_MENUS
63
64 // accessors
65 // ---------
66
67 // Get or change the active MDI child window
68 virtual wxMDIChildFrame *GetActiveChild() const
69 { return m_currentChild; }
70 virtual void SetActiveChild(wxMDIChildFrame *child)
71 { m_currentChild = child; }
72
73
74 // Get the client window
75 wxMDIClientWindowBase *GetClientWindow() const { return m_clientWindow; }
76
77
78 // MDI windows menu functions
79 // --------------------------
80
81 #if wxUSE_MENUS
82 // return the pointer to the current window menu or NULL if we don't have
83 // because of wxFRAME_NO_WINDOW_MENU style
84 wxMenu* GetWindowMenu() const { return m_windowMenu; }
85
86 // use the given menu instead of the default window menu
87 //
88 // menu can be NULL to disable the window menu completely
89 virtual void SetWindowMenu(wxMenu *menu)
90 {
91 if ( menu != m_windowMenu )
92 {
93 delete m_windowMenu;
94 m_windowMenu = menu;
95 }
96 }
97 #endif // wxUSE_MENUS
98
99
100 // standard MDI window management functions
101 // ----------------------------------------
102
103 virtual void Cascade() { }
104 virtual void Tile(wxOrientation WXUNUSED(orient) = wxHORIZONTAL) { }
105 virtual void ArrangeIcons() { }
106 virtual void ActivateNext() = 0;
107 virtual void ActivatePrevious() = 0;
108
109 /*
110 Derived classes must provide the following function:
111
112 static bool IsTDI();
113 */
114
115 // Create the client window class (don't Create() the window here, just
116 // return a new object of a wxMDIClientWindow-derived class)
117 //
118 // Notice that if you override this method you should use the default
119 // constructor and Create() and not the constructor creating the window
120 // when creating the frame or your overridden version is not going to be
121 // called (as the call to a virtual function from ctor will be dispatched
122 // to this class version)
123 virtual wxMDIClientWindow *OnCreateClient();
124
125 protected:
126 // Override to pass menu/toolbar events to the active child first.
127 virtual bool TryBefore(wxEvent& event);
128
129
130 // This is wxMDIClientWindow for all the native implementations but not for
131 // the generic MDI version which has its own wxGenericMDIClientWindow and
132 // so we store it as just a base class pointer because we don't need its
133 // exact type anyhow
134 wxMDIClientWindowBase *m_clientWindow;
135 wxMDIChildFrame *m_currentChild;
136
137 #if wxUSE_MENUS
138 // the current window menu or NULL if we are not using it
139 wxMenu *m_windowMenu;
140 #endif // wxUSE_MENUS
141 };
142
143 // ----------------------------------------------------------------------------
144 // wxMDIChildFrameBase: child frame managed by wxMDIParentFrame
145 // ----------------------------------------------------------------------------
146
147 class WXDLLIMPEXP_CORE wxMDIChildFrameBase : public wxFrame
148 {
149 public:
150 wxMDIChildFrameBase() { m_mdiParent = NULL; }
151
152 /*
153 Derived classes should provide Create() with the following signature:
154
155 bool Create(wxMDIParentFrame *parent,
156 wxWindowID id,
157 const wxString& title,
158 const wxPoint& pos = wxDefaultPosition,
159 const wxSize& size = wxDefaultSize,
160 long style = wxDEFAULT_FRAME_STYLE,
161 const wxString& name = wxFrameNameStr);
162
163 And setting m_mdiParent to parent parameter.
164 */
165
166 // MDI children specific methods
167 virtual void Activate() = 0;
168
169 // Return the MDI parent frame: notice that it may not be the same as
170 // GetParent() (our parent may be the client window or even its subwindow
171 // in some implementations)
172 wxMDIParentFrame *GetMDIParent() const { return m_mdiParent; }
173
174 // Synonym for GetMDIParent(), was used in some other ports
175 wxMDIParentFrame *GetMDIParentFrame() const { return GetMDIParent(); }
176
177
178 // in most ports MDI children frames are not really top-level, the only
179 // exception are the Mac ports in which MDI children are just normal top
180 // level windows too
181 virtual bool IsTopLevel() const { return false; }
182
183 // In all ports keyboard navigation must stop at MDI child frame level and
184 // can't cross its boundary. Indicate this by overriding this function to
185 // return true.
186 virtual bool IsTopNavigationDomain() const { return true; }
187
188 // Raising any frame is supposed to show it but wxFrame Raise()
189 // implementation doesn't work for MDI child frames in most forms so
190 // forward this to Activate() which serves the same purpose by default.
191 virtual void Raise() { Activate(); }
192
193 protected:
194 wxMDIParentFrame *m_mdiParent;
195 };
196
197 // ----------------------------------------------------------------------------
198 // wxTDIChildFrame: child frame used by TDI implementations
199 // ----------------------------------------------------------------------------
200
201 class WXDLLIMPEXP_CORE wxTDIChildFrame : public wxMDIChildFrameBase
202 {
203 public:
204 // override wxFrame methods for this non top-level window
205
206 #if wxUSE_STATUSBAR
207 // no status bars
208 //
209 // TODO: MDI children should have their own status bars, why not?
210 virtual wxStatusBar* CreateStatusBar(int WXUNUSED(number) = 1,
211 long WXUNUSED(style) = 1,
212 wxWindowID WXUNUSED(id) = 1,
213 const wxString& WXUNUSED(name)
214 = wxEmptyString)
215 { return NULL; }
216
217 virtual wxStatusBar *GetStatusBar() const
218 { return NULL; }
219 virtual void SetStatusText(const wxString &WXUNUSED(text),
220 int WXUNUSED(number)=0)
221 { }
222 virtual void SetStatusWidths(int WXUNUSED(n),
223 const int WXUNUSED(widths)[])
224 { }
225 #endif // wxUSE_STATUSBAR
226
227 #if wxUSE_TOOLBAR
228 // no toolbar
229 //
230 // TODO: again, it should be possible to have tool bars
231 virtual wxToolBar *CreateToolBar(long WXUNUSED(style),
232 wxWindowID WXUNUSED(id),
233 const wxString& WXUNUSED(name))
234 { return NULL; }
235 virtual wxToolBar *GetToolBar() const { return NULL; }
236 #endif // wxUSE_TOOLBAR
237
238 // no icon
239 virtual void SetIcons(const wxIconBundle& WXUNUSED(icons)) { }
240
241 // title is used as the tab label
242 virtual wxString GetTitle() const { return m_title; }
243 virtual void SetTitle(const wxString& title) = 0;
244
245 // no maximize etc
246 virtual void Maximize(bool WXUNUSED(maximize) = true) { }
247 virtual bool IsMaximized() const { return true; }
248 virtual bool IsAlwaysMaximized() const { return true; }
249 virtual void Iconize(bool WXUNUSED(iconize) = true) { }
250 virtual bool IsIconized() const { return false; }
251 virtual void Restore() { }
252
253 virtual bool ShowFullScreen(bool WXUNUSED(show),
254 long WXUNUSED(style)) { return false; }
255 virtual bool IsFullScreen() const { return false; }
256
257
258 // we need to override these functions to ensure that a child window is
259 // created even though we derive from wxFrame -- basically we make it
260 // behave as just a wxWindow by short-circuiting wxTLW changes to the base
261 // class behaviour
262
263 virtual void AddChild(wxWindowBase *child) { wxWindow::AddChild(child); }
264
265 virtual bool Destroy() { return wxWindow::Destroy(); }
266
267 // extra platform-specific hacks
268 #ifdef __WXMSW__
269 virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const
270 {
271 return wxWindow::MSWGetStyle(flags, exstyle);
272 }
273
274 virtual WXHWND MSWGetParent() const
275 {
276 return wxWindow::MSWGetParent();
277 }
278
279 WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
280 {
281 return wxWindow::MSWWindowProc(message, wParam, lParam);
282 }
283 #endif // __WXMSW__
284
285 protected:
286 virtual void DoGetSize(int *width, int *height) const
287 {
288 wxWindow::DoGetSize(width, height);
289 }
290
291 virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags)
292 {
293 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
294 }
295
296 virtual void DoGetClientSize(int *width, int *height) const
297 {
298 wxWindow::DoGetClientSize(width, height);
299 }
300
301 virtual void DoSetClientSize(int width, int height)
302 {
303 wxWindow::DoSetClientSize(width, height);
304 }
305
306 // no size hints
307 virtual void DoSetSizeHints(int WXUNUSED(minW), int WXUNUSED(minH),
308 int WXUNUSED(maxW), int WXUNUSED(maxH),
309 int WXUNUSED(incW), int WXUNUSED(incH)) { }
310
311 wxString m_title;
312 };
313
314 // ----------------------------------------------------------------------------
315 // wxMDIClientWindowBase: child of parent frame, parent of children frames
316 // ----------------------------------------------------------------------------
317
318 class WXDLLIMPEXP_CORE wxMDIClientWindowBase : public wxWindow
319 {
320 public:
321 /*
322 The derived class must provide the default ctor only (CreateClient()
323 will be called later).
324 */
325
326 // Can be overridden in the derived classes but the base class version must
327 // be usually called first to really create the client window.
328 virtual bool CreateClient(wxMDIParentFrame *parent,
329 long style = wxVSCROLL | wxHSCROLL) = 0;
330 };
331
332 // ----------------------------------------------------------------------------
333 // Include the port-specific implementation of the base classes defined above
334 // ----------------------------------------------------------------------------
335
336 // wxUSE_GENERIC_MDI_AS_NATIVE may be predefined to force the generic MDI
337 // implementation use even on the platforms which usually don't use it
338 //
339 // notice that generic MDI can still be used without this, but you would need
340 // to explicitly use wxGenericMDIXXX classes in your code (and currently also
341 // add src/generic/mdig.cpp to your build as it's not compiled in if generic
342 // MDI is not used by default -- but this may change later...)
343 #ifndef wxUSE_GENERIC_MDI_AS_NATIVE
344 // wxUniv always uses the generic MDI implementation and so do the ports
345 // without native version (although wxCocoa seems to have one -- but it's
346 // probably not functional?)
347 #if defined(__WXCOCOA__) || \
348 defined(__WXMOTIF__) || \
349 defined(__WXPM__) || \
350 defined(__WXUNIVERSAL__)
351 #define wxUSE_GENERIC_MDI_AS_NATIVE 1
352 #else
353 #define wxUSE_GENERIC_MDI_AS_NATIVE 0
354 #endif
355 #endif // wxUSE_GENERIC_MDI_AS_NATIVE
356
357 #if wxUSE_GENERIC_MDI_AS_NATIVE
358 #include "wx/generic/mdig.h"
359 #elif defined(__WXMSW__)
360 #include "wx/msw/mdi.h"
361 #elif defined(__WXGTK20__)
362 #include "wx/gtk/mdi.h"
363 #elif defined(__WXGTK__)
364 #include "wx/gtk1/mdi.h"
365 #elif defined(__WXMAC__)
366 #include "wx/osx/mdi.h"
367 #elif defined(__WXCOCOA__)
368 #include "wx/cocoa/mdi.h"
369 #endif
370
371 inline wxMDIClientWindow *wxMDIParentFrameBase::OnCreateClient()
372 {
373 return new wxMDIClientWindow;
374 }
375
376 inline bool wxMDIParentFrameBase::TryBefore(wxEvent& event)
377 {
378 // Menu (and toolbar) events should be sent to the active child frame
379 // first, if any.
380 if ( event.GetEventType() == wxEVT_MENU ||
381 event.GetEventType() == wxEVT_UPDATE_UI )
382 {
383 wxMDIChildFrame * const child = GetActiveChild();
384 if ( child )
385 {
386 // However avoid sending the event back to the child if it's
387 // currently being propagated to us from it.
388 wxWindow* const
389 from = static_cast<wxWindow*>(event.GetPropagatedFrom());
390 if ( !from || !from->IsDescendant(child) )
391 {
392 if ( child->ProcessWindowEventLocally(event) )
393 return true;
394 }
395 }
396 }
397
398 return wxFrame::TryBefore(event);
399 }
400
401 #endif // wxUSE_MDI
402
403 #endif // _WX_MDI_H_BASE_