]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/aui/tabmdi.cpp
revert nested event loop support for wxGTK1 because it causes applications hangs
[wxWidgets.git] / src / aui / tabmdi.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/aui/tabmdi.cpp
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
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
26#if wxUSE_AUI
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"
36 #include "wx/settings.h"
37#endif //WX_PRECOMP
38
39#include "wx/stockitem.h"
40#include "wx/aui/dockart.h"
41
42enum MDI_MENU_ID
43{
44 wxWINDOWCLOSE = 4001,
45 wxWINDOWCLOSEALL,
46 wxWINDOWNEXT,
47 wxWINDOWPREV
48};
49
50//-----------------------------------------------------------------------------
51// wxAuiMDIParentFrame
52//-----------------------------------------------------------------------------
53
54IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIParentFrame, wxFrame)
55
56BEGIN_EVENT_TABLE(wxAuiMDIParentFrame, wxFrame)
57#if wxUSE_MENUS
58 EVT_MENU (wxID_ANY, wxAuiMDIParentFrame::DoHandleMenu)
59 EVT_UPDATE_UI (wxID_ANY, wxAuiMDIParentFrame::DoHandleUpdateUI)
60#endif
61END_EVENT_TABLE()
62
63wxAuiMDIParentFrame::wxAuiMDIParentFrame()
64{
65 Init();
66}
67
68wxAuiMDIParentFrame::wxAuiMDIParentFrame(wxWindow *parent,
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
80wxAuiMDIParentFrame::~wxAuiMDIParentFrame()
81{
82 // Avoid having GetActiveChild() called after m_pClientWindow is destroyed
83 SendDestroyEvent();
84 // Make sure the client window is destructed before the menu bars are!
85 wxDELETE(m_pClientWindow);
86
87#if wxUSE_MENUS
88 wxDELETE(m_pMyMenuBar);
89 RemoveWindowMenu(GetMenuBar());
90 wxDELETE(m_pWindowMenu);
91#endif // wxUSE_MENUS
92}
93
94bool wxAuiMDIParentFrame::Create(wxWindow *parent,
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
116 if ( !wxFrame::Create(parent, id, title, pos, size, style, name) )
117 return false;
118
119 m_pClientWindow = OnCreateClient();
120 return m_pClientWindow != NULL;
121}
122
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;
136
137 return m_pClientWindow->GetArtProvider();
138}
139
140wxAuiNotebook* wxAuiMDIParentFrame::GetNotebook() const
141{
142 return static_cast<wxAuiNotebook*>(m_pClientWindow);
143}
144
145
146
147#if wxUSE_MENUS
148void wxAuiMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
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
166void wxAuiMDIParentFrame::SetMenuBar(wxMenuBar* pMenuBar)
167{
168 // Remove the Window menu from the old menu bar
169 RemoveWindowMenu(GetMenuBar());
170
171 // Add the Window menu to the new menu bar.
172 AddWindowMenu(pMenuBar);
173
174 wxFrame::SetMenuBar(pMenuBar);
175 //m_pMyMenuBar = GetMenuBar();
176}
177#endif // wxUSE_MENUS
178
179void wxAuiMDIParentFrame::SetChildMenuBar(wxAuiMDIChildFrame* pChild)
180{
181#if wxUSE_MENUS
182 if (!pChild)
183 {
184 // No Child, set Our menu bar back.
185 if (m_pMyMenuBar)
186 SetMenuBar(m_pMyMenuBar);
187 else
188 SetMenuBar(GetMenuBar());
189
190 // Make sure we know our menu bar is in use
191 m_pMyMenuBar = NULL;
192 }
193 else
194 {
195 if (pChild->GetMenuBar() == NULL)
196 return;
197
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
207bool wxAuiMDIParentFrame::ProcessEvent(wxEvent& event)
208{
209 // stops the same event being processed repeatedly
210 if (m_pLastEvt == &event)
211 return false;
212 m_pLastEvt = &event;
213
214 // let the active child (if any) process the event first.
215 bool res = false;
216 wxAuiMDIChildFrame* pActiveChild = GetActiveChild();
217 if (pActiveChild &&
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 {
228 res = pActiveChild->GetEventHandler()->ProcessEvent(event);
229 }
230
231 if (!res)
232 {
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
236 res = wxEvtHandler::ProcessEvent(event);
237 }
238
239 m_pLastEvt = NULL;
240
241 return res;
242}
243
244wxAuiMDIChildFrame *wxAuiMDIParentFrame::GetActiveChild() const
245{
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;
250}
251
252void wxAuiMDIParentFrame::SetActiveChild(wxAuiMDIChildFrame* pChildFrame)
253{
254 wxAuiMDIClientWindow* const client = GetClientWindow();
255 if (client && client->GetActiveChild() != pChildFrame)
256 {
257 client->SetActiveChild(pChildFrame);
258 }
259}
260
261wxAuiMDIClientWindow *wxAuiMDIParentFrame::GetClientWindow() const
262{
263 return m_pClientWindow;
264}
265
266wxAuiMDIClientWindow *wxAuiMDIParentFrame::OnCreateClient()
267{
268 return new wxAuiMDIClientWindow( this );
269}
270
271void wxAuiMDIParentFrame::ActivateNext()
272{
273 if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND)
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
283void wxAuiMDIParentFrame::ActivatePrevious()
284{
285 if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND)
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
295void wxAuiMDIParentFrame::Init()
296{
297 m_pLastEvt = NULL;
298 m_pClientWindow = NULL;
299#if wxUSE_MENUS
300 m_pWindowMenu = NULL;
301 m_pMyMenuBar = NULL;
302#endif // wxUSE_MENUS
303}
304
305#if wxUSE_MENUS
306void wxAuiMDIParentFrame::RemoveWindowMenu(wxMenuBar* pMenuBar)
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
321void wxAuiMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
322{
323 if (pMenuBar && m_pWindowMenu)
324 {
325 int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,wxSTOCK_NOFLAGS));
326 if (pos == wxNOT_FOUND)
327 pMenuBar->Append(m_pWindowMenu, _("&Window"));
328 else
329 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
330 }
331}
332
333void wxAuiMDIParentFrame::DoHandleMenu(wxCommandEvent& event)
334{
335 switch (event.GetId())
336 {
337 case wxWINDOWCLOSE:
338 {
339 wxAuiMDIChildFrame* pActiveChild = GetActiveChild();
340 if (pActiveChild)
341 pActiveChild->Close();
342 break;
343 }
344 case wxWINDOWCLOSEALL:
345 {
346 wxAuiMDIChildFrame* pActiveChild;
347 while ((pActiveChild = GetActiveChild()) != NULL)
348 {
349 if (!pActiveChild->Close())
350 {
351 return; // failure
352 }
353 }
354 break;
355 }
356 case wxWINDOWNEXT:
357 ActivateNext();
358 break;
359 case wxWINDOWPREV:
360 ActivatePrevious();
361 break;
362 default:
363 event.Skip();
364 }
365}
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}
395#endif // wxUSE_MENUS
396
397void wxAuiMDIParentFrame::DoGetClientSize(int* width, int* height) const
398{
399 wxFrame::DoGetClientSize(width, height);
400}
401
402void wxAuiMDIParentFrame::Tile(wxOrientation orient)
403{
404 wxAuiMDIClientWindow* client_window = GetClientWindow();
405 wxASSERT_MSG(client_window, wxT("Missing MDI Client Window"));
406
407 int cur_idx = client_window->GetSelection();
408 if (cur_idx == -1)
409 return;
410
411 if (orient == wxVERTICAL)
412 {
413 client_window->Split(cur_idx, wxLEFT);
414 }
415 else if (orient == wxHORIZONTAL)
416 {
417 client_window->Split(cur_idx, wxTOP);
418 }
419}
420
421
422//-----------------------------------------------------------------------------
423// wxAuiMDIChildFrame
424//-----------------------------------------------------------------------------
425
426IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIChildFrame, wxPanel)
427
428BEGIN_EVENT_TABLE(wxAuiMDIChildFrame, wxPanel)
429 EVT_MENU_HIGHLIGHT_ALL(wxAuiMDIChildFrame::OnMenuHighlight)
430 EVT_ACTIVATE(wxAuiMDIChildFrame::OnActivate)
431 EVT_CLOSE(wxAuiMDIChildFrame::OnCloseWindow)
432END_EVENT_TABLE()
433
434wxAuiMDIChildFrame::wxAuiMDIChildFrame()
435{
436 Init();
437}
438
439wxAuiMDIChildFrame::wxAuiMDIChildFrame(wxAuiMDIParentFrame *parent,
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();
448
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)
457 m_activateOnCreate = false;
458
459 Create(parent, id, title, wxDefaultPosition, size, 0, name);
460}
461
462wxAuiMDIChildFrame::~wxAuiMDIChildFrame()
463{
464 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
465 if (pParentFrame)
466 {
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 }
479 }
480
481#if wxUSE_MENUS
482 wxDELETE(m_pMenuBar);
483#endif // wxUSE_MENUS
484}
485
486bool wxAuiMDIChildFrame::Create(wxAuiMDIParentFrame* parent,
487 wxWindowID id,
488 const wxString& title,
489 const wxPoint& WXUNUSED(pos),
490 const wxSize& size,
491 long style,
492 const wxString& name)
493{
494 wxAuiMDIClientWindow* pClientWindow = parent->GetClientWindow();
495 wxASSERT_MSG((pClientWindow != NULL), wxT("Missing MDI client window."));
496
497 // see comment in constructor
498 if (style & wxMINIMIZE)
499 m_activateOnCreate = false;
500
501 wxSize cli_size = pClientWindow->GetClientSize();
502
503 // create the window off-screen to prevent flicker
504 wxPanel::Create(pClientWindow,
505 id,
506 wxPoint(cli_size.x+1, cli_size.y+1),
507 size,
508 wxNO_BORDER, name);
509
510 DoShow(false);
511
512 SetMDIParentFrame(parent);
513
514 m_title = title;
515
516 pClientWindow->AddPage(this, title, m_activateOnCreate);
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
529 pClientWindow->Refresh();
530
531 return true;
532}
533
534bool wxAuiMDIChildFrame::Destroy()
535{
536 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
537 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
538
539 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
540 wxASSERT_MSG(pClientWindow, wxT("Missing MDI Client Window"));
541
542 if (pParentFrame->GetActiveChild() == this)
543 {
544 // deactivate ourself
545 wxActivateEvent event(wxEVT_ACTIVATE, false, GetId());
546 event.SetEventObject(this);
547 GetEventHandler()->ProcessEvent(event);
548
549 pParentFrame->SetChildMenuBar(NULL);
550 }
551
552 size_t page_count = pClientWindow->GetPageCount();
553 for (size_t pos = 0; pos < page_count; pos++)
554 {
555 if (pClientWindow->GetPage(pos) == this)
556 return pClientWindow->DeletePage(pos);
557 }
558
559 return false;
560}
561
562#if wxUSE_MENUS
563void wxAuiMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
564{
565 wxMenuBar *pOldMenuBar = m_pMenuBar;
566 m_pMenuBar = menu_bar;
567
568 if (m_pMenuBar)
569 {
570 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
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
584wxMenuBar *wxAuiMDIChildFrame::GetMenuBar() const
585{
586 return m_pMenuBar;
587}
588#endif // wxUSE_MENUS
589
590void wxAuiMDIChildFrame::SetTitle(const wxString& title)
591{
592 m_title = title;
593
594 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
595 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
596
597 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
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
612wxString wxAuiMDIChildFrame::GetTitle() const
613{
614 return m_title;
615}
616
617void wxAuiMDIChildFrame::SetIcons(const wxIconBundle& icons)
618{
619 // get icon with the system icon size
620 SetIcon(icons.GetIcon(-1));
621 m_iconBundle = icons;
622}
623
624const wxIconBundle& wxAuiMDIChildFrame::GetIcons() const
625{
626 return m_iconBundle;
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;
635
636 wxBitmap bmp;
637 bmp.CopyFromIcon(m_icon);
638
639 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
640 if (pClientWindow != NULL)
641 {
642 int idx = pClientWindow->GetPageIndex(this);
643
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}
655
656
657void wxAuiMDIChildFrame::Activate()
658{
659 wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame();
660 wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame"));
661
662 wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow();
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
678void wxAuiMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
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
692void wxAuiMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
693{
694 // do nothing
695}
696
697void wxAuiMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
698{
699 Destroy();
700}
701
702void wxAuiMDIChildFrame::SetMDIParentFrame(wxAuiMDIParentFrame* parentFrame)
703{
704 m_pMDIParentFrame = parentFrame;
705}
706
707wxAuiMDIParentFrame* wxAuiMDIChildFrame::GetMDIParentFrame() const
708{
709 return m_pMDIParentFrame;
710}
711
712void wxAuiMDIChildFrame::Init()
713{
714 m_activateOnCreate = true;
715 m_pMDIParentFrame = NULL;
716#if wxUSE_MENUS
717 m_pMenuBar = NULL;
718#endif // wxUSE_MENUS
719}
720
721bool wxAuiMDIChildFrame::Show(bool show)
722{
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
731 m_activateOnCreate = show;
732
733 // do nothing
734 return true;
735}
736
737void wxAuiMDIChildFrame::DoShow(bool show)
738{
739 wxWindow::Show(show);
740}
741
742void wxAuiMDIChildFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
743{
744 m_mdiNewRect = wxRect(x, y, width, height);
745#ifdef __WXGTK__
746 wxPanel::DoSetSize(x,y,width, height, sizeFlags);
747#else
748 wxUnusedVar(sizeFlags);
749#endif
750}
751
752void wxAuiMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
753{
754 m_mdiNewRect = wxRect(x, y, width, height);
755}
756
757void wxAuiMDIChildFrame::ApplyMDIChildFrameRect()
758{
759 if (m_mdiCurRect != m_mdiNewRect)
760 {
761 wxPanel::DoMoveWindow(m_mdiNewRect.x, m_mdiNewRect.y,
762 m_mdiNewRect.width, m_mdiNewRect.height);
763 m_mdiCurRect = m_mdiNewRect;
764 }
765}
766
767
768//-----------------------------------------------------------------------------
769// wxAuiMDIClientWindow
770//-----------------------------------------------------------------------------
771
772IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIClientWindow, wxAuiNotebook)
773
774BEGIN_EVENT_TABLE(wxAuiMDIClientWindow, wxAuiNotebook)
775 EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, wxAuiMDIClientWindow::OnPageChanged)
776 EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, wxAuiMDIClientWindow::OnPageClose)
777 EVT_SIZE(wxAuiMDIClientWindow::OnSize)
778END_EVENT_TABLE()
779
780wxAuiMDIClientWindow::wxAuiMDIClientWindow()
781{
782}
783
784wxAuiMDIClientWindow::wxAuiMDIClientWindow(wxAuiMDIParentFrame* parent, long style)
785{
786 CreateClient(parent, style);
787}
788
789bool wxAuiMDIClientWindow::CreateClient(wxAuiMDIParentFrame* parent, long style)
790{
791 SetWindowStyleFlag(style);
792
793 wxSize caption_icon_size =
794 wxSize(wxSystemSettings::GetMetric(wxSYS_SMALLICON_X),
795 wxSystemSettings::GetMetric(wxSYS_SMALLICON_Y));
796 SetUniformBitmapSize(caption_icon_size);
797
798 if (!wxAuiNotebook::Create(parent,
799 wxID_ANY,
800 wxPoint(0,0),
801 wxSize(100, 100),
802 wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER))
803 {
804 return false;
805 }
806
807 wxColour bkcolour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
808 SetOwnBackgroundColour(bkcolour);
809
810 m_mgr.GetArtProvider()->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, bkcolour);
811
812 return true;
813}
814
815int wxAuiMDIClientWindow::SetSelection(size_t nPage)
816{
817 return wxAuiNotebook::SetSelection(nPage);
818}
819
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
829void wxAuiMDIClientWindow::PageChanged(int old_selection, int new_selection)
830{
831 // don't do anything if the page doesn't actually change
832 if (old_selection == new_selection)
833 return;
834
835 /*
836 // don't do anything if the new page is already active
837 if (new_selection != -1)
838 {
839 wxAuiMDIChildFrame* child = (wxAuiMDIChildFrame*)GetPage(new_selection);
840 if (child->GetMDIParentFrame()->GetActiveChild() == child)
841 return;
842 }*/
843
844
845 // notify old active child that it has been deactivated
846 if ((old_selection != -1) && (old_selection < (int)GetPageCount()))
847 {
848 wxAuiMDIChildFrame* old_child = (wxAuiMDIChildFrame*)GetPage(old_selection);
849 wxASSERT_MSG(old_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer"));
850
851 wxActivateEvent event(wxEVT_ACTIVATE, false, old_child->GetId());
852 event.SetEventObject(old_child);
853 old_child->GetEventHandler()->ProcessEvent(event);
854 }
855
856 // notify new active child that it has been activated
857 if (new_selection != -1)
858 {
859 wxAuiMDIChildFrame* active_child = (wxAuiMDIChildFrame*)GetPage(new_selection);
860 wxASSERT_MSG(active_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer"));
861
862 wxActivateEvent event(wxEVT_ACTIVATE, true, active_child->GetId());
863 event.SetEventObject(active_child);
864 active_child->GetEventHandler()->ProcessEvent(event);
865
866 if (active_child->GetMDIParentFrame())
867 {
868 active_child->GetMDIParentFrame()->SetActiveChild(active_child);
869 active_child->GetMDIParentFrame()->SetChildMenuBar(active_child);
870 }
871 }
872
873
874}
875
876void wxAuiMDIClientWindow::OnPageClose(wxAuiNotebookEvent& evt)
877{
878 wxAuiMDIChildFrame* wnd;
879 wnd = static_cast<wxAuiMDIChildFrame*>(GetPage(evt.GetSelection()));
880
881 wnd->Close();
882
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();
887}
888
889void wxAuiMDIClientWindow::OnPageChanged(wxAuiNotebookEvent& evt)
890{
891 PageChanged(evt.GetOldSelection(), evt.GetSelection());
892}
893
894void wxAuiMDIClientWindow::OnSize(wxSizeEvent& evt)
895{
896 wxAuiNotebook::OnSize(evt);
897
898 for (size_t pos = 0; pos < GetPageCount(); pos++)
899 ((wxAuiMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
900}
901
902#endif //wxUSE_AUI
903#endif // wxUSE_MDI