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