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