--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/generic/mdig.h
+// Purpose: Generic MDI (Multiple Document Interface) classes
+// Author: Hans Van Leemputten
+// Modified by:
+// Created: 29/07/2002
+// RCS-ID: $Id$
+// Copyright: (c) Hans Van Leemputten
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_MDIG_H_
+#define _WX_MDIG_H_
+
+#ifdef __GNUG__
+ #pragma interface "mdig.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "wx/frame.h"
+#include "wx/panel.h"
+#include "wx/notebook.h"
+
+WXDLLEXPORT_DATA(extern const wxChar*) wxFrameNameStr;
+WXDLLEXPORT_DATA(extern const wxChar*) wxStatusLineNameStr;
+
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxGenericMDIParentFrame;
+class WXDLLEXPORT wxGenericMDIClientWindow;
+class WXDLLEXPORT wxGenericMDIChildFrame;
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIParentFrame
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxGenericMDIParentFrame: public wxFrame
+{
+public:
+ wxGenericMDIParentFrame();
+ wxGenericMDIParentFrame(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+ const wxString& name = wxFrameNameStr);
+
+ ~wxGenericMDIParentFrame();
+ bool Create( wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+ const wxString& name = wxFrameNameStr );
+
+#if wxUSE_MENUS
+ wxMenu* GetWindowMenu() const { return m_pWindowMenu; };
+ void SetWindowMenu(wxMenu* pMenu);
+
+ virtual void SetMenuBar(wxMenuBar *pMenuBar);
+#endif // wxUSE_MENUS
+
+ void SetChildMenuBar(wxGenericMDIChildFrame *pChild);
+
+ virtual bool ProcessEvent(wxEvent& event);
+
+ wxGenericMDIChildFrame *GetActiveChild() const;
+ inline void SetActiveChild(wxGenericMDIChildFrame* pChildFrame);
+
+ wxGenericMDIClientWindow *GetClientWindow() const;
+ virtual wxGenericMDIClientWindow *OnCreateClient();
+
+ virtual void Cascade() { /* Has no effect */ }
+ virtual void Tile() { /* Has no effect */ }
+ virtual void ArrangeIcons() { /* Has no effect */ }
+ virtual void ActivateNext();
+ virtual void ActivatePrevious();
+
+protected:
+ wxGenericMDIClientWindow *m_pClientWindow;
+ wxGenericMDIChildFrame *m_pActiveChild;
+#if wxUSE_MENUS
+ wxMenu *m_pWindowMenu;
+ wxMenuBar *m_pMyMenuBar;
+#endif // wxUSE_MENUS
+
+protected:
+ void Init();
+
+#if wxUSE_MENUS
+ void RemoveWindowMenu(wxMenuBar *pMenuBar);
+ void AddWindowMenu(wxMenuBar *pMenuBar);
+
+ void DoHandleMenu(wxCommandEvent &event);
+#endif // wxUSE_MENUS
+
+ virtual void DoGetClientSize(int *width, int *height) const;
+
+private:
+ DECLARE_EVENT_TABLE()
+ DECLARE_DYNAMIC_CLASS(wxGenericMDIParentFrame)
+};
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIChildFrame
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxGenericMDIChildFrame: public wxPanel
+{
+public:
+ wxGenericMDIChildFrame();
+ wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr );
+
+ virtual ~wxGenericMDIChildFrame();
+ bool Create( wxGenericMDIParentFrame *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr );
+
+#if wxUSE_MENUS
+ virtual void SetMenuBar( wxMenuBar *menu_bar );
+ virtual wxMenuBar *GetMenuBar() const;
+#endif // wxUSE_MENUS
+
+ virtual void SetTitle(const wxString& title);
+ virtual wxString GetTitle();
+
+ virtual void Activate();
+
+#if wxUSE_STATUSBAR
+ // no status bars
+ virtual wxStatusBar* CreateStatusBar( int WXUNUSED(number) = 1,
+ long WXUNUSED(style) = 1,
+ wxWindowID WXUNUSED(id) = 1,
+ const wxString& WXUNUSED(name) = wxEmptyString)
+ { return (wxStatusBar*)NULL; }
+
+ virtual wxStatusBar *GetStatusBar() const { return (wxStatusBar*)NULL; }
+ virtual void SetStatusText( const wxString &WXUNUSED(text), int WXUNUSED(number)=0 ) {}
+ virtual void SetStatusWidths( int WXUNUSED(n), const int WXUNUSED(widths_field)[] ) {}
+#endif
+
+ // no size hints
+ virtual void SetSizeHints( int WXUNUSED(minW),
+ int WXUNUSED(minH),
+ int WXUNUSED(maxW) = -1,
+ int WXUNUSED(maxH) = -1,
+ int WXUNUSED(incW) = -1,
+ int WXUNUSED(incH) = -1) {}
+
+#if wxUSE_TOOLBAR
+ // no toolbar bars
+ virtual wxToolBar* CreateToolBar( long WXUNUSED(style),
+ wxWindowID WXUNUSED(id),
+ const wxString& WXUNUSED(name) )
+ { return (wxToolBar*)NULL; }
+ virtual wxToolBar *GetToolBar() const { return (wxToolBar*)NULL; }
+#endif
+
+ // no icon
+ void SetIcon( const wxIcon &icon ) { /*m_icons = wxIconBundle( icon );*/}
+ void SetIcons( const wxIconBundle &icons ) { /*m_icons = icons;*/ }
+
+ // no maximize etc
+ virtual void Maximize( bool WXUNUSED(maximize) = TRUE) { /* Has no effect */ }
+ virtual void Restore() { /* Has no effect */ }
+ virtual void Iconize(bool WXUNUSED(iconize) = TRUE) { /* Has no effect */ }
+ virtual bool IsMaximized() const { return TRUE; }
+ virtual bool IsIconized() const { return FALSE; }
+ virtual bool ShowFullScreen(bool WXUNUSED(show), long WXUNUSED(style)) { return FALSE; }
+ virtual bool IsFullScreen() const { return FALSE; }
+
+ virtual bool IsTopLevel() const { return FALSE; }
+
+ void OnMenuHighlight(wxMenuEvent& event);
+ void OnActivate(wxActivateEvent& event);
+
+ // The next 2 are copied from top level...
+ void OnCloseWindow(wxCloseEvent& event);
+ void OnSize(wxSizeEvent& event);
+
+ void SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame);
+ wxGenericMDIParentFrame* GetMDIParentFrame() const;
+
+protected:
+ wxGenericMDIParentFrame *m_pMDIParentFrame;
+ wxRect m_MDIRect;
+ wxString m_Title;
+
+#if wxUSE_MENUS
+ wxMenuBar *m_pMenuBar;
+#endif // wxUSE_MENUS
+
+protected:
+ void Init();
+
+ virtual void DoMoveWindow(int x, int y, int width, int height);
+
+ // This function needs to be called when a size change is confirmed,
+ // we needed this function to prevent any body from the outside
+ // changing the panel... it messes the UI layout when we would allow it.
+ void ApplyMDIChildFrameRect();
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxGenericMDIChildFrame)
+ DECLARE_EVENT_TABLE()
+
+ friend class wxGenericMDIClientWindow;
+};
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIClientWindow
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxGenericMDIClientWindow: public wxNotebook
+{
+public:
+ wxGenericMDIClientWindow();
+ wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style = 0 );
+ ~wxGenericMDIClientWindow();
+ virtual bool CreateClient( wxGenericMDIParentFrame *parent, long style = wxVSCROLL | wxHSCROLL );
+
+ virtual int SetSelection(int nPage);
+
+protected:
+ void PageChanged(int OldSelection, int newSelection);
+
+ void OnPageChanged(wxNotebookEvent& event);
+ void OnSize(wxSizeEvent& event);
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxGenericMDIClientWindow)
+ DECLARE_EVENT_TABLE()
+};
+
+
+/*
+ * Define normal wxMDI classes based on wxGenericMDI
+ */
+
+#ifndef wxUSE_GENERIC_MDI_AS_NATIVE
+#if defined(__WXUNIVERSAL__)
+#define wxUSE_GENERIC_MDI_AS_NATIVE 1
+#else
+#define wxUSE_GENERIC_MDI_AS_NATIVE 0
+#endif
+#endif // wxUSE_GENERIC_MDI_AS_NATIVE
+
+#if wxUSE_GENERIC_MDI_AS_NATIVE
+
+//-----------------------------------------------------------------------------
+// wxMDIParentFrame
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMDIParentFrame: public wxGenericMDIParentFrame
+{
+public:
+ wxMDIParentFrame() {}
+ wxMDIParentFrame(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+ const wxString& name = wxFrameNameStr)
+ :wxGenericMDIParentFrame(parent, id, title, pos, size, style, name)
+ {
+ }
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIChildFrame
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMDIChildFrame: public wxGenericMDIChildFrame
+{
+public:
+ wxMDIChildFrame() {}
+
+ wxMDIChildFrame( wxGenericMDIParentFrame *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr )
+ :wxGenericMDIChildFrame(parent, id, title, pos, size, style, name)
+ {
+ }
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxMDIChildFrame)
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMDIClientWindow: public wxGenericMDIClientWindow
+{
+public:
+ wxMDIClientWindow() {}
+
+ wxMDIClientWindow( wxGenericMDIParentFrame *parent, long style = 0 )
+ :wxGenericMDIClientWindow(parent, style)
+ {
+ }
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
+};
+
+#endif
+
+#endif
+ // _WX_MDIG_H_
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/generic/mdig.cpp
+// Purpose: Generic MDI (Multiple Document Interface) classes
+// Author: Hans Van Leemputten
+// Modified by:
+// Created: 29/07/2002
+// RCS-ID: $Id$
+// Copyright: (c) Hans Van Leemputten
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ===========================================================================
+// declarations
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// headers
+// ---------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "mdig.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/panel.h"
+ #include "wx/menu.h"
+#endif //WX_PRECOMP
+
+#include "wx/generic/mdig.h"
+
+enum MDI_MENU_ID
+{
+ wxWINDOWCLOSE = 4001,
+ wxWINDOWCLOSEALL,
+ wxWINDOWNEXT,
+ wxWINDOWPREV
+};
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIParentFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
+
+BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
+ EVT_MENU (-1, wxGenericMDIParentFrame::DoHandleMenu)
+END_EVENT_TABLE()
+
+wxGenericMDIParentFrame::wxGenericMDIParentFrame()
+{
+ Init();
+}
+
+wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ Init();
+
+ (void)Create(parent, id, title, pos, size, style, name);
+}
+
+wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
+{
+ // Make sure the client window is destructed before the menu bars are!
+ wxDELETE(m_pClientWindow);
+
+#if wxUSE_MENUS
+ if (m_pMyMenuBar)
+ {
+ delete m_pMyMenuBar;
+ m_pMyMenuBar = (wxMenuBar *) NULL;
+ }
+
+ RemoveWindowMenu(GetMenuBar());
+
+ if (m_pWindowMenu)
+ {
+ delete m_pWindowMenu;
+ m_pWindowMenu = (wxMenu*) NULL;
+ }
+#endif // wxUSE_MENUS
+}
+
+bool wxGenericMDIParentFrame::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ // this style can be used to prevent a window from having the standard MDI
+ // "Window" menu
+ if ( !(style & wxFRAME_NO_WINDOW_MENU) )
+ {
+#if wxUSE_MENUS
+ m_pWindowMenu = new wxMenu;
+
+ m_pWindowMenu->Append(wxWINDOWCLOSE, _T("Cl&ose"));
+ m_pWindowMenu->Append(wxWINDOWCLOSEALL, _T("Close Al&l"));
+ m_pWindowMenu->AppendSeparator();
+ m_pWindowMenu->Append(wxWINDOWNEXT, _T("&Next"));
+ m_pWindowMenu->Append(wxWINDOWPREV, _T("&Previouse"));
+#endif // wxUSE_MENUS
+ }
+
+ wxFrame::Create( parent, id, title, pos, size, style, name );
+
+ OnCreateClient();
+
+ return TRUE;
+}
+
+#if wxUSE_MENUS
+void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
+{
+ // Replace the window menu from the currently loaded menu bar.
+ wxMenuBar *pMenuBar = GetMenuBar();
+
+ if (m_pWindowMenu)
+ {
+ RemoveWindowMenu(pMenuBar);
+
+ wxDELETE(m_pWindowMenu);
+ }
+
+ if (pMenu)
+ {
+ m_pWindowMenu = pMenu;
+
+ AddWindowMenu(pMenuBar);
+ }
+}
+
+void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
+{
+ // Remove the Window menu from the old menu bar
+ RemoveWindowMenu(GetMenuBar());
+ // Add the Window menu to the new menu bar.
+ AddWindowMenu(pMenuBar);
+
+ wxFrame::SetMenuBar(pMenuBar);
+}
+#endif // wxUSE_MENUS
+
+void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
+{
+#if wxUSE_MENUS
+ if (pChild == (wxGenericMDIChildFrame *) NULL)
+ {
+ // No Child, set Our menu bar back.
+ SetMenuBar(m_pMyMenuBar);
+
+ // Make sure we know our menu bar is in use
+ m_pMyMenuBar = (wxMenuBar*) NULL;
+ }
+ else
+ {
+ if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
+ return;
+
+ // Do we need to save the current bar?
+ if (m_pMyMenuBar == NULL)
+ m_pMyMenuBar = GetMenuBar();
+
+ SetMenuBar(pChild->GetMenuBar());
+ }
+#endif // wxUSE_MENUS
+}
+
+bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
+{
+ /*
+ * Redirect events to active child first.
+ */
+
+ // Stops the same event being processed repeatedly
+ static wxEventType inEvent = wxEVT_NULL;
+ if (inEvent == event.GetEventType())
+ return FALSE;
+
+ inEvent = event.GetEventType();
+
+ // Let the active child (if any) process the event first.
+ bool res = FALSE;
+ if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
+#if 0
+ /* This is sure to not give problems... */
+ && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
+ event.GetEventType() == wxEVT_UPDATE_UI ))
+#else
+ /* This was tested on wxMSW and worked... */
+ && event.GetEventObject() != m_pClientWindow
+ && !(event.GetEventType() == wxEVT_ACTIVATE ||
+ event.GetEventType() == wxEVT_SET_FOCUS ||
+ event.GetEventType() == wxEVT_KILL_FOCUS ||
+ event.GetEventType() == wxEVT_CHILD_FOCUS ||
+ event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
+ event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS ))
+#endif
+ {
+ res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
+ }
+
+ // If the event was not handled this frame will handle it!
+ if (!res)
+ {
+ res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
+ }
+
+ inEvent = wxEVT_NULL;
+
+ return res;
+}
+
+wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
+{
+ return m_pActiveChild;
+}
+
+void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
+{
+ m_pActiveChild = pChildFrame;
+}
+
+wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
+{
+ return m_pClientWindow;
+}
+
+wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
+{
+#if wxUSE_GENERIC_MDI_AS_NATIVE
+ m_pClientWindow = new wxMDIClientWindow( this );
+#else
+ m_pClientWindow = new wxGenericMDIClientWindow( this );
+#endif
+ return m_pClientWindow;
+}
+
+void wxGenericMDIParentFrame::ActivateNext()
+{
+ if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
+ {
+ int active = m_pClientWindow->GetSelection() + 1;
+ if (active >= m_pClientWindow->GetPageCount())
+ active = 0;
+
+ m_pClientWindow->SetSelection(active);
+ }
+}
+
+void wxGenericMDIParentFrame::ActivatePrevious()
+{
+ if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
+ {
+ int active = m_pClientWindow->GetSelection() - 1;
+ if (active < 0)
+ active = m_pClientWindow->GetPageCount() - 1;
+
+ m_pClientWindow->SetSelection(active);
+ }
+}
+
+void wxGenericMDIParentFrame::Init()
+{
+ m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
+ m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
+#if wxUSE_MENUS
+ m_pWindowMenu = (wxMenu *) NULL;
+ m_pMyMenuBar = (wxMenuBar*) NULL;
+#endif // wxUSE_MENUS
+}
+
+#if wxUSE_MENUS
+void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
+{
+ if (pMenuBar && m_pWindowMenu)
+ {
+ // Remove old window menu
+ int pos = pMenuBar->FindMenu(_T("&Window"));
+ if (pos != wxNOT_FOUND)
+ {
+ wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
+ pMenuBar->Remove(pos);
+ }
+ }
+}
+
+void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
+{
+ if (pMenuBar && m_pWindowMenu)
+ {
+ int pos = pMenuBar->FindMenu(_T("Help"));
+ if (pos == wxNOT_FOUND)
+ {
+ pMenuBar->Append(m_pWindowMenu, _T("&Window"));
+ }
+ else
+ {
+ pMenuBar->Insert(pos, m_pWindowMenu, _T("&Window"));
+ }
+ }
+}
+
+void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
+{
+ switch (event.GetId())
+ {
+ case wxWINDOWCLOSE:
+ if (m_pActiveChild)
+ {
+ m_pActiveChild->Close();
+ }
+ break;
+ case wxWINDOWCLOSEALL:
+ {
+#if 0 // code is only needed if next #if is set to 0!
+ wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
+#endif
+ while (m_pActiveChild)
+ {
+ if (!m_pActiveChild->Close())
+ {
+ return; // We failed...
+ }
+ else
+ {
+#if 1 // What's best? Delayed deleting or immediate deleting?
+ delete m_pActiveChild;
+#else
+ ActivateNext();
+
+ if (pFirstActiveChild == m_pActiveChild)
+ return; // We've called Close on all items, no need to continue.
+#endif
+ }
+ }
+ }
+ break;
+ case wxWINDOWNEXT:
+ ActivateNext();
+ break;
+ case wxWINDOWPREV:
+ ActivatePrevious();
+ break;
+ default :
+ event.Skip();
+ }
+}
+#endif // wxUSE_MENUS
+
+void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
+{
+ wxFrame::DoGetClientSize( width, height );
+}
+
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIChildFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
+
+BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
+ EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
+ EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)
+
+ EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
+ EVT_SIZE(wxGenericMDIChildFrame::OnSize)
+END_EVENT_TABLE()
+
+wxGenericMDIChildFrame::wxGenericMDIChildFrame()
+{
+ Init();
+}
+
+wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
+ wxWindowID id, const wxString& title,
+ const wxPoint& WXUNUSED(pos), const wxSize& size,
+ long style, const wxString& name )
+{
+ Init();
+
+ Create( parent, id, title, wxDefaultPosition, size, style, name );
+}
+
+#include "wx/log.h"
+wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
+{
+ wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
+
+ if (pParentFrame != NULL)
+ {
+ bool bActive = FALSE;
+ if (pParentFrame->GetActiveChild() == this)
+ {
+ pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
+ pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
+ bActive = TRUE;
+ }
+
+ wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
+
+ // Remove page if still there
+ int pos;
+ for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
+ {
+ if (pClientWindow->GetPage(pos) == this)
+ {
+ if (pClientWindow->RemovePage(pos))
+ pClientWindow->Refresh();
+ break;
+ }
+ }
+
+ if (bActive)
+ {
+ // Set the new selection to the a remaining page
+ if (pClientWindow->GetPageCount() > pos)
+ {
+ pClientWindow->SetSelection(pos);
+ }
+ else
+ {
+ if (pClientWindow->GetPageCount() - 1 >= 0)
+ pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
+ }
+ }
+ }
+
+#if wxUSE_MENUS
+ wxDELETE(m_pMenuBar);
+#endif // wxUSE_MENUS
+}
+
+bool wxGenericMDIChildFrame::Create( wxGenericMDIParentFrame *parent,
+ wxWindowID id, const wxString& title,
+ const wxPoint& WXUNUSED(pos), const wxSize& size,
+ long style, const wxString& name )
+{
+ wxGenericMDIClientWindow* pClientWindow = parent->GetClientWindow();
+
+ wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), "Missing MDI client window.");
+
+ wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
+
+ SetMDIParentFrame(parent);
+
+ // This is the currently active child
+ parent->SetActiveChild(this);
+
+ m_Title = title;
+
+ pClientWindow->AddPage(this, title, TRUE);
+ ApplyMDIChildFrameRect(); // Ok confirme the size change!
+ pClientWindow->Refresh();
+
+ return TRUE;
+}
+
+#if wxUSE_MENUS
+void wxGenericMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
+{
+ wxMenuBar *pOldMenuBar = m_pMenuBar;
+ m_pMenuBar = menu_bar;
+
+ if (m_pMenuBar)
+ {
+ wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
+
+ if (pParentFrame != NULL)
+ {
+ m_pMenuBar->SetParent(pParentFrame);
+
+ if (pParentFrame->GetActiveChild() == this)
+ {
+ // Replace current menu bars
+ if (pOldMenuBar)
+ pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
+ pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) this);
+ }
+ }
+ }
+}
+
+wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
+{
+ return m_pMenuBar;
+}
+#endif // wxUSE_MENUS
+
+void wxGenericMDIChildFrame::SetTitle(const wxString& title)
+{
+ m_Title = title;
+
+ wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
+
+ if (pParentFrame != NULL)
+ {
+ wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
+
+ if (pClientWindow != NULL)
+ {
+ int pos;
+ for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
+ {
+ if (pClientWindow->GetPage(pos) == this)
+ {
+ pClientWindow->SetPageText(pos, m_Title);
+ break;
+ }
+ }
+ }
+ }
+}
+
+wxString wxGenericMDIChildFrame::GetTitle()
+{
+ return m_Title;
+}
+
+void wxGenericMDIChildFrame::Activate()
+{
+ wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
+
+ if (pParentFrame != NULL)
+ {
+ wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
+
+ if (pClientWindow != NULL)
+ {
+ int pos;
+ for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
+ {
+ if (pClientWindow->GetPage(pos) == this)
+ {
+ pClientWindow->SetSelection(pos);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
+{
+#if wxUSE_STATUSBAR
+ if ( m_pMDIParentFrame)
+ {
+ // we don't have any help text for this item,
+ // but may be the MDI frame does?
+ m_pMDIParentFrame->OnMenuHighlight(event);
+ }
+#endif // wxUSE_STATUSBAR
+}
+
+void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& event)
+{
+ // Do mothing.
+}
+
+/*** Copied from top level..! ***/
+// default resizing behaviour - if only ONE subwindow, resize to fill the
+// whole client area
+void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+ // if we're using constraints or sizers - do use them
+ if ( GetAutoLayout() )
+ {
+ Layout();
+ }
+ else
+ {
+ // do we have _exactly_ one child?
+ wxWindow *child = (wxWindow *)NULL;
+ for ( wxWindowList::Node *node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxWindow *win = node->GetData();
+
+ // exclude top level and managed windows (status bar isn't
+ // currently in the children list except under wxMac anyhow, but
+ // it makes no harm to test for it)
+ if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
+ {
+ if ( child )
+ {
+ return; // it's our second subwindow - nothing to do
+ }
+
+ child = win;
+ }
+ }
+
+ // do we have any children at all?
+ if ( child )
+ {
+ // exactly one child - set it's size to fill the whole frame
+ int clientW, clientH;
+ DoGetClientSize(&clientW, &clientH);
+
+ // for whatever reasons, wxGTK wants to have a small offset - it
+ // probably looks better with it?
+#ifdef __WXGTK__
+ static const int ofs = 1;
+#else
+ static const int ofs = 0;
+#endif
+
+ child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
+ }
+ }
+}
+
+/*** Copied from top level..! ***/
+// The default implementation for the close window event.
+void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
+{
+ Destroy();
+}
+
+void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
+{
+ m_pMDIParentFrame = parentFrame;
+}
+
+wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
+{
+ return m_pMDIParentFrame;
+}
+
+void wxGenericMDIChildFrame::Init()
+{
+ m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
+#if wxUSE_MENUS
+ m_pMenuBar = (wxMenuBar *) NULL;
+#endif // wxUSE_MENUS
+}
+
+void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
+{
+ m_MDIRect = wxRect(x, y, width, height);
+}
+
+void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
+{
+ wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
+}
+
+//-----------------------------------------------------------------------------
+// wxGenericMDIClientWindow
+//-----------------------------------------------------------------------------
+
+#define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
+
+BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
+ EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
+ EVT_SIZE(wxGenericMDIClientWindow::OnSize)
+END_EVENT_TABLE()
+
+
+wxGenericMDIClientWindow::wxGenericMDIClientWindow()
+{
+}
+
+wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
+{
+ CreateClient( parent, style );
+}
+
+wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
+{
+ DestroyChildren();
+}
+
+bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
+{
+ SetWindowStyleFlag(style);
+
+ bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0);
+ if (success)
+ {
+ /*
+ wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
+ wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
+ GetTabView()->SetTabFont(font);
+ GetTabView()->SetSelectedTabFont(selFont);
+ GetTabView()->SetTabSize(120, 18);
+ GetTabView()->SetTabSelectionHeight(20);
+ */
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+int wxGenericMDIClientWindow::SetSelection(int nPage)
+{
+ int oldSelection = wxNotebook::SetSelection(nPage);
+
+#if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
+ // will already cause this to be done!
+ // Handle the page change.
+ PageChanged(oldSelection, nPage);
+#endif
+
+ return oldSelection;
+}
+
+void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
+{
+ // Don't do to much work, only when something realy should change!
+ if (OldSelection == newSelection)
+ return;
+ // Again check if we realy need to do this...
+ if (newSelection != -1)
+ {
+ wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
+
+ if (child->GetMDIParentFrame()->GetActiveChild() == child)
+ return;
+ }
+
+ // Notify old active child that it has been deactivated
+ if (OldSelection != -1)
+ {
+ wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
+ if (oldChild)
+ {
+ wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldChild->GetId());
+ event.SetEventObject( oldChild );
+ oldChild->GetEventHandler()->ProcessEvent(event);
+ }
+ }
+
+ // Notify new active child that it has been activated
+ if (newSelection != -1)
+ {
+ wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
+ if (activeChild)
+ {
+ wxActivateEvent event(wxEVT_ACTIVATE, TRUE, activeChild->GetId());
+ event.SetEventObject( activeChild );
+ activeChild->GetEventHandler()->ProcessEvent(event);
+
+ if (activeChild->GetMDIParentFrame())
+ {
+ activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
+ activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
+ }
+ }
+ }
+}
+
+void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
+{
+ PageChanged(event.GetOldSelection(), event.GetSelection());
+
+ event.Skip();
+}
+
+void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
+{
+ wxNotebook::OnSize(event);
+
+ int pos;
+ for (pos = 0; pos < GetPageCount(); pos++)
+ {
+ ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
+ }
+}
+
+
+/*
+ * Define normal wxMDI classes based on wxGenericMDI
+ */
+
+#if wxUSE_GENERIC_MDI_AS_NATIVE
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
+
+#endif
+