]> git.saurik.com Git - wxWidgets.git/blob - src/generic/mdig.cpp
added a menu allowing to quickly switch to any page
[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 #ifndef WX_PRECOMP
28 #include "wx/panel.h"
29 #include "wx/menu.h"
30 #include "wx/intl.h"
31 #endif //WX_PRECOMP
32
33 #include "wx/generic/mdig.h"
34 #include "wx/stockitem.h"
35
36 enum MDI_MENU_ID
37 {
38 wxWINDOWCLOSE = 4001,
39 wxWINDOWCLOSEALL,
40 wxWINDOWNEXT,
41 wxWINDOWPREV
42 };
43
44 //-----------------------------------------------------------------------------
45 // wxGenericMDIParentFrame
46 //-----------------------------------------------------------------------------
47
48 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
49
50 BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
51 #if wxUSE_MENUS
52 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
53 #endif
54 END_EVENT_TABLE()
55
56 wxGenericMDIParentFrame::wxGenericMDIParentFrame()
57 {
58 Init();
59 }
60
61 wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
62 wxWindowID id,
63 const wxString& title,
64 const wxPoint& pos,
65 const wxSize& size,
66 long style,
67 const wxString& name)
68 {
69 Init();
70
71 (void)Create(parent, id, title, pos, size, style, name);
72 }
73
74 wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
75 {
76 // Make sure the client window is destructed before the menu bars are!
77 wxDELETE(m_pClientWindow);
78
79 #if wxUSE_MENUS
80 if (m_pMyMenuBar)
81 {
82 delete m_pMyMenuBar;
83 m_pMyMenuBar = (wxMenuBar *) NULL;
84 }
85
86 RemoveWindowMenu(GetMenuBar());
87
88 if (m_pWindowMenu)
89 {
90 delete m_pWindowMenu;
91 m_pWindowMenu = (wxMenu*) NULL;
92 }
93 #endif // wxUSE_MENUS
94 }
95
96 bool wxGenericMDIParentFrame::Create(wxWindow *parent,
97 wxWindowID id,
98 const wxString& title,
99 const wxPoint& pos,
100 const wxSize& size,
101 long style,
102 const wxString& name)
103 {
104 // this style can be used to prevent a window from having the standard MDI
105 // "Window" menu
106 if ( !(style & wxFRAME_NO_WINDOW_MENU) )
107 {
108 #if wxUSE_MENUS
109 m_pWindowMenu = new wxMenu;
110
111 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
112 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
113 m_pWindowMenu->AppendSeparator();
114 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
115 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
116 #endif // wxUSE_MENUS
117 }
118
119 wxFrame::Create( parent, id, title, pos, size, style, name );
120
121 OnCreateClient();
122
123 return true;
124 }
125
126 #if wxUSE_MENUS
127 void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
128 {
129 // Replace the window menu from the currently loaded menu bar.
130 wxMenuBar *pMenuBar = GetMenuBar();
131
132 if (m_pWindowMenu)
133 {
134 RemoveWindowMenu(pMenuBar);
135
136 wxDELETE(m_pWindowMenu);
137 }
138
139 if (pMenu)
140 {
141 m_pWindowMenu = pMenu;
142
143 AddWindowMenu(pMenuBar);
144 }
145 }
146
147 void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
148 {
149 // Remove the Window menu from the old menu bar
150 RemoveWindowMenu(GetMenuBar());
151 // Add the Window menu to the new menu bar.
152 AddWindowMenu(pMenuBar);
153
154 wxFrame::SetMenuBar(pMenuBar);
155 }
156 #endif // wxUSE_MENUS
157
158 void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
159 {
160 #if wxUSE_MENUS
161 if (pChild == (wxGenericMDIChildFrame *) NULL)
162 {
163 // No Child, set Our menu bar back.
164 SetMenuBar(m_pMyMenuBar);
165
166 // Make sure we know our menu bar is in use
167 m_pMyMenuBar = (wxMenuBar*) NULL;
168 }
169 else
170 {
171 if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
172 return;
173
174 // Do we need to save the current bar?
175 if (m_pMyMenuBar == NULL)
176 m_pMyMenuBar = GetMenuBar();
177
178 SetMenuBar(pChild->GetMenuBar());
179 }
180 #endif // wxUSE_MENUS
181 }
182
183 bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
184 {
185 /*
186 * Redirect events to active child first.
187 */
188
189 // Stops the same event being processed repeatedly
190 static wxEventType inEvent = wxEVT_NULL;
191 if (inEvent == event.GetEventType())
192 return false;
193
194 inEvent = event.GetEventType();
195
196 // Let the active child (if any) process the event first.
197 bool res = false;
198 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
199 #if 0
200 /* This is sure to not give problems... */
201 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
202 event.GetEventType() == wxEVT_UPDATE_UI )
203 #else
204 /* This was tested on wxMSW and worked... */
205 && event.GetEventObject() != m_pClientWindow
206 && !(event.GetEventType() == wxEVT_ACTIVATE ||
207 event.GetEventType() == wxEVT_SET_FOCUS ||
208 event.GetEventType() == wxEVT_KILL_FOCUS ||
209 event.GetEventType() == wxEVT_CHILD_FOCUS ||
210 event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
211 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
212 #endif
213 )
214 {
215 res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
216 }
217
218 // If the event was not handled this frame will handle it!
219 if (!res)
220 {
221 res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
222 }
223
224 inEvent = wxEVT_NULL;
225
226 return res;
227 }
228
229 wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
230 {
231 return m_pActiveChild;
232 }
233
234 void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
235 {
236 m_pActiveChild = pChildFrame;
237 }
238
239 wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
240 {
241 return m_pClientWindow;
242 }
243
244 wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
245 {
246 #if wxUSE_GENERIC_MDI_AS_NATIVE
247 m_pClientWindow = new wxMDIClientWindow( this );
248 #else
249 m_pClientWindow = new wxGenericMDIClientWindow( this );
250 #endif
251 return m_pClientWindow;
252 }
253
254 void wxGenericMDIParentFrame::ActivateNext()
255 {
256 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
257 {
258 size_t active = m_pClientWindow->GetSelection() + 1;
259 if (active >= m_pClientWindow->GetPageCount())
260 active = 0;
261
262 m_pClientWindow->SetSelection(active);
263 }
264 }
265
266 void wxGenericMDIParentFrame::ActivatePrevious()
267 {
268 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
269 {
270 int active = m_pClientWindow->GetSelection() - 1;
271 if (active < 0)
272 active = m_pClientWindow->GetPageCount() - 1;
273
274 m_pClientWindow->SetSelection(active);
275 }
276 }
277
278 void wxGenericMDIParentFrame::Init()
279 {
280 m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
281 m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
282 #if wxUSE_MENUS
283 m_pWindowMenu = (wxMenu *) NULL;
284 m_pMyMenuBar = (wxMenuBar*) NULL;
285 #endif // wxUSE_MENUS
286 }
287
288 #if wxUSE_MENUS
289 void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
290 {
291 if (pMenuBar && m_pWindowMenu)
292 {
293 // Remove old window menu
294 int pos = pMenuBar->FindMenu(_("&Window"));
295 if (pos != wxNOT_FOUND)
296 {
297 wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
298 pMenuBar->Remove(pos);
299 }
300 }
301 }
302
303 void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
304 {
305 if (pMenuBar && m_pWindowMenu)
306 {
307 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false));
308 if (pos == wxNOT_FOUND)
309 {
310 pMenuBar->Append(m_pWindowMenu, _("&Window"));
311 }
312 else
313 {
314 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
315 }
316 }
317 }
318
319 void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
320 {
321 switch (event.GetId())
322 {
323 case wxWINDOWCLOSE:
324 if (m_pActiveChild)
325 {
326 m_pActiveChild->Close();
327 }
328 break;
329 case wxWINDOWCLOSEALL:
330 {
331 #if 0 // code is only needed if next #if is set to 0!
332 wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
333 #endif
334 while (m_pActiveChild)
335 {
336 if (!m_pActiveChild->Close())
337 {
338 return; // We failed...
339 }
340 else
341 {
342 #if 1 // What's best? Delayed deleting or immediate deleting?
343 delete m_pActiveChild;
344 m_pActiveChild = NULL;
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 size_t 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 ((int)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 size_t 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 size_t 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 #else
570 wxUnusedVar(event);
571 #endif // wxUSE_STATUSBAR
572 }
573
574 void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
575 {
576 // Do mothing.
577 }
578
579 /*** Copied from top level..! ***/
580 // default resizing behaviour - if only ONE subwindow, resize to fill the
581 // whole client area
582 void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
583 {
584 // if we're using constraints or sizers - do use them
585 if ( GetAutoLayout() )
586 {
587 Layout();
588 }
589 else
590 {
591 // do we have _exactly_ one child?
592 wxWindow *child = (wxWindow *)NULL;
593 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
594 node;
595 node = node->GetNext() )
596 {
597 wxWindow *win = node->GetData();
598
599 // exclude top level and managed windows (status bar isn't
600 // currently in the children list except under wxMac anyhow, but
601 // it makes no harm to test for it)
602 if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
603 {
604 if ( child )
605 {
606 return; // it's our second subwindow - nothing to do
607 }
608
609 child = win;
610 }
611 }
612
613 // do we have any children at all?
614 if ( child )
615 {
616 // exactly one child - set it's size to fill the whole frame
617 int clientW, clientH;
618 DoGetClientSize(&clientW, &clientH);
619
620 // for whatever reasons, wxGTK wants to have a small offset - it
621 // probably looks better with it?
622 #ifdef __WXGTK__
623 static const int ofs = 1;
624 #else
625 static const int ofs = 0;
626 #endif
627
628 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
629 }
630 }
631 }
632
633 /*** Copied from top level..! ***/
634 // The default implementation for the close window event.
635 void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
636 {
637 Destroy();
638 }
639
640 void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
641 {
642 m_pMDIParentFrame = parentFrame;
643 }
644
645 wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
646 {
647 return m_pMDIParentFrame;
648 }
649
650 void wxGenericMDIChildFrame::Init()
651 {
652 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
653 #if wxUSE_MENUS
654 m_pMenuBar = (wxMenuBar *) NULL;
655 #endif // wxUSE_MENUS
656 }
657
658 void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
659 {
660 m_MDIRect = wxRect(x, y, width, height);
661 }
662
663 void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
664 {
665 wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
666 }
667
668 //-----------------------------------------------------------------------------
669 // wxGenericMDIClientWindow
670 //-----------------------------------------------------------------------------
671
672 #define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
673
674 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
675
676 BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
677 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
678 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
679 END_EVENT_TABLE()
680
681
682 wxGenericMDIClientWindow::wxGenericMDIClientWindow()
683 {
684 }
685
686 wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
687 {
688 CreateClient( parent, style );
689 }
690
691 wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
692 {
693 DestroyChildren();
694 }
695
696 bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
697 {
698 SetWindowStyleFlag(style);
699
700 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0,0), wxSize(100, 100), 0);
701 if (success)
702 {
703 /*
704 wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
705 wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
706 GetTabView()->SetTabFont(font);
707 GetTabView()->SetSelectedTabFont(selFont);
708 GetTabView()->SetTabSize(120, 18);
709 GetTabView()->SetTabSelectionHeight(20);
710 */
711 return true;
712 }
713 else
714 return false;
715 }
716
717 int wxGenericMDIClientWindow::SetSelection(size_t nPage)
718 {
719 int oldSelection = wxNotebook::SetSelection(nPage);
720
721 #if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
722 // will already cause this to be done!
723 // Handle the page change.
724 PageChanged(oldSelection, nPage);
725 #endif
726
727 return oldSelection;
728 }
729
730 void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
731 {
732 // Don't do to much work, only when something realy should change!
733 if (OldSelection == newSelection)
734 return;
735 // Again check if we realy need to do this...
736 if (newSelection != -1)
737 {
738 wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
739
740 if (child->GetMDIParentFrame()->GetActiveChild() == child)
741 return;
742 }
743
744 // Notify old active child that it has been deactivated
745 if (OldSelection != -1)
746 {
747 wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
748 if (oldChild)
749 {
750 wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId());
751 event.SetEventObject( oldChild );
752 oldChild->GetEventHandler()->ProcessEvent(event);
753 }
754 }
755
756 // Notify new active child that it has been activated
757 if (newSelection != -1)
758 {
759 wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
760 if (activeChild)
761 {
762 wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId());
763 event.SetEventObject( activeChild );
764 activeChild->GetEventHandler()->ProcessEvent(event);
765
766 if (activeChild->GetMDIParentFrame())
767 {
768 activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
769 activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
770 }
771 }
772 }
773 }
774
775 void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
776 {
777 PageChanged(event.GetOldSelection(), event.GetSelection());
778
779 event.Skip();
780 }
781
782 void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
783 {
784 wxNotebook::OnSize(event);
785
786 size_t pos;
787 for (pos = 0; pos < GetPageCount(); pos++)
788 {
789 ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
790 }
791 }
792
793
794 /*
795 * Define normal wxMDI classes based on wxGenericMDI
796 */
797
798 #if wxUSE_GENERIC_MDI_AS_NATIVE
799
800 wxMDIChildFrame * wxMDIParentFrame::GetActiveChild() const
801 {
802 wxGenericMDIChildFrame *pGFrame = wxGenericMDIParentFrame::GetActiveChild();
803 wxMDIChildFrame *pFrame = wxDynamicCast(pGFrame, wxMDIChildFrame);
804
805 wxASSERT_MSG(!(pFrame == NULL && pGFrame != NULL), wxT("Active frame is class not derived from wxMDIChildFrame!"));
806
807 return pFrame;
808 }
809
810 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
811 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
812 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
813
814 #endif
815