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