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