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