home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / mdig.cpp < prev    next >
C/C++ Source or Header  |  2002-11-09  |  23KB  |  814 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        src/generic/mdig.cpp
  3. // Purpose:     Generic MDI (Multiple Document Interface) classes
  4. // Author:      Hans Van Leemputten
  5. // Modified by:
  6. // Created:     29/07/2002
  7. // RCS-ID:      $Id: mdig.cpp,v 1.1.2.5 2002/11/09 13:51:26 RR Exp $
  8. // Copyright:   (c) Hans Van Leemputten
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ===========================================================================
  13. // declarations
  14. // ===========================================================================
  15.  
  16. // ---------------------------------------------------------------------------
  17. // headers
  18. // ---------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "mdig.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28.     #pragma hdrstop
  29. #endif
  30.  
  31. #ifndef WX_PRECOMP
  32.     #include "wx/panel.h"
  33.     #include "wx/menu.h"
  34.     #include "wx/intl.h"
  35. #endif //WX_PRECOMP
  36.  
  37. #include "wx/generic/mdig.h"
  38.  
  39. enum MDI_MENU_ID
  40. {
  41.     wxWINDOWCLOSE = 4001,
  42.     wxWINDOWCLOSEALL,
  43.     wxWINDOWNEXT,
  44.     wxWINDOWPREV
  45. };
  46.  
  47. //-----------------------------------------------------------------------------
  48. // wxGenericMDIParentFrame
  49. //-----------------------------------------------------------------------------
  50.  
  51. IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
  52.  
  53. BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
  54.     EVT_MENU (-1, wxGenericMDIParentFrame::DoHandleMenu)
  55. END_EVENT_TABLE()
  56.  
  57. wxGenericMDIParentFrame::wxGenericMDIParentFrame()
  58. {
  59.     Init();
  60. }
  61.  
  62. wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
  63.                                    wxWindowID id,
  64.                                    const wxString& title,
  65.                                    const wxPoint& pos,
  66.                                    const wxSize& size,
  67.                                    long style,
  68.                                    const wxString& name)
  69. {
  70.     Init();
  71.  
  72.     (void)Create(parent, id, title, pos, size, style, name);
  73. }
  74.  
  75. wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
  76. {
  77.     // Make sure the client window is destructed before the menu bars are!
  78.     wxDELETE(m_pClientWindow);
  79.  
  80. #if wxUSE_MENUS
  81.     if (m_pMyMenuBar)
  82.     {
  83.         delete m_pMyMenuBar;
  84.         m_pMyMenuBar = (wxMenuBar *) NULL;
  85.     }
  86.  
  87.     RemoveWindowMenu(GetMenuBar());
  88.  
  89.     if (m_pWindowMenu)
  90.     {
  91.         delete m_pWindowMenu;
  92.         m_pWindowMenu = (wxMenu*) NULL;
  93.     }
  94. #endif // wxUSE_MENUS
  95. }
  96.  
  97. bool wxGenericMDIParentFrame::Create(wxWindow *parent,
  98.                               wxWindowID id,
  99.                               const wxString& title,
  100.                               const wxPoint& pos,
  101.                               const wxSize& size,
  102.                               long style,
  103.                               const wxString& name)
  104. {
  105.   // this style can be used to prevent a window from having the standard MDI
  106.   // "Window" menu
  107.   if ( !(style & wxFRAME_NO_WINDOW_MENU) )
  108.   {
  109. #if wxUSE_MENUS
  110.       m_pWindowMenu = new wxMenu;
  111.  
  112.       m_pWindowMenu->Append(wxWINDOWCLOSE,    _("Cl&ose"));
  113.       m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
  114.       m_pWindowMenu->AppendSeparator();
  115.       m_pWindowMenu->Append(wxWINDOWNEXT,     _("&Next"));
  116.       m_pWindowMenu->Append(wxWINDOWPREV,     _("&Previous"));
  117. #endif // wxUSE_MENUS
  118.   }
  119.  
  120.   wxFrame::Create( parent, id, title, pos, size, style, name );
  121.  
  122.   OnCreateClient();
  123.  
  124.   return TRUE;
  125. }
  126.  
  127. #if wxUSE_MENUS
  128. void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
  129. {
  130.     // Replace the window menu from the currently loaded menu bar.
  131.     wxMenuBar *pMenuBar = GetMenuBar();
  132.  
  133.     if (m_pWindowMenu)
  134.     {
  135.         RemoveWindowMenu(pMenuBar);
  136.  
  137.         wxDELETE(m_pWindowMenu);
  138.     }
  139.  
  140.     if (pMenu)
  141.     {
  142.         m_pWindowMenu = pMenu;
  143.  
  144.         AddWindowMenu(pMenuBar);
  145.     }
  146. }
  147.  
  148. void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
  149. {
  150.     // Remove the Window menu from the old menu bar
  151.     RemoveWindowMenu(GetMenuBar());
  152.     // Add the Window menu to the new menu bar.
  153.     AddWindowMenu(pMenuBar);
  154.  
  155.     wxFrame::SetMenuBar(pMenuBar);
  156. }
  157. #endif // wxUSE_MENUS
  158.  
  159. void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
  160. {
  161. #if wxUSE_MENUS
  162.     if (pChild  == (wxGenericMDIChildFrame *) NULL)
  163.     {
  164.         // No Child, set Our menu bar back.
  165.         SetMenuBar(m_pMyMenuBar);
  166.  
  167.         // Make sure we know our menu bar is in use
  168.         m_pMyMenuBar = (wxMenuBar*) NULL;
  169.     }
  170.     else
  171.     {
  172.         if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
  173.             return;
  174.  
  175.         // Do we need to save the current bar?
  176.         if (m_pMyMenuBar == NULL)
  177.             m_pMyMenuBar = GetMenuBar();
  178.  
  179.         SetMenuBar(pChild->GetMenuBar());
  180.     }
  181. #endif // wxUSE_MENUS
  182. }
  183.  
  184. bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
  185. {
  186.     /*
  187.      * Redirect events to active child first.
  188.      */
  189.  
  190.     // Stops the same event being processed repeatedly
  191.     static wxEventType inEvent = wxEVT_NULL;
  192.     if (inEvent == event.GetEventType())
  193.         return FALSE;
  194.  
  195.     inEvent = event.GetEventType();
  196.  
  197.     // Let the active child (if any) process the event first.
  198.     bool res = FALSE;
  199.     if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
  200. #if 0
  201.         /* This is sure to not give problems... */
  202.         && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
  203.             event.GetEventType() == wxEVT_UPDATE_UI )
  204. #else
  205.         /* This was tested on wxMSW and worked... */
  206.         && event.GetEventObject() != m_pClientWindow
  207.         && !(event.GetEventType() == wxEVT_ACTIVATE ||
  208.              event.GetEventType() == wxEVT_SET_FOCUS ||
  209.              event.GetEventType() == wxEVT_KILL_FOCUS ||
  210.              event.GetEventType() == wxEVT_CHILD_FOCUS ||
  211.              event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
  212.              event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
  213. #endif
  214.        )
  215.     {
  216.         res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
  217.     }
  218.  
  219.     // If the event was not handled this frame will handle it!
  220.     if (!res)
  221.     {
  222.         res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
  223.     }
  224.  
  225.     inEvent = wxEVT_NULL;
  226.  
  227.     return res;
  228. }
  229.  
  230. wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
  231. {
  232.     return m_pActiveChild;
  233. }
  234.  
  235. void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
  236. {
  237.     m_pActiveChild = pChildFrame;
  238. }
  239.  
  240. wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
  241. {
  242.     return m_pClientWindow;
  243. }
  244.  
  245. wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
  246. {
  247. #if wxUSE_GENERIC_MDI_AS_NATIVE
  248.     m_pClientWindow = new wxMDIClientWindow( this );
  249. #else
  250.     m_pClientWindow = new wxGenericMDIClientWindow( this );
  251. #endif
  252.     return m_pClientWindow;
  253. }
  254.  
  255. void wxGenericMDIParentFrame::ActivateNext()
  256. {
  257.     if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
  258.     {
  259.         int active = m_pClientWindow->GetSelection() + 1;
  260.         if (active >= m_pClientWindow->GetPageCount())
  261.             active = 0;
  262.  
  263.         m_pClientWindow->SetSelection(active);
  264.     }
  265. }
  266.  
  267. void wxGenericMDIParentFrame::ActivatePrevious()
  268. {
  269.     if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
  270.     {
  271.         int active = m_pClientWindow->GetSelection() - 1;
  272.         if (active < 0)
  273.             active = m_pClientWindow->GetPageCount() - 1;
  274.  
  275.         m_pClientWindow->SetSelection(active);
  276.     }
  277. }
  278.  
  279. void wxGenericMDIParentFrame::Init()
  280. {
  281.     m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
  282.     m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
  283. #if wxUSE_MENUS
  284.     m_pWindowMenu = (wxMenu *) NULL;
  285.     m_pMyMenuBar = (wxMenuBar*) NULL;
  286. #endif // wxUSE_MENUS
  287. }
  288.  
  289. #if wxUSE_MENUS
  290. void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
  291. {
  292.     if (pMenuBar && m_pWindowMenu)
  293.     {
  294.         // Remove old window menu
  295.         int pos = pMenuBar->FindMenu(_("&Window"));
  296.         if (pos != wxNOT_FOUND)
  297.         {
  298.             wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
  299.             pMenuBar->Remove(pos);
  300.         }
  301.     }
  302. }
  303.  
  304. void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
  305. {
  306.     if (pMenuBar && m_pWindowMenu)
  307.     {
  308.         int pos = pMenuBar->FindMenu(_("Help"));
  309.         if (pos == wxNOT_FOUND)
  310.         {
  311.             pMenuBar->Append(m_pWindowMenu, _("&Window"));
  312.         }
  313.         else
  314.         {
  315.             pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
  316.         }
  317.     }
  318. }
  319.  
  320. void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
  321. {
  322.     switch (event.GetId())
  323.     {
  324.     case wxWINDOWCLOSE:
  325.         if (m_pActiveChild)
  326.         {
  327.             m_pActiveChild->Close();
  328.         }
  329.         break;
  330.     case wxWINDOWCLOSEALL:
  331.         {
  332. #if 0   // code is only needed if next #if is set to 0!
  333.             wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
  334. #endif
  335.             while (m_pActiveChild)
  336.             {
  337.                 if (!m_pActiveChild->Close())
  338.                 {
  339.                     return; // We failed...
  340.                 }
  341.                 else
  342.                 {
  343. #if 1   // What's best? Delayed deleting or immediate deleting?
  344.                     delete m_pActiveChild;
  345. #else
  346.                     ActivateNext();
  347.  
  348.                     if (pFirstActiveChild == m_pActiveChild)
  349.                         return; // We've called Close on all items, no need to continue.
  350. #endif
  351.                 }
  352.             }
  353.         }
  354.         break;
  355.     case wxWINDOWNEXT:
  356.         ActivateNext();
  357.         break;
  358.     case wxWINDOWPREV:
  359.         ActivatePrevious();
  360.         break;
  361.     default :
  362.         event.Skip();
  363.     }
  364. }
  365. #endif // wxUSE_MENUS
  366.  
  367. void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
  368. {
  369.     wxFrame::DoGetClientSize( width, height );
  370. }
  371.  
  372.  
  373. //-----------------------------------------------------------------------------
  374. // wxGenericMDIChildFrame
  375. //-----------------------------------------------------------------------------
  376.  
  377. IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
  378.  
  379. BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
  380.     EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
  381.     EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)
  382.  
  383.     EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
  384.     EVT_SIZE(wxGenericMDIChildFrame::OnSize)
  385. END_EVENT_TABLE()
  386.  
  387. wxGenericMDIChildFrame::wxGenericMDIChildFrame()
  388. {
  389.     Init();
  390. }
  391.  
  392. wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
  393.       wxWindowID id, const wxString& title,
  394.       const wxPoint& WXUNUSED(pos), const wxSize& size,
  395.       long style, const wxString& name )
  396. {
  397.     Init();
  398.  
  399.     Create( parent, id, title, wxDefaultPosition, size, style, name );
  400. }
  401.  
  402. #include "wx/log.h"
  403. wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
  404. {
  405.     wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
  406.  
  407.     if (pParentFrame != NULL)
  408.     {
  409.         bool bActive = FALSE;
  410.         if (pParentFrame->GetActiveChild() == this)
  411.         {
  412.             pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
  413.             pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
  414.             bActive = TRUE;
  415.         }
  416.  
  417.         wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
  418.  
  419.         // Remove page if still there
  420.         int pos;
  421.         for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
  422.         {
  423.             if (pClientWindow->GetPage(pos) == this)
  424.             {
  425.                 if (pClientWindow->RemovePage(pos))
  426.                     pClientWindow->Refresh();
  427.                 break;
  428.             }
  429.         }
  430.  
  431.         if (bActive)
  432.         {
  433.             // Set the new selection to the a remaining page
  434.             if (pClientWindow->GetPageCount() > pos)
  435.             {
  436.                 pClientWindow->SetSelection(pos);
  437.             }
  438.             else
  439.             {
  440.                 if (pClientWindow->GetPageCount() - 1 >= 0)
  441.                     pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
  442.             }
  443.         }
  444.     }
  445.  
  446. #if wxUSE_MENUS
  447.     wxDELETE(m_pMenuBar);
  448. #endif // wxUSE_MENUS
  449. }
  450.  
  451. bool wxGenericMDIChildFrame::Create( wxGenericMDIParentFrame *parent,
  452.       wxWindowID id, const wxString& title,
  453.       const wxPoint& WXUNUSED(pos), const wxSize& size,
  454.       long style, const wxString& name )
  455. {
  456.     wxGenericMDIClientWindow* pClientWindow = parent->GetClientWindow();
  457.  
  458.     wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), wxT("Missing MDI client window.") );
  459.  
  460.     wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
  461.  
  462.     SetMDIParentFrame(parent);
  463.  
  464.     // This is the currently active child
  465.     parent->SetActiveChild(this);
  466.  
  467.     m_Title = title;
  468.  
  469.     pClientWindow->AddPage(this, title, TRUE);
  470.     ApplyMDIChildFrameRect();   // Ok confirme the size change!
  471.     pClientWindow->Refresh();
  472.  
  473.     return TRUE;
  474. }
  475.  
  476. #if wxUSE_MENUS
  477. void wxGenericMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
  478. {
  479.     wxMenuBar *pOldMenuBar = m_pMenuBar;
  480.     m_pMenuBar = menu_bar;
  481.  
  482.     if (m_pMenuBar)
  483.     {
  484.         wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
  485.  
  486.         if (pParentFrame != NULL)
  487.         {
  488.             m_pMenuBar->SetParent(pParentFrame);
  489.  
  490.             if (pParentFrame->GetActiveChild() == this)
  491.             {
  492.                 // Replace current menu bars
  493.                 if (pOldMenuBar)
  494.                     pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
  495.                 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) this);
  496.             }
  497.         }
  498.     }
  499. }
  500.  
  501. wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
  502. {
  503.     return m_pMenuBar;
  504. }
  505. #endif // wxUSE_MENUS
  506.  
  507. void wxGenericMDIChildFrame::SetTitle(const wxString& title)
  508. {
  509.     m_Title = title;
  510.  
  511.     wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
  512.  
  513.     if (pParentFrame != NULL)
  514.     {
  515.         wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
  516.  
  517.         if (pClientWindow != NULL)
  518.         {
  519.             int pos;
  520.             for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
  521.             {
  522.                 if (pClientWindow->GetPage(pos) == this)
  523.                 {
  524.                     pClientWindow->SetPageText(pos, m_Title);
  525.                     break;
  526.                 }
  527.             }
  528.         }
  529.     }
  530. }
  531.  
  532. wxString wxGenericMDIChildFrame::GetTitle() const
  533. {
  534.     return m_Title;
  535. }
  536.  
  537. void wxGenericMDIChildFrame::Activate()
  538. {
  539.     wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
  540.  
  541.     if (pParentFrame != NULL)
  542.     {
  543.         wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
  544.  
  545.         if (pClientWindow != NULL)
  546.         {
  547.             int pos;
  548.             for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
  549.             {
  550.                 if (pClientWindow->GetPage(pos) == this)
  551.                 {
  552.                     pClientWindow->SetSelection(pos);
  553.                     break;
  554.                 }
  555.             }
  556.         }
  557.     }
  558. }
  559.  
  560. void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
  561. {
  562. #if wxUSE_STATUSBAR
  563.     if ( m_pMDIParentFrame)
  564.     {
  565.         // we don't have any help text for this item,
  566.         // but may be the MDI frame does?
  567.         m_pMDIParentFrame->OnMenuHighlight(event);
  568.     }
  569. #endif // wxUSE_STATUSBAR
  570. }
  571.  
  572. void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& event)
  573. {
  574.     // Do mothing.
  575. }
  576.  
  577. /*** Copied from top level..! ***/
  578. // default resizing behaviour - if only ONE subwindow, resize to fill the
  579. // whole client area
  580. void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
  581. {
  582.     // if we're using constraints or sizers - do use them
  583.     if ( GetAutoLayout() )
  584.     {
  585.         Layout();
  586.     }
  587.     else
  588.     {
  589.         // do we have _exactly_ one child?
  590.         wxWindow *child = (wxWindow *)NULL;
  591.         for ( wxWindowList::Node *node = GetChildren().GetFirst();
  592.               node;
  593.               node = node->GetNext() )
  594.         {
  595.             wxWindow *win = node->GetData();
  596.  
  597.             // exclude top level and managed windows (status bar isn't
  598.             // currently in the children list except under wxMac anyhow, but
  599.             // it makes no harm to test for it)
  600.             if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
  601.             {
  602.                 if ( child )
  603.                 {
  604.                     return;     // it's our second subwindow - nothing to do
  605.                 }
  606.  
  607.                 child = win;
  608.             }
  609.         }
  610.  
  611.         // do we have any children at all?
  612.         if ( child )
  613.         {
  614.             // exactly one child - set it's size to fill the whole frame
  615.             int clientW, clientH;
  616.             DoGetClientSize(&clientW, &clientH);
  617.  
  618.             // for whatever reasons, wxGTK wants to have a small offset - it
  619.             // probably looks better with it?
  620. #ifdef __WXGTK__
  621.             static const int ofs = 1;
  622. #else
  623.             static const int ofs = 0;
  624. #endif
  625.  
  626.             child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
  627.         }
  628.     }
  629. }
  630.  
  631. /*** Copied from top level..! ***/
  632. // The default implementation for the close window event.
  633. void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
  634. {
  635.     Destroy();
  636. }
  637.  
  638. void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
  639. {
  640.     m_pMDIParentFrame = parentFrame;
  641. }
  642.  
  643. wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
  644. {
  645.     return m_pMDIParentFrame;
  646. }
  647.  
  648. void wxGenericMDIChildFrame::Init()
  649. {
  650.     m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
  651. #if wxUSE_MENUS
  652.     m_pMenuBar = (wxMenuBar *) NULL;
  653. #endif // wxUSE_MENUS
  654. }
  655.  
  656. void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
  657. {
  658.     m_MDIRect = wxRect(x, y, width, height);
  659. }
  660.  
  661. void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
  662. {
  663.     wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
  664. }
  665.  
  666. //-----------------------------------------------------------------------------
  667. // wxGenericMDIClientWindow
  668. //-----------------------------------------------------------------------------
  669.  
  670. #define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
  671.  
  672. IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
  673.  
  674. BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
  675.     EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
  676.     EVT_SIZE(wxGenericMDIClientWindow::OnSize)
  677. END_EVENT_TABLE()
  678.  
  679.  
  680. wxGenericMDIClientWindow::wxGenericMDIClientWindow()
  681. {
  682. }
  683.  
  684. wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
  685. {
  686.     CreateClient( parent, style );
  687. }
  688.  
  689. wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
  690. {
  691.     DestroyChildren();
  692. }
  693.  
  694. bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
  695. {
  696.     SetWindowStyleFlag(style);
  697.  
  698.     bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0);
  699.     if (success)
  700.     {
  701.         /*
  702.         wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
  703.         wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
  704.         GetTabView()->SetTabFont(font);
  705.         GetTabView()->SetSelectedTabFont(selFont);
  706.         GetTabView()->SetTabSize(120, 18);
  707.         GetTabView()->SetTabSelectionHeight(20);
  708.         */
  709.         return TRUE;
  710.     }
  711.     else
  712.         return FALSE;
  713. }
  714.  
  715. int wxGenericMDIClientWindow::SetSelection(int nPage)
  716. {
  717.     int oldSelection = wxNotebook::SetSelection(nPage);
  718.  
  719. #if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
  720.                         // will already cause this to be done!
  721.     // Handle the page change.
  722.     PageChanged(oldSelection, nPage);
  723. #endif
  724.  
  725.     return oldSelection;
  726. }
  727.  
  728. void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
  729. {
  730.     // Don't do to much work, only when something realy should change!
  731.     if (OldSelection == newSelection)
  732.         return;
  733.     // Again check if we realy need to do this...
  734.     if (newSelection != -1)
  735.     {
  736.         wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
  737.  
  738.         if (child->GetMDIParentFrame()->GetActiveChild() == child)
  739.             return;
  740.     }
  741.  
  742.     // Notify old active child that it has been deactivated
  743.     if (OldSelection != -1)
  744.     {
  745.         wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
  746.         if (oldChild)
  747.         {
  748.             wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldChild->GetId());
  749.             event.SetEventObject( oldChild );
  750.             oldChild->GetEventHandler()->ProcessEvent(event);
  751.         }
  752.     }
  753.  
  754.     // Notify new active child that it has been activated
  755.     if (newSelection != -1)
  756.     {
  757.         wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
  758.         if (activeChild)
  759.         {
  760.             wxActivateEvent event(wxEVT_ACTIVATE, TRUE, activeChild->GetId());
  761.             event.SetEventObject( activeChild );
  762.             activeChild->GetEventHandler()->ProcessEvent(event);
  763.  
  764.             if (activeChild->GetMDIParentFrame())
  765.             {
  766.                 activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
  767.                 activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
  768.             }
  769.         }
  770.     }
  771. }
  772.  
  773. void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
  774. {
  775.     PageChanged(event.GetOldSelection(), event.GetSelection());
  776.  
  777.     event.Skip();
  778. }
  779.  
  780. void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
  781. {
  782.     wxNotebook::OnSize(event);
  783.  
  784.     int pos;
  785.     for (pos = 0; pos < GetPageCount(); pos++)
  786.     {
  787.         ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
  788.     }
  789. }
  790.  
  791.  
  792. /*
  793.  * Define normal wxMDI classes based on wxGenericMDI
  794.  */
  795.  
  796. #if wxUSE_GENERIC_MDI_AS_NATIVE
  797.  
  798. wxMDIChildFrame * wxMDIParentFrame::GetActiveChild() const
  799.     {
  800.         wxGenericMDIChildFrame *pGFrame = wxGenericMDIParentFrame::GetActiveChild();
  801.         wxMDIChildFrame *pFrame = wxDynamicCast(pGFrame, wxMDIChildFrame);
  802.  
  803.         wxASSERT_MSG(!(pFrame == NULL && pGFrame != NULL), wxT("Active frame is class not derived from wxMDIChildFrame!"));
  804.  
  805.         return pFrame;
  806.     }
  807.  
  808. IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
  809. IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
  810. IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
  811.  
  812. #endif
  813.  
  814.