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