1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/classic/mdi.cpp
3 // Purpose: MDI classes
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
21 #include "wx/settings.h"
23 #include "wx/mac/private.h"
24 #include "wx/mac/uma.h"
26 extern wxWindowList wxModelessWindows
;
28 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
)
29 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
)
30 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
)
32 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
33 EVT_ACTIVATE(wxMDIParentFrame::OnActivate
)
34 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
)
37 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
)
38 EVT_SCROLL(wxMDIClientWindow::OnScroll
)
41 static const int IDM_WINDOWTILE
= 4001;
42 static const int IDM_WINDOWTILEHOR
= 4001;
43 static const int IDM_WINDOWCASCADE
= 4002;
44 static const int IDM_WINDOWICONS
= 4003;
45 static const int IDM_WINDOWNEXT
= 4004;
46 static const int IDM_WINDOWTILEVERT
= 4005;
47 static const int IDM_WINDOWPREV
= 4006;
49 // This range gives a maximum of 500 MDI children. Should be enough :-)
50 static const int wxFIRST_MDI_CHILD
= 4100;
51 static const int wxLAST_MDI_CHILD
= 4600;
53 // Status border dimensions
54 static const int wxTHICK_LINE_BORDER
= 3;
58 wxMDIParentFrame::wxMDIParentFrame()
60 m_clientWindow
= NULL
;
61 m_currentChild
= NULL
;
62 m_windowMenu
= (wxMenu
*) NULL
;
63 m_parentFrameActive
= TRUE
;
66 bool wxMDIParentFrame::Create(wxWindow
*parent
,
68 const wxString
& title
,
74 m_clientWindow
= NULL
;
75 m_currentChild
= NULL
;
77 // this style can be used to prevent a window from having the standard MDI
79 if ( style
& wxFRAME_NO_WINDOW_MENU
)
81 m_windowMenu
= (wxMenu
*)NULL
;
82 style
-= wxFRAME_NO_WINDOW_MENU
;
84 else // normal case: we have the window menu, so construct it
86 m_windowMenu
= new wxMenu
;
88 m_windowMenu
->Append(IDM_WINDOWCASCADE
, wxT("&Cascade"));
89 m_windowMenu
->Append(IDM_WINDOWTILEHOR
, wxT("Tile &Horizontally"));
90 m_windowMenu
->Append(IDM_WINDOWTILEVERT
, wxT("Tile &Vertically"));
91 m_windowMenu
->AppendSeparator();
92 m_windowMenu
->Append(IDM_WINDOWICONS
, wxT("&Arrange Icons"));
93 m_windowMenu
->Append(IDM_WINDOWNEXT
, wxT("&Next"));
96 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
) ;
97 m_parentFrameActive
= TRUE
;
104 wxMDIParentFrame::~wxMDIParentFrame()
107 // already delete by DestroyChildren()
109 m_frameToolBar
= NULL
;
112 m_frameStatusBar
= NULL
;
114 m_clientWindow
= NULL
;
119 m_windowMenu
= (wxMenu
*) NULL
;
122 if ( m_clientWindow
)
124 delete m_clientWindow
;
125 m_clientWindow
= NULL
;
130 void wxMDIParentFrame::SetMenuBar(wxMenuBar
*menu_bar
)
132 wxFrame::SetMenuBar( menu_bar
) ;
135 void wxMDIParentFrame::MacActivate(long timestamp
, bool activating
)
137 wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
140 if(s_macDeactivateWindow
&& s_macDeactivateWindow
->GetParent()==this)
142 wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting"));
143 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
144 wxLogDebug(wxT("done highliting child"));
145 s_macDeactivateWindow
= NULL
;
147 else if(s_macDeactivateWindow
== this)
149 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this);
150 s_macDeactivateWindow
= NULL
;
152 else // window to deactivate is NULL or is not us or one of our kids
154 // activate kid instead
156 m_currentChild
->MacActivate(timestamp
,activating
);
158 wxFrame::MacActivate(timestamp
,activating
);
163 // We were scheduled for deactivation, and now we do it.
164 if(s_macDeactivateWindow
==this)
166 s_macDeactivateWindow
= NULL
;
168 m_currentChild
->MacActivate(timestamp
,activating
);
169 wxFrame::MacActivate(timestamp
,activating
);
171 else // schedule ourselves for deactivation
173 if(s_macDeactivateWindow
)
174 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
175 wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation"));
176 s_macDeactivateWindow
= this;
181 void wxMDIParentFrame::OnActivate(wxActivateEvent
& event
)
186 // Returns the active MDI child window
187 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
189 return m_currentChild
;
192 // Create the client window class (don't Create the window,
193 // just return a new class)
194 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
196 m_clientWindow
= new wxMDIClientWindow( this );
197 return m_clientWindow
;
200 // Responds to colour changes, and passes event on to children.
201 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
205 // Propagate the event to the non-top-level children
206 wxFrame::OnSysColourChanged(event
);
210 void wxMDIParentFrame::Cascade()
215 void wxMDIParentFrame::Tile(wxOrientation
WXUNUSED(orient
))
220 void wxMDIParentFrame::ArrangeIcons()
225 void wxMDIParentFrame::ActivateNext()
230 void wxMDIParentFrame::ActivatePrevious()
237 wxMDIChildFrame::wxMDIChildFrame()
241 void wxMDIChildFrame::Init()
245 bool wxMDIChildFrame::Create(wxMDIParentFrame
*parent
,
247 const wxString
& title
,
251 const wxString
& name
)
258 m_windowId
= (int)NewControlId();
260 if (parent
) parent
->AddChild(this);
262 MacCreateRealWindow( title
, pos
, size
, MacRemoveBordersFromStyle(style
) , name
) ;
264 m_macWindowBackgroundTheme
= kThemeBrushDocumentWindowBackground
;
265 SetThemeWindowBackground( (WindowRef
) m_macWindow
, m_macWindowBackgroundTheme
, false ) ;
267 wxModelessWindows
.Append(this);
271 wxMDIChildFrame::~wxMDIChildFrame()
273 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
275 if(mdiparent
->m_currentChild
== this)
276 mdiparent
->m_currentChild
= NULL
;
278 // already delete by DestroyChildren()
280 m_frameToolBar
= NULL
;
283 m_frameStatusBar
= NULL
;
287 void wxMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
289 return wxFrame::SetMenuBar( menu_bar
) ;
292 void wxMDIChildFrame::MacActivate(long timestamp
, bool activating
)
294 wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
295 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
299 if(s_macDeactivateWindow
== m_parent
)
301 wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting"));
302 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
303 wxLogDebug(wxT("done highliting parent"));
304 s_macDeactivateWindow
= NULL
;
306 else if((mdiparent
->m_currentChild
==this) || !s_macDeactivateWindow
)
307 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
309 if(mdiparent
->m_currentChild
&& mdiparent
->m_currentChild
!=this)
310 mdiparent
->m_currentChild
->wxFrame::MacActivate(timestamp
,false);
311 mdiparent
->m_currentChild
= this;
313 if(s_macDeactivateWindow
==this)
315 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this);
316 s_macDeactivateWindow
=NULL
;
319 wxFrame::MacActivate(timestamp
, activating
);
323 // We were scheduled for deactivation, and now we do it.
324 if(s_macDeactivateWindow
==this)
326 s_macDeactivateWindow
= NULL
;
327 wxFrame::MacActivate(timestamp
,activating
);
328 if(mdiparent
->m_currentChild
==this)
329 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
331 else // schedule ourselves for deactivation
333 if(s_macDeactivateWindow
)
334 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
335 wxLogDebug(wxT("Scheduling delayed deactivation"));
336 s_macDeactivateWindow
= this;
342 void wxMDIChildFrame::Maximize()
344 wxFrame::Maximize() ;
347 void wxMDIChildFrame::Restore()
352 void wxMDIChildFrame::Activate()
356 //-----------------------------------------------------------------------------
358 //-----------------------------------------------------------------------------
360 wxMDIClientWindow::wxMDIClientWindow()
364 wxMDIClientWindow::~wxMDIClientWindow()
369 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame
*parent
, long style
)
372 m_windowId
= (int)NewControlId();
376 parent
->AddChild(this);
378 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
);
380 wxModelessWindows
.Append(this);
384 // Get size *available for subwindows* i.e. excluding menu bar.
385 void wxMDIClientWindow::DoGetClientSize(int *x
, int *y
) const
387 wxDisplaySize( x
, y
) ;
390 // Explicitly call default scroll behaviour
391 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
)