]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dialog.cpp
2acc18174e7886995ac5cf6114f40fc9e7dc6f4c
[wxWidgets.git] / src / mac / carbon / dialog.cpp
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
22 #include <wx/mac/uma.h>
23
24 // Lists to keep track of windows, so we can disable/enable them
25 // for modal dialogs
26 wxList wxModalDialogs;
27 wxList wxModelessWindows; // Frames and modeless dialogs
28 extern wxList wxPendingDelete;
29
30 #if !USE_SHARED_LIBRARY
31 IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
32
33 BEGIN_EVENT_TABLE(wxDialog, wxPanel)
34 EVT_SIZE(wxDialog::OnSize)
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)
41 END_EVENT_TABLE()
42
43 #endif
44
45 wxDialog::wxDialog()
46 {
47 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
48 }
49
50 bool 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;
58
59 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
60 SetName(name);
61
62 if (!parent)
63 wxTopLevelWindows.Append(this);
64
65 if (parent) parent->AddChild(this);
66
67 if ( id == -1 )
68 m_windowId = (int)NewControlId();
69 else
70 m_windowId = id;
71
72 Rect theBoundsRect;
73
74 m_x = (int)pos.x;
75 m_y = (int)pos.y;
76 if ( m_y < 50 )
77 m_y = 50 ;
78 if ( m_x < 20 )
79 m_x = 20 ;
80
81 m_width = size.x;
82 if (m_width == -1)
83 m_width = 20;
84 m_height = size.y;
85 if (m_height == -1)
86 m_height = 20;
87
88 ::SetRect(&theBoundsRect, m_x, m_y, m_x + m_width, m_y + m_height);
89 m_macWindowData = new MacWindowData() ;
90
91 WindowClass wclass = kMovableModalWindowClass ;
92 WindowAttributes attr = kWindowNoAttributes ;
93
94 if ( ( m_windowStyle & wxMINIMIZE_BOX ) || ( m_windowStyle & wxMAXIMIZE_BOX ) )
95 {
96 attr |= kWindowFullZoomAttribute ;
97 attr |= kWindowResizableAttribute ;
98 }
99
100 UMACreateNewWindow( wclass , attr , &theBoundsRect , &m_macWindowData->m_macWindow ) ;
101 wxAssociateWinWithMacWindow( m_macWindowData->m_macWindow , this ) ;
102 wxString label ;
103 if( wxApp::s_macDefaultEncodingIsPC )
104 label = wxMacMakeMacStringFromPC( title ) ;
105 else
106 label = title ;
107 UMASetWTitleC( m_macWindowData->m_macWindow , label ) ;
108 m_macWindowData->m_macWindowBackgroundTheme = kThemeBrushDialogBackgroundActive ;
109 UMACreateRootControl( m_macWindowData->m_macWindow , &m_macWindowData->m_macRootControl ) ;
110 m_macWindowData->m_macFocus = NULL ;
111 return TRUE;
112 }
113
114 void wxDialog::SetModal(bool flag)
115 {
116 if ( flag )
117 m_windowStyle |= wxDIALOG_MODAL ;
118 else
119 if ( m_windowStyle & wxDIALOG_MODAL )
120 m_windowStyle -= wxDIALOG_MODAL ;
121
122 wxModelessWindows.DeleteObject(this);
123 if (!flag)
124 wxModelessWindows.Append(this);
125 }
126
127 wxDialog::~wxDialog()
128 {
129 m_isBeingDeleted = TRUE ;
130 wxTopLevelWindows.DeleteObject(this);
131
132 m_modalShowing = FALSE;
133
134 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
135 wxModelessWindows.DeleteObject(this);
136
137 // If this is the last top-level window, exit.
138 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
139 {
140 wxTheApp->SetTopWindow(NULL);
141
142 if (wxTheApp->GetExitOnFrameDelete())
143 {
144 wxTheApp->ExitMainLoop() ;
145 }
146 }
147 }
148
149 // By default, pressing escape cancels the dialog
150 void wxDialog::OnCharHook(wxKeyEvent& event)
151 {
152 if (event.m_keyCode == WXK_ESCAPE)
153 {
154 // Behaviour changed in 2.0: we'll send a Cancel message
155 // to the dialog instead of Close.
156 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
157 cancelEvent.SetEventObject( this );
158 GetEventHandler()->ProcessEvent(cancelEvent);
159
160 return;
161 }
162 // We didn't process this event.
163 event.Skip();
164 }
165
166 void wxDialog::Iconize(bool WXUNUSED(iconize))
167 {
168 // TODO
169 }
170
171 bool wxDialog::IsIconized() const
172 {
173 // TODO
174 return FALSE;
175 }
176
177 extern bool s_macIsInModalLoop ;
178
179 bool wxDialog::Show(bool show)
180 {
181 m_isShown = show;
182
183 if (show)
184 InitDialog();
185
186 bool modal = ((GetWindowStyleFlag() & wxDIALOG_MODAL) == wxDIALOG_MODAL) ;
187
188 #if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
189 if (!modal)
190 {
191 if (show)
192 {
193 if (!wxModelessWindows.Find(this))
194 wxModelessWindows.Append(this);
195 }
196 else
197 wxModelessWindows.DeleteObject(this);
198 }
199 if (show)
200 {
201 if (!wxTopLevelWindows.Find(this))
202 wxTopLevelWindows.Append(this);
203 }
204 else
205 wxTopLevelWindows.DeleteObject(this);
206 #endif
207
208 if ( modal )
209 {
210 s_macIsInModalLoop = true ;
211 if (show)
212 {
213 if (m_modalShowing)
214 {
215 // BringWindowToTop((HWND) GetHWND());
216 return TRUE;
217 }
218
219 m_modalShowing = TRUE;
220 // if we don't do it, some window might be deleted while we have pointers
221 // to them in our disabledWindows list and the program will crash when it
222 // will try to reenable them after the modal dialog end
223 wxTheApp->DeletePendingObjects();
224
225 UMAShowWindow( m_macWindowData->m_macWindow ) ;
226 UMASelectWindow( m_macWindowData->m_macWindow ) ;
227
228 if (!wxModalDialogs.Member(this))
229 wxModalDialogs.Append(this);
230
231 while (wxModalDialogs.Member(this) )
232 {
233 wxTheApp->MacDoOneEvent() ;
234 }
235 }
236 else
237 {
238 wxModalDialogs.DeleteObject(this);
239 UMAHideWindow( m_macWindowData->m_macWindow ) ;
240 }
241 s_macIsInModalLoop = false ;
242 }
243 else // !modal
244 {
245 if (show)
246 {
247 UMAShowWindow( m_macWindowData->m_macWindow ) ;
248 UMASelectWindow( m_macWindowData->m_macWindow ) ;
249 }
250 else
251 {
252 UMAHideWindow( m_macWindowData->m_macWindow ) ;
253 }
254 }
255 return TRUE ;
256 }
257
258
259 // Replacement for Show(TRUE) for modal dialogs - returns return code
260 int wxDialog::ShowModal()
261 {
262 m_windowStyle |= wxDIALOG_MODAL;
263 Show(TRUE);
264 return GetReturnCode();
265 }
266
267 void wxDialog::EndModal(int retCode)
268 {
269 SetReturnCode(retCode);
270 // TODO modal un-showing
271 Show(FALSE);
272 }
273
274 // Standard buttons
275 void wxDialog::OnOK(wxCommandEvent& event)
276 {
277 if ( Validate() && TransferDataFromWindow() )
278 {
279 if ( IsModal() )
280 EndModal(wxID_OK);
281 else
282 {
283 SetReturnCode(wxID_OK);
284 this->Show(FALSE);
285 }
286 }
287 }
288
289 void wxDialog::OnApply(wxCommandEvent& event)
290 {
291 if (Validate())
292 TransferDataFromWindow();
293 // TODO probably need to disable the Apply button until things change again
294 }
295
296 void wxDialog::OnCancel(wxCommandEvent& event)
297 {
298 if ( IsModal() )
299 EndModal(wxID_CANCEL);
300 else
301 {
302 SetReturnCode(wxID_CANCEL);
303 this->Show(FALSE);
304 }
305 }
306
307 void wxDialog::OnCloseWindow(wxCloseEvent& event)
308 {
309 // We'll send a Cancel message by default,
310 // which may close the dialog.
311 // Check for looping if the Cancel event handler calls Close().
312
313 // Note that if a cancel button and handler aren't present in the dialog,
314 // nothing will happen when you close the dialog via the window manager, or
315 // via Close().
316 // We wouldn't want to destroy the dialog by default, since the dialog may have been
317 // created on the stack.
318 // However, this does mean that calling dialog->Close() won't delete the dialog
319 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
320 // sure to destroy the dialog.
321 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
322
323 static wxList closing;
324
325 if ( closing.Member(this) )
326 return;
327
328 closing.Append(this);
329
330 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
331 cancelEvent.SetEventObject( this );
332 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
333
334 closing.DeleteObject(this);
335 }
336
337 // Destroy the window (delayed, if a managed window)
338 bool wxDialog::Destroy()
339 {
340 if (!wxPendingDelete.Member(this))
341 wxPendingDelete.Append(this);
342 return TRUE;
343 }
344
345 void wxDialog::OnSize(wxSizeEvent& WXUNUSED(event))
346 {
347 // if we're using constraints - do use them
348 #if wxUSE_CONSTRAINTS
349 if ( GetAutoLayout() ) {
350 Layout();
351 }
352 #endif
353 }
354
355 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event)
356 {
357 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
358 Refresh();
359 }
360
361 void wxDialog::Fit()
362 {
363 wxWindow::Fit();
364 }
365