]> git.saurik.com Git - wxWidgets.git/blame - src/aui/tabmdi.cpp
revert nested event loop support for wxGTK1 because it causes applications hangs
[wxWidgets.git] / src / aui / tabmdi.cpp
CommitLineData
cd05bf23 1/////////////////////////////////////////////////////////////////////////////
25f70bc4 2// Name: src/aui/tabmdi.cpp
cd05bf23
BW
3// Purpose: Generic MDI (Multiple Document Interface) classes
4// Author: Hans Van Leemputten
5// Modified by: Benjamin I. Williams / Kirix Corporation
6// Created: 29/07/2002
cd05bf23
BW
7// Copyright: (c) Hans Van Leemputten
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ===========================================================================
12// declarations
13// ===========================================================================
14
15// ---------------------------------------------------------------------------
16// headers
17// ---------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
25f70bc4 26#if wxUSE_AUI
cd05bf23
BW
27#if wxUSE_MDI
28
29#include "wx/aui/tabmdi.h"
30
31#ifndef WX_PRECOMP
32 #include "wx/panel.h"
33 #include "wx/menu.h"
34 #include "wx/intl.h"
35 #include "wx/log.h"
4444d148 36 #include "wx/settings.h"
cd05bf23
BW
37#endif //WX_PRECOMP
38
39#include "wx/stockitem.h"
445a98c7 40#include "wx/aui/dockart.h"
cd05bf23
BW
41
42enum MDI_MENU_ID
43{
44 wxWINDOWCLOSE = 4001,
45 wxWINDOWCLOSEALL,
46 wxWINDOWNEXT,
47 wxWINDOWPREV
48};
49
50//-----------------------------------------------------------------------------
a3a5df9d 51// wxAuiMDIParentFrame
cd05bf23
BW
52//-----------------------------------------------------------------------------
53
a3a5df9d 54IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIParentFrame, wxFrame)
cd05bf23 55
a3a5df9d 56BEGIN_EVENT_TABLE(wxAuiMDIParentFrame, wxFrame)
cd05bf23 57#if wxUSE_MENUS
a3a5df9d 58 EVT_MENU (wxID_ANY, wxAuiMDIParentFrame::DoHandleMenu)
9827ce92 59 EVT_UPDATE_UI (wxID_ANY, wxAuiMDIParentFrame::DoHandleUpdateUI)
cd05bf23
BW
60#endif
61END_EVENT_TABLE()
62
a3a5df9d 63wxAuiMDIParentFrame::wxAuiMDIParentFrame()
cd05bf23
BW
64{
65 Init();
66}
67
a3a5df9d 68wxAuiMDIParentFrame::wxAuiMDIParentFrame(wxWindow *parent,
cd05bf23
BW
69 wxWindowID id,
70 const wxString& title,
71 const wxPoint& pos,
72 const wxSize& size,
73 long style,
74 const wxString& name)
75{
76 Init();
77 (void)Create(parent, id, title, pos, size, style, name);
78}
79
a3a5df9d 80wxAuiMDIParentFrame::~wxAuiMDIParentFrame()
cd05bf23 81{
0d1dd76b
VZ
82 // Avoid having GetActiveChild() called after m_pClientWindow is destroyed
83 SendDestroyEvent();
cd05bf23
BW
84 // Make sure the client window is destructed before the menu bars are!
85 wxDELETE(m_pClientWindow);
86
87#if wxUSE_MENUS
b0a54b8a 88 wxDELETE(m_pMyMenuBar);
cd05bf23 89 RemoveWindowMenu(GetMenuBar());
b0a54b8a 90 wxDELETE(m_pWindowMenu);
cd05bf23
BW
91#endif // wxUSE_MENUS
92}
93
a3a5df9d 94bool wxAuiMDIParentFrame::Create(wxWindow *parent,
cd05bf23
BW
95 wxWindowID id,
96 const wxString& title,
97 const wxPoint& pos,
98 const wxSize& size,
99 long style,
100 const wxString& name)
101{
102#if wxUSE_MENUS
103 // this style can be used to prevent a window from having the standard MDI
104 // "Window" menu
105 if (!(style & wxFRAME_NO_WINDOW_MENU))
106 {
107 m_pWindowMenu = new wxMenu;
108 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
109 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
110 m_pWindowMenu->AppendSeparator();
111 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
112 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
113 }
114#endif // wxUSE_MENUS
115
6e42617a
VZ
116 if ( !wxFrame::Create(parent, id, title, pos, size, style, name) )
117 return false;
118
119 m_pClientWindow = OnCreateClient();
120 return m_pClientWindow != NULL;
cd05bf23
BW
121}
122
f39fddcd
BW
123
124void wxAuiMDIParentFrame::SetArtProvider(wxAuiTabArt* provider)
125{
126 if (m_pClientWindow)
127 {
128 m_pClientWindow->SetArtProvider(provider);
129 }
130}
131
132wxAuiTabArt* wxAuiMDIParentFrame::GetArtProvider()
133{
134 if (!m_pClientWindow)
135 return NULL;
ccc8c01a 136
f39fddcd
BW
137 return m_pClientWindow->GetArtProvider();
138}
139
140wxAuiNotebook* wxAuiMDIParentFrame::GetNotebook() const
141{
142 return static_cast<wxAuiNotebook*>(m_pClientWindow);
143}
144
145
146
cd05bf23 147#if wxUSE_MENUS
a3a5df9d 148void wxAuiMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
cd05bf23
BW
149{
150 // Replace the window menu from the currently loaded menu bar.
151 wxMenuBar *pMenuBar = GetMenuBar();
152
153 if (m_pWindowMenu)
154 {
155 RemoveWindowMenu(pMenuBar);
156 wxDELETE(m_pWindowMenu);
157 }
158
159 if (pMenu)
160 {
161 m_pWindowMenu = pMenu;
162 AddWindowMenu(pMenuBar);
163 }
164}
165
a3a5df9d 166void wxAuiMDIParentFrame::SetMenuBar(wxMenuBar* pMenuBar)
cd05bf23
BW
167{
168 // Remove the Window menu from the old menu bar
169 RemoveWindowMenu(GetMenuBar());
4444d148 170
cd05bf23
BW
171 // Add the Window menu to the new menu bar.
172 AddWindowMenu(pMenuBar);
4444d148 173
cd05bf23 174 wxFrame::SetMenuBar(pMenuBar);
b0a54b8a 175 //m_pMyMenuBar = GetMenuBar();
cd05bf23
BW
176}
177#endif // wxUSE_MENUS
178
a3a5df9d 179void wxAuiMDIParentFrame::SetChildMenuBar(wxAuiMDIChildFrame* pChild)
cd05bf23
BW
180{
181#if wxUSE_MENUS
182 if (!pChild)
183 {
184 // No Child, set Our menu bar back.
092d7f88
BW
185 if (m_pMyMenuBar)
186 SetMenuBar(m_pMyMenuBar);
cedd7b22 187 else
092d7f88 188 SetMenuBar(GetMenuBar());
cd05bf23
BW
189
190 // Make sure we know our menu bar is in use
b0a54b8a 191 m_pMyMenuBar = NULL;
cd05bf23 192 }
cedd7b22 193 else
cd05bf23
BW
194 {
195 if (pChild->GetMenuBar() == NULL)
196 return;
ee0a94cf 197
cd05bf23
BW
198 // Do we need to save the current bar?
199 if (m_pMyMenuBar == NULL)
200 m_pMyMenuBar = GetMenuBar();
201
202 SetMenuBar(pChild->GetMenuBar());
203 }
204#endif // wxUSE_MENUS
205}
206
a3a5df9d 207bool wxAuiMDIParentFrame::ProcessEvent(wxEvent& event)
cd05bf23 208{
7e1f1a13
BW
209 // stops the same event being processed repeatedly
210 if (m_pLastEvt == &event)
cd05bf23 211 return false;
7e1f1a13 212 m_pLastEvt = &event;
ccc8c01a 213
7e1f1a13 214 // let the active child (if any) process the event first.
cd05bf23 215 bool res = false;
0d1dd76b
VZ
216 wxAuiMDIChildFrame* pActiveChild = GetActiveChild();
217 if (pActiveChild &&
cd05bf23
BW
218 event.IsCommandEvent() &&
219 event.GetEventObject() != m_pClientWindow &&
220 !(event.GetEventType() == wxEVT_ACTIVATE ||
221 event.GetEventType() == wxEVT_SET_FOCUS ||
222 event.GetEventType() == wxEVT_KILL_FOCUS ||
223 event.GetEventType() == wxEVT_CHILD_FOCUS ||
224 event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
225 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
226 )
227 {
0d1dd76b 228 res = pActiveChild->GetEventHandler()->ProcessEvent(event);
cd05bf23
BW
229 }
230
cd05bf23
BW
231 if (!res)
232 {
7e1f1a13
BW
233 // if the event was not handled this frame will handle it,
234 // which is why we need the protection code at the beginning
235 // of this method
cd05bf23
BW
236 res = wxEvtHandler::ProcessEvent(event);
237 }
238
7e1f1a13 239 m_pLastEvt = NULL;
cd05bf23
BW
240
241 return res;
242}
243
a3a5df9d 244wxAuiMDIChildFrame *wxAuiMDIParentFrame::GetActiveChild() const
cd05bf23 245{
91ad3a26
VZ
246 // We can be called before the client window is created, so check for its
247 // existence.
248 wxAuiMDIClientWindow* const client = GetClientWindow();
249 return client ? client->GetActiveChild() : NULL;
cd05bf23
BW
250}
251
a3a5df9d 252void wxAuiMDIParentFrame::SetActiveChild(wxAuiMDIChildFrame* pChildFrame)
cd05bf23 253{
91ad3a26
VZ
254 wxAuiMDIClientWindow* const client = GetClientWindow();
255 if (client && client->GetActiveChild() != pChildFrame)
0d1dd76b 256 {
91ad3a26 257 client->SetActiveChild(pChildFrame);
0d1dd76b 258 }
cd05bf23
BW
259}
260
8856768e 261wxAuiMDIClientWindow *wxAuiMDIParentFrame::GetClientWindow() const
cd05bf23
BW
262{
263 return m_pClientWindow;
264}
265
8856768e 266wxAuiMDIClientWindow *wxAuiMDIParentFrame::OnCreateClient()
cd05bf23 267{
6e42617a 268 return new wxAuiMDIClientWindow( this );
cd05bf23
BW
269}
270
a3a5df9d 271void wxAuiMDIParentFrame::ActivateNext()
cd05bf23 272{
4444d148 273 if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND)
cd05bf23
BW
274 {
275 size_t active = m_pClientWindow->GetSelection() + 1;
276 if (active >= m_pClientWindow->GetPageCount())
277 active = 0;
278
279 m_pClientWindow->SetSelection(active);
280 }
281}
282
a3a5df9d 283void wxAuiMDIParentFrame::ActivatePrevious()
cd05bf23 284{
4444d148 285 if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND)
cd05bf23
BW
286 {
287 int active = m_pClientWindow->GetSelection() - 1;
288 if (active < 0)
289 active = m_pClientWindow->GetPageCount() - 1;
290
291 m_pClientWindow->SetSelection(active);
292 }
293}
294
a3a5df9d 295void wxAuiMDIParentFrame::Init()
cd05bf23 296{
7e1f1a13 297 m_pLastEvt = NULL;
cd05bf23 298 m_pClientWindow = NULL;
cd05bf23
BW
299#if wxUSE_MENUS
300 m_pWindowMenu = NULL;
301 m_pMyMenuBar = NULL;
302#endif // wxUSE_MENUS
303}
304
305#if wxUSE_MENUS
a3a5df9d 306void wxAuiMDIParentFrame::RemoveWindowMenu(wxMenuBar* pMenuBar)
cd05bf23
BW
307{
308 if (pMenuBar && m_pWindowMenu)
309 {
310 // Remove old window menu
311 int pos = pMenuBar->FindMenu(_("&Window"));
312 if (pos != wxNOT_FOUND)
313 {
314 // DBG:: We're going to delete the wrong menu!!!
315 wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos));
316 pMenuBar->Remove(pos);
317 }
318 }
319}
320
a3a5df9d 321void wxAuiMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
cd05bf23
BW
322{
323 if (pMenuBar && m_pWindowMenu)
324 {
ee0a94cf 325 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,wxSTOCK_NOFLAGS));
cd05bf23
BW
326 if (pos == wxNOT_FOUND)
327 pMenuBar->Append(m_pWindowMenu, _("&Window"));
cedd7b22 328 else
cd05bf23
BW
329 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
330 }
331}
332
a3a5df9d 333void wxAuiMDIParentFrame::DoHandleMenu(wxCommandEvent& event)
cd05bf23
BW
334{
335 switch (event.GetId())
336 {
337 case wxWINDOWCLOSE:
0d1dd76b
VZ
338 {
339 wxAuiMDIChildFrame* pActiveChild = GetActiveChild();
340 if (pActiveChild)
341 pActiveChild->Close();
cd05bf23 342 break;
0d1dd76b 343 }
cd05bf23 344 case wxWINDOWCLOSEALL:
0d1dd76b
VZ
345 {
346 wxAuiMDIChildFrame* pActiveChild;
347 while ((pActiveChild = GetActiveChild()) != NULL)
cd05bf23 348 {
0d1dd76b 349 if (!pActiveChild->Close())
cd05bf23
BW
350 {
351 return; // failure
352 }
cd05bf23
BW
353 }
354 break;
0d1dd76b 355 }
cd05bf23
BW
356 case wxWINDOWNEXT:
357 ActivateNext();
358 break;
359 case wxWINDOWPREV:
360 ActivatePrevious();
361 break;
362 default:
363 event.Skip();
364 }
365}
9827ce92
VZ
366
367void wxAuiMDIParentFrame::DoHandleUpdateUI(wxUpdateUIEvent& event)
368{
369 switch (event.GetId())
370 {
371 case wxWINDOWCLOSE:
372 case wxWINDOWCLOSEALL:
373 {
374 wxAuiMDIClientWindow* client_window = GetClientWindow();
375 wxCHECK_RET(client_window, wxS("Missing MDI Client Window"));
376 size_t pages = client_window->GetPageCount();
377 event.Enable(pages >= 1);
378 break;
379 }
380
381 case wxWINDOWNEXT:
382 case wxWINDOWPREV:
383 {
384 wxAuiMDIClientWindow* client_window = GetClientWindow();
385 wxCHECK_RET(client_window, wxS("Missing MDI Client Window"));
386 size_t pages = client_window->GetPageCount();
387 event.Enable(pages >= 2);
388 break;
389 }
390
391 default:
392 event.Skip();
393 }
394}
cd05bf23
BW
395#endif // wxUSE_MENUS
396
a3a5df9d 397void wxAuiMDIParentFrame::DoGetClientSize(int* width, int* height) const
cd05bf23
BW
398{
399 wxFrame::DoGetClientSize(width, height);
400}
401
d606b6e9
BW
402void wxAuiMDIParentFrame::Tile(wxOrientation orient)
403{
404 wxAuiMDIClientWindow* client_window = GetClientWindow();
405 wxASSERT_MSG(client_window, wxT("Missing MDI Client Window"));
ccc8c01a 406
d606b6e9
BW
407 int cur_idx = client_window->GetSelection();
408 if (cur_idx == -1)
409 return;
ccc8c01a 410
d606b6e9
BW
411 if (orient == wxVERTICAL)
412 {
413 client_window->Split(cur_idx, wxLEFT);
414 }
cedd7b22 415 else if (orient == wxHORIZONTAL)
d606b6e9
BW
416 {
417 client_window->Split(cur_idx, wxTOP);
418 }
419}
420
421
cd05bf23 422//-----------------------------------------------------------------------------
a3a5df9d 423// wxAuiMDIChildFrame
cd05bf23
BW
424//-----------------------------------------------------------------------------
425
a3a5df9d 426IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIChildFrame, wxPanel)
cd05bf23 427
a3a5df9d
BW
428BEGIN_EVENT_TABLE(wxAuiMDIChildFrame, wxPanel)
429 EVT_MENU_HIGHLIGHT_ALL(wxAuiMDIChildFrame::OnMenuHighlight)
430 EVT_ACTIVATE(wxAuiMDIChildFrame::OnActivate)
431 EVT_CLOSE(wxAuiMDIChildFrame::OnCloseWindow)
cd05bf23
BW
432END_EVENT_TABLE()
433
a3a5df9d 434wxAuiMDIChildFrame::wxAuiMDIChildFrame()
cd05bf23
BW
435{
436 Init();
437}
438
a3a5df9d 439wxAuiMDIChildFrame::wxAuiMDIChildFrame(wxAuiMDIParentFrame *parent,
cd05bf23
BW
440 wxWindowID id,
441 const wxString& title,
442 const wxPoint& WXUNUSED(pos),
443 const wxSize& size,
444 long style,
445 const wxString& name)
446{
447 Init();
ccc8c01a 448
e7e324be
BW
449 // There are two ways to create an tabbed mdi child fram without
450 // making it the active document. Either Show(false) can be called
451 // before Create() (as is customary on some ports with wxFrame-type
452 // windows), or wxMINIMIZE can be passed in the style flags. Note that
453 // wxAuiMDIChildFrame is not really derived from wxFrame, as wxMDIChildFrame
454 // is, but those are the expected symantics. No style flag is passed
455 // onto the panel underneath.
456 if (style & wxMINIMIZE)
9a29fe70 457 m_activateOnCreate = false;
ccc8c01a 458
e7e324be 459 Create(parent, id, title, wxDefaultPosition, size, 0, name);
cd05bf23
BW
460}
461
a3a5df9d 462wxAuiMDIChildFrame::~wxAuiMDIChildFrame()
cd05bf23 463{
b0a54b8a 464 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
8691bf11 465 if (pParentFrame)
b0a54b8a 466 {
8691bf11
BW
467 if (pParentFrame->GetActiveChild() == this)
468 {
469 pParentFrame->SetActiveChild(NULL);
470 pParentFrame->SetChildMenuBar(NULL);
471 }
472 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
473 wxASSERT(pClientWindow);
474 int idx = pClientWindow->GetPageIndex(this);
475 if (idx != wxNOT_FOUND)
476 {
477 pClientWindow->RemovePage(idx);
478 }
b0a54b8a 479 }
ccc8c01a 480
cd05bf23
BW
481#if wxUSE_MENUS
482 wxDELETE(m_pMenuBar);
483#endif // wxUSE_MENUS
484}
485
a3a5df9d 486bool wxAuiMDIChildFrame::Create(wxAuiMDIParentFrame* parent,
cd05bf23
BW
487 wxWindowID id,
488 const wxString& title,
489 const wxPoint& WXUNUSED(pos),
490 const wxSize& size,
491 long style,
492 const wxString& name)
493{
8856768e 494 wxAuiMDIClientWindow* pClientWindow = parent->GetClientWindow();
d3b9f782 495 wxASSERT_MSG((pClientWindow != NULL), wxT("Missing MDI client window."));
cd05bf23 496
e7e324be
BW
497 // see comment in constructor
498 if (style & wxMINIMIZE)
9a29fe70 499 m_activateOnCreate = false;
e7e324be 500
ea53a601
BW
501 wxSize cli_size = pClientWindow->GetClientSize();
502
503 // create the window off-screen to prevent flicker
504 wxPanel::Create(pClientWindow,
cedd7b22
PC
505 id,
506 wxPoint(cli_size.x+1, cli_size.y+1),
507 size,
508 wxNO_BORDER, name);
e7e324be
BW
509
510 DoShow(false);
cd05bf23
BW
511
512 SetMDIParentFrame(parent);
513
cd05bf23
BW
514 m_title = title;
515
9a29fe70 516 pClientWindow->AddPage(this, title, m_activateOnCreate);
0d1dd76b
VZ
517
518 // Check that the parent notion of the active child coincides with our one.
519 // This is less obvious that it seems because we must honour
520 // m_activateOnCreate flag but only if it's not the first child because
521 // this one becomes active unconditionally.
522 wxASSERT_MSG
523 (
524 (m_activateOnCreate || pClientWindow->GetPageCount() == 1)
525 == (parent->GetActiveChild() == this),
526 wxS("Logic error: child [not] activated when it should [not] have been.")
527 );
528
cd05bf23 529 pClientWindow->Refresh();
ccc8c01a 530
cd05bf23
BW
531 return true;
532}
533
a3a5df9d 534bool wxAuiMDIChildFrame::Destroy()
cd05bf23 535{
a3a5df9d 536 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
cd05bf23 537 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
4444d148 538
8856768e 539 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
cd05bf23 540 wxASSERT_MSG(pClientWindow, wxT("Missing MDI Client Window"));
4444d148 541
cd05bf23
BW
542 if (pParentFrame->GetActiveChild() == this)
543 {
c5e2ca7c
BW
544 // deactivate ourself
545 wxActivateEvent event(wxEVT_ACTIVATE, false, GetId());
546 event.SetEventObject(this);
547 GetEventHandler()->ProcessEvent(event);
ccc8c01a 548
cd05bf23 549 pParentFrame->SetChildMenuBar(NULL);
cd05bf23 550 }
4444d148 551
c5e2ca7c 552 size_t page_count = pClientWindow->GetPageCount();
d3b647c2 553 for (size_t pos = 0; pos < page_count; pos++)
cd05bf23
BW
554 {
555 if (pClientWindow->GetPage(pos) == this)
556 return pClientWindow->DeletePage(pos);
557 }
4444d148 558
cd05bf23
BW
559 return false;
560}
561
cd05bf23 562#if wxUSE_MENUS
a3a5df9d 563void wxAuiMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
cd05bf23
BW
564{
565 wxMenuBar *pOldMenuBar = m_pMenuBar;
566 m_pMenuBar = menu_bar;
567
568 if (m_pMenuBar)
569 {
a3a5df9d 570 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
cd05bf23
BW
571 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
572
573 m_pMenuBar->SetParent(pParentFrame);
574 if (pParentFrame->GetActiveChild() == this)
575 {
576 // replace current menu bars
577 if (pOldMenuBar)
578 pParentFrame->SetChildMenuBar(NULL);
579 pParentFrame->SetChildMenuBar(this);
580 }
581 }
582}
583
a3a5df9d 584wxMenuBar *wxAuiMDIChildFrame::GetMenuBar() const
cd05bf23
BW
585{
586 return m_pMenuBar;
587}
588#endif // wxUSE_MENUS
589
a3a5df9d 590void wxAuiMDIChildFrame::SetTitle(const wxString& title)
cd05bf23
BW
591{
592 m_title = title;
593
a3a5df9d 594 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
cd05bf23
BW
595 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
596
8856768e 597 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
cd05bf23
BW
598 if (pClientWindow != NULL)
599 {
600 size_t pos;
601 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
602 {
603 if (pClientWindow->GetPage(pos) == this)
604 {
605 pClientWindow->SetPageText(pos, m_title);
606 break;
607 }
608 }
609 }
610}
611
a3a5df9d 612wxString wxAuiMDIChildFrame::GetTitle() const
cd05bf23
BW
613{
614 return m_title;
615}
616
e0dc13d4
BW
617void wxAuiMDIChildFrame::SetIcons(const wxIconBundle& icons)
618{
619 // get icon with the system icon size
620 SetIcon(icons.GetIcon(-1));
9a29fe70 621 m_iconBundle = icons;
e0dc13d4
BW
622}
623
624const wxIconBundle& wxAuiMDIChildFrame::GetIcons() const
625{
9a29fe70 626 return m_iconBundle;
e0dc13d4
BW
627}
628
629void wxAuiMDIChildFrame::SetIcon(const wxIcon& icon)
630{
631 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
632 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
633
634 m_icon = icon;
ccc8c01a 635
e0dc13d4
BW
636 wxBitmap bmp;
637 bmp.CopyFromIcon(m_icon);
ccc8c01a 638
e0dc13d4
BW
639 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
640 if (pClientWindow != NULL)
641 {
642 int idx = pClientWindow->GetPageIndex(this);
ccc8c01a 643
e0dc13d4
BW
644 if (idx != -1)
645 {
646 pClientWindow->SetPageBitmap((size_t)idx, bmp);
647 }
648 }
649}
650
651const wxIcon& wxAuiMDIChildFrame::GetIcon() const
652{
653 return m_icon;
654}
ccc8c01a
VZ
655
656
a3a5df9d 657void wxAuiMDIChildFrame::Activate()
cd05bf23 658{
a3a5df9d 659 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
cd05bf23
BW
660 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
661
8856768e 662 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
cd05bf23
BW
663
664 if (pClientWindow != NULL)
665 {
666 size_t pos;
667 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
668 {
669 if (pClientWindow->GetPage(pos) == this)
670 {
671 pClientWindow->SetSelection(pos);
672 break;
673 }
674 }
675 }
676}
677
a3a5df9d 678void wxAuiMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
cd05bf23
BW
679{
680#if wxUSE_STATUSBAR
681 if (m_pMDIParentFrame)
682 {
683 // we don't have any help text for this item,
684 // but may be the MDI frame does?
685 m_pMDIParentFrame->OnMenuHighlight(event);
686 }
687#else
688 wxUnusedVar(event);
689#endif // wxUSE_STATUSBAR
690}
691
a3a5df9d 692void wxAuiMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
cd05bf23
BW
693{
694 // do nothing
695}
696
a3a5df9d 697void wxAuiMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
cd05bf23
BW
698{
699 Destroy();
700}
701
a3a5df9d 702void wxAuiMDIChildFrame::SetMDIParentFrame(wxAuiMDIParentFrame* parentFrame)
cd05bf23
BW
703{
704 m_pMDIParentFrame = parentFrame;
705}
706
a3a5df9d 707wxAuiMDIParentFrame* wxAuiMDIChildFrame::GetMDIParentFrame() const
cd05bf23
BW
708{
709 return m_pMDIParentFrame;
710}
711
a3a5df9d 712void wxAuiMDIChildFrame::Init()
cd05bf23 713{
9a29fe70 714 m_activateOnCreate = true;
cd05bf23
BW
715 m_pMDIParentFrame = NULL;
716#if wxUSE_MENUS
717 m_pMenuBar = NULL;
718#endif // wxUSE_MENUS
719}
720
e7e324be 721bool wxAuiMDIChildFrame::Show(bool show)
cd05bf23 722{
0d1dd76b
VZ
723 // wxAuiMDIChildFrame uses m_activateOnCreate only to decide whether to
724 // activate the frame when it is created. After Create() is called,
725 // m_activateOnCreate will never be read again. Therefore, calling this
726 // function after Create() is pointless and you probably want to call
727 // Activate() instead.
728 wxCHECK_MSG( !GetHandle(), false,
729 wxS("Show() has no effect after Create(). Do you mean Activate()?") );
730
9a29fe70 731 m_activateOnCreate = show;
ccc8c01a 732
cd05bf23
BW
733 // do nothing
734 return true;
735}
736
a3a5df9d 737void wxAuiMDIChildFrame::DoShow(bool show)
cd05bf23
BW
738{
739 wxWindow::Show(show);
740}
741
a3a5df9d 742void wxAuiMDIChildFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
cd05bf23 743{
9a29fe70 744 m_mdiNewRect = wxRect(x, y, width, height);
a94476de
BW
745#ifdef __WXGTK__
746 wxPanel::DoSetSize(x,y,width, height, sizeFlags);
f9c240ec
BW
747#else
748 wxUnusedVar(sizeFlags);
a94476de 749#endif
cd05bf23
BW
750}
751
a3a5df9d 752void wxAuiMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
cd05bf23 753{
9a29fe70 754 m_mdiNewRect = wxRect(x, y, width, height);
cd05bf23
BW
755}
756
a3a5df9d 757void wxAuiMDIChildFrame::ApplyMDIChildFrameRect()
cd05bf23 758{
9a29fe70 759 if (m_mdiCurRect != m_mdiNewRect)
cd05bf23 760 {
9a29fe70
VZ
761 wxPanel::DoMoveWindow(m_mdiNewRect.x, m_mdiNewRect.y,
762 m_mdiNewRect.width, m_mdiNewRect.height);
763 m_mdiCurRect = m_mdiNewRect;
cd05bf23
BW
764 }
765}
766
767
768//-----------------------------------------------------------------------------
8856768e 769// wxAuiMDIClientWindow
cd05bf23
BW
770//-----------------------------------------------------------------------------
771
8856768e 772IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIClientWindow, wxAuiNotebook)
cd05bf23 773
8856768e
BW
774BEGIN_EVENT_TABLE(wxAuiMDIClientWindow, wxAuiNotebook)
775 EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, wxAuiMDIClientWindow::OnPageChanged)
c5e2ca7c 776 EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, wxAuiMDIClientWindow::OnPageClose)
8856768e 777 EVT_SIZE(wxAuiMDIClientWindow::OnSize)
cd05bf23
BW
778END_EVENT_TABLE()
779
8856768e 780wxAuiMDIClientWindow::wxAuiMDIClientWindow()
cd05bf23
BW
781{
782}
783
8856768e 784wxAuiMDIClientWindow::wxAuiMDIClientWindow(wxAuiMDIParentFrame* parent, long style)
cd05bf23
BW
785{
786 CreateClient(parent, style);
787}
788
8856768e 789bool wxAuiMDIClientWindow::CreateClient(wxAuiMDIParentFrame* parent, long style)
cd05bf23
BW
790{
791 SetWindowStyleFlag(style);
792
ccc8c01a 793 wxSize caption_icon_size =
9fbb7d80
BW
794 wxSize(wxSystemSettings::GetMetric(wxSYS_SMALLICON_X),
795 wxSystemSettings::GetMetric(wxSYS_SMALLICON_Y));
796 SetUniformBitmapSize(caption_icon_size);
ccc8c01a 797
a3a5df9d 798 if (!wxAuiNotebook::Create(parent,
695c0088
BW
799 wxID_ANY,
800 wxPoint(0,0),
801 wxSize(100, 100),
802 wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER))
cd05bf23
BW
803 {
804 return false;
805 }
4444d148 806
cd05bf23 807 wxColour bkcolour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
e7e324be 808 SetOwnBackgroundColour(bkcolour);
4444d148 809
254a3429 810 m_mgr.GetArtProvider()->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, bkcolour);
4444d148 811
cd05bf23
BW
812 return true;
813}
814
8856768e 815int wxAuiMDIClientWindow::SetSelection(size_t nPage)
cd05bf23 816{
a3a5df9d 817 return wxAuiNotebook::SetSelection(nPage);
cd05bf23
BW
818}
819
0d1dd76b
VZ
820wxAuiMDIChildFrame* wxAuiMDIClientWindow::GetActiveChild()
821{
822 const int sel = GetSelection();
823 if ( sel == wxNOT_FOUND )
824 return NULL;
825
826 return wxStaticCast(GetPage(sel), wxAuiMDIChildFrame);
827}
828
8856768e 829void wxAuiMDIClientWindow::PageChanged(int old_selection, int new_selection)
cd05bf23
BW
830{
831 // don't do anything if the page doesn't actually change
832 if (old_selection == new_selection)
833 return;
ccc8c01a 834
c5e2ca7c 835 /*
cd05bf23
BW
836 // don't do anything if the new page is already active
837 if (new_selection != -1)
838 {
a3a5df9d 839 wxAuiMDIChildFrame* child = (wxAuiMDIChildFrame*)GetPage(new_selection);
cd05bf23
BW
840 if (child->GetMDIParentFrame()->GetActiveChild() == child)
841 return;
c5e2ca7c 842 }*/
ccc8c01a
VZ
843
844
cd05bf23 845 // notify old active child that it has been deactivated
8691bf11 846 if ((old_selection != -1) && (old_selection < (int)GetPageCount()))
cd05bf23 847 {
a3a5df9d 848 wxAuiMDIChildFrame* old_child = (wxAuiMDIChildFrame*)GetPage(old_selection);
8856768e 849 wxASSERT_MSG(old_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer"));
4444d148 850
cd05bf23
BW
851 wxActivateEvent event(wxEVT_ACTIVATE, false, old_child->GetId());
852 event.SetEventObject(old_child);
853 old_child->GetEventHandler()->ProcessEvent(event);
854 }
ccc8c01a 855
cd05bf23
BW
856 // notify new active child that it has been activated
857 if (new_selection != -1)
858 {
a3a5df9d 859 wxAuiMDIChildFrame* active_child = (wxAuiMDIChildFrame*)GetPage(new_selection);
8856768e 860 wxASSERT_MSG(active_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer"));
ccc8c01a 861
cd05bf23
BW
862 wxActivateEvent event(wxEVT_ACTIVATE, true, active_child->GetId());
863 event.SetEventObject(active_child);
864 active_child->GetEventHandler()->ProcessEvent(event);
ccc8c01a 865
cd05bf23
BW
866 if (active_child->GetMDIParentFrame())
867 {
868 active_child->GetMDIParentFrame()->SetActiveChild(active_child);
869 active_child->GetMDIParentFrame()->SetChildMenuBar(active_child);
870 }
871 }
ccc8c01a 872
c5e2ca7c
BW
873
874}
875
876void wxAuiMDIClientWindow::OnPageClose(wxAuiNotebookEvent& evt)
877{
878 wxAuiMDIChildFrame* wnd;
879 wnd = static_cast<wxAuiMDIChildFrame*>(GetPage(evt.GetSelection()));
ccc8c01a 880
c5e2ca7c 881 wnd->Close();
ccc8c01a 882
c5e2ca7c
BW
883 // regardless of the result of wnd->Close(), we've
884 // already taken care of the close operations, so
885 // suppress further processing
886 evt.Veto();
cd05bf23
BW
887}
888
8856768e 889void wxAuiMDIClientWindow::OnPageChanged(wxAuiNotebookEvent& evt)
cd05bf23
BW
890{
891 PageChanged(evt.GetOldSelection(), evt.GetSelection());
cd05bf23
BW
892}
893
8856768e 894void wxAuiMDIClientWindow::OnSize(wxSizeEvent& evt)
4444d148 895{
a3a5df9d 896 wxAuiNotebook::OnSize(evt);
cd05bf23
BW
897
898 for (size_t pos = 0; pos < GetPageCount(); pos++)
a3a5df9d 899 ((wxAuiMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
cd05bf23
BW
900}
901
25f70bc4 902#endif //wxUSE_AUI
cd05bf23 903#endif // wxUSE_MDI