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