Document domain parameter of wxTranslations::GetTranslatedString().
[wxWidgets.git] / src / aui / tabmdi.cpp
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
42 enum MDI_MENU_ID
43 {
44 wxWINDOWCLOSE = 4001,
45 wxWINDOWCLOSEALL,
46 wxWINDOWNEXT,
47 wxWINDOWPREV
48 };
49
50 //-----------------------------------------------------------------------------
51 // wxAuiMDIParentFrame
52 //-----------------------------------------------------------------------------
53
54 IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIParentFrame, wxFrame)
55
56 BEGIN_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
61 END_EVENT_TABLE()
62
63 wxAuiMDIParentFrame::wxAuiMDIParentFrame()
64 {
65 Init();
66 }
67
68 wxAuiMDIParentFrame::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
80 wxAuiMDIParentFrame::~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
94 bool 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
124 void wxAuiMDIParentFrame::SetArtProvider(wxAuiTabArt* provider)
125 {
126 if (m_pClientWindow)
127 {
128 m_pClientWindow->SetArtProvider(provider);
129 }
130 }
131
132 wxAuiTabArt* wxAuiMDIParentFrame::GetArtProvider()
133 {
134 if (!m_pClientWindow)
135 return NULL;
136
137 return m_pClientWindow->GetArtProvider();
138 }
139
140 wxAuiNotebook* wxAuiMDIParentFrame::GetNotebook() const
141 {
142 return static_cast<wxAuiNotebook*>(m_pClientWindow);
143 }
144
145
146
147 #if wxUSE_MENUS
148 void 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
166 void 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
179 void 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
207 bool 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
244 wxAuiMDIChildFrame *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
252 void wxAuiMDIParentFrame::SetActiveChild(wxAuiMDIChildFrame* pChildFrame)
253 {
254 wxAuiMDIClientWindow* const client = GetClientWindow();
255 if (client && client->GetActiveChild() != pChildFrame)
256 {
257 client->SetActiveChild(pChildFrame);
258 }
259 }
260
261 wxAuiMDIClientWindow *wxAuiMDIParentFrame::GetClientWindow() const
262 {
263 return m_pClientWindow;
264 }
265
266 wxAuiMDIClientWindow *wxAuiMDIParentFrame::OnCreateClient()
267 {
268 return new wxAuiMDIClientWindow( this );
269 }
270
271 void 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
283 void 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
295 void 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
306 void 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
321 void 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
333 void 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
367 void 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
397 void wxAuiMDIParentFrame::DoGetClientSize(int* width, int* height) const
398 {
399 wxFrame::DoGetClientSize(width, height);
400 }
401
402 void 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
426 IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIChildFrame, wxPanel)
427
428 BEGIN_EVENT_TABLE(wxAuiMDIChildFrame, wxPanel)
429 EVT_MENU_HIGHLIGHT_ALL(wxAuiMDIChildFrame::OnMenuHighlight)
430 EVT_ACTIVATE(wxAuiMDIChildFrame::OnActivate)
431 EVT_CLOSE(wxAuiMDIChildFrame::OnCloseWindow)
432 END_EVENT_TABLE()
433
434 wxAuiMDIChildFrame::wxAuiMDIChildFrame()
435 {
436 Init();
437 }
438
439 wxAuiMDIChildFrame::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
462 wxAuiMDIChildFrame::~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
486 bool 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
534 bool 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
563 void 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
584 wxMenuBar *wxAuiMDIChildFrame::GetMenuBar() const
585 {
586 return m_pMenuBar;
587 }
588 #endif // wxUSE_MENUS
589
590 void 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
612 wxString wxAuiMDIChildFrame::GetTitle() const
613 {
614 return m_title;
615 }
616
617 void 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
624 const wxIconBundle& wxAuiMDIChildFrame::GetIcons() const
625 {
626 return m_iconBundle;
627 }
628
629 void 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
651 const wxIcon& wxAuiMDIChildFrame::GetIcon() const
652 {
653 return m_icon;
654 }
655
656
657 void 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
678 void 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
692 void wxAuiMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
693 {
694 // do nothing
695 }
696
697 void wxAuiMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
698 {
699 Destroy();
700 }
701
702 void wxAuiMDIChildFrame::SetMDIParentFrame(wxAuiMDIParentFrame* parentFrame)
703 {
704 m_pMDIParentFrame = parentFrame;
705 }
706
707 wxAuiMDIParentFrame* wxAuiMDIChildFrame::GetMDIParentFrame() const
708 {
709 return m_pMDIParentFrame;
710 }
711
712 void 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
721 bool 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
737 void wxAuiMDIChildFrame::DoShow(bool show)
738 {
739 wxWindow::Show(show);
740 }
741
742 void 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
752 void wxAuiMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
753 {
754 m_mdiNewRect = wxRect(x, y, width, height);
755 }
756
757 void 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
772 IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIClientWindow, wxAuiNotebook)
773
774 BEGIN_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)
778 END_EVENT_TABLE()
779
780 wxAuiMDIClientWindow::wxAuiMDIClientWindow()
781 {
782 }
783
784 wxAuiMDIClientWindow::wxAuiMDIClientWindow(wxAuiMDIParentFrame* parent, long style)
785 {
786 CreateClient(parent, style);
787 }
788
789 bool 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
815 int wxAuiMDIClientWindow::SetSelection(size_t nPage)
816 {
817 return wxAuiNotebook::SetSelection(nPage);
818 }
819
820 wxAuiMDIChildFrame* 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
829 void 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
876 void 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
889 void wxAuiMDIClientWindow::OnPageChanged(wxAuiNotebookEvent& evt)
890 {
891 PageChanged(evt.GetOldSelection(), evt.GetSelection());
892 }
893
894 void 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