]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/mdi.cpp
slowly approaching dcscreen...
[wxWidgets.git] / src / mac / carbon / mdi.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: mdi.cpp
3// Purpose: MDI classes
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3d1a4878 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
e9576ca5
SC
13#pragma implementation "mdi.h"
14#endif
15
3d1a4878
SC
16#include "wx/wxprec.h"
17
e9576ca5
SC
18#include "wx/mdi.h"
19#include "wx/menu.h"
20#include "wx/settings.h"
70024cfb 21#include "wx/log.h"
e9576ca5 22
76a5e5d2 23#include "wx/mac/private.h"
70024cfb 24#include "wx/mac/uma.h"
76a5e5d2 25
fe08e597 26extern wxWindowList wxModelessWindows;
e9576ca5 27
2f1ae414 28#if !USE_SHARED_LIBRARY
e9576ca5
SC
29IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
30IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
31IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
32
33BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
e9576ca5
SC
34 EVT_ACTIVATE(wxMDIParentFrame::OnActivate)
35 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
36END_EVENT_TABLE()
37
38BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
39 EVT_SCROLL(wxMDIClientWindow::OnScroll)
40END_EVENT_TABLE()
41
2f1ae414 42#endif
e9576ca5 43
fd8278bf
VZ
44static const wxChar *TRACE_MDI = _T("mdi");
45
0a67a93b
SC
46static const int IDM_WINDOWTILE = 4001;
47static const int IDM_WINDOWTILEHOR = 4001;
48static const int IDM_WINDOWCASCADE = 4002;
49static const int IDM_WINDOWICONS = 4003;
50static const int IDM_WINDOWNEXT = 4004;
51static const int IDM_WINDOWTILEVERT = 4005;
4f3b37fd 52static const int IDM_WINDOWPREV = 4006;
0a67a93b
SC
53
54// This range gives a maximum of 500 MDI children. Should be enough :-)
55static const int wxFIRST_MDI_CHILD = 4100;
56static const int wxLAST_MDI_CHILD = 4600;
57
58// Status border dimensions
59static const int wxTHICK_LINE_BORDER = 3;
60
e9576ca5
SC
61// Parent frame
62
63wxMDIParentFrame::wxMDIParentFrame()
64{
0a67a93b
SC
65 m_clientWindow = NULL;
66 m_currentChild = NULL;
67 m_windowMenu = (wxMenu*) NULL;
68 m_parentFrameActive = TRUE;
e9576ca5
SC
69}
70
71bool wxMDIParentFrame::Create(wxWindow *parent,
72 wxWindowID id,
73 const wxString& title,
74 const wxPoint& pos,
75 const wxSize& size,
76 long style,
77 const wxString& name)
78{
e40298d5
JS
79 m_clientWindow = NULL;
80 m_currentChild = NULL;
81
82 // this style can be used to prevent a window from having the standard MDI
83 // "Window" menu
84 if ( style & wxFRAME_NO_WINDOW_MENU )
85 {
86 m_windowMenu = (wxMenu *)NULL;
87 style -= wxFRAME_NO_WINDOW_MENU ;
88 }
89 else // normal case: we have the window menu, so construct it
90 {
91 m_windowMenu = new wxMenu;
0a67a93b 92
e40298d5
JS
93 m_windowMenu->Append(IDM_WINDOWCASCADE, wxT("&Cascade"));
94 m_windowMenu->Append(IDM_WINDOWTILEHOR, wxT("Tile &Horizontally"));
95 m_windowMenu->Append(IDM_WINDOWTILEVERT, wxT("Tile &Vertically"));
96 m_windowMenu->AppendSeparator();
97 m_windowMenu->Append(IDM_WINDOWICONS, wxT("&Arrange Icons"));
98 m_windowMenu->Append(IDM_WINDOWNEXT, wxT("&Next"));
99 }
100
70024cfb 101 wxFrame::Create( parent , id , title , pos , size , style , name ) ;
e40298d5
JS
102 m_parentFrameActive = TRUE;
103
104 OnCreateClient();
105
e9576ca5
SC
106 return TRUE;
107}
108
109wxMDIParentFrame::~wxMDIParentFrame()
110{
0a67a93b 111 DestroyChildren();
ea3cdc4f 112 // already deleted by DestroyChildren()
0a67a93b 113 m_clientWindow = NULL ;
e40298d5 114
ea3cdc4f 115 delete m_windowMenu;
e9576ca5
SC
116}
117
0a67a93b 118
e9576ca5
SC
119void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
120{
e40298d5 121 wxFrame::SetMenuBar( menu_bar ) ;
e9576ca5
SC
122}
123
0bba37f5
DE
124void wxMDIParentFrame::GetRectForTopLevelChildren(int *x, int *y, int *w, int *h)
125{
126 if(x)
127 *x = 0;
128 if(y)
129 *y = 0;
130 wxDisplaySize(w,h);
131}
132
70024cfb 133void wxMDIParentFrame::MacActivate(long timestamp, bool activating)
e9576ca5 134{
fd8278bf 135 wxLogTrace(TRACE_MDI, wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact"));
70024cfb 136 if(activating)
e40298d5 137 {
70024cfb
DE
138 if(s_macDeactivateWindow && s_macDeactivateWindow->GetParent()==this)
139 {
fd8278bf 140 wxLogTrace(TRACE_MDI, wxT("child had been scheduled for deactivation, rehighlighting"));
70024cfb 141 UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true);
fd8278bf 142 wxLogTrace(TRACE_MDI, wxT("done highliting child"));
70024cfb
DE
143 s_macDeactivateWindow = NULL;
144 }
145 else if(s_macDeactivateWindow == this)
146 {
fd8278bf 147 wxLogTrace(TRACE_MDI, wxT("Avoided deactivation/activation of this=%p"), this);
70024cfb
DE
148 s_macDeactivateWindow = NULL;
149 }
150 else // window to deactivate is NULL or is not us or one of our kids
151 {
152 // activate kid instead
153 if(m_currentChild)
154 m_currentChild->MacActivate(timestamp,activating);
155 else
156 wxFrame::MacActivate(timestamp,activating);
157 }
e40298d5 158 }
70024cfb 159 else
e40298d5 160 {
70024cfb
DE
161 // We were scheduled for deactivation, and now we do it.
162 if(s_macDeactivateWindow==this)
e40298d5 163 {
70024cfb
DE
164 s_macDeactivateWindow = NULL;
165 if(m_currentChild)
166 m_currentChild->MacActivate(timestamp,activating);
167 wxFrame::MacActivate(timestamp,activating);
168 }
169 else // schedule ourselves for deactivation
170 {
171 if(s_macDeactivateWindow)
fd8278bf
VZ
172 wxLogTrace(TRACE_MDI, wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow);
173 wxLogTrace(TRACE_MDI, wxT("Scheduling delayed MDI Parent deactivation"));
70024cfb 174 s_macDeactivateWindow = this;
e40298d5 175 }
e40298d5 176 }
e9576ca5
SC
177}
178
70024cfb
DE
179void wxMDIParentFrame::OnActivate(wxActivateEvent& event)
180{
181 event.Skip();
182}
183
e9576ca5
SC
184// Returns the active MDI child window
185wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
186{
e40298d5 187 return m_currentChild ;
e9576ca5
SC
188}
189
190// Create the client window class (don't Create the window,
191// just return a new class)
192wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
193{
0a67a93b
SC
194 m_clientWindow = new wxMDIClientWindow( this );
195 return m_clientWindow;
e9576ca5
SC
196}
197
198// Responds to colour changes, and passes event on to children.
199void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
200{
201 // TODO
e40298d5 202
e9576ca5
SC
203 // Propagate the event to the non-top-level children
204 wxFrame::OnSysColourChanged(event);
205}
206
207// MDI operations
208void wxMDIParentFrame::Cascade()
209{
210 // TODO
211}
212
213void wxMDIParentFrame::Tile()
214{
215 // TODO
216}
217
218void wxMDIParentFrame::ArrangeIcons()
219{
220 // TODO
221}
222
223void wxMDIParentFrame::ActivateNext()
224{
225 // TODO
226}
227
228void wxMDIParentFrame::ActivatePrevious()
229{
230 // TODO
231}
232
29e92efb
VZ
233bool wxMDIParentFrame::Show( bool show )
234{
29e92efb
VZ
235 // don't really show the MDI frame unless it has any children other than
236 // MDI children as it is pretty useless in this case
507ad426 237
29e92efb
VZ
238 if ( show )
239 {
240 // TODO: check for other children
7bf8eb78
DE
241 if(!GetToolBar())
242 Move(-10000, -10000);
29e92efb
VZ
243 }
244
507ad426
SC
245 if ( !wxFrame::Show(show) )
246 return false;
247
29e92efb
VZ
248 return true;
249}
250
e9576ca5
SC
251// Child frame
252
253wxMDIChildFrame::wxMDIChildFrame()
0a67a93b
SC
254{
255 Init() ;
256}
257void wxMDIChildFrame::Init()
e9576ca5
SC
258{
259}
260
261bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
e40298d5
JS
262 wxWindowID id,
263 const wxString& title,
264 const wxPoint& pos,
265 const wxSize& size,
266 long style,
267 const wxString& name)
e9576ca5
SC
268{
269 SetName(name);
e40298d5 270
e9576ca5
SC
271 if ( id > -1 )
272 m_windowId = id;
273 else
274 m_windowId = (int)NewControlId();
e40298d5 275
e9576ca5 276 if (parent) parent->AddChild(this);
e40298d5
JS
277
278 MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
279
facd6764
SC
280 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
281
e9576ca5
SC
282 wxModelessWindows.Append(this);
283 return FALSE;
284}
285
286wxMDIChildFrame::~wxMDIChildFrame()
287{
70024cfb
DE
288 wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame);
289 wxASSERT(mdiparent);
290 if(mdiparent->m_currentChild == this)
291 mdiparent->m_currentChild = NULL;
0a67a93b 292 DestroyChildren();
e9576ca5
SC
293}
294
295void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
296{
e40298d5 297 return wxFrame::SetMenuBar( menu_bar ) ;
e9576ca5
SC
298}
299
70024cfb
DE
300void wxMDIChildFrame::MacActivate(long timestamp, bool activating)
301{
fd8278bf 302 wxLogTrace(TRACE_MDI, wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact"));
70024cfb
DE
303 wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame);
304 wxASSERT(mdiparent);
305 if(activating)
306 {
307 if(s_macDeactivateWindow == m_parent)
308 {
fd8278bf 309 wxLogTrace(TRACE_MDI, wxT("parent had been scheduled for deactivation, rehighlighting"));
70024cfb 310 UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true);
fd8278bf 311 wxLogTrace(TRACE_MDI, wxT("done highliting parent"));
70024cfb
DE
312 s_macDeactivateWindow = NULL;
313 }
314 else if((mdiparent->m_currentChild==this) || !s_macDeactivateWindow)
315 mdiparent->wxFrame::MacActivate(timestamp,activating);
316
317 if(mdiparent->m_currentChild && mdiparent->m_currentChild!=this)
318 mdiparent->m_currentChild->wxFrame::MacActivate(timestamp,false);
319 mdiparent->m_currentChild = this;
320
321 if(s_macDeactivateWindow==this)
322 {
fd8278bf 323 wxLogTrace(TRACE_MDI, wxT("Avoided deactivation/activation of this=%p"),this);
70024cfb
DE
324 s_macDeactivateWindow=NULL;
325 }
326 else
327 wxFrame::MacActivate(timestamp, activating);
328 }
329 else
330 {
331 // We were scheduled for deactivation, and now we do it.
332 if(s_macDeactivateWindow==this)
333 {
334 s_macDeactivateWindow = NULL;
335 wxFrame::MacActivate(timestamp,activating);
336 if(mdiparent->m_currentChild==this)
337 mdiparent->wxFrame::MacActivate(timestamp,activating);
338 }
339 else // schedule ourselves for deactivation
340 {
341 if(s_macDeactivateWindow)
fd8278bf
VZ
342 wxLogTrace(TRACE_MDI, wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow);
343 wxLogTrace(TRACE_MDI, wxT("Scheduling delayed deactivation"));
70024cfb
DE
344 s_macDeactivateWindow = this;
345 }
346 }
347}
348
e9576ca5
SC
349// MDI operations
350void wxMDIChildFrame::Maximize()
351{
0a67a93b 352 wxFrame::Maximize() ;
e9576ca5
SC
353}
354
355void wxMDIChildFrame::Restore()
356{
0a67a93b 357 wxFrame::Restore() ;
e9576ca5
SC
358}
359
360void wxMDIChildFrame::Activate()
361{
e9576ca5
SC
362}
363
0a67a93b
SC
364//-----------------------------------------------------------------------------
365// wxMDIClientWindow
366//-----------------------------------------------------------------------------
e9576ca5
SC
367
368wxMDIClientWindow::wxMDIClientWindow()
369{
370}
371
372wxMDIClientWindow::~wxMDIClientWindow()
373{
0a67a93b 374 DestroyChildren();
e9576ca5
SC
375}
376
377bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
378{
84be293d
KO
379 if ( !wxWindow::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style))
380 return FALSE;
e40298d5 381
0a67a93b
SC
382 wxModelessWindows.Append(this);
383 return TRUE;
e9576ca5
SC
384}
385
be7a1013
DE
386// Get size *available for subwindows* i.e. excluding menu bar.
387void wxMDIClientWindow::DoGetClientSize(int *x, int *y) const
388{
389 wxDisplaySize( x , y ) ;
390}
391
e9576ca5
SC
392// Explicitly call default scroll behaviour
393void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
394{
e9576ca5
SC
395}
396