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