1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: MDI classes
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
14 #include "wx/settings.h"
17 #include "wx/mac/private.h"
18 #include "wx/mac/uma.h"
20 extern wxWindowList wxModelessWindows
;
22 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
)
23 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
)
24 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
)
26 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
27 EVT_ACTIVATE(wxMDIParentFrame::OnActivate
)
28 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
)
31 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
)
32 EVT_SCROLL(wxMDIClientWindow::OnScroll
)
35 static const int IDM_WINDOWTILE
= 4001;
36 static const int IDM_WINDOWTILEHOR
= 4001;
37 static const int IDM_WINDOWCASCADE
= 4002;
38 static const int IDM_WINDOWICONS
= 4003;
39 static const int IDM_WINDOWNEXT
= 4004;
40 static const int IDM_WINDOWTILEVERT
= 4005;
41 static const int IDM_WINDOWPREV
= 4006;
43 // This range gives a maximum of 500 MDI children. Should be enough :-)
44 static const int wxFIRST_MDI_CHILD
= 4100;
45 static const int wxLAST_MDI_CHILD
= 4600;
47 // Status border dimensions
48 static const int wxTHICK_LINE_BORDER
= 3;
52 wxMDIParentFrame::wxMDIParentFrame()
54 m_clientWindow
= NULL
;
55 m_currentChild
= NULL
;
56 m_windowMenu
= (wxMenu
*) NULL
;
57 m_parentFrameActive
= TRUE
;
60 bool wxMDIParentFrame::Create(wxWindow
*parent
,
62 const wxString
& title
,
68 m_clientWindow
= NULL
;
69 m_currentChild
= NULL
;
71 // this style can be used to prevent a window from having the standard MDI
73 if ( style
& wxFRAME_NO_WINDOW_MENU
)
75 m_windowMenu
= (wxMenu
*)NULL
;
76 style
-= wxFRAME_NO_WINDOW_MENU
;
78 else // normal case: we have the window menu, so construct it
80 m_windowMenu
= new wxMenu
;
82 m_windowMenu
->Append(IDM_WINDOWCASCADE
, wxT("&Cascade"));
83 m_windowMenu
->Append(IDM_WINDOWTILEHOR
, wxT("Tile &Horizontally"));
84 m_windowMenu
->Append(IDM_WINDOWTILEVERT
, wxT("Tile &Vertically"));
85 m_windowMenu
->AppendSeparator();
86 m_windowMenu
->Append(IDM_WINDOWICONS
, wxT("&Arrange Icons"));
87 m_windowMenu
->Append(IDM_WINDOWNEXT
, wxT("&Next"));
90 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
) ;
91 m_parentFrameActive
= TRUE
;
98 wxMDIParentFrame::~wxMDIParentFrame()
101 // already delete by DestroyChildren()
103 m_frameToolBar
= NULL
;
106 m_frameStatusBar
= NULL
;
108 m_clientWindow
= NULL
;
113 m_windowMenu
= (wxMenu
*) NULL
;
116 if ( m_clientWindow
)
118 delete m_clientWindow
;
119 m_clientWindow
= NULL
;
124 void wxMDIParentFrame::SetMenuBar(wxMenuBar
*menu_bar
)
126 wxFrame::SetMenuBar( menu_bar
) ;
129 void wxMDIParentFrame::MacActivate(long timestamp
, bool activating
)
131 wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
134 if(s_macDeactivateWindow
&& s_macDeactivateWindow
->GetParent()==this)
136 wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting"));
137 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
138 wxLogDebug(wxT("done highliting child"));
139 s_macDeactivateWindow
= NULL
;
141 else if(s_macDeactivateWindow
== this)
143 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this);
144 s_macDeactivateWindow
= NULL
;
146 else // window to deactivate is NULL or is not us or one of our kids
148 // activate kid instead
150 m_currentChild
->MacActivate(timestamp
,activating
);
152 wxFrame::MacActivate(timestamp
,activating
);
157 // We were scheduled for deactivation, and now we do it.
158 if(s_macDeactivateWindow
==this)
160 s_macDeactivateWindow
= NULL
;
162 m_currentChild
->MacActivate(timestamp
,activating
);
163 wxFrame::MacActivate(timestamp
,activating
);
165 else // schedule ourselves for deactivation
167 if(s_macDeactivateWindow
)
168 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
169 wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation"));
170 s_macDeactivateWindow
= this;
175 void wxMDIParentFrame::OnActivate(wxActivateEvent
& event
)
180 // Returns the active MDI child window
181 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
183 return m_currentChild
;
186 // Create the client window class (don't Create the window,
187 // just return a new class)
188 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
190 m_clientWindow
= new wxMDIClientWindow( this );
191 return m_clientWindow
;
194 // Responds to colour changes, and passes event on to children.
195 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
199 // Propagate the event to the non-top-level children
200 wxFrame::OnSysColourChanged(event
);
204 void wxMDIParentFrame::Cascade()
209 void wxMDIParentFrame::Tile(wxOrientation
WXUNUSED(orient
))
214 void wxMDIParentFrame::ArrangeIcons()
219 void wxMDIParentFrame::ActivateNext()
224 void wxMDIParentFrame::ActivatePrevious()
231 wxMDIChildFrame::wxMDIChildFrame()
235 void wxMDIChildFrame::Init()
239 bool wxMDIChildFrame::Create(wxMDIParentFrame
*parent
,
241 const wxString
& title
,
245 const wxString
& name
)
252 m_windowId
= (int)NewControlId();
254 if (parent
) parent
->AddChild(this);
256 MacCreateRealWindow( title
, pos
, size
, MacRemoveBordersFromStyle(style
) , name
) ;
258 m_macWindowBackgroundTheme
= kThemeBrushDocumentWindowBackground
;
259 SetThemeWindowBackground( (WindowRef
) m_macWindow
, m_macWindowBackgroundTheme
, false ) ;
261 wxModelessWindows
.Append(this);
265 wxMDIChildFrame::~wxMDIChildFrame()
267 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
269 if(mdiparent
->m_currentChild
== this)
270 mdiparent
->m_currentChild
= NULL
;
272 // already delete by DestroyChildren()
274 m_frameToolBar
= NULL
;
277 m_frameStatusBar
= NULL
;
281 void wxMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
283 return wxFrame::SetMenuBar( menu_bar
) ;
286 void wxMDIChildFrame::MacActivate(long timestamp
, bool activating
)
288 wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
289 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
293 if(s_macDeactivateWindow
== m_parent
)
295 wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting"));
296 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
297 wxLogDebug(wxT("done highliting parent"));
298 s_macDeactivateWindow
= NULL
;
300 else if((mdiparent
->m_currentChild
==this) || !s_macDeactivateWindow
)
301 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
303 if(mdiparent
->m_currentChild
&& mdiparent
->m_currentChild
!=this)
304 mdiparent
->m_currentChild
->wxFrame::MacActivate(timestamp
,false);
305 mdiparent
->m_currentChild
= this;
307 if(s_macDeactivateWindow
==this)
309 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this);
310 s_macDeactivateWindow
=NULL
;
313 wxFrame::MacActivate(timestamp
, activating
);
317 // We were scheduled for deactivation, and now we do it.
318 if(s_macDeactivateWindow
==this)
320 s_macDeactivateWindow
= NULL
;
321 wxFrame::MacActivate(timestamp
,activating
);
322 if(mdiparent
->m_currentChild
==this)
323 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
325 else // schedule ourselves for deactivation
327 if(s_macDeactivateWindow
)
328 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
329 wxLogDebug(wxT("Scheduling delayed deactivation"));
330 s_macDeactivateWindow
= this;
336 void wxMDIChildFrame::Maximize()
338 wxFrame::Maximize() ;
341 void wxMDIChildFrame::Restore()
346 void wxMDIChildFrame::Activate()
350 //-----------------------------------------------------------------------------
352 //-----------------------------------------------------------------------------
354 wxMDIClientWindow::wxMDIClientWindow()
358 wxMDIClientWindow::~wxMDIClientWindow()
363 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame
*parent
, long style
)
366 m_windowId
= (int)NewControlId();
370 parent
->AddChild(this);
372 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
);
374 wxModelessWindows
.Append(this);
378 // Get size *available for subwindows* i.e. excluding menu bar.
379 void wxMDIClientWindow::DoGetClientSize(int *x
, int *y
) const
381 wxDisplaySize( x
, y
) ;
384 // Explicitly call default scroll behaviour
385 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
)