]> git.saurik.com Git - wxWidgets.git/blame - src/generic/mdig.cpp
More bakfile changes needed for bmpcbox. Rebaked.
[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
9a6384ca
WS
27#if wxUSE_MDI
28
e4db172a
WS
29#include "wx/generic/mdig.h"
30
6c70a9b5
JS
31#ifndef WX_PRECOMP
32 #include "wx/panel.h"
33 #include "wx/menu.h"
2b5f62a0 34 #include "wx/intl.h"
e4db172a 35 #include "wx/log.h"
6c70a9b5
JS
36#endif //WX_PRECOMP
37
e27d9a91 38#include "wx/stockitem.h"
6c70a9b5 39
c0924519 40enum MDI_MENU_ID
6c70a9b5
JS
41{
42 wxWINDOWCLOSE = 4001,
43 wxWINDOWCLOSEALL,
44 wxWINDOWNEXT,
45 wxWINDOWPREV
46};
47
48//-----------------------------------------------------------------------------
49// wxGenericMDIParentFrame
50//-----------------------------------------------------------------------------
51
52IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
53
54BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
d7260478 55#if wxUSE_MENUS
ca65c044 56 EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
d7260478 57#endif
6c70a9b5
JS
58END_EVENT_TABLE()
59
c0924519
DW
60wxGenericMDIParentFrame::wxGenericMDIParentFrame()
61{
62 Init();
6c70a9b5
JS
63}
64
65wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
66 wxWindowID id,
67 const wxString& title,
68 const wxPoint& pos,
69 const wxSize& size,
70 long style,
71 const wxString& name)
72{
73 Init();
c0924519 74
6c70a9b5
JS
75 (void)Create(parent, id, title, pos, size, style, name);
76}
77
78wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
c0924519 79{
6c70a9b5
JS
80 // Make sure the client window is destructed before the menu bars are!
81 wxDELETE(m_pClientWindow);
82
c0924519 83#if wxUSE_MENUS
6c70a9b5
JS
84 if (m_pMyMenuBar)
85 {
86 delete m_pMyMenuBar;
87 m_pMyMenuBar = (wxMenuBar *) NULL;
88 }
c0924519 89
6c70a9b5
JS
90 RemoveWindowMenu(GetMenuBar());
91
92 if (m_pWindowMenu)
93 {
94 delete m_pWindowMenu;
95 m_pWindowMenu = (wxMenu*) NULL;
96 }
97#endif // wxUSE_MENUS
98}
99
100bool wxGenericMDIParentFrame::Create(wxWindow *parent,
101 wxWindowID id,
102 const wxString& title,
103 const wxPoint& pos,
104 const wxSize& size,
105 long style,
106 const wxString& name)
107{
108 // this style can be used to prevent a window from having the standard MDI
109 // "Window" menu
110 if ( !(style & wxFRAME_NO_WINDOW_MENU) )
111 {
112#if wxUSE_MENUS
113 m_pWindowMenu = new wxMenu;
114
2b5f62a0
VZ
115 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
116 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
6c70a9b5 117 m_pWindowMenu->AppendSeparator();
2b5f62a0
VZ
118 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
119 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
6c70a9b5
JS
120#endif // wxUSE_MENUS
121 }
122
123 wxFrame::Create( parent, id, title, pos, size, style, name );
124
125 OnCreateClient();
126
ca65c044 127 return true;
6c70a9b5
JS
128}
129
130#if wxUSE_MENUS
131void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
132{
133 // Replace the window menu from the currently loaded menu bar.
134 wxMenuBar *pMenuBar = GetMenuBar();
135
136 if (m_pWindowMenu)
137 {
138 RemoveWindowMenu(pMenuBar);
139
140 wxDELETE(m_pWindowMenu);
141 }
142
143 if (pMenu)
144 {
145 m_pWindowMenu = pMenu;
146
147 AddWindowMenu(pMenuBar);
148 }
149}
150
151void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
152{
153 // Remove the Window menu from the old menu bar
154 RemoveWindowMenu(GetMenuBar());
155 // Add the Window menu to the new menu bar.
156 AddWindowMenu(pMenuBar);
157
158 wxFrame::SetMenuBar(pMenuBar);
159}
160#endif // wxUSE_MENUS
161
162void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
163{
164#if wxUSE_MENUS
165 if (pChild == (wxGenericMDIChildFrame *) NULL)
166 {
167 // No Child, set Our menu bar back.
168 SetMenuBar(m_pMyMenuBar);
c0924519 169
6c70a9b5
JS
170 // Make sure we know our menu bar is in use
171 m_pMyMenuBar = (wxMenuBar*) NULL;
172 }
173 else
174 {
175 if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
176 return;
177
178 // Do we need to save the current bar?
179 if (m_pMyMenuBar == NULL)
180 m_pMyMenuBar = GetMenuBar();
181
182 SetMenuBar(pChild->GetMenuBar());
183 }
184#endif // wxUSE_MENUS
185}
186
187bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
188{
189 /*
190 * Redirect events to active child first.
191 */
192
193 // Stops the same event being processed repeatedly
194 static wxEventType inEvent = wxEVT_NULL;
195 if (inEvent == event.GetEventType())
ca65c044 196 return false;
6c70a9b5
JS
197
198 inEvent = event.GetEventType();
199
200 // Let the active child (if any) process the event first.
ca65c044 201 bool res = false;
c0924519 202 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
6c70a9b5
JS
203#if 0
204 /* This is sure to not give problems... */
205 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
2b5f62a0 206 event.GetEventType() == wxEVT_UPDATE_UI )
6c70a9b5
JS
207#else
208 /* This was tested on wxMSW and worked... */
209 && event.GetEventObject() != m_pClientWindow
210 && !(event.GetEventType() == wxEVT_ACTIVATE ||
211 event.GetEventType() == wxEVT_SET_FOCUS ||
212 event.GetEventType() == wxEVT_KILL_FOCUS ||
213 event.GetEventType() == wxEVT_CHILD_FOCUS ||
214 event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
2b5f62a0 215 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
6c70a9b5 216#endif
2b5f62a0 217 )
6c70a9b5
JS
218 {
219 res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
220 }
221
222 // If the event was not handled this frame will handle it!
223 if (!res)
224 {
225 res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
226 }
227
228 inEvent = wxEVT_NULL;
229
230 return res;
231}
232
233wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
234{
235 return m_pActiveChild;
236}
237
238void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
239{
240 m_pActiveChild = pChildFrame;
241}
242
243wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
244{
245 return m_pClientWindow;
246}
247
248wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
249{
250#if wxUSE_GENERIC_MDI_AS_NATIVE
251 m_pClientWindow = new wxMDIClientWindow( this );
252#else
253 m_pClientWindow = new wxGenericMDIClientWindow( this );
254#endif
255 return m_pClientWindow;
256}
257
258void wxGenericMDIParentFrame::ActivateNext()
259{
260 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
261 {
34a0c9f4 262 size_t active = m_pClientWindow->GetSelection() + 1;
6c70a9b5
JS
263 if (active >= m_pClientWindow->GetPageCount())
264 active = 0;
265
266 m_pClientWindow->SetSelection(active);
267 }
268}
269
270void wxGenericMDIParentFrame::ActivatePrevious()
271{
272 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
273 {
274 int active = m_pClientWindow->GetSelection() - 1;
275 if (active < 0)
276 active = m_pClientWindow->GetPageCount() - 1;
277
278 m_pClientWindow->SetSelection(active);
279 }
280}
281
282void wxGenericMDIParentFrame::Init()
283{
284 m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
285 m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
286#if wxUSE_MENUS
287 m_pWindowMenu = (wxMenu *) NULL;
288 m_pMyMenuBar = (wxMenuBar*) NULL;
289#endif // wxUSE_MENUS
290}
291
292#if wxUSE_MENUS
293void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
294{
295 if (pMenuBar && m_pWindowMenu)
296 {
297 // Remove old window menu
2b5f62a0 298 int pos = pMenuBar->FindMenu(_("&Window"));
6c70a9b5
JS
299 if (pos != wxNOT_FOUND)
300 {
301 wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
302 pMenuBar->Remove(pos);
303 }
304 }
305}
306
307void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
308{
309 if (pMenuBar && m_pWindowMenu)
c0924519 310 {
e27d9a91 311 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false));
6c70a9b5
JS
312 if (pos == wxNOT_FOUND)
313 {
2b5f62a0 314 pMenuBar->Append(m_pWindowMenu, _("&Window"));
6c70a9b5
JS
315 }
316 else
317 {
2b5f62a0 318 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
6c70a9b5
JS
319 }
320 }
321}
322
323void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
324{
325 switch (event.GetId())
326 {
c0924519 327 case wxWINDOWCLOSE:
6c70a9b5
JS
328 if (m_pActiveChild)
329 {
330 m_pActiveChild->Close();
331 }
332 break;
333 case wxWINDOWCLOSEALL:
334 {
c0924519 335#if 0 // code is only needed if next #if is set to 0!
6c70a9b5
JS
336 wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
337#endif
338 while (m_pActiveChild)
339 {
340 if (!m_pActiveChild->Close())
341 {
342 return; // We failed...
343 }
344 else
345 {
346#if 1 // What's best? Delayed deleting or immediate deleting?
347 delete m_pActiveChild;
902725ee 348 m_pActiveChild = NULL;
c0924519 349#else
6c70a9b5
JS
350 ActivateNext();
351
352 if (pFirstActiveChild == m_pActiveChild)
353 return; // We've called Close on all items, no need to continue.
354#endif
355 }
356 }
357 }
358 break;
359 case wxWINDOWNEXT:
360 ActivateNext();
361 break;
362 case wxWINDOWPREV:
363 ActivatePrevious();
364 break;
365 default :
366 event.Skip();
367 }
368}
369#endif // wxUSE_MENUS
370
371void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
372{
373 wxFrame::DoGetClientSize( width, height );
374}
375
376
377//-----------------------------------------------------------------------------
378// wxGenericMDIChildFrame
379//-----------------------------------------------------------------------------
380
381IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
382
383BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
384 EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
385 EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)
386
387 EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
388 EVT_SIZE(wxGenericMDIChildFrame::OnSize)
389END_EVENT_TABLE()
390
391wxGenericMDIChildFrame::wxGenericMDIChildFrame()
392{
393 Init();
394}
395
396wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
397 wxWindowID id, const wxString& title,
398 const wxPoint& WXUNUSED(pos), const wxSize& size,
399 long style, const wxString& name )
400{
401 Init();
402
403 Create( parent, id, title, wxDefaultPosition, size, style, name );
404}
405
6c70a9b5
JS
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
9a6384ca
WS
817#endif // wxUSE_GENERIC_MDI_AS_NATIVE
818
b4ca5976
VS
819#endif // wxUSE_MDI
820