Reuse functionality of wxGetStockLabel().
[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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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 #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 wxFrame::Create( parent, id, title, pos, size, style, name );
124
125 OnCreateClient();
126
127 return true;
128 }
129
130 #if wxUSE_MENUS
131 void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
132 {
133 // Replace the window menu from the currently loaded menu bar.
134 wxMenuBar *pMenuBar = GetMenuBar();
135
136 if (m_pWindowMenu)
137 {
138 RemoveWindowMenu(pMenuBar);
139
140 wxDELETE(m_pWindowMenu);
141 }
142
143 if (pMenu)
144 {
145 m_pWindowMenu = pMenu;
146
147 AddWindowMenu(pMenuBar);
148 }
149 }
150
151 void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
152 {
153 // Remove the Window menu from the old menu bar
154 RemoveWindowMenu(GetMenuBar());
155 // Add the Window menu to the new menu bar.
156 AddWindowMenu(pMenuBar);
157
158 wxFrame::SetMenuBar(pMenuBar);
159 }
160 #endif // wxUSE_MENUS
161
162 void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
163 {
164 #if wxUSE_MENUS
165 if (pChild == (wxGenericMDIChildFrame *) NULL)
166 {
167 // No Child, set Our menu bar back.
168 SetMenuBar(m_pMyMenuBar);
169
170 // Make sure we know our menu bar is in use
171 m_pMyMenuBar = (wxMenuBar*) NULL;
172 }
173 else
174 {
175 if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
176 return;
177
178 // Do we need to save the current bar?
179 if (m_pMyMenuBar == NULL)
180 m_pMyMenuBar = GetMenuBar();
181
182 SetMenuBar(pChild->GetMenuBar());
183 }
184 #endif // wxUSE_MENUS
185 }
186
187 bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
188 {
189 /*
190 * Redirect events to active child first.
191 */
192
193 // Stops the same event being processed repeatedly
194 static wxEventType inEvent = wxEVT_NULL;
195 if (inEvent == event.GetEventType())
196 return false;
197
198 inEvent = event.GetEventType();
199
200 // Let the active child (if any) process the event first.
201 bool res = false;
202 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
203 #if 0
204 /* This is sure to not give problems... */
205 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
206 event.GetEventType() == wxEVT_UPDATE_UI )
207 #else
208 /* This was tested on wxMSW and worked... */
209 && event.GetEventObject() != m_pClientWindow
210 && !(event.GetEventType() == wxEVT_ACTIVATE ||
211 event.GetEventType() == wxEVT_SET_FOCUS ||
212 event.GetEventType() == wxEVT_KILL_FOCUS ||
213 event.GetEventType() == wxEVT_CHILD_FOCUS ||
214 event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
215 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
216 #endif
217 )
218 {
219 res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
220 }
221
222 // If the event was not handled this frame will handle it!
223 if (!res)
224 {
225 res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
226 }
227
228 inEvent = wxEVT_NULL;
229
230 return res;
231 }
232
233 wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
234 {
235 return m_pActiveChild;
236 }
237
238 void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
239 {
240 m_pActiveChild = pChildFrame;
241 }
242
243 wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
244 {
245 return m_pClientWindow;
246 }
247
248 wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
249 {
250 #if wxUSE_GENERIC_MDI_AS_NATIVE
251 m_pClientWindow = new wxMDIClientWindow( this );
252 #else
253 m_pClientWindow = new wxGenericMDIClientWindow( this );
254 #endif
255 return m_pClientWindow;
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 #include "wx/log.h"
407 wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
408 {
409 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
410
411 if (pParentFrame != NULL)
412 {
413 bool bActive = false;
414 if (pParentFrame->GetActiveChild() == this)
415 {
416 pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
417 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
418 bActive = true;
419 }
420
421 wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
422
423 // Remove page if still there
424 size_t pos;
425 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
426 {
427 if (pClientWindow->GetPage(pos) == this)
428 {
429 if (pClientWindow->RemovePage(pos))
430 pClientWindow->Refresh();
431 break;
432 }
433 }
434
435 if (bActive)
436 {
437 // Set the new selection to the a remaining page
438 if (pClientWindow->GetPageCount() > pos)
439 {
440 pClientWindow->SetSelection(pos);
441 }
442 else
443 {
444 if ((int)pClientWindow->GetPageCount() - 1 >= 0)
445 pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
446 }
447 }
448 }
449
450 #if wxUSE_MENUS
451 wxDELETE(m_pMenuBar);
452 #endif // wxUSE_MENUS
453 }
454
455 bool wxGenericMDIChildFrame::Create( wxGenericMDIParentFrame *parent,
456 wxWindowID id, const wxString& title,
457 const wxPoint& WXUNUSED(pos), const wxSize& size,
458 long style, const wxString& name )
459 {
460 wxGenericMDIClientWindow* pClientWindow = parent->GetClientWindow();
461
462 wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), wxT("Missing MDI client window.") );
463
464 wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
465
466 SetMDIParentFrame(parent);
467
468 // This is the currently active child
469 parent->SetActiveChild(this);
470
471 m_Title = title;
472
473 pClientWindow->AddPage(this, title, true);
474 ApplyMDIChildFrameRect(); // Ok confirme the size change!
475 pClientWindow->Refresh();
476
477 return true;
478 }
479
480 #if wxUSE_MENUS
481 void wxGenericMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
482 {
483 wxMenuBar *pOldMenuBar = m_pMenuBar;
484 m_pMenuBar = menu_bar;
485
486 if (m_pMenuBar)
487 {
488 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
489
490 if (pParentFrame != NULL)
491 {
492 m_pMenuBar->SetParent(pParentFrame);
493
494 if (pParentFrame->GetActiveChild() == this)
495 {
496 // Replace current menu bars
497 if (pOldMenuBar)
498 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
499 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) this);
500 }
501 }
502 }
503 }
504
505 wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
506 {
507 return m_pMenuBar;
508 }
509 #endif // wxUSE_MENUS
510
511 void wxGenericMDIChildFrame::SetTitle(const wxString& title)
512 {
513 m_Title = title;
514
515 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
516
517 if (pParentFrame != NULL)
518 {
519 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
520
521 if (pClientWindow != NULL)
522 {
523 size_t pos;
524 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
525 {
526 if (pClientWindow->GetPage(pos) == this)
527 {
528 pClientWindow->SetPageText(pos, m_Title);
529 break;
530 }
531 }
532 }
533 }
534 }
535
536 wxString wxGenericMDIChildFrame::GetTitle() const
537 {
538 return m_Title;
539 }
540
541 void wxGenericMDIChildFrame::Activate()
542 {
543 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
544
545 if (pParentFrame != NULL)
546 {
547 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
548
549 if (pClientWindow != NULL)
550 {
551 size_t pos;
552 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
553 {
554 if (pClientWindow->GetPage(pos) == this)
555 {
556 pClientWindow->SetSelection(pos);
557 break;
558 }
559 }
560 }
561 }
562 }
563
564 void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
565 {
566 #if wxUSE_STATUSBAR
567 if ( m_pMDIParentFrame)
568 {
569 // we don't have any help text for this item,
570 // but may be the MDI frame does?
571 m_pMDIParentFrame->OnMenuHighlight(event);
572 }
573 #else
574 wxUnusedVar(event);
575 #endif // wxUSE_STATUSBAR
576 }
577
578 void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
579 {
580 // Do mothing.
581 }
582
583 /*** Copied from top level..! ***/
584 // default resizing behaviour - if only ONE subwindow, resize to fill the
585 // whole client area
586 void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
587 {
588 // if we're using constraints or sizers - do use them
589 if ( GetAutoLayout() )
590 {
591 Layout();
592 }
593 else
594 {
595 // do we have _exactly_ one child?
596 wxWindow *child = (wxWindow *)NULL;
597 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
598 node;
599 node = node->GetNext() )
600 {
601 wxWindow *win = node->GetData();
602
603 // exclude top level and managed windows (status bar isn't
604 // currently in the children list except under wxMac anyhow, but
605 // it makes no harm to test for it)
606 if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
607 {
608 if ( child )
609 {
610 return; // it's our second subwindow - nothing to do
611 }
612
613 child = win;
614 }
615 }
616
617 // do we have any children at all?
618 if ( child )
619 {
620 // exactly one child - set it's size to fill the whole frame
621 int clientW, clientH;
622 DoGetClientSize(&clientW, &clientH);
623
624 // for whatever reasons, wxGTK wants to have a small offset - it
625 // probably looks better with it?
626 #ifdef __WXGTK__
627 static const int ofs = 1;
628 #else
629 static const int ofs = 0;
630 #endif
631
632 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
633 }
634 }
635 }
636
637 /*** Copied from top level..! ***/
638 // The default implementation for the close window event.
639 void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
640 {
641 Destroy();
642 }
643
644 void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
645 {
646 m_pMDIParentFrame = parentFrame;
647 }
648
649 wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
650 {
651 return m_pMDIParentFrame;
652 }
653
654 void wxGenericMDIChildFrame::Init()
655 {
656 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
657 #if wxUSE_MENUS
658 m_pMenuBar = (wxMenuBar *) NULL;
659 #endif // wxUSE_MENUS
660 }
661
662 void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
663 {
664 m_MDIRect = wxRect(x, y, width, height);
665 }
666
667 void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
668 {
669 wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
670 }
671
672 //-----------------------------------------------------------------------------
673 // wxGenericMDIClientWindow
674 //-----------------------------------------------------------------------------
675
676 #define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
677
678 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
679
680 BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
681 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
682 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
683 END_EVENT_TABLE()
684
685
686 wxGenericMDIClientWindow::wxGenericMDIClientWindow()
687 {
688 }
689
690 wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
691 {
692 CreateClient( parent, style );
693 }
694
695 wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
696 {
697 DestroyChildren();
698 }
699
700 bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
701 {
702 SetWindowStyleFlag(style);
703
704 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0,0), wxSize(100, 100), 0);
705 if (success)
706 {
707 /*
708 wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
709 wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
710 GetTabView()->SetTabFont(font);
711 GetTabView()->SetSelectedTabFont(selFont);
712 GetTabView()->SetTabSize(120, 18);
713 GetTabView()->SetTabSelectionHeight(20);
714 */
715 return true;
716 }
717 else
718 return false;
719 }
720
721 int wxGenericMDIClientWindow::SetSelection(size_t nPage)
722 {
723 int oldSelection = wxNotebook::SetSelection(nPage);
724
725 #if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
726 // will already cause this to be done!
727 // Handle the page change.
728 PageChanged(oldSelection, nPage);
729 #endif
730
731 return oldSelection;
732 }
733
734 void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
735 {
736 // Don't do to much work, only when something realy should change!
737 if (OldSelection == newSelection)
738 return;
739 // Again check if we realy need to do this...
740 if (newSelection != -1)
741 {
742 wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
743
744 if (child->GetMDIParentFrame()->GetActiveChild() == child)
745 return;
746 }
747
748 // Notify old active child that it has been deactivated
749 if (OldSelection != -1)
750 {
751 wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
752 if (oldChild)
753 {
754 wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId());
755 event.SetEventObject( oldChild );
756 oldChild->GetEventHandler()->ProcessEvent(event);
757 }
758 }
759
760 // Notify new active child that it has been activated
761 if (newSelection != -1)
762 {
763 wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
764 if (activeChild)
765 {
766 wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId());
767 event.SetEventObject( activeChild );
768 activeChild->GetEventHandler()->ProcessEvent(event);
769
770 if (activeChild->GetMDIParentFrame())
771 {
772 activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
773 activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
774 }
775 }
776 }
777 }
778
779 void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
780 {
781 PageChanged(event.GetOldSelection(), event.GetSelection());
782
783 event.Skip();
784 }
785
786 void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
787 {
788 wxNotebook::OnSize(event);
789
790 size_t pos;
791 for (pos = 0; pos < GetPageCount(); pos++)
792 {
793 ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
794 }
795 }
796
797
798 /*
799 * Define normal wxMDI classes based on wxGenericMDI
800 */
801
802 #if wxUSE_GENERIC_MDI_AS_NATIVE
803
804 wxMDIChildFrame * wxMDIParentFrame::GetActiveChild() const
805 {
806 wxGenericMDIChildFrame *pGFrame = wxGenericMDIParentFrame::GetActiveChild();
807 wxMDIChildFrame *pFrame = wxDynamicCast(pGFrame, wxMDIChildFrame);
808
809 wxASSERT_MSG(!(pFrame == NULL && pGFrame != NULL), wxT("Active frame is class not derived from wxMDIChildFrame!"));
810
811 return pFrame;
812 }
813
814 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
815 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
816 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
817
818 #endif
819