]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dialog.cpp
Include wx/msgdlg.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / mac / carbon / dialog.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/dialog.cpp
3 // Purpose: wxDialog class
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/dialog.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/app.h"
18 #include "wx/utils.h"
19 #include "wx/frame.h"
20 #include "wx/settings.h"
21 #endif // WX_PRECOMP
22
23 #include "wx/mac/uma.h"
24
25
26 // Lists to keep track of windows, so we can disable/enable them
27 // for modal dialogs
28 wxList wxModalDialogs;
29
30 extern wxList wxPendingDelete;
31
32 IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
33
34 BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
35 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
36 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
37 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
38
39 EVT_CHAR_HOOK(wxDialog::OnCharHook)
40
41 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
42
43 EVT_CLOSE(wxDialog::OnCloseWindow)
44 END_EVENT_TABLE()
45
46
47 void wxDialog::Init()
48 {
49 m_isModalStyle = false;
50 }
51
52 bool wxDialog::Create( wxWindow *parent,
53 wxWindowID id,
54 const wxString& title,
55 const wxPoint& pos,
56 const wxSize& size,
57 long style,
58 const wxString& name )
59 {
60 SetExtraStyle( GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
61
62 // All dialogs should really have this style...
63 style |= wxTAB_TRAVERSAL;
64
65 // ...but not these styles
66 style &= ~(wxYES | wxOK | wxNO); // | wxCANCEL
67
68 if ( !wxTopLevelWindow::Create( parent, id, title, pos, size, style, name ) )
69 return false;
70
71 #if TARGET_API_MAC_OSX
72 HIViewRef growBoxRef = 0 ;
73 OSStatus err = HIViewFindByID( HIViewGetRoot( (WindowRef)m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef );
74 if ( err == noErr && growBoxRef != 0 )
75 HIGrowBoxViewSetTransparent( growBoxRef, true ) ;
76 #endif
77
78 return true;
79 }
80
81 void wxDialog::SetModal( bool flag )
82 {
83 if ( flag )
84 {
85 m_isModalStyle = true;
86
87 wxModelessWindows.DeleteObject( this );
88
89 #if TARGET_CARBON
90 SetWindowModality( (WindowRef)MacGetWindowRef(), kWindowModalityAppModal, NULL ) ;
91 #endif
92 }
93 else
94 {
95 m_isModalStyle = false;
96
97 wxModelessWindows.Append( this );
98 }
99 }
100
101 wxDialog::~wxDialog()
102 {
103 m_isBeingDeleted = true;
104 Show(false);
105 }
106
107 // By default, pressing escape cancels the dialog; on mac command-stop does the same thing
108 void wxDialog::OnCharHook(wxKeyEvent& event)
109 {
110 if (( event.m_keyCode == WXK_ESCAPE ||
111 ( event.m_keyCode == '.' && event.MetaDown() ) )
112 && FindWindow(wxID_CANCEL) )
113 {
114 // Behaviour changed in 2.0: we'll send a Cancel message
115 // to the dialog instead of Close.
116 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
117 cancelEvent.SetEventObject( this );
118 GetEventHandler()->ProcessEvent(cancelEvent);
119
120 return;
121 }
122
123 // We didn't process this event.
124 event.Skip();
125 }
126
127 bool wxDialog::IsModal() const
128 {
129 return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
130 // return m_isModalStyle;
131 }
132
133
134 bool wxDialog::IsModalShowing() const
135 {
136 return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
137 }
138
139 bool wxDialog::Show(bool show)
140 {
141 if ( !wxDialogBase::Show(show) )
142 // nothing to do
143 return false;
144
145 if ( show )
146 // usually will result in TransferDataToWindow() being called
147 InitDialog();
148
149 if ( m_isModalStyle )
150 {
151 if ( show )
152 {
153 DoShowModal();
154 }
155 else // end of modal dialog
156 {
157 // this will cause IsModalShowing() return false and our local
158 // message loop will terminate
159 wxModalDialogs.DeleteObject(this);
160 }
161 }
162
163 return true;
164 }
165
166 #if !TARGET_CARBON
167 extern bool s_macIsInModalLoop ;
168 #endif
169
170 void wxDialog::DoShowModal()
171 {
172 wxCHECK_RET( !IsModalShowing(), wxT("DoShowModal() called twice") );
173
174 wxModalDialogs.Append(this);
175
176 SetFocus() ;
177
178 #if TARGET_CARBON
179 BeginAppModalStateForWindow( (WindowRef) MacGetWindowRef()) ;
180 #else
181 // TODO : test whether parent gets disabled
182 bool formerModal = s_macIsInModalLoop ;
183 s_macIsInModalLoop = true ;
184 #endif
185
186 while ( IsModalShowing() )
187 {
188 wxTheApp->MacDoOneEvent() ;
189 // calls process idle itself
190 }
191
192 #if TARGET_CARBON
193 EndAppModalStateForWindow( (WindowRef) MacGetWindowRef() ) ;
194 #else
195 // TODO probably reenable the parent window if any
196 s_macIsInModalLoop = formerModal ;
197 #endif
198 }
199
200
201 // Replacement for Show(true) for modal dialogs - returns return code
202 int wxDialog::ShowModal()
203 {
204 if ( !m_isModalStyle )
205 SetModal(true);
206
207 Show(true);
208
209 return GetReturnCode();
210 }
211
212 // NB: this function (surprizingly) may be called for both modal and modeless
213 // dialogs and should work for both of them
214 void wxDialog::EndModal(int retCode)
215 {
216 SetReturnCode(retCode);
217 Show(false);
218 SetModal(false);
219 }
220
221 // Standard buttons
222 void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
223 {
224 if ( Validate() && TransferDataFromWindow() )
225 EndModal(wxID_OK);
226 }
227
228 void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
229 {
230 if (Validate())
231 TransferDataFromWindow();
232
233 // TODO probably need to disable the Apply button until things change again
234 }
235
236 void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
237 {
238 EndModal(wxID_CANCEL);
239 }
240
241 void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
242 {
243 // We'll send a Cancel message by default,
244 // which may close the dialog.
245 // Check for looping if the Cancel event handler calls Close().
246
247 // Note that if a cancel button and handler aren't present in the dialog,
248 // nothing will happen when you close the dialog via the window manager, or
249 // via Close().
250 // We wouldn't want to destroy the dialog by default, since the dialog may have been
251 // created on the stack.
252 // However, this does mean that calling dialog->Close() won't delete the dialog
253 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
254 // sure to destroy the dialog.
255 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
256
257 static wxList closing;
258
259 if ( closing.Member(this) )
260 return;
261
262 closing.Append(this);
263
264 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
265 cancelEvent.SetEventObject( this );
266 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
267
268 closing.DeleteObject(this);
269 }
270
271 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
272 {
273 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
274 Refresh();
275 }