1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/tabmdi.cpp
3 // Purpose: Generic MDI (Multiple Document Interface) classes
4 // Author: Hans Van Leemputten
5 // Modified by: Benjamin I. Williams / Kirix Corporation
8 // Copyright: (c) Hans Van Leemputten
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/aui/tabmdi.h"
36 #include "wx/settings.h"
39 #include "wx/stockitem.h"
49 //-----------------------------------------------------------------------------
50 // wxTabMDIParentFrame
51 //-----------------------------------------------------------------------------
53 IMPLEMENT_DYNAMIC_CLASS(wxTabMDIParentFrame
, wxFrame
)
55 BEGIN_EVENT_TABLE(wxTabMDIParentFrame
, wxFrame
)
57 EVT_MENU (wxID_ANY
, wxTabMDIParentFrame::DoHandleMenu
)
61 wxTabMDIParentFrame::wxTabMDIParentFrame()
66 wxTabMDIParentFrame::wxTabMDIParentFrame(wxWindow
*parent
,
68 const wxString
& title
,
75 (void)Create(parent
, id
, title
, pos
, size
, style
, name
);
78 wxTabMDIParentFrame::~wxTabMDIParentFrame()
80 // Make sure the client window is destructed before the menu bars are!
81 wxDELETE(m_pClientWindow
);
84 RemoveWindowMenu(GetMenuBar());
89 bool wxTabMDIParentFrame::Create(wxWindow
*parent
,
91 const wxString
& title
,
98 // this style can be used to prevent a window from having the standard MDI
100 if (!(style
& wxFRAME_NO_WINDOW_MENU
))
102 m_pWindowMenu
= new wxMenu
;
103 m_pWindowMenu
->Append(wxWINDOWCLOSE
, _("Cl&ose"));
104 m_pWindowMenu
->Append(wxWINDOWCLOSEALL
, _("Close All"));
105 m_pWindowMenu
->AppendSeparator();
106 m_pWindowMenu
->Append(wxWINDOWNEXT
, _("&Next"));
107 m_pWindowMenu
->Append(wxWINDOWPREV
, _("&Previous"));
109 #endif // wxUSE_MENUS
111 wxFrame::Create(parent
, id
, title
, pos
, size
, style
, name
);
117 void wxTabMDIParentFrame::SetWindowMenu(wxMenu
* pMenu
)
119 // Replace the window menu from the currently loaded menu bar.
120 wxMenuBar
*pMenuBar
= GetMenuBar();
124 RemoveWindowMenu(pMenuBar
);
125 wxDELETE(m_pWindowMenu
);
130 m_pWindowMenu
= pMenu
;
131 AddWindowMenu(pMenuBar
);
135 void wxTabMDIParentFrame::SetMenuBar(wxMenuBar
* pMenuBar
)
137 // Remove the Window menu from the old menu bar
138 RemoveWindowMenu(GetMenuBar());
140 // Add the Window menu to the new menu bar.
141 AddWindowMenu(pMenuBar
);
143 wxFrame::SetMenuBar(pMenuBar
);
144 m_pMyMenuBar
= GetMenuBar();
146 #endif // wxUSE_MENUS
148 void wxTabMDIParentFrame::SetChildMenuBar(wxTabMDIChildFrame
* pChild
)
153 // No Child, set Our menu bar back.
154 SetMenuBar(m_pMyMenuBar
);
156 // Make sure we know our menu bar is in use
157 //m_pMyMenuBar = NULL;
161 if (pChild
->GetMenuBar() == NULL
)
164 // Do we need to save the current bar?
165 if (m_pMyMenuBar
== NULL
)
166 m_pMyMenuBar
= GetMenuBar();
168 SetMenuBar(pChild
->GetMenuBar());
170 #endif // wxUSE_MENUS
173 bool wxTabMDIParentFrame::ProcessEvent(wxEvent
& event
)
175 // Stops the same event being processed repeatedly
176 static wxEventType inEvent
= wxEVT_NULL
;
177 if (inEvent
== event
.GetEventType())
180 inEvent
= event
.GetEventType();
182 // Let the active child (if any) process the event first.
184 if (m_pActiveChild
&&
185 event
.IsCommandEvent() &&
186 event
.GetEventObject() != m_pClientWindow
&&
187 !(event
.GetEventType() == wxEVT_ACTIVATE
||
188 event
.GetEventType() == wxEVT_SET_FOCUS
||
189 event
.GetEventType() == wxEVT_KILL_FOCUS
||
190 event
.GetEventType() == wxEVT_CHILD_FOCUS
||
191 event
.GetEventType() == wxEVT_COMMAND_SET_FOCUS
||
192 event
.GetEventType() == wxEVT_COMMAND_KILL_FOCUS
)
195 res
= m_pActiveChild
->GetEventHandler()->ProcessEvent(event
);
198 // If the event was not handled this frame will handle it!
201 //res = GetEventHandler()->ProcessEvent(event);
202 res
= wxEvtHandler::ProcessEvent(event
);
205 inEvent
= wxEVT_NULL
;
210 wxTabMDIChildFrame
*wxTabMDIParentFrame::GetActiveChild() const
212 return m_pActiveChild
;
215 void wxTabMDIParentFrame::SetActiveChild(wxTabMDIChildFrame
* pChildFrame
)
217 m_pActiveChild
= pChildFrame
;
220 wxTabMDIClientWindow
*wxTabMDIParentFrame::GetClientWindow() const
222 return m_pClientWindow
;
225 wxTabMDIClientWindow
*wxTabMDIParentFrame::OnCreateClient()
227 m_pClientWindow
= new wxTabMDIClientWindow( this );
228 return m_pClientWindow
;
231 void wxTabMDIParentFrame::ActivateNext()
233 if (m_pClientWindow
&& m_pClientWindow
->GetSelection() != wxNOT_FOUND
)
235 size_t active
= m_pClientWindow
->GetSelection() + 1;
236 if (active
>= m_pClientWindow
->GetPageCount())
239 m_pClientWindow
->SetSelection(active
);
243 void wxTabMDIParentFrame::ActivatePrevious()
245 if (m_pClientWindow
&& m_pClientWindow
->GetSelection() != wxNOT_FOUND
)
247 int active
= m_pClientWindow
->GetSelection() - 1;
249 active
= m_pClientWindow
->GetPageCount() - 1;
251 m_pClientWindow
->SetSelection(active
);
255 void wxTabMDIParentFrame::Init()
257 m_pClientWindow
= NULL
;
258 m_pActiveChild
= NULL
;
260 m_pWindowMenu
= NULL
;
262 #endif // wxUSE_MENUS
266 void wxTabMDIParentFrame::RemoveWindowMenu(wxMenuBar
* pMenuBar
)
268 if (pMenuBar
&& m_pWindowMenu
)
270 // Remove old window menu
271 int pos
= pMenuBar
->FindMenu(_("&Window"));
272 if (pos
!= wxNOT_FOUND
)
274 // DBG:: We're going to delete the wrong menu!!!
275 wxASSERT(m_pWindowMenu
== pMenuBar
->GetMenu(pos
));
276 pMenuBar
->Remove(pos
);
281 void wxTabMDIParentFrame::AddWindowMenu(wxMenuBar
*pMenuBar
)
283 if (pMenuBar
&& m_pWindowMenu
)
285 int pos
= pMenuBar
->FindMenu(wxGetStockLabel(wxID_HELP
,false));
286 if (pos
== wxNOT_FOUND
)
287 pMenuBar
->Append(m_pWindowMenu
, _("&Window"));
289 pMenuBar
->Insert(pos
, m_pWindowMenu
, _("&Window"));
293 void wxTabMDIParentFrame::DoHandleMenu(wxCommandEvent
& event
)
295 switch (event
.GetId())
299 m_pActiveChild
->Close();
301 case wxWINDOWCLOSEALL
:
302 while (m_pActiveChild
)
304 if (!m_pActiveChild
->Close())
310 delete m_pActiveChild
;
311 m_pActiveChild
= NULL
;
325 #endif // wxUSE_MENUS
327 void wxTabMDIParentFrame::DoGetClientSize(int* width
, int* height
) const
329 wxFrame::DoGetClientSize(width
, height
);
332 //-----------------------------------------------------------------------------
333 // wxTabMDIChildFrame
334 //-----------------------------------------------------------------------------
336 IMPLEMENT_DYNAMIC_CLASS(wxTabMDIChildFrame
, wxPanel
)
338 BEGIN_EVENT_TABLE(wxTabMDIChildFrame
, wxPanel
)
339 EVT_MENU_HIGHLIGHT_ALL(wxTabMDIChildFrame::OnMenuHighlight
)
340 EVT_ACTIVATE(wxTabMDIChildFrame::OnActivate
)
341 EVT_CLOSE(wxTabMDIChildFrame::OnCloseWindow
)
344 wxTabMDIChildFrame::wxTabMDIChildFrame()
349 wxTabMDIChildFrame::wxTabMDIChildFrame(wxTabMDIParentFrame
*parent
,
351 const wxString
& title
,
352 const wxPoint
& WXUNUSED(pos
),
355 const wxString
& name
)
358 Create(parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
361 wxTabMDIChildFrame::~wxTabMDIChildFrame()
364 wxDELETE(m_pMenuBar
);
365 #endif // wxUSE_MENUS
368 bool wxTabMDIChildFrame::Create(wxTabMDIParentFrame
* parent
,
370 const wxString
& title
,
371 const wxPoint
& WXUNUSED(pos
),
374 const wxString
& name
)
376 wxTabMDIClientWindow
* pClientWindow
= parent
->GetClientWindow();
377 wxASSERT_MSG((pClientWindow
!= (wxWindow
*) NULL
), wxT("Missing MDI client window."));
379 wxPanel::Create(pClientWindow
, id
, wxDefaultPosition
, size
, style
|wxNO_BORDER
, name
);
381 SetMDIParentFrame(parent
);
383 // this is the currently active child
384 parent
->SetActiveChild(this);
388 pClientWindow
->AddPage(this, title
, true);
389 pClientWindow
->Refresh();
394 bool wxTabMDIChildFrame::Destroy()
396 wxTabMDIParentFrame
* pParentFrame
= GetMDIParentFrame();
397 wxASSERT_MSG(pParentFrame
, wxT("Missing MDI Parent Frame"));
399 wxTabMDIClientWindow
* pClientWindow
= pParentFrame
->GetClientWindow();
400 wxASSERT_MSG(pClientWindow
, wxT("Missing MDI Client Window"));
402 bool bActive
= false;
403 if (pParentFrame
->GetActiveChild() == this)
405 pParentFrame
->SetActiveChild(NULL
);
406 pParentFrame
->SetChildMenuBar(NULL
);
410 size_t pos
, page_count
= pClientWindow
->GetPageCount();
411 for (pos
= 0; pos
< page_count
; pos
++)
413 if (pClientWindow
->GetPage(pos
) == this)
414 return pClientWindow
->DeletePage(pos
);
421 void wxTabMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
423 wxMenuBar
*pOldMenuBar
= m_pMenuBar
;
424 m_pMenuBar
= menu_bar
;
428 wxTabMDIParentFrame
* pParentFrame
= GetMDIParentFrame();
429 wxASSERT_MSG(pParentFrame
, wxT("Missing MDI Parent Frame"));
431 m_pMenuBar
->SetParent(pParentFrame
);
432 if (pParentFrame
->GetActiveChild() == this)
434 // replace current menu bars
436 pParentFrame
->SetChildMenuBar(NULL
);
437 pParentFrame
->SetChildMenuBar(this);
442 wxMenuBar
*wxTabMDIChildFrame::GetMenuBar() const
446 #endif // wxUSE_MENUS
448 void wxTabMDIChildFrame::SetTitle(const wxString
& title
)
452 wxTabMDIParentFrame
* pParentFrame
= GetMDIParentFrame();
453 wxASSERT_MSG(pParentFrame
, wxT("Missing MDI Parent Frame"));
455 wxTabMDIClientWindow
* pClientWindow
= pParentFrame
->GetClientWindow();
456 if (pClientWindow
!= NULL
)
459 for (pos
= 0; pos
< pClientWindow
->GetPageCount(); pos
++)
461 if (pClientWindow
->GetPage(pos
) == this)
463 pClientWindow
->SetPageText(pos
, m_title
);
470 wxString
wxTabMDIChildFrame::GetTitle() const
475 void wxTabMDIChildFrame::Activate()
477 wxTabMDIParentFrame
* pParentFrame
= GetMDIParentFrame();
478 wxASSERT_MSG(pParentFrame
, wxT("Missing MDI Parent Frame"));
480 wxTabMDIClientWindow
* pClientWindow
= pParentFrame
->GetClientWindow();
482 if (pClientWindow
!= NULL
)
485 for (pos
= 0; pos
< pClientWindow
->GetPageCount(); pos
++)
487 if (pClientWindow
->GetPage(pos
) == this)
489 pClientWindow
->SetSelection(pos
);
496 void wxTabMDIChildFrame::OnMenuHighlight(wxMenuEvent
& event
)
499 if (m_pMDIParentFrame
)
501 // we don't have any help text for this item,
502 // but may be the MDI frame does?
503 m_pMDIParentFrame
->OnMenuHighlight(event
);
507 #endif // wxUSE_STATUSBAR
510 void wxTabMDIChildFrame::OnActivate(wxActivateEvent
& WXUNUSED(event
))
515 void wxTabMDIChildFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
520 void wxTabMDIChildFrame::SetMDIParentFrame(wxTabMDIParentFrame
* parentFrame
)
522 m_pMDIParentFrame
= parentFrame
;
525 wxTabMDIParentFrame
* wxTabMDIChildFrame::GetMDIParentFrame() const
527 return m_pMDIParentFrame
;
530 void wxTabMDIChildFrame::Init()
532 m_pMDIParentFrame
= NULL
;
535 #endif // wxUSE_MENUS
538 bool wxTabMDIChildFrame::Show(bool WXUNUSED(show
))
544 void wxTabMDIChildFrame::DoShow(bool show
)
546 wxWindow::Show(show
);
549 void wxTabMDIChildFrame::DoSetSize(int x
, int y
, int width
, int height
, int WXUNUSED(sizeFlags
))
551 m_mdi_newrect
= wxRect(x
, y
, width
, height
);
554 void wxTabMDIChildFrame::DoMoveWindow(int x
, int y
, int width
, int height
)
556 m_mdi_newrect
= wxRect(x
, y
, width
, height
);
559 void wxTabMDIChildFrame::ApplyMDIChildFrameRect()
561 if (m_mdi_currect
!= m_mdi_newrect
)
563 wxPanel::DoMoveWindow(m_mdi_newrect
.x
, m_mdi_newrect
.y
,
564 m_mdi_newrect
.width
, m_mdi_newrect
.height
);
565 m_mdi_currect
= m_mdi_newrect
;
570 //-----------------------------------------------------------------------------
571 // wxTabMDIClientWindow
572 //-----------------------------------------------------------------------------
574 IMPLEMENT_DYNAMIC_CLASS(wxTabMDIClientWindow
, wxAuiMultiNotebook
)
576 BEGIN_EVENT_TABLE(wxTabMDIClientWindow
, wxAuiMultiNotebook
)
577 EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY
, wxTabMDIClientWindow::OnPageChanged
)
578 EVT_SIZE(wxTabMDIClientWindow::OnSize
)
581 wxTabMDIClientWindow::wxTabMDIClientWindow()
585 wxTabMDIClientWindow::wxTabMDIClientWindow(wxTabMDIParentFrame
* parent
, long style
)
587 CreateClient(parent
, style
);
590 wxTabMDIClientWindow::~wxTabMDIClientWindow()
595 bool wxTabMDIClientWindow::CreateClient(wxTabMDIParentFrame
* parent
, long style
)
597 SetWindowStyleFlag(style
);
599 if (!wxAuiMultiNotebook::Create(parent
,
608 wxColour bkcolour
= wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
);
609 SetBackgroundColour(bkcolour
);
611 m_mgr
.GetArtProvider()->SetColour(wxAUI_ART_BACKGROUND_COLOUR
, bkcolour
);
616 int wxTabMDIClientWindow::SetSelection(size_t nPage
)
618 return wxAuiMultiNotebook::SetSelection(nPage
);
621 void wxTabMDIClientWindow::PageChanged(int old_selection
, int new_selection
)
623 // don't do anything if the page doesn't actually change
624 if (old_selection
== new_selection
)
627 // don't do anything if the new page is already active
628 if (new_selection
!= -1)
630 wxTabMDIChildFrame
* child
= (wxTabMDIChildFrame
*)GetPage(new_selection
);
631 if (child
->GetMDIParentFrame()->GetActiveChild() == child
)
635 // notify old active child that it has been deactivated
636 if (old_selection
!= -1)
638 wxTabMDIChildFrame
* old_child
= (wxTabMDIChildFrame
*)GetPage(old_selection
);
639 wxASSERT_MSG(old_child
, wxT("wxTabMDIClientWindow::PageChanged - null page pointer"));
641 wxActivateEvent
event(wxEVT_ACTIVATE
, false, old_child
->GetId());
642 event
.SetEventObject(old_child
);
643 old_child
->GetEventHandler()->ProcessEvent(event
);
646 // notify new active child that it has been activated
647 if (new_selection
!= -1)
649 wxTabMDIChildFrame
* active_child
= (wxTabMDIChildFrame
*)GetPage(new_selection
);
650 wxASSERT_MSG(active_child
, wxT("wxTabMDIClientWindow::PageChanged - null page pointer"));
652 wxActivateEvent
event(wxEVT_ACTIVATE
, true, active_child
->GetId());
653 event
.SetEventObject(active_child
);
654 active_child
->GetEventHandler()->ProcessEvent(event
);
656 if (active_child
->GetMDIParentFrame())
658 active_child
->GetMDIParentFrame()->SetActiveChild(active_child
);
659 active_child
->GetMDIParentFrame()->SetChildMenuBar(active_child
);
664 void wxTabMDIClientWindow::OnPageChanged(wxAuiNotebookEvent
& evt
)
666 PageChanged(evt
.GetOldSelection(), evt
.GetSelection());
670 void wxTabMDIClientWindow::OnSize(wxSizeEvent
& evt
)
672 wxAuiMultiNotebook::OnSize(evt
);
674 for (size_t pos
= 0; pos
< GetPageCount(); pos
++)
675 ((wxTabMDIChildFrame
*)GetPage(pos
))->ApplyMDIChildFrameRect();