]> git.saurik.com Git - wxWidgets.git/blame - src/generic/mdig.cpp
Fail for assert(0,...).
[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
e4db172a
WS
27#include "wx/generic/mdig.h"
28
6c70a9b5
JS
29#ifndef WX_PRECOMP
30 #include "wx/panel.h"
31 #include "wx/menu.h"
2b5f62a0 32 #include "wx/intl.h"
e4db172a 33 #include "wx/log.h"
6c70a9b5
JS
34#endif //WX_PRECOMP
35
e27d9a91 36#include "wx/stockitem.h"
6c70a9b5 37
c0924519 38enum MDI_MENU_ID
6c70a9b5
JS
39{
40 wxWINDOWCLOSE = 4001,
41 wxWINDOWCLOSEALL,
42 wxWINDOWNEXT,
43 wxWINDOWPREV
44};
45
46//-----------------------------------------------------------------------------
47// wxGenericMDIParentFrame
48//-----------------------------------------------------------------------------
49
50IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
51
52BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
d7260478 53#if wxUSE_MENUS
ca65c044 54 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
d7260478 55#endif
6c70a9b5
JS
56END_EVENT_TABLE()
57
c0924519
DW
58wxGenericMDIParentFrame::wxGenericMDIParentFrame()
59{
60 Init();
6c70a9b5
JS
61}
62
63wxGenericMDIParentFrame::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();
c0924519 72
6c70a9b5
JS
73 (void)Create(parent, id, title, pos, size, style, name);
74}
75
76wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
c0924519 77{
6c70a9b5
JS
78 // Make sure the client window is destructed before the menu bars are!
79 wxDELETE(m_pClientWindow);
80
c0924519 81#if wxUSE_MENUS
6c70a9b5
JS
82 if (m_pMyMenuBar)
83 {
84 delete m_pMyMenuBar;
85 m_pMyMenuBar = (wxMenuBar *) NULL;
86 }
c0924519 87
6c70a9b5
JS
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
98bool 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
2b5f62a0
VZ
113 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
114 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
6c70a9b5 115 m_pWindowMenu->AppendSeparator();
2b5f62a0
VZ
116 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
117 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
6c70a9b5
JS
118#endif // wxUSE_MENUS
119 }
120
121 wxFrame::Create( parent, id, title, pos, size, style, name );
122
123 OnCreateClient();
124
ca65c044 125 return true;
6c70a9b5
JS
126}
127
128#if wxUSE_MENUS
129void 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
149void 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
160void 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);
c0924519 167
6c70a9b5
JS
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
185bool 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())
ca65c044 194 return false;
6c70a9b5
JS
195
196 inEvent = event.GetEventType();
197
198 // Let the active child (if any) process the event first.
ca65c044 199 bool res = false;
c0924519 200 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
6c70a9b5
JS
201#if 0
202 /* This is sure to not give problems... */
203 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
2b5f62a0 204 event.GetEventType() == wxEVT_UPDATE_UI )
6c70a9b5
JS
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 ||
2b5f62a0 213 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
6c70a9b5 214#endif
2b5f62a0 215 )
6c70a9b5
JS
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
231wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
232{
233 return m_pActiveChild;
234}
235
236void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
237{
238 m_pActiveChild = pChildFrame;
239}
240
241wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
242{
243 return m_pClientWindow;
244}
245
246wxGenericMDIClientWindow *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
256void wxGenericMDIParentFrame::ActivateNext()
257{
258 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
259 {
34a0c9f4 260 size_t active = m_pClientWindow->GetSelection() + 1;
6c70a9b5
JS
261 if (active >= m_pClientWindow->GetPageCount())
262 active = 0;
263
264 m_pClientWindow->SetSelection(active);
265 }
266}
267
268void 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
280void 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
291void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
292{
293 if (pMenuBar && m_pWindowMenu)
294 {
295 // Remove old window menu
2b5f62a0 296 int pos = pMenuBar->FindMenu(_("&Window"));
6c70a9b5
JS
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
305void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
306{
307 if (pMenuBar && m_pWindowMenu)
c0924519 308 {
e27d9a91 309 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false));
6c70a9b5
JS
310 if (pos == wxNOT_FOUND)
311 {
2b5f62a0 312 pMenuBar->Append(m_pWindowMenu, _("&Window"));
6c70a9b5
JS
313 }
314 else
315 {
2b5f62a0 316 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
6c70a9b5
JS
317 }
318 }
319}
320
321void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
322{
323 switch (event.GetId())
324 {
c0924519 325 case wxWINDOWCLOSE:
6c70a9b5
JS
326 if (m_pActiveChild)
327 {
328 m_pActiveChild->Close();
329 }
330 break;
331 case wxWINDOWCLOSEALL:
332 {
c0924519 333#if 0 // code is only needed if next #if is set to 0!
6c70a9b5
JS
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;
902725ee 346 m_pActiveChild = NULL;
c0924519 347#else
6c70a9b5
JS
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
369void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
370{
371 wxFrame::DoGetClientSize( width, height );
372}
373
374
375//-----------------------------------------------------------------------------
376// wxGenericMDIChildFrame
377//-----------------------------------------------------------------------------
378
379IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
380
381BEGIN_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)
387END_EVENT_TABLE()
388
389wxGenericMDIChildFrame::wxGenericMDIChildFrame()
390{
391 Init();
392}
393
394wxGenericMDIChildFrame::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
6c70a9b5
JS
404wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
405{
406 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
407
408 if (pParentFrame != NULL)
409 {
ca65c044 410 bool bActive = false;
6c70a9b5
JS
411 if (pParentFrame->GetActiveChild() == this)
412 {
413 pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
414 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
ca65c044 415 bActive = true;
6c70a9b5
JS
416 }
417
418 wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
419
420 // Remove page if still there
34a0c9f4 421 size_t pos;
6c70a9b5
JS
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 }
c0924519 431
6c70a9b5
JS
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 {
8a39593e 441 if ((int)pClientWindow->GetPageCount() - 1 >= 0)
6c70a9b5
JS
442 pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
443 }
444 }
445 }
446
447#if wxUSE_MENUS
448 wxDELETE(m_pMenuBar);
449#endif // wxUSE_MENUS
450}
451
452bool 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
2b5f62a0 459 wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), wxT("Missing MDI client window.") );
6c70a9b5
JS
460
461 wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
c0924519 462
6c70a9b5
JS
463 SetMDIParentFrame(parent);
464
465 // This is the currently active child
466 parent->SetActiveChild(this);
467
468 m_Title = title;
469
ca65c044 470 pClientWindow->AddPage(this, title, true);
6c70a9b5
JS
471 ApplyMDIChildFrameRect(); // Ok confirme the size change!
472 pClientWindow->Refresh();
473
ca65c044 474 return true;
6c70a9b5
JS
475}
476
c0924519 477#if wxUSE_MENUS
6c70a9b5
JS
478void 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();
c0924519 486
6c70a9b5
JS
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
502wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
503{
504 return m_pMenuBar;
505}
c0924519 506#endif // wxUSE_MENUS
6c70a9b5
JS
507
508void wxGenericMDIChildFrame::SetTitle(const wxString& title)
509{
510 m_Title = title;
511
512 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
c0924519 513
6c70a9b5
JS
514 if (pParentFrame != NULL)
515 {
516 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
c0924519 517
6c70a9b5 518 if (pClientWindow != NULL)
c0924519 519 {
34a0c9f4 520 size_t pos;
6c70a9b5
JS
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 }
c0924519 528 }
6c70a9b5
JS
529 }
530 }
531}
532
c0924519 533wxString wxGenericMDIChildFrame::GetTitle() const
6c70a9b5
JS
534{
535 return m_Title;
536}
537
538void wxGenericMDIChildFrame::Activate()
539{
540 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
541
542 if (pParentFrame != NULL)
543 {
544 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
545
546 if (pClientWindow != NULL)
547 {
34a0c9f4 548 size_t pos;
6c70a9b5
JS
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
561void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
562{
563#if wxUSE_STATUSBAR
564 if ( m_pMDIParentFrame)
565 {
c0924519 566 // we don't have any help text for this item,
6c70a9b5
JS
567 // but may be the MDI frame does?
568 m_pMDIParentFrame->OnMenuHighlight(event);
569 }
67a99992
WS
570#else
571 wxUnusedVar(event);
6c70a9b5
JS
572#endif // wxUSE_STATUSBAR
573}
574
61fef19b 575void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
6c70a9b5
JS
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
583void 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;
ac32ba44 594 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6c70a9b5
JS
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.
636void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
637{
638 Destroy();
639}
640
c0924519
DW
641void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
642{
643 m_pMDIParentFrame = parentFrame;
6c70a9b5
JS
644}
645
c0924519
DW
646wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
647{
648 return m_pMDIParentFrame;
6c70a9b5
JS
649}
650
651void wxGenericMDIChildFrame::Init()
652{
653 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
654#if wxUSE_MENUS
655 m_pMenuBar = (wxMenuBar *) NULL;
c0924519 656#endif // wxUSE_MENUS
6c70a9b5
JS
657}
658
659void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
c0924519 660{
6c70a9b5
JS
661 m_MDIRect = wxRect(x, y, width, height);
662}
663
664void 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
675IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
676
677BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
678 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
679 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
680END_EVENT_TABLE()
681
682
683wxGenericMDIClientWindow::wxGenericMDIClientWindow()
684{
685}
686
687wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
688{
689 CreateClient( parent, style );
690}
691
692wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
693{
694 DestroyChildren();
695}
696
697bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
698{
699 SetWindowStyleFlag(style);
700
c47addef 701 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0,0), wxSize(100, 100), 0);
6c70a9b5
JS
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 */
ca65c044 712 return true;
6c70a9b5
JS
713 }
714 else
ca65c044 715 return false;
6c70a9b5
JS
716}
717
8a39593e 718int wxGenericMDIClientWindow::SetSelection(size_t nPage)
6c70a9b5
JS
719{
720 int oldSelection = wxNotebook::SetSelection(nPage);
721
c0924519 722#if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
6c70a9b5
JS
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
731void 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 {
ca65c044 751 wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId());
6c70a9b5
JS
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 {
ca65c044 763 wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId());
6c70a9b5
JS
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
776void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
777{
778 PageChanged(event.GetOldSelection(), event.GetSelection());
779
780 event.Skip();
781}
782
783void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
784{
785 wxNotebook::OnSize(event);
786
34a0c9f4 787 size_t pos;
6c70a9b5
JS
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
2b5f62a0
VZ
801wxMDIChildFrame * 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
6c70a9b5
JS
811IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
812IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
813IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
814
815#endif