mdi.h 13 KB

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