1 /////////////////////////////////////////////////////////////////////////////
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 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_MDI_H_BASE_
12 #define _WX_MDI_H_BASE_
21 // forward declarations
22 class WXDLLIMPEXP_FWD_CORE wxMDIParentFrame
;
23 class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame
;
24 class WXDLLIMPEXP_FWD_CORE wxMDIClientWindowBase
;
25 class WXDLLIMPEXP_FWD_CORE wxMDIClientWindow
;
27 // ----------------------------------------------------------------------------
28 // wxMDIParentFrameBase: base class for parent frame for MDI children
29 // ----------------------------------------------------------------------------
31 class WXDLLIMPEXP_CORE wxMDIParentFrameBase
: public wxFrame
34 wxMDIParentFrameBase()
36 m_clientWindow
= NULL
;
37 m_currentChild
= NULL
;
44 Derived classes should provide ctor and Create() with the following
47 bool Create(wxWindow *parent,
49 const wxString& title,
50 const wxPoint& pos = wxDefaultPosition,
51 const wxSize& size = wxDefaultSize,
52 long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
53 const wxString& name = wxFrameNameStr);
57 virtual ~wxMDIParentFrameBase()
66 // Get or change the active MDI child window
67 virtual wxMDIChildFrame
*GetActiveChild() const
68 { return m_currentChild
; }
69 virtual void SetActiveChild(wxMDIChildFrame
*child
)
70 { m_currentChild
= child
; }
73 // Get the client window
74 wxMDIClientWindowBase
*GetClientWindow() const { return m_clientWindow
; }
77 // MDI windows menu functions
78 // --------------------------
81 // return the pointer to the current window menu or NULL if we don't have
82 // because of wxFRAME_NO_WINDOW_MENU style
83 wxMenu
* GetWindowMenu() const { return m_windowMenu
; }
85 // use the given menu instead of the default window menu
87 // menu can be NULL to disable the window menu completely
88 virtual void SetWindowMenu(wxMenu
*menu
)
90 if ( menu
!= m_windowMenu
)
99 // standard MDI window management functions
100 // ----------------------------------------
102 virtual void Cascade() { }
103 virtual void Tile(wxOrientation
WXUNUSED(orient
) = wxHORIZONTAL
) { }
104 virtual void ArrangeIcons() { }
105 virtual void ActivateNext() = 0;
106 virtual void ActivatePrevious() = 0;
109 Derived classes must provide the following function:
114 // Create the client window class (don't Create() the window here, just
115 // return a new object of a wxMDIClientWindow-derived class)
117 // Notice that if you override this method you should use the default
118 // constructor and Create() and not the constructor creating the window
119 // when creating the frame or your overridden version is not going to be
120 // called (as the call to a virtual function from ctor will be dispatched
121 // to this class version)
122 virtual wxMDIClientWindow
*OnCreateClient();
125 // Override to pass menu/toolbar events to the active child first.
126 virtual bool TryBefore(wxEvent
& event
);
129 // This is wxMDIClientWindow for all the native implementations but not for
130 // the generic MDI version which has its own wxGenericMDIClientWindow and
131 // so we store it as just a base class pointer because we don't need its
133 wxMDIClientWindowBase
*m_clientWindow
;
134 wxMDIChildFrame
*m_currentChild
;
137 // the current window menu or NULL if we are not using it
138 wxMenu
*m_windowMenu
;
139 #endif // wxUSE_MENUS
142 // ----------------------------------------------------------------------------
143 // wxMDIChildFrameBase: child frame managed by wxMDIParentFrame
144 // ----------------------------------------------------------------------------
146 class WXDLLIMPEXP_CORE wxMDIChildFrameBase
: public wxFrame
149 wxMDIChildFrameBase() { m_mdiParent
= NULL
; }
152 Derived classes should provide Create() with the following signature:
154 bool Create(wxMDIParentFrame *parent,
156 const wxString& title,
157 const wxPoint& pos = wxDefaultPosition,
158 const wxSize& size = wxDefaultSize,
159 long style = wxDEFAULT_FRAME_STYLE,
160 const wxString& name = wxFrameNameStr);
162 And setting m_mdiParent to parent parameter.
165 // MDI children specific methods
166 virtual void Activate() = 0;
168 // Return the MDI parent frame: notice that it may not be the same as
169 // GetParent() (our parent may be the client window or even its subwindow
170 // in some implementations)
171 wxMDIParentFrame
*GetMDIParent() const { return m_mdiParent
; }
173 // Synonym for GetMDIParent(), was used in some other ports
174 wxMDIParentFrame
*GetMDIParentFrame() const { return GetMDIParent(); }
177 // in most ports MDI children frames are not really top-level, the only
178 // exception are the Mac ports in which MDI children are just normal top
180 virtual bool IsTopLevel() const { return false; }
182 // In all ports keyboard navigation must stop at MDI child frame level and
183 // can't cross its boundary. Indicate this by overriding this function to
185 virtual bool IsTopNavigationDomain() const { return true; }
187 // Raising any frame is supposed to show it but wxFrame Raise()
188 // implementation doesn't work for MDI child frames in most forms so
189 // forward this to Activate() which serves the same purpose by default.
190 virtual void Raise() { Activate(); }
193 wxMDIParentFrame
*m_mdiParent
;
196 // ----------------------------------------------------------------------------
197 // wxTDIChildFrame: child frame used by TDI implementations
198 // ----------------------------------------------------------------------------
200 class WXDLLIMPEXP_CORE wxTDIChildFrame
: public wxMDIChildFrameBase
203 // override wxFrame methods for this non top-level window
208 // TODO: MDI children should have their own status bars, why not?
209 virtual wxStatusBar
* CreateStatusBar(int WXUNUSED(number
) = 1,
210 long WXUNUSED(style
) = 1,
211 wxWindowID
WXUNUSED(id
) = 1,
212 const wxString
& WXUNUSED(name
)
216 virtual wxStatusBar
*GetStatusBar() const
218 virtual void SetStatusText(const wxString
&WXUNUSED(text
),
219 int WXUNUSED(number
)=0)
221 virtual void SetStatusWidths(int WXUNUSED(n
),
222 const int WXUNUSED(widths
)[])
224 #endif // wxUSE_STATUSBAR
229 // TODO: again, it should be possible to have tool bars
230 virtual wxToolBar
*CreateToolBar(long WXUNUSED(style
),
231 wxWindowID
WXUNUSED(id
),
232 const wxString
& WXUNUSED(name
))
234 virtual wxToolBar
*GetToolBar() const { return NULL
; }
235 #endif // wxUSE_TOOLBAR
238 virtual void SetIcons(const wxIconBundle
& WXUNUSED(icons
)) { }
240 // title is used as the tab label
241 virtual wxString
GetTitle() const { return m_title
; }
242 virtual void SetTitle(const wxString
& title
) = 0;
245 virtual void Maximize(bool WXUNUSED(maximize
) = true) { }
246 virtual bool IsMaximized() const { return true; }
247 virtual bool IsAlwaysMaximized() const { return true; }
248 virtual void Iconize(bool WXUNUSED(iconize
) = true) { }
249 virtual bool IsIconized() const { return false; }
250 virtual void Restore() { }
252 virtual bool ShowFullScreen(bool WXUNUSED(show
),
253 long WXUNUSED(style
)) { return false; }
254 virtual bool IsFullScreen() const { return false; }
257 // we need to override these functions to ensure that a child window is
258 // created even though we derive from wxFrame -- basically we make it
259 // behave as just a wxWindow by short-circuiting wxTLW changes to the base
262 virtual void AddChild(wxWindowBase
*child
) { wxWindow::AddChild(child
); }
264 virtual bool Destroy() { return wxWindow::Destroy(); }
266 // extra platform-specific hacks
268 virtual WXDWORD
MSWGetStyle(long flags
, WXDWORD
*exstyle
= NULL
) const
270 return wxWindow::MSWGetStyle(flags
, exstyle
);
273 virtual WXHWND
MSWGetParent() const
275 return wxWindow::MSWGetParent();
278 WXLRESULT
MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
)
280 return wxWindow::MSWWindowProc(message
, wParam
, lParam
);
285 virtual void DoGetSize(int *width
, int *height
) const
287 wxWindow::DoGetSize(width
, height
);
290 virtual void DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
292 wxWindow::DoSetSize(x
, y
, width
, height
, sizeFlags
);
295 virtual void DoGetClientSize(int *width
, int *height
) const
297 wxWindow::DoGetClientSize(width
, height
);
300 virtual void DoSetClientSize(int width
, int height
)
302 wxWindow::DoSetClientSize(width
, height
);
306 virtual void DoSetSizeHints(int WXUNUSED(minW
), int WXUNUSED(minH
),
307 int WXUNUSED(maxW
), int WXUNUSED(maxH
),
308 int WXUNUSED(incW
), int WXUNUSED(incH
)) { }
313 // ----------------------------------------------------------------------------
314 // wxMDIClientWindowBase: child of parent frame, parent of children frames
315 // ----------------------------------------------------------------------------
317 class WXDLLIMPEXP_CORE wxMDIClientWindowBase
: public wxWindow
321 The derived class must provide the default ctor only (CreateClient()
322 will be called later).
325 // Can be overridden in the derived classes but the base class version must
326 // be usually called first to really create the client window.
327 virtual bool CreateClient(wxMDIParentFrame
*parent
,
328 long style
= wxVSCROLL
| wxHSCROLL
) = 0;
331 // ----------------------------------------------------------------------------
332 // Include the port-specific implementation of the base classes defined above
333 // ----------------------------------------------------------------------------
335 // wxUSE_GENERIC_MDI_AS_NATIVE may be predefined to force the generic MDI
336 // implementation use even on the platforms which usually don't use it
338 // notice that generic MDI can still be used without this, but you would need
339 // to explicitly use wxGenericMDIXXX classes in your code (and currently also
340 // add src/generic/mdig.cpp to your build as it's not compiled in if generic
341 // MDI is not used by default -- but this may change later...)
342 #ifndef wxUSE_GENERIC_MDI_AS_NATIVE
343 // wxUniv always uses the generic MDI implementation and so do the ports
344 // without native version (although wxCocoa seems to have one -- but it's
345 // probably not functional?)
346 #if defined(__WXCOCOA__) || \
347 defined(__WXMOTIF__) || \
348 defined(__WXPM__) || \
349 defined(__WXUNIVERSAL__)
350 #define wxUSE_GENERIC_MDI_AS_NATIVE 1
352 #define wxUSE_GENERIC_MDI_AS_NATIVE 0
354 #endif // wxUSE_GENERIC_MDI_AS_NATIVE
356 #if wxUSE_GENERIC_MDI_AS_NATIVE
357 #include "wx/generic/mdig.h"
358 #elif defined(__WXMSW__)
359 #include "wx/msw/mdi.h"
360 #elif defined(__WXGTK20__)
361 #include "wx/gtk/mdi.h"
362 #elif defined(__WXGTK__)
363 #include "wx/gtk1/mdi.h"
364 #elif defined(__WXMAC__)
365 #include "wx/osx/mdi.h"
366 #elif defined(__WXCOCOA__)
367 #include "wx/cocoa/mdi.h"
370 inline wxMDIClientWindow
*wxMDIParentFrameBase::OnCreateClient()
372 return new wxMDIClientWindow
;
375 inline bool wxMDIParentFrameBase::TryBefore(wxEvent
& event
)
377 // Menu (and toolbar) events should be sent to the active child frame
379 if ( event
.GetEventType() == wxEVT_MENU
||
380 event
.GetEventType() == wxEVT_UPDATE_UI
)
382 wxMDIChildFrame
* const child
= GetActiveChild();
385 // However avoid sending the event back to the child if it's
386 // currently being propagated to us from it.
388 from
= static_cast<wxWindow
*>(event
.GetPropagatedFrom());
389 if ( !from
|| !from
->IsDescendant(child
) )
391 if ( child
->ProcessWindowEventLocally(event
) )
397 return wxFrame::TryBefore(event
);
402 #endif // _WX_MDI_H_BASE_