]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/generic/mdig.cpp
don't pass NULL pointer to printf(), this crashes Solaris printf
[wxWidgets.git] / src / generic / mdig.cpp
... / ...
CommitLineData
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
40enum MDI_MENU_ID
41{
42 wxWINDOWCLOSE = 4001,
43 wxWINDOWCLOSEALL,
44 wxWINDOWNEXT,
45 wxWINDOWPREV
46};
47
48//-----------------------------------------------------------------------------
49// wxGenericMDIParentFrame
50//-----------------------------------------------------------------------------
51
52IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
53
54BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
55#if wxUSE_MENUS
56 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
57#endif
58END_EVENT_TABLE()
59
60wxGenericMDIParentFrame::wxGenericMDIParentFrame()
61{
62 Init();
63}
64
65wxGenericMDIParentFrame::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
78wxGenericMDIParentFrame::~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
100bool 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
131void 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
151void 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
162void 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
187bool 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
233wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
234{
235 return m_pActiveChild;
236}
237
238void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
239{
240 m_pActiveChild = pChildFrame;
241}
242
243wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
244{
245 return m_pClientWindow;
246}
247
248wxGenericMDIClientWindow *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
258void 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
270void 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
282void 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
293void 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
307void 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
323void 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
371void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
372{
373 wxFrame::DoGetClientSize( width, height );
374}
375
376
377//-----------------------------------------------------------------------------
378// wxGenericMDIChildFrame
379//-----------------------------------------------------------------------------
380
381IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
382
383BEGIN_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)
389END_EVENT_TABLE()
390
391wxGenericMDIChildFrame::wxGenericMDIChildFrame()
392{
393 Init();
394}
395
396wxGenericMDIChildFrame::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"
407wxGenericMDIChildFrame::~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
455bool 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
481void 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
505wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
506{
507 return m_pMenuBar;
508}
509#endif // wxUSE_MENUS
510
511void 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
536wxString wxGenericMDIChildFrame::GetTitle() const
537{
538 return m_Title;
539}
540
541void 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
564void 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
578void 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
586void 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.
639void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
640{
641 Destroy();
642}
643
644void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
645{
646 m_pMDIParentFrame = parentFrame;
647}
648
649wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
650{
651 return m_pMDIParentFrame;
652}
653
654void wxGenericMDIChildFrame::Init()
655{
656 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
657#if wxUSE_MENUS
658 m_pMenuBar = (wxMenuBar *) NULL;
659#endif // wxUSE_MENUS
660}
661
662void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
663{
664 m_MDIRect = wxRect(x, y, width, height);
665}
666
667void 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
678IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
679
680BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
681 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
682 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
683END_EVENT_TABLE()
684
685
686wxGenericMDIClientWindow::wxGenericMDIClientWindow()
687{
688}
689
690wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
691{
692 CreateClient( parent, style );
693}
694
695wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
696{
697 DestroyChildren();
698}
699
700bool 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
721int 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
734void 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
779void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
780{
781 PageChanged(event.GetOldSelection(), event.GetSelection());
782
783 event.Skip();
784}
785
786void 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
804wxMDIChildFrame * 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
814IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
815IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
816IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
817
818#endif
819