1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: MDI classes
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "mdi.h"
18 #include "wx/settings.h"
21 #include "wx/mac/private.h"
22 #include "wx/mac/uma.h"
24 extern wxWindowList wxModelessWindows
;
26 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
)
27 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
)
28 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
)
30 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
31 EVT_ACTIVATE(wxMDIParentFrame::OnActivate
)
32 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
)
35 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
)
36 EVT_SCROLL(wxMDIClientWindow::OnScroll
)
39 static const int IDM_WINDOWTILE
= 4001;
40 static const int IDM_WINDOWTILEHOR
= 4001;
41 static const int IDM_WINDOWCASCADE
= 4002;
42 static const int IDM_WINDOWICONS
= 4003;
43 static const int IDM_WINDOWNEXT
= 4004;
44 static const int IDM_WINDOWTILEVERT
= 4005;
45 static const int IDM_WINDOWPREV
= 4006;
47 // This range gives a maximum of 500 MDI children. Should be enough :-)
48 static const int wxFIRST_MDI_CHILD
= 4100;
49 static const int wxLAST_MDI_CHILD
= 4600;
51 // Status border dimensions
52 static const int wxTHICK_LINE_BORDER
= 3;
56 wxMDIParentFrame::wxMDIParentFrame()
58 m_clientWindow
= NULL
;
59 m_currentChild
= NULL
;
60 m_windowMenu
= (wxMenu
*) NULL
;
61 m_parentFrameActive
= TRUE
;
64 bool wxMDIParentFrame::Create(wxWindow
*parent
,
66 const wxString
& title
,
72 m_clientWindow
= NULL
;
73 m_currentChild
= NULL
;
75 // this style can be used to prevent a window from having the standard MDI
77 if ( style
& wxFRAME_NO_WINDOW_MENU
)
79 m_windowMenu
= (wxMenu
*)NULL
;
80 style
-= wxFRAME_NO_WINDOW_MENU
;
82 else // normal case: we have the window menu, so construct it
84 m_windowMenu
= new wxMenu
;
86 m_windowMenu
->Append(IDM_WINDOWCASCADE
, wxT("&Cascade"));
87 m_windowMenu
->Append(IDM_WINDOWTILEHOR
, wxT("Tile &Horizontally"));
88 m_windowMenu
->Append(IDM_WINDOWTILEVERT
, wxT("Tile &Vertically"));
89 m_windowMenu
->AppendSeparator();
90 m_windowMenu
->Append(IDM_WINDOWICONS
, wxT("&Arrange Icons"));
91 m_windowMenu
->Append(IDM_WINDOWNEXT
, wxT("&Next"));
94 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
) ;
95 m_parentFrameActive
= TRUE
;
102 wxMDIParentFrame::~wxMDIParentFrame()
105 // already delete by DestroyChildren()
107 m_frameToolBar
= NULL
;
110 m_frameStatusBar
= NULL
;
112 m_clientWindow
= NULL
;
117 m_windowMenu
= (wxMenu
*) NULL
;
120 if ( m_clientWindow
)
122 delete m_clientWindow
;
123 m_clientWindow
= NULL
;
128 void wxMDIParentFrame::SetMenuBar(wxMenuBar
*menu_bar
)
130 wxFrame::SetMenuBar( menu_bar
) ;
133 void wxMDIParentFrame::MacActivate(long timestamp
, bool activating
)
135 wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
138 if(s_macDeactivateWindow
&& s_macDeactivateWindow
->GetParent()==this)
140 wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting"));
141 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
142 wxLogDebug(wxT("done highliting child"));
143 s_macDeactivateWindow
= NULL
;
145 else if(s_macDeactivateWindow
== this)
147 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this);
148 s_macDeactivateWindow
= NULL
;
150 else // window to deactivate is NULL or is not us or one of our kids
152 // activate kid instead
154 m_currentChild
->MacActivate(timestamp
,activating
);
156 wxFrame::MacActivate(timestamp
,activating
);
161 // We were scheduled for deactivation, and now we do it.
162 if(s_macDeactivateWindow
==this)
164 s_macDeactivateWindow
= NULL
;
166 m_currentChild
->MacActivate(timestamp
,activating
);
167 wxFrame::MacActivate(timestamp
,activating
);
169 else // schedule ourselves for deactivation
171 if(s_macDeactivateWindow
)
172 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
173 wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation"));
174 s_macDeactivateWindow
= this;
179 void wxMDIParentFrame::OnActivate(wxActivateEvent
& event
)
184 // Returns the active MDI child window
185 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
187 return m_currentChild
;
190 // Create the client window class (don't Create the window,
191 // just return a new class)
192 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
194 m_clientWindow
= new wxMDIClientWindow( this );
195 return m_clientWindow
;
198 // Responds to colour changes, and passes event on to children.
199 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
203 // Propagate the event to the non-top-level children
204 wxFrame::OnSysColourChanged(event
);
208 void wxMDIParentFrame::Cascade()
213 void wxMDIParentFrame::Tile(wxOrientation
WXUNUSED(orient
))
218 void wxMDIParentFrame::ArrangeIcons()
223 void wxMDIParentFrame::ActivateNext()
228 void wxMDIParentFrame::ActivatePrevious()
235 wxMDIChildFrame::wxMDIChildFrame()
239 void wxMDIChildFrame::Init()
243 bool wxMDIChildFrame::Create(wxMDIParentFrame
*parent
,
245 const wxString
& title
,
249 const wxString
& name
)
256 m_windowId
= (int)NewControlId();
258 if (parent
) parent
->AddChild(this);
260 MacCreateRealWindow( title
, pos
, size
, MacRemoveBordersFromStyle(style
) , name
) ;
262 m_macWindowBackgroundTheme
= kThemeBrushDocumentWindowBackground
;
263 SetThemeWindowBackground( (WindowRef
) m_macWindow
, m_macWindowBackgroundTheme
, false ) ;
265 wxModelessWindows
.Append(this);
269 wxMDIChildFrame::~wxMDIChildFrame()
271 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
273 if(mdiparent
->m_currentChild
== this)
274 mdiparent
->m_currentChild
= NULL
;
276 // already delete by DestroyChildren()
278 m_frameToolBar
= NULL
;
281 m_frameStatusBar
= NULL
;
285 void wxMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
287 return wxFrame::SetMenuBar( menu_bar
) ;
290 void wxMDIChildFrame::MacActivate(long timestamp
, bool activating
)
292 wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
293 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
297 if(s_macDeactivateWindow
== m_parent
)
299 wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting"));
300 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
301 wxLogDebug(wxT("done highliting parent"));
302 s_macDeactivateWindow
= NULL
;
304 else if((mdiparent
->m_currentChild
==this) || !s_macDeactivateWindow
)
305 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
307 if(mdiparent
->m_currentChild
&& mdiparent
->m_currentChild
!=this)
308 mdiparent
->m_currentChild
->wxFrame::MacActivate(timestamp
,false);
309 mdiparent
->m_currentChild
= this;
311 if(s_macDeactivateWindow
==this)
313 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this);
314 s_macDeactivateWindow
=NULL
;
317 wxFrame::MacActivate(timestamp
, activating
);
321 // We were scheduled for deactivation, and now we do it.
322 if(s_macDeactivateWindow
==this)
324 s_macDeactivateWindow
= NULL
;
325 wxFrame::MacActivate(timestamp
,activating
);
326 if(mdiparent
->m_currentChild
==this)
327 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
329 else // schedule ourselves for deactivation
331 if(s_macDeactivateWindow
)
332 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
333 wxLogDebug(wxT("Scheduling delayed deactivation"));
334 s_macDeactivateWindow
= this;
340 void wxMDIChildFrame::Maximize()
342 wxFrame::Maximize() ;
345 void wxMDIChildFrame::Restore()
350 void wxMDIChildFrame::Activate()
354 //-----------------------------------------------------------------------------
356 //-----------------------------------------------------------------------------
358 wxMDIClientWindow::wxMDIClientWindow()
362 wxMDIClientWindow::~wxMDIClientWindow()
367 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame
*parent
, long style
)
370 m_windowId
= (int)NewControlId();
374 parent
->AddChild(this);
376 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
);
378 wxModelessWindows
.Append(this);
382 // Get size *available for subwindows* i.e. excluding menu bar.
383 void wxMDIClientWindow::DoGetClientSize(int *x
, int *y
) const
385 wxDisplaySize( x
, y
) ;
388 // Explicitly call default scroll behaviour
389 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
)