]> git.saurik.com Git - wxWidgets.git/blame - src/generic/mdig.cpp
trick the sizer code into thinking that the wizard pages are shown so that it takes...
[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
65571936 9// Licence: wxWindows licence
6c70a9b5
JS
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
6c70a9b5
JS
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"
2b5f62a0 30 #include "wx/intl.h"
6c70a9b5
JS
31#endif //WX_PRECOMP
32
33#include "wx/generic/mdig.h"
e27d9a91 34#include "wx/stockitem.h"
6c70a9b5 35
c0924519 36enum MDI_MENU_ID
6c70a9b5
JS
37{
38 wxWINDOWCLOSE = 4001,
39 wxWINDOWCLOSEALL,
40 wxWINDOWNEXT,
41 wxWINDOWPREV
42};
43
44//-----------------------------------------------------------------------------
45// wxGenericMDIParentFrame
46//-----------------------------------------------------------------------------
47
48IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
49
50BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
d7260478 51#if wxUSE_MENUS
ca65c044 52 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
d7260478 53#endif
6c70a9b5
JS
54END_EVENT_TABLE()
55
c0924519
DW
56wxGenericMDIParentFrame::wxGenericMDIParentFrame()
57{
58 Init();
6c70a9b5
JS
59}
60
61wxGenericMDIParentFrame::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();
c0924519 70
6c70a9b5
JS
71 (void)Create(parent, id, title, pos, size, style, name);
72}
73
74wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
c0924519 75{
6c70a9b5
JS
76 // Make sure the client window is destructed before the menu bars are!
77 wxDELETE(m_pClientWindow);
78
c0924519 79#if wxUSE_MENUS
6c70a9b5
JS
80 if (m_pMyMenuBar)
81 {
82 delete m_pMyMenuBar;
83 m_pMyMenuBar = (wxMenuBar *) NULL;
84 }
c0924519 85
6c70a9b5
JS
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
96bool 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
2b5f62a0
VZ
111 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
112 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
6c70a9b5 113 m_pWindowMenu->AppendSeparator();
2b5f62a0
VZ
114 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
115 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
6c70a9b5
JS
116#endif // wxUSE_MENUS
117 }
118
119 wxFrame::Create( parent, id, title, pos, size, style, name );
120
121 OnCreateClient();
122
ca65c044 123 return true;
6c70a9b5
JS
124}
125
126#if wxUSE_MENUS
127void 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
147void 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
158void 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);
c0924519 165
6c70a9b5
JS
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
183bool 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())
ca65c044 192 return false;
6c70a9b5
JS
193
194 inEvent = event.GetEventType();
195
196 // Let the active child (if any) process the event first.
ca65c044 197 bool res = false;
c0924519 198 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
6c70a9b5
JS
199#if 0
200 /* This is sure to not give problems... */
201 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
2b5f62a0 202 event.GetEventType() == wxEVT_UPDATE_UI )
6c70a9b5
JS
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 ||
2b5f62a0 211 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
6c70a9b5 212#endif
2b5f62a0 213 )
6c70a9b5
JS
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
229wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
230{
231 return m_pActiveChild;
232}
233
234void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
235{
236 m_pActiveChild = pChildFrame;
237}
238
239wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
240{
241 return m_pClientWindow;
242}
243
244wxGenericMDIClientWindow *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
254void wxGenericMDIParentFrame::ActivateNext()
255{
256 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
257 {
34a0c9f4 258 size_t active = m_pClientWindow->GetSelection() + 1;
6c70a9b5
JS
259 if (active >= m_pClientWindow->GetPageCount())
260 active = 0;
261
262 m_pClientWindow->SetSelection(active);
263 }
264}
265
266void 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
278void 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
289void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
290{
291 if (pMenuBar && m_pWindowMenu)
292 {
293 // Remove old window menu
2b5f62a0 294 int pos = pMenuBar->FindMenu(_("&Window"));
6c70a9b5
JS
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
303void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
304{
305 if (pMenuBar && m_pWindowMenu)
c0924519 306 {
e27d9a91 307 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false));
6c70a9b5
JS
308 if (pos == wxNOT_FOUND)
309 {
2b5f62a0 310 pMenuBar->Append(m_pWindowMenu, _("&Window"));
6c70a9b5
JS
311 }
312 else
313 {
2b5f62a0 314 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
6c70a9b5
JS
315 }
316 }
317}
318
319void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
320{
321 switch (event.GetId())
322 {
c0924519 323 case wxWINDOWCLOSE:
6c70a9b5
JS
324 if (m_pActiveChild)
325 {
326 m_pActiveChild->Close();
327 }
328 break;
329 case wxWINDOWCLOSEALL:
330 {
c0924519 331#if 0 // code is only needed if next #if is set to 0!
6c70a9b5
JS
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;
902725ee 344 m_pActiveChild = NULL;
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 {
ca65c044 409 bool bActive = false;
6c70a9b5
JS
410 if (pParentFrame->GetActiveChild() == this)
411 {
412 pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
413 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
ca65c044 414 bActive = true;
6c70a9b5
JS
415 }
416
417 wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
418
419 // Remove page if still there
34a0c9f4 420 size_t pos;
6c70a9b5
JS
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 {
8a39593e 440 if ((int)pClientWindow->GetPageCount() - 1 >= 0)
6c70a9b5
JS
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
ca65c044 469 pClientWindow->AddPage(this, title, true);
6c70a9b5
JS
470 ApplyMDIChildFrameRect(); // Ok confirme the size change!
471 pClientWindow->Refresh();
472
ca65c044 473 return true;
6c70a9b5
JS
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 {
34a0c9f4 519 size_t pos;
6c70a9b5
JS
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 {
34a0c9f4 547 size_t pos;
6c70a9b5
JS
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 }
67a99992
WS
569#else
570 wxUnusedVar(event);
6c70a9b5
JS
571#endif // wxUSE_STATUSBAR
572}
573
61fef19b 574void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
6c70a9b5
JS
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
582void 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;
ac32ba44 593 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6c70a9b5
JS
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.
635void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
636{
637 Destroy();
638}
639
c0924519
DW
640void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
641{
642 m_pMDIParentFrame = parentFrame;
6c70a9b5
JS
643}
644
c0924519
DW
645wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
646{
647 return m_pMDIParentFrame;
6c70a9b5
JS
648}
649
650void wxGenericMDIChildFrame::Init()
651{
652 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
653#if wxUSE_MENUS
654 m_pMenuBar = (wxMenuBar *) NULL;
c0924519 655#endif // wxUSE_MENUS
6c70a9b5
JS
656}
657
658void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
c0924519 659{
6c70a9b5
JS
660 m_MDIRect = wxRect(x, y, width, height);
661}
662
663void 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
674IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
675
676BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
677 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
678 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
679END_EVENT_TABLE()
680
681
682wxGenericMDIClientWindow::wxGenericMDIClientWindow()
683{
684}
685
686wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
687{
688 CreateClient( parent, style );
689}
690
691wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
692{
693 DestroyChildren();
694}
695
696bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
697{
698 SetWindowStyleFlag(style);
699
c47addef 700 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0,0), wxSize(100, 100), 0);
6c70a9b5
JS
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 */
ca65c044 711 return true;
6c70a9b5
JS
712 }
713 else
ca65c044 714 return false;
6c70a9b5
JS
715}
716
8a39593e 717int wxGenericMDIClientWindow::SetSelection(size_t nPage)
6c70a9b5
JS
718{
719 int oldSelection = wxNotebook::SetSelection(nPage);
720
c0924519 721#if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
6c70a9b5
JS
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
730void 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 {
ca65c044 750 wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId());
6c70a9b5
JS
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 {
ca65c044 762 wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId());
6c70a9b5
JS
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
775void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
776{
777 PageChanged(event.GetOldSelection(), event.GetSelection());
778
779 event.Skip();
780}
781
782void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
783{
784 wxNotebook::OnSize(event);
785
34a0c9f4 786 size_t pos;
6c70a9b5
JS
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
2b5f62a0
VZ
800wxMDIChildFrame * 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
6c70a9b5
JS
810IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
811IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
812IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
813
814#endif
815