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 #if !USE_SHARED_LIBRARY
27 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
)
28 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
)
29 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
)
31 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
32 EVT_ACTIVATE(wxMDIParentFrame::OnActivate
)
33 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
)
36 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
)
37 EVT_SCROLL(wxMDIClientWindow::OnScroll
)
42 static const int IDM_WINDOWTILE
= 4001;
43 static const int IDM_WINDOWTILEHOR
= 4001;
44 static const int IDM_WINDOWCASCADE
= 4002;
45 static const int IDM_WINDOWICONS
= 4003;
46 static const int IDM_WINDOWNEXT
= 4004;
47 static const int IDM_WINDOWTILEVERT
= 4005;
48 static const int IDM_WINDOWPREV
= 4006;
50 // This range gives a maximum of 500 MDI children. Should be enough :-)
51 static const int wxFIRST_MDI_CHILD
= 4100;
52 static const int wxLAST_MDI_CHILD
= 4600;
54 // Status border dimensions
55 static const int wxTHICK_LINE_BORDER
= 3;
59 wxMDIParentFrame::wxMDIParentFrame()
61 m_clientWindow
= NULL
;
62 m_currentChild
= NULL
;
63 m_windowMenu
= (wxMenu
*) NULL
;
64 m_parentFrameActive
= TRUE
;
67 bool wxMDIParentFrame::Create(wxWindow
*parent
,
69 const wxString
& title
,
75 m_clientWindow
= NULL
;
76 m_currentChild
= NULL
;
78 // this style can be used to prevent a window from having the standard MDI
80 if ( style
& wxFRAME_NO_WINDOW_MENU
)
82 m_windowMenu
= (wxMenu
*)NULL
;
83 style
-= wxFRAME_NO_WINDOW_MENU
;
85 else // normal case: we have the window menu, so construct it
87 m_windowMenu
= new wxMenu
;
89 m_windowMenu
->Append(IDM_WINDOWCASCADE
, wxT("&Cascade"));
90 m_windowMenu
->Append(IDM_WINDOWTILEHOR
, wxT("Tile &Horizontally"));
91 m_windowMenu
->Append(IDM_WINDOWTILEVERT
, wxT("Tile &Vertically"));
92 m_windowMenu
->AppendSeparator();
93 m_windowMenu
->Append(IDM_WINDOWICONS
, wxT("&Arrange Icons"));
94 m_windowMenu
->Append(IDM_WINDOWNEXT
, wxT("&Next"));
97 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
) ;
98 m_parentFrameActive
= TRUE
;
105 wxMDIParentFrame::~wxMDIParentFrame()
108 // already delete by DestroyChildren()
110 m_frameToolBar
= NULL
;
113 m_frameStatusBar
= NULL
;
115 m_clientWindow
= NULL
;
120 m_windowMenu
= (wxMenu
*) NULL
;
123 if ( m_clientWindow
)
125 delete m_clientWindow
;
126 m_clientWindow
= NULL
;
131 void wxMDIParentFrame::SetMenuBar(wxMenuBar
*menu_bar
)
133 wxFrame::SetMenuBar( menu_bar
) ;
136 void wxMDIParentFrame::MacActivate(long timestamp
, bool activating
)
138 wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
141 if(s_macDeactivateWindow
&& s_macDeactivateWindow
->GetParent()==this)
143 wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting"));
144 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
145 wxLogDebug(wxT("done highliting child"));
146 s_macDeactivateWindow
= NULL
;
148 else if(s_macDeactivateWindow
== this)
150 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this);
151 s_macDeactivateWindow
= NULL
;
153 else // window to deactivate is NULL or is not us or one of our kids
155 // activate kid instead
157 m_currentChild
->MacActivate(timestamp
,activating
);
159 wxFrame::MacActivate(timestamp
,activating
);
164 // We were scheduled for deactivation, and now we do it.
165 if(s_macDeactivateWindow
==this)
167 s_macDeactivateWindow
= NULL
;
169 m_currentChild
->MacActivate(timestamp
,activating
);
170 wxFrame::MacActivate(timestamp
,activating
);
172 else // schedule ourselves for deactivation
174 if(s_macDeactivateWindow
)
175 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
176 wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation"));
177 s_macDeactivateWindow
= this;
182 void wxMDIParentFrame::OnActivate(wxActivateEvent
& event
)
187 // Returns the active MDI child window
188 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
190 return m_currentChild
;
193 // Create the client window class (don't Create the window,
194 // just return a new class)
195 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
197 m_clientWindow
= new wxMDIClientWindow( this );
198 return m_clientWindow
;
201 // Responds to colour changes, and passes event on to children.
202 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
206 // Propagate the event to the non-top-level children
207 wxFrame::OnSysColourChanged(event
);
211 void wxMDIParentFrame::Cascade()
216 void wxMDIParentFrame::Tile()
221 void wxMDIParentFrame::ArrangeIcons()
226 void wxMDIParentFrame::ActivateNext()
231 void wxMDIParentFrame::ActivatePrevious()
236 bool wxMDIParentFrame::Show( bool show
)
238 if ( !wxFrame::Show(show
) )
241 // don't really show the MDI frame unless it has any children other than
242 // MDI children as it is pretty useless in this case
245 // TODO: check for other children
246 Move(-10000, -10000);
254 wxMDIChildFrame::wxMDIChildFrame()
258 void wxMDIChildFrame::Init()
262 bool wxMDIChildFrame::Create(wxMDIParentFrame
*parent
,
264 const wxString
& title
,
268 const wxString
& name
)
275 m_windowId
= (int)NewControlId();
277 if (parent
) parent
->AddChild(this);
279 MacCreateRealWindow( title
, pos
, size
, MacRemoveBordersFromStyle(style
) , name
) ;
281 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
));
283 wxModelessWindows
.Append(this);
287 wxMDIChildFrame::~wxMDIChildFrame()
289 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
291 if(mdiparent
->m_currentChild
== this)
292 mdiparent
->m_currentChild
= NULL
;
294 // already delete by DestroyChildren()
296 m_frameToolBar
= NULL
;
299 m_frameStatusBar
= NULL
;
303 void wxMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
305 return wxFrame::SetMenuBar( menu_bar
) ;
308 void wxMDIChildFrame::MacActivate(long timestamp
, bool activating
)
310 wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp
,activating
?wxT("ACTIV"):wxT("deact"));
311 wxMDIParentFrame
*mdiparent
= wxDynamicCast(m_parent
, wxMDIParentFrame
);
315 if(s_macDeactivateWindow
== m_parent
)
317 wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting"));
318 UMAHighlightAndActivateWindow((WindowRef
)s_macDeactivateWindow
->MacGetWindowRef(), true);
319 wxLogDebug(wxT("done highliting parent"));
320 s_macDeactivateWindow
= NULL
;
322 else if((mdiparent
->m_currentChild
==this) || !s_macDeactivateWindow
)
323 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
325 if(mdiparent
->m_currentChild
&& mdiparent
->m_currentChild
!=this)
326 mdiparent
->m_currentChild
->wxFrame::MacActivate(timestamp
,false);
327 mdiparent
->m_currentChild
= this;
329 if(s_macDeactivateWindow
==this)
331 wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this);
332 s_macDeactivateWindow
=NULL
;
335 wxFrame::MacActivate(timestamp
, activating
);
339 // We were scheduled for deactivation, and now we do it.
340 if(s_macDeactivateWindow
==this)
342 s_macDeactivateWindow
= NULL
;
343 wxFrame::MacActivate(timestamp
,activating
);
344 if(mdiparent
->m_currentChild
==this)
345 mdiparent
->wxFrame::MacActivate(timestamp
,activating
);
347 else // schedule ourselves for deactivation
349 if(s_macDeactivateWindow
)
350 wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow
);
351 wxLogDebug(wxT("Scheduling delayed deactivation"));
352 s_macDeactivateWindow
= this;
358 void wxMDIChildFrame::Maximize()
360 wxFrame::Maximize() ;
363 void wxMDIChildFrame::Restore()
368 void wxMDIChildFrame::Activate()
372 //-----------------------------------------------------------------------------
374 //-----------------------------------------------------------------------------
376 wxMDIClientWindow::wxMDIClientWindow()
380 wxMDIClientWindow::~wxMDIClientWindow()
385 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame
*parent
, long style
)
387 if ( !wxWindow::Create(parent
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, style
))
390 wxModelessWindows
.Append(this);
394 // Get size *available for subwindows* i.e. excluding menu bar.
395 void wxMDIClientWindow::DoGetClientSize(int *x
, int *y
) const
397 wxDisplaySize( x
, y
) ;
400 // Explicitly call default scroll behaviour
401 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
)