1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDialog class
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dialog.h"
16 #include "wx/dialog.h"
20 #include "wx/settings.h"
22 #include <wx/mac/uma.h>
24 // Lists to keep track of windows, so we can disable/enable them
26 wxList wxModalDialogs
;
27 wxList wxModelessWindows
; // Frames and modeless dialogs
28 extern wxList wxPendingDelete
;
30 #if !USE_SHARED_LIBRARY
31 IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxPanel
)
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
)
48 m_modalShowing
= FALSE
;
49 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
52 bool wxDialog::Create(wxWindow
*parent
, wxWindowID id
,
53 const wxString
& title
,
59 m_windowStyle
= style
;
61 m_modalShowing
= FALSE
;
66 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
70 wxTopLevelWindows
.Append(this);
72 if (parent
) parent
->AddChild(this);
75 m_windowId
= (int)NewControlId();
95 ::SetRect(&theBoundsRect
, m_x
, m_y
, m_x
+ m_width
, m_y
+ m_height
);
96 m_macWindowData
= new MacWindowData() ;
98 WindowClass wclass
= kMovableModalWindowClass
;
99 WindowAttributes attr
= kWindowNoAttributes
;
101 if ( ( m_windowStyle
& wxMINIMIZE_BOX
) || ( m_windowStyle
& wxMAXIMIZE_BOX
) )
103 attr
|= kWindowFullZoomAttribute
;
104 attr
|= kWindowResizableAttribute
;
107 UMACreateNewWindow( wclass
, attr
, &theBoundsRect
, &m_macWindowData
->m_macWindow
) ;
108 wxAssociateWinWithMacWindow( m_macWindowData
->m_macWindow
, this ) ;
110 if( wxApp::s_macDefaultEncodingIsPC
)
111 label
= wxMacMakeMacStringFromPC( 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
;
121 void wxDialog::SetModal(bool flag
)
124 m_windowStyle
|= wxDIALOG_MODAL
;
126 if ( m_windowStyle
& wxDIALOG_MODAL
)
127 m_windowStyle
-= wxDIALOG_MODAL
;
129 wxModelessWindows
.DeleteObject(this);
131 wxModelessWindows
.Append(this);
134 wxDialog::~wxDialog()
136 m_isBeingDeleted
= TRUE
;
137 wxTopLevelWindows
.DeleteObject(this);
139 m_modalShowing
= FALSE
;
141 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
142 wxModelessWindows
.DeleteObject(this);
144 // If this is the last top-level window, exit.
145 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
147 wxTheApp
->SetTopWindow(NULL
);
149 if (wxTheApp
->GetExitOnFrameDelete())
151 wxTheApp
->ExitMainLoop() ;
156 // By default, pressing escape cancels the dialog
157 void wxDialog::OnCharHook(wxKeyEvent
& event
)
159 if (event
.m_keyCode
== WXK_ESCAPE
)
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
);
169 // We didn't process this event.
173 void wxDialog::Iconize(bool WXUNUSED(iconize
))
175 // mac dialogs cannot be iconized
178 bool wxDialog::IsIconized() const
180 // mac dialogs cannot be iconized
184 void wxDialog::DoSetClientSize(int width
, int height
)
186 wxWindow::DoSetClientSize( width
, height
) ;
189 void wxDialog::GetPosition(int *x
, int *y
) const
191 DoGetPosition( x
, y
) ;
194 bool wxDialog::IsShown() const
199 bool wxDialog::IsModal() const
201 return wxModalDialogs
.Find((wxDialog
*)this) != 0; // const_cast
205 extern bool s_macIsInModalLoop
;
207 bool wxDialog::Show(bool show
)
214 bool modal
= ((GetWindowStyleFlag() & wxDIALOG_MODAL
) == wxDIALOG_MODAL
) ;
216 #if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
221 if (!wxModelessWindows
.Find(this))
222 wxModelessWindows
.Append(this);
225 wxModelessWindows
.DeleteObject(this);
229 if (!wxTopLevelWindows
.Find(this))
230 wxTopLevelWindows
.Append(this);
233 wxTopLevelWindows
.DeleteObject(this);
238 s_macIsInModalLoop
= true ;
243 // BringWindowToTop((HWND) GetHWND());
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();
253 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
254 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
256 if (!wxModalDialogs
.Member(this))
257 wxModalDialogs
.Append(this);
259 while (wxModalDialogs
.Member(this) )
261 wxTheApp
->MacDoOneEvent() ;
266 wxModalDialogs
.DeleteObject(this);
267 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
269 s_macIsInModalLoop
= false ;
275 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
276 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
280 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
286 void wxDialog::SetTitle(const wxString
& title
)
288 wxWindow::SetTitle( title
) ;
291 wxString
wxDialog::GetTitle() const
293 return wxWindow::GetTitle() ;
296 void wxDialog::Centre(int direction
)
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
)
304 parent
->GetPosition(&x_offset
,&y_offset
) ;
305 parent
->GetSize(&display_width
,&display_height
) ;
309 wxDisplaySize(&display_width
, &display_height
);
314 GetSize(&width
, &height
);
317 if (direction
& wxHORIZONTAL
)
318 x
= (int)((display_width
- width
)/2);
319 if (direction
& wxVERTICAL
)
320 y
= (int)((display_height
- height
)/2);
322 SetSize(x
+x_offset
, y
+y_offset
, width
, height
);
325 // Replacement for Show(TRUE) for modal dialogs - returns return code
326 int wxDialog::ShowModal()
328 m_windowStyle
|= wxDIALOG_MODAL
;
330 return GetReturnCode();
333 void wxDialog::EndModal(int retCode
)
335 SetReturnCode(retCode
);
340 void wxDialog::OnOK(wxCommandEvent
& event
)
342 if ( Validate() && TransferDataFromWindow() )
348 SetReturnCode(wxID_OK
);
354 void wxDialog::OnApply(wxCommandEvent
& event
)
357 TransferDataFromWindow();
358 // TODO probably need to disable the Apply button until things change again
361 void wxDialog::OnCancel(wxCommandEvent
& event
)
364 EndModal(wxID_CANCEL
);
367 SetReturnCode(wxID_CANCEL
);
372 void wxDialog::OnPaint(wxPaintEvent
& event
)
374 // No: if you call the default procedure, it makes
375 // the following painting code not work.
376 // wxWindow::OnPaint(event);
379 void wxDialog::OnCloseWindow(wxCloseEvent
& event
)
381 // We'll send a Cancel message by default,
382 // which may close the dialog.
383 // Check for looping if the Cancel event handler calls Close().
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
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.
395 static wxList closing
;
397 if ( closing
.Member(this) )
400 closing
.Append(this);
402 wxCommandEvent
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
403 cancelEvent
.SetEventObject( this );
404 GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog
406 closing
.DeleteObject(this);
409 // Destroy the window (delayed, if a managed window)
410 bool wxDialog::Destroy()
412 if (!wxPendingDelete
.Member(this))
413 wxPendingDelete
.Append(this);
417 void wxDialog::OnSize(wxSizeEvent
& WXUNUSED(event
))
419 // if we're using constraints - do use them
420 #if wxUSE_CONSTRAINTS
421 if ( GetAutoLayout() )
428 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& event
)
430 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));