]> git.saurik.com Git - wxWidgets.git/blame - src/mac/dialog.cpp
fatal bug in wxSplitPath fixed
[wxWidgets.git] / src / mac / dialog.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: dialog.cpp
3// Purpose: wxDialog class
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dialog.h"
14#endif
15
16#include "wx/dialog.h"
17#include "wx/utils.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/settings.h"
21
519cb848
SC
22#include <wx/mac/uma.h>
23
e9576ca5
SC
24// Lists to keep track of windows, so we can disable/enable them
25// for modal dialogs
26wxList wxModalDialogs;
27wxList wxModelessWindows; // Frames and modeless dialogs
28extern wxList wxPendingDelete;
29
e9576ca5
SC
30IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
31
32BEGIN_EVENT_TABLE(wxDialog, wxPanel)
519cb848 33 EVT_SIZE(wxDialog::OnSize)
e9576ca5
SC
34 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
35 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
36 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
37 EVT_CHAR_HOOK(wxDialog::OnCharHook)
38 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
39 EVT_CLOSE(wxDialog::OnCloseWindow)
40END_EVENT_TABLE()
41
e9576ca5
SC
42
43wxDialog::wxDialog()
44{
51abe921
SC
45 m_isShown = FALSE;
46 m_modalShowing = FALSE;
e9576ca5
SC
47 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
48}
49
50bool wxDialog::Create(wxWindow *parent, wxWindowID id,
51 const wxString& title,
52 const wxPoint& pos,
53 const wxSize& size,
54 long style,
55 const wxString& name)
56{
57 m_windowStyle = style;
51abe921
SC
58 m_isShown = FALSE;
59 m_modalShowing = FALSE;
e9576ca5 60
51abe921
SC
61#if wxUSE_TOOLTIPS
62 m_hwndToolTip = 0;
63#endif
e9576ca5
SC
64 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
65 SetName(name);
66
67 if (!parent)
68 wxTopLevelWindows.Append(this);
69
70 if (parent) parent->AddChild(this);
71
72 if ( id == -1 )
73 m_windowId = (int)NewControlId();
74 else
75 m_windowId = id;
76
519cb848
SC
77 Rect theBoundsRect;
78
79 m_x = (int)pos.x;
80 m_y = (int)pos.y;
81 if ( m_y < 50 )
82 m_y = 50 ;
83 if ( m_x < 20 )
84 m_x = 20 ;
85
86 m_width = size.x;
87 if (m_width == -1)
88 m_width = 20;
89 m_height = size.y;
90 if (m_height == -1)
91 m_height = 20;
92
93 ::SetRect(&theBoundsRect, m_x, m_y, m_x + m_width, m_y + m_height);
94 m_macWindowData = new MacWindowData() ;
95
96 WindowClass wclass = kMovableModalWindowClass ;
97 WindowAttributes attr = kWindowNoAttributes ;
98
99 if ( ( m_windowStyle & wxMINIMIZE_BOX ) || ( m_windowStyle & wxMAXIMIZE_BOX ) )
100 {
101 attr |= kWindowFullZoomAttribute ;
102 attr |= kWindowResizableAttribute ;
103 }
e9576ca5 104
519cb848
SC
105 UMACreateNewWindow( wclass , attr , &theBoundsRect , &m_macWindowData->m_macWindow ) ;
106 wxAssociateWinWithMacWindow( m_macWindowData->m_macWindow , this ) ;
107 wxString label ;
108 if( wxApp::s_macDefaultEncodingIsPC )
109 label = wxMacMakeMacStringFromPC( title ) ;
110 else
111 label = title ;
112 UMASetWTitleC( m_macWindowData->m_macWindow , label ) ;
113 m_macWindowData->m_macWindowBackgroundTheme = kThemeBrushDialogBackgroundActive ;
114 UMACreateRootControl( m_macWindowData->m_macWindow , &m_macWindowData->m_macRootControl ) ;
115 m_macWindowData->m_macFocus = NULL ;
519cb848 116 return TRUE;
e9576ca5
SC
117}
118
119void wxDialog::SetModal(bool flag)
120{
121 if ( flag )
122 m_windowStyle |= wxDIALOG_MODAL ;
123 else
124 if ( m_windowStyle & wxDIALOG_MODAL )
125 m_windowStyle -= wxDIALOG_MODAL ;
126
127 wxModelessWindows.DeleteObject(this);
128 if (!flag)
129 wxModelessWindows.Append(this);
130}
131
132wxDialog::~wxDialog()
133{
e7549107 134 m_isBeingDeleted = TRUE ;
e9576ca5
SC
135 wxTopLevelWindows.DeleteObject(this);
136
e7549107
SC
137 m_modalShowing = FALSE;
138
139 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
140 wxModelessWindows.DeleteObject(this);
e9576ca5
SC
141
142 // If this is the last top-level window, exit.
143 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
144 {
145 wxTheApp->SetTopWindow(NULL);
146
147 if (wxTheApp->GetExitOnFrameDelete())
148 {
519cb848 149 wxTheApp->ExitMainLoop() ;
e9576ca5
SC
150 }
151 }
152}
153
154// By default, pressing escape cancels the dialog
155void wxDialog::OnCharHook(wxKeyEvent& event)
156{
157 if (event.m_keyCode == WXK_ESCAPE)
158 {
159 // Behaviour changed in 2.0: we'll send a Cancel message
160 // to the dialog instead of Close.
161 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
162 cancelEvent.SetEventObject( this );
163 GetEventHandler()->ProcessEvent(cancelEvent);
164
165 return;
166 }
167 // We didn't process this event.
168 event.Skip();
169}
170
171void wxDialog::Iconize(bool WXUNUSED(iconize))
172{
51abe921 173 // mac dialogs cannot be iconized
e9576ca5
SC
174}
175
176bool wxDialog::IsIconized() const
177{
51abe921 178 // mac dialogs cannot be iconized
e9576ca5
SC
179 return FALSE;
180}
181
51abe921
SC
182void wxDialog::DoSetClientSize(int width, int height)
183{
184 wxWindow::DoSetClientSize( width , height ) ;
185}
186
187void wxDialog::GetPosition(int *x, int *y) const
188{
189 DoGetPosition( x , y ) ;
190}
191
192bool wxDialog::IsShown() const
193{
194 return m_isShown;
195}
196
197bool wxDialog::IsModal() const
198{
199 return wxModalDialogs.Find((wxDialog *)this) != 0; // const_cast
200}
201
202
519cb848 203extern bool s_macIsInModalLoop ;
e9576ca5
SC
204
205bool wxDialog::Show(bool show)
206{
e7549107 207 m_isShown = show;
e9576ca5 208
e7549107
SC
209 if (show)
210 InitDialog();
e9576ca5 211
519cb848 212 bool modal = ((GetWindowStyleFlag() & wxDIALOG_MODAL) == wxDIALOG_MODAL) ;
e9576ca5 213
e7549107
SC
214#if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
215 if (!modal)
216 {
217 if (show)
218 {
219 if (!wxModelessWindows.Find(this))
220 wxModelessWindows.Append(this);
221 }
222 else
223 wxModelessWindows.DeleteObject(this);
224 }
225 if (show)
226 {
227 if (!wxTopLevelWindows.Find(this))
228 wxTopLevelWindows.Append(this);
229 }
230 else
231 wxTopLevelWindows.DeleteObject(this);
232#endif
233
519cb848
SC
234 if ( modal )
235 {
236 s_macIsInModalLoop = true ;
e7549107
SC
237 if (show)
238 {
239 if (m_modalShowing)
240 {
241// BringWindowToTop((HWND) GetHWND());
242 return TRUE;
243 }
244
245 m_modalShowing = TRUE;
246 // if we don't do it, some window might be deleted while we have pointers
247 // to them in our disabledWindows list and the program will crash when it
248 // will try to reenable them after the modal dialog end
249 wxTheApp->DeletePendingObjects();
250
251 UMAShowWindow( m_macWindowData->m_macWindow ) ;
252 UMASelectWindow( m_macWindowData->m_macWindow ) ;
253
254 if (!wxModalDialogs.Member(this))
255 wxModalDialogs.Append(this);
256
257 while (wxModalDialogs.Member(this) )
258 {
259 wxTheApp->MacDoOneEvent() ;
260 }
519cb848
SC
261 }
262 else
263 {
e7549107 264 wxModalDialogs.DeleteObject(this);
519cb848
SC
265 UMAHideWindow( m_macWindowData->m_macWindow ) ;
266 }
267 s_macIsInModalLoop = false ;
268 }
269 else // !modal
270 {
271 if (show)
272 {
273 UMAShowWindow( m_macWindowData->m_macWindow ) ;
274 UMASelectWindow( m_macWindowData->m_macWindow ) ;
275 }
276 else
277 {
278 UMAHideWindow( m_macWindowData->m_macWindow ) ;
279 }
280 }
281 return TRUE ;
e9576ca5
SC
282}
283
51abe921
SC
284void wxDialog::SetTitle(const wxString& title)
285{
286 wxWindow::SetTitle( title ) ;
287}
288
289wxString wxDialog::GetTitle() const
290{
291 return wxWindow::GetTitle() ;
292}
293
294void wxDialog::Centre(int direction)
295{
296 int x_offset,y_offset ;
297 int display_width, display_height;
298 int width, height, x, y;
299 wxWindow *parent = GetParent();
300 if ((direction & wxCENTER_FRAME) && parent)
301 {
302 parent->GetPosition(&x_offset,&y_offset) ;
303 parent->GetSize(&display_width,&display_height) ;
304 }
305 else
306 {
307 wxDisplaySize(&display_width, &display_height);
308 x_offset = 0 ;
309 y_offset = 0 ;
310 }
311
312 GetSize(&width, &height);
313 GetPosition(&x, &y);
314
315 if (direction & wxHORIZONTAL)
316 x = (int)((display_width - width)/2);
317 if (direction & wxVERTICAL)
318 y = (int)((display_height - height)/2);
319
320 SetSize(x+x_offset, y+y_offset, width, height);
321}
519cb848 322
e9576ca5
SC
323// Replacement for Show(TRUE) for modal dialogs - returns return code
324int wxDialog::ShowModal()
325{
519cb848 326 m_windowStyle |= wxDIALOG_MODAL;
51abe921
SC
327 Show(TRUE);
328 return GetReturnCode();
e9576ca5
SC
329}
330
331void wxDialog::EndModal(int retCode)
332{
51abe921
SC
333 SetReturnCode(retCode);
334 Show(FALSE);
e9576ca5
SC
335}
336
337// Standard buttons
338void wxDialog::OnOK(wxCommandEvent& event)
339{
51abe921
SC
340 if ( Validate() && TransferDataFromWindow() )
341 {
e9576ca5
SC
342 if ( IsModal() )
343 EndModal(wxID_OK);
344 else
345 {
51abe921
SC
346 SetReturnCode(wxID_OK);
347 this->Show(FALSE);
e9576ca5 348 }
51abe921 349 }
e9576ca5
SC
350}
351
352void wxDialog::OnApply(wxCommandEvent& event)
353{
51abe921
SC
354 if (Validate())
355 TransferDataFromWindow();
356 // TODO probably need to disable the Apply button until things change again
e9576ca5
SC
357}
358
359void wxDialog::OnCancel(wxCommandEvent& event)
360{
361 if ( IsModal() )
362 EndModal(wxID_CANCEL);
363 else
364 {
365 SetReturnCode(wxID_CANCEL);
51abe921 366 this->Show(FALSE);
e9576ca5
SC
367 }
368}
369
7c74e7fe
SC
370void wxDialog::OnPaint(wxPaintEvent& event)
371{
372 // No: if you call the default procedure, it makes
373 // the following painting code not work.
374// wxWindow::OnPaint(event);
375}
376
e3065973 377void wxDialog::OnCloseWindow(wxCloseEvent& event)
e9576ca5 378{
e3065973 379 // We'll send a Cancel message by default,
e9576ca5 380 // which may close the dialog.
e3065973
JS
381 // Check for looping if the Cancel event handler calls Close().
382
383 // Note that if a cancel button and handler aren't present in the dialog,
384 // nothing will happen when you close the dialog via the window manager, or
385 // via Close().
386 // We wouldn't want to destroy the dialog by default, since the dialog may have been
387 // created on the stack.
388 // However, this does mean that calling dialog->Close() won't delete the dialog
389 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
390 // sure to destroy the dialog.
391 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
e9576ca5
SC
392
393 static wxList closing;
51abe921 394
e9576ca5 395 if ( closing.Member(this) )
e3065973 396 return;
51abe921 397
e9576ca5 398 closing.Append(this);
51abe921 399
e3065973
JS
400 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
401 cancelEvent.SetEventObject( this );
402 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
e9576ca5
SC
403
404 closing.DeleteObject(this);
e9576ca5
SC
405}
406
407// Destroy the window (delayed, if a managed window)
408bool wxDialog::Destroy()
409{
410 if (!wxPendingDelete.Member(this))
411 wxPendingDelete.Append(this);
412 return TRUE;
413}
414
519cb848
SC
415void wxDialog::OnSize(wxSizeEvent& WXUNUSED(event))
416{
417 // if we're using constraints - do use them
418 #if wxUSE_CONSTRAINTS
51abe921
SC
419 if ( GetAutoLayout() )
420 {
519cb848
SC
421 Layout();
422 }
423 #endif
424}
425
e9576ca5
SC
426void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event)
427{
428 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
429 Refresh();
430}
431
432void wxDialog::Fit()
433{
519cb848 434 wxWindow::Fit();
e9576ca5 435}
519cb848 436