]> git.saurik.com Git - wxWidgets.git/blame - src/generic/mdig.cpp
Apply mask origin patch for blitting.
[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
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
6c70a9b5
JS
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)
d7260478 54#if wxUSE_MENUS
ca65c044 55 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
d7260478 56#endif
6c70a9b5
JS
57END_EVENT_TABLE()
58
c0924519
DW
59wxGenericMDIParentFrame::wxGenericMDIParentFrame()
60{
61 Init();
6c70a9b5
JS
62}
63
64wxGenericMDIParentFrame::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();
c0924519 73
6c70a9b5
JS
74 (void)Create(parent, id, title, pos, size, style, name);
75}
76
77wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
c0924519 78{
6c70a9b5
JS
79 // Make sure the client window is destructed before the menu bars are!
80 wxDELETE(m_pClientWindow);
81
c0924519 82#if wxUSE_MENUS
6c70a9b5
JS
83 if (m_pMyMenuBar)
84 {
85 delete m_pMyMenuBar;
86 m_pMyMenuBar = (wxMenuBar *) NULL;
87 }
c0924519 88
6c70a9b5
JS
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
99bool 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
2b5f62a0
VZ
114 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
115 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
6c70a9b5 116 m_pWindowMenu->AppendSeparator();
2b5f62a0
VZ
117 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
118 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
6c70a9b5
JS
119#endif // wxUSE_MENUS
120 }
121
122 wxFrame::Create( parent, id, title, pos, size, style, name );
123
124 OnCreateClient();
125
ca65c044 126 return true;
6c70a9b5
JS
127}
128
129#if wxUSE_MENUS
130void 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
150void 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
161void 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);
c0924519 168
6c70a9b5
JS
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
186bool 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())
ca65c044 195 return false;
6c70a9b5
JS
196
197 inEvent = event.GetEventType();
198
199 // Let the active child (if any) process the event first.
ca65c044 200 bool res = false;
c0924519 201 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
6c70a9b5
JS
202#if 0
203 /* This is sure to not give problems... */
204 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
2b5f62a0 205 event.GetEventType() == wxEVT_UPDATE_UI )
6c70a9b5
JS
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 ||
2b5f62a0 214 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
6c70a9b5 215#endif
2b5f62a0 216 )
6c70a9b5
JS
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
232wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
233{
234 return m_pActiveChild;
235}
236
237void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
238{
239 m_pActiveChild = pChildFrame;
240}
241
242wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
243{
244 return m_pClientWindow;
245}
246
247wxGenericMDIClientWindow *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
257void wxGenericMDIParentFrame::ActivateNext()
258{
259 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
260 {
34a0c9f4 261 size_t active = m_pClientWindow->GetSelection() + 1;
6c70a9b5
JS
262 if (active >= m_pClientWindow->GetPageCount())
263 active = 0;
264
265 m_pClientWindow->SetSelection(active);
266 }
267}
268
269void 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
281void 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
292void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
293{
294 if (pMenuBar && m_pWindowMenu)
295 {
296 // Remove old window menu
2b5f62a0 297 int pos = pMenuBar->FindMenu(_("&Window"));
6c70a9b5
JS
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
306void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
307{
308 if (pMenuBar && m_pWindowMenu)
c0924519 309 {
2b5f62a0 310 int pos = pMenuBar->FindMenu(_("Help"));
6c70a9b5
JS
311 if (pos == wxNOT_FOUND)
312 {
2b5f62a0 313 pMenuBar->Append(m_pWindowMenu, _("&Window"));
6c70a9b5
JS
314 }
315 else
316 {
2b5f62a0 317 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
6c70a9b5
JS
318 }
319 }
320}
321
322void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
323{
324 switch (event.GetId())
325 {
c0924519 326 case wxWINDOWCLOSE:
6c70a9b5
JS
327 if (m_pActiveChild)
328 {
329 m_pActiveChild->Close();
330 }
331 break;
332 case wxWINDOWCLOSEALL:
333 {
c0924519 334#if 0 // code is only needed if next #if is set to 0!
6c70a9b5
JS
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;
902725ee 347 m_pActiveChild = NULL;
c0924519 348#else
6c70a9b5
JS
349 ActivateNext();
350
351 if (pFirstActiveChild == m_pActiveChild)
352 return; // We've called Close on all items, no need to continue.
353#endif
354 }
355 }
356 }
357 break;
358 case wxWINDOWNEXT:
359 ActivateNext();
360 break;
361 case wxWINDOWPREV:
362 ActivatePrevious();
363 break;
364 default :
365 event.Skip();
366 }
367}
368#endif // wxUSE_MENUS
369
370void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
371{
372 wxFrame::DoGetClientSize( width, height );
373}
374
375
376//-----------------------------------------------------------------------------
377// wxGenericMDIChildFrame
378//-----------------------------------------------------------------------------
379
380IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
381
382BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
383 EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
384 EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)
385
386 EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
387 EVT_SIZE(wxGenericMDIChildFrame::OnSize)
388END_EVENT_TABLE()
389
390wxGenericMDIChildFrame::wxGenericMDIChildFrame()
391{
392 Init();
393}
394
395wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
396 wxWindowID id, const wxString& title,
397 const wxPoint& WXUNUSED(pos), const wxSize& size,
398 long style, const wxString& name )
399{
400 Init();
401
402 Create( parent, id, title, wxDefaultPosition, size, style, name );
403}
404
405#include "wx/log.h"
406wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
407{
408 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
409
410 if (pParentFrame != NULL)
411 {
ca65c044 412 bool bActive = false;
6c70a9b5
JS
413 if (pParentFrame->GetActiveChild() == this)
414 {
415 pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
416 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
ca65c044 417 bActive = true;
6c70a9b5
JS
418 }
419
420 wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
421
422 // Remove page if still there
34a0c9f4 423 size_t pos;
6c70a9b5
JS
424 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
425 {
426 if (pClientWindow->GetPage(pos) == this)
427 {
428 if (pClientWindow->RemovePage(pos))
429 pClientWindow->Refresh();
430 break;
431 }
432 }
c0924519 433
6c70a9b5
JS
434 if (bActive)
435 {
436 // Set the new selection to the a remaining page
437 if (pClientWindow->GetPageCount() > pos)
438 {
439 pClientWindow->SetSelection(pos);
440 }
441 else
442 {
8a39593e 443 if ((int)pClientWindow->GetPageCount() - 1 >= 0)
6c70a9b5
JS
444 pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
445 }
446 }
447 }
448
449#if wxUSE_MENUS
450 wxDELETE(m_pMenuBar);
451#endif // wxUSE_MENUS
452}
453
454bool wxGenericMDIChildFrame::Create( wxGenericMDIParentFrame *parent,
455 wxWindowID id, const wxString& title,
456 const wxPoint& WXUNUSED(pos), const wxSize& size,
457 long style, const wxString& name )
458{
459 wxGenericMDIClientWindow* pClientWindow = parent->GetClientWindow();
460
2b5f62a0 461 wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), wxT("Missing MDI client window.") );
6c70a9b5
JS
462
463 wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
c0924519 464
6c70a9b5
JS
465 SetMDIParentFrame(parent);
466
467 // This is the currently active child
468 parent->SetActiveChild(this);
469
470 m_Title = title;
471
ca65c044 472 pClientWindow->AddPage(this, title, true);
6c70a9b5
JS
473 ApplyMDIChildFrameRect(); // Ok confirme the size change!
474 pClientWindow->Refresh();
475
ca65c044 476 return true;
6c70a9b5
JS
477}
478
c0924519 479#if wxUSE_MENUS
6c70a9b5
JS
480void wxGenericMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
481{
482 wxMenuBar *pOldMenuBar = m_pMenuBar;
483 m_pMenuBar = menu_bar;
484
485 if (m_pMenuBar)
486 {
487 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
c0924519 488
6c70a9b5
JS
489 if (pParentFrame != NULL)
490 {
491 m_pMenuBar->SetParent(pParentFrame);
492
493 if (pParentFrame->GetActiveChild() == this)
494 {
495 // Replace current menu bars
496 if (pOldMenuBar)
497 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
498 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) this);
499 }
500 }
501 }
502}
503
504wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
505{
506 return m_pMenuBar;
507}
c0924519 508#endif // wxUSE_MENUS
6c70a9b5
JS
509
510void wxGenericMDIChildFrame::SetTitle(const wxString& title)
511{
512 m_Title = title;
513
514 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
c0924519 515
6c70a9b5
JS
516 if (pParentFrame != NULL)
517 {
518 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
c0924519 519
6c70a9b5 520 if (pClientWindow != NULL)
c0924519 521 {
34a0c9f4 522 size_t pos;
6c70a9b5
JS
523 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
524 {
525 if (pClientWindow->GetPage(pos) == this)
526 {
527 pClientWindow->SetPageText(pos, m_Title);
528 break;
529 }
c0924519 530 }
6c70a9b5
JS
531 }
532 }
533}
534
c0924519 535wxString wxGenericMDIChildFrame::GetTitle() const
6c70a9b5
JS
536{
537 return m_Title;
538}
539
540void wxGenericMDIChildFrame::Activate()
541{
542 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
543
544 if (pParentFrame != NULL)
545 {
546 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
547
548 if (pClientWindow != NULL)
549 {
34a0c9f4 550 size_t pos;
6c70a9b5
JS
551 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
552 {
553 if (pClientWindow->GetPage(pos) == this)
554 {
555 pClientWindow->SetSelection(pos);
556 break;
557 }
558 }
559 }
560 }
561}
562
563void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
564{
565#if wxUSE_STATUSBAR
566 if ( m_pMDIParentFrame)
567 {
c0924519 568 // we don't have any help text for this item,
6c70a9b5
JS
569 // but may be the MDI frame does?
570 m_pMDIParentFrame->OnMenuHighlight(event);
571 }
67a99992
WS
572#else
573 wxUnusedVar(event);
6c70a9b5
JS
574#endif // wxUSE_STATUSBAR
575}
576
61fef19b 577void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
6c70a9b5
JS
578{
579 // Do mothing.
580}
581
582/*** Copied from top level..! ***/
583// default resizing behaviour - if only ONE subwindow, resize to fill the
584// whole client area
585void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
586{
587 // if we're using constraints or sizers - do use them
588 if ( GetAutoLayout() )
589 {
590 Layout();
591 }
592 else
593 {
594 // do we have _exactly_ one child?
595 wxWindow *child = (wxWindow *)NULL;
ac32ba44 596 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6c70a9b5
JS
597 node;
598 node = node->GetNext() )
599 {
600 wxWindow *win = node->GetData();
601
602 // exclude top level and managed windows (status bar isn't
603 // currently in the children list except under wxMac anyhow, but
604 // it makes no harm to test for it)
605 if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
606 {
607 if ( child )
608 {
609 return; // it's our second subwindow - nothing to do
610 }
611
612 child = win;
613 }
614 }
615
616 // do we have any children at all?
617 if ( child )
618 {
619 // exactly one child - set it's size to fill the whole frame
620 int clientW, clientH;
621 DoGetClientSize(&clientW, &clientH);
622
623 // for whatever reasons, wxGTK wants to have a small offset - it
624 // probably looks better with it?
625#ifdef __WXGTK__
626 static const int ofs = 1;
627#else
628 static const int ofs = 0;
629#endif
630
631 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
632 }
633 }
634}
635
636/*** Copied from top level..! ***/
637// The default implementation for the close window event.
638void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
639{
640 Destroy();
641}
642
c0924519
DW
643void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
644{
645 m_pMDIParentFrame = parentFrame;
6c70a9b5
JS
646}
647
c0924519
DW
648wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
649{
650 return m_pMDIParentFrame;
6c70a9b5
JS
651}
652
653void wxGenericMDIChildFrame::Init()
654{
655 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
656#if wxUSE_MENUS
657 m_pMenuBar = (wxMenuBar *) NULL;
c0924519 658#endif // wxUSE_MENUS
6c70a9b5
JS
659}
660
661void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
c0924519 662{
6c70a9b5
JS
663 m_MDIRect = wxRect(x, y, width, height);
664}
665
666void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
667{
668 wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
669}
670
671//-----------------------------------------------------------------------------
672// wxGenericMDIClientWindow
673//-----------------------------------------------------------------------------
674
675#define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
676
677IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
678
679BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
680 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
681 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
682END_EVENT_TABLE()
683
684
685wxGenericMDIClientWindow::wxGenericMDIClientWindow()
686{
687}
688
689wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
690{
691 CreateClient( parent, style );
692}
693
694wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
695{
696 DestroyChildren();
697}
698
699bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
700{
701 SetWindowStyleFlag(style);
702
c47addef 703 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0,0), wxSize(100, 100), 0);
6c70a9b5
JS
704 if (success)
705 {
706 /*
707 wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
708 wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
709 GetTabView()->SetTabFont(font);
710 GetTabView()->SetSelectedTabFont(selFont);
711 GetTabView()->SetTabSize(120, 18);
712 GetTabView()->SetTabSelectionHeight(20);
713 */
ca65c044 714 return true;
6c70a9b5
JS
715 }
716 else
ca65c044 717 return false;
6c70a9b5
JS
718}
719
8a39593e 720int wxGenericMDIClientWindow::SetSelection(size_t nPage)
6c70a9b5
JS
721{
722 int oldSelection = wxNotebook::SetSelection(nPage);
723
c0924519 724#if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
6c70a9b5
JS
725 // will already cause this to be done!
726 // Handle the page change.
727 PageChanged(oldSelection, nPage);
728#endif
729
730 return oldSelection;
731}
732
733void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
734{
735 // Don't do to much work, only when something realy should change!
736 if (OldSelection == newSelection)
737 return;
738 // Again check if we realy need to do this...
739 if (newSelection != -1)
740 {
741 wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
742
743 if (child->GetMDIParentFrame()->GetActiveChild() == child)
744 return;
745 }
746
747 // Notify old active child that it has been deactivated
748 if (OldSelection != -1)
749 {
750 wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
751 if (oldChild)
752 {
ca65c044 753 wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId());
6c70a9b5
JS
754 event.SetEventObject( oldChild );
755 oldChild->GetEventHandler()->ProcessEvent(event);
756 }
757 }
758
759 // Notify new active child that it has been activated
760 if (newSelection != -1)
761 {
762 wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
763 if (activeChild)
764 {
ca65c044 765 wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId());
6c70a9b5
JS
766 event.SetEventObject( activeChild );
767 activeChild->GetEventHandler()->ProcessEvent(event);
768
769 if (activeChild->GetMDIParentFrame())
770 {
771 activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
772 activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
773 }
774 }
775 }
776}
777
778void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
779{
780 PageChanged(event.GetOldSelection(), event.GetSelection());
781
782 event.Skip();
783}
784
785void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
786{
787 wxNotebook::OnSize(event);
788
34a0c9f4 789 size_t pos;
6c70a9b5
JS
790 for (pos = 0; pos < GetPageCount(); pos++)
791 {
792 ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
793 }
794}
795
796
797/*
798 * Define normal wxMDI classes based on wxGenericMDI
799 */
800
801#if wxUSE_GENERIC_MDI_AS_NATIVE
802
2b5f62a0
VZ
803wxMDIChildFrame * wxMDIParentFrame::GetActiveChild() const
804 {
805 wxGenericMDIChildFrame *pGFrame = wxGenericMDIParentFrame::GetActiveChild();
806 wxMDIChildFrame *pFrame = wxDynamicCast(pGFrame, wxMDIChildFrame);
807
808 wxASSERT_MSG(!(pFrame == NULL && pGFrame != NULL), wxT("Active frame is class not derived from wxMDIChildFrame!"));
809
810 return pFrame;
811 }
812
6c70a9b5
JS
813IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
814IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
815IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
816
817#endif
818