X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2f1ae4143271ae63a17e052a1a471d16e9cd8c44..eb69d46e705906142f5c814f31c892282f4b583c:/src/mac/carbon/mdi.cpp diff --git a/src/mac/carbon/mdi.cpp b/src/mac/carbon/mdi.cpp index 887f726504..31d91ad9c8 100644 --- a/src/mac/carbon/mdi.cpp +++ b/src/mac/carbon/mdi.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// // Name: mdi.cpp // Purpose: MDI classes -// Author: AUTHOR +// Author: Stefan Csomor // Modified by: -// Created: ??/??/98 +// Created: 1998-01-01 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -16,8 +16,12 @@ #include "wx/mdi.h" #include "wx/menu.h" #include "wx/settings.h" +#include "wx/log.h" -extern wxList wxModelessWindows; +#include "wx/mac/private.h" +#include "wx/mac/uma.h" + +extern wxWindowList wxModelessWindows; #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame) @@ -25,7 +29,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame) IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) - EVT_SIZE(wxMDIParentFrame::OnSize) EVT_ACTIVATE(wxMDIParentFrame::OnActivate) EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged) END_EVENT_TABLE() @@ -36,10 +39,29 @@ END_EVENT_TABLE() #endif +static const int IDM_WINDOWTILE = 4001; +static const int IDM_WINDOWTILEHOR = 4001; +static const int IDM_WINDOWCASCADE = 4002; +static const int IDM_WINDOWICONS = 4003; +static const int IDM_WINDOWNEXT = 4004; +static const int IDM_WINDOWTILEVERT = 4005; +static const int IDM_WINDOWPREV = 4006; + +// This range gives a maximum of 500 MDI children. Should be enough :-) +static const int wxFIRST_MDI_CHILD = 4100; +static const int wxLAST_MDI_CHILD = 4600; + +// Status border dimensions +static const int wxTHICK_LINE_BORDER = 3; + // Parent frame wxMDIParentFrame::wxMDIParentFrame() { + m_clientWindow = NULL; + m_currentChild = NULL; + m_windowMenu = (wxMenu*) NULL; + m_parentFrameActive = TRUE; } bool wxMDIParentFrame::Create(wxWindow *parent, @@ -50,80 +72,137 @@ bool wxMDIParentFrame::Create(wxWindow *parent, long style, const wxString& name) { - if (!parent) - wxTopLevelWindows.Append(this); - - SetName(name); - m_windowStyle = style; - - if (parent) parent->AddChild(this); - - if ( id > -1 ) - m_windowId = id; - else - m_windowId = (int)NewControlId(); - - // this window does not exist really - - wxModelessWindows.Append(this); - + m_clientWindow = NULL; + m_currentChild = NULL; + + // this style can be used to prevent a window from having the standard MDI + // "Window" menu + if ( style & wxFRAME_NO_WINDOW_MENU ) + { + m_windowMenu = (wxMenu *)NULL; + style -= wxFRAME_NO_WINDOW_MENU ; + } + else // normal case: we have the window menu, so construct it + { + m_windowMenu = new wxMenu; + + m_windowMenu->Append(IDM_WINDOWCASCADE, wxT("&Cascade")); + m_windowMenu->Append(IDM_WINDOWTILEHOR, wxT("Tile &Horizontally")); + m_windowMenu->Append(IDM_WINDOWTILEVERT, wxT("Tile &Vertically")); + m_windowMenu->AppendSeparator(); + m_windowMenu->Append(IDM_WINDOWICONS, wxT("&Arrange Icons")); + m_windowMenu->Append(IDM_WINDOWNEXT, wxT("&Next")); + } + + wxFrame::Create( parent , id , title , pos , size , style , name ) ; + m_parentFrameActive = TRUE; + + OnCreateClient(); + return TRUE; } wxMDIParentFrame::~wxMDIParentFrame() { + DestroyChildren(); + // already delete by DestroyChildren() +#if wxUSE_TOOLBAR + m_frameToolBar = NULL; +#endif +#if wxUSE_STATUSBAR + m_frameStatusBar = NULL; +#endif + m_clientWindow = NULL ; + + if (m_windowMenu) + { + delete m_windowMenu; + m_windowMenu = (wxMenu*) NULL; + } + + if ( m_clientWindow ) + { + delete m_clientWindow; + m_clientWindow = NULL ; + } } -// Get size *available for subwindows* i.e. excluding menu bar. -void wxMDIParentFrame::DoGetClientSize(int *x, int *y) const -{ - wxDisplaySize( x , y ) ; -} void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar) { - wxFrame::SetMenuBar( menu_bar ) ; + wxFrame::SetMenuBar( menu_bar ) ; } -void wxMDIParentFrame::OnSize(wxSizeEvent& event) +void wxMDIParentFrame::MacActivate(long timestamp, bool activating) { -#if wxUSE_CONSTRAINTS - if (GetAutoLayout()) - Layout(); -#endif - int x = 0; - int y = 0; - int width, height; - GetClientSize(&width, &height); - - if ( GetClientWindow() ) - GetClientWindow()->SetSize(x, y, width, height); + wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact")); + if(activating) + { + if(s_macDeactivateWindow && s_macDeactivateWindow->GetParent()==this) + { + wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting")); + UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true); + wxLogDebug(wxT("done highliting child")); + s_macDeactivateWindow = NULL; + } + else if(s_macDeactivateWindow == this) + { + wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this); + s_macDeactivateWindow = NULL; + } + else // window to deactivate is NULL or is not us or one of our kids + { + // activate kid instead + if(m_currentChild) + m_currentChild->MacActivate(timestamp,activating); + else + wxFrame::MacActivate(timestamp,activating); + } + } + else + { + // We were scheduled for deactivation, and now we do it. + if(s_macDeactivateWindow==this) + { + s_macDeactivateWindow = NULL; + if(m_currentChild) + m_currentChild->MacActivate(timestamp,activating); + wxFrame::MacActivate(timestamp,activating); + } + else // schedule ourselves for deactivation + { + if(s_macDeactivateWindow) + wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow); + wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation")); + s_macDeactivateWindow = this; + } + } } void wxMDIParentFrame::OnActivate(wxActivateEvent& event) { - // Do nothing + event.Skip(); } // Returns the active MDI child window wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const { - // TODO - return NULL; + return m_currentChild ; } // Create the client window class (don't Create the window, // just return a new class) wxMDIClientWindow *wxMDIParentFrame::OnCreateClient() { - return new wxMDIClientWindow ; + m_clientWindow = new wxMDIClientWindow( this ); + return m_clientWindow; } // Responds to colour changes, and passes event on to children. void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { // TODO - + // Propagate the event to the non-top-level children wxFrame::OnSysColourChanged(event); } @@ -157,29 +236,33 @@ void wxMDIParentFrame::ActivatePrevious() // Child frame wxMDIChildFrame::wxMDIChildFrame() +{ + Init() ; +} +void wxMDIChildFrame::Init() { } bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { SetName(name); - + if ( id > -1 ) m_windowId = id; else m_windowId = (int)NewControlId(); - + if (parent) parent->AddChild(this); - - MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ; - - m_macWindowData->m_macWindowBackgroundTheme = kThemeBrushDocumentWindowBackground ; + + MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ; + + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); wxModelessWindows.Append(this); return FALSE; @@ -187,42 +270,92 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, wxMDIChildFrame::~wxMDIChildFrame() { + wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame); + wxASSERT(mdiparent); + if(mdiparent->m_currentChild == this) + mdiparent->m_currentChild = NULL; + DestroyChildren(); + // already delete by DestroyChildren() +#if wxUSE_TOOLBAR + m_frameToolBar = NULL; +#endif +#if wxUSE_STATUSBAR + m_frameStatusBar = NULL; +#endif } -// Set the client size (i.e. leave the calculation of borders etc. -// to wxWindows) -void wxMDIChildFrame::SetClientSize(int width, int height) -{ - // TODO -} - -void wxMDIChildFrame::GetPosition(int *x, int *y) const +void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar) { - // TODO + return wxFrame::SetMenuBar( menu_bar ) ; } -void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar) +void wxMDIChildFrame::MacActivate(long timestamp, bool activating) { - return wxFrame::SetMenuBar( menu_bar ) ; + wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact")); + wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame); + wxASSERT(mdiparent); + if(activating) + { + if(s_macDeactivateWindow == m_parent) + { + wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting")); + UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true); + wxLogDebug(wxT("done highliting parent")); + s_macDeactivateWindow = NULL; + } + else if((mdiparent->m_currentChild==this) || !s_macDeactivateWindow) + mdiparent->wxFrame::MacActivate(timestamp,activating); + + if(mdiparent->m_currentChild && mdiparent->m_currentChild!=this) + mdiparent->m_currentChild->wxFrame::MacActivate(timestamp,false); + mdiparent->m_currentChild = this; + + if(s_macDeactivateWindow==this) + { + wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this); + s_macDeactivateWindow=NULL; + } + else + wxFrame::MacActivate(timestamp, activating); + } + else + { + // We were scheduled for deactivation, and now we do it. + if(s_macDeactivateWindow==this) + { + s_macDeactivateWindow = NULL; + wxFrame::MacActivate(timestamp,activating); + if(mdiparent->m_currentChild==this) + mdiparent->wxFrame::MacActivate(timestamp,activating); + } + else // schedule ourselves for deactivation + { + if(s_macDeactivateWindow) + wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow); + wxLogDebug(wxT("Scheduling delayed deactivation")); + s_macDeactivateWindow = this; + } + } } // MDI operations void wxMDIChildFrame::Maximize() { - // TODO + wxFrame::Maximize() ; } void wxMDIChildFrame::Restore() { - // TODO + wxFrame::Restore() ; } void wxMDIChildFrame::Activate() { - // TODO } -// Client window +//----------------------------------------------------------------------------- +// wxMDIClientWindow +//----------------------------------------------------------------------------- wxMDIClientWindow::wxMDIClientWindow() { @@ -230,14 +363,28 @@ wxMDIClientWindow::wxMDIClientWindow() wxMDIClientWindow::~wxMDIClientWindow() { + DestroyChildren(); } bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) { - // TODO create client window - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); + + m_windowId = (int)NewControlId(); + + if ( parent ) + { + parent->AddChild(this); + } + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE); + + wxModelessWindows.Append(this); + return TRUE; +} - return FALSE; +// Get size *available for subwindows* i.e. excluding menu bar. +void wxMDIClientWindow::DoGetClientSize(int *x, int *y) const +{ + wxDisplaySize( x , y ) ; } // Explicitly call default scroll behaviour