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 IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxPanel
)
32 BEGIN_EVENT_TABLE(wxDialog
, wxPanel
)
33 EVT_SIZE(wxDialog::OnSize
)
34 EVT_BUTTON(wxID_OK
, wxDialog::OnOK
)
35 EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
)
36 EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
)
37 EVT_CHAR_HOOK(wxDialog::OnCharHook
)
38 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
)
39 EVT_CLOSE(wxDialog::OnCloseWindow
)
46 m_modalShowing
= FALSE
;
47 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
50 bool wxDialog::Create(wxWindow
*parent
, wxWindowID id
,
51 const wxString
& title
,
57 m_windowStyle
= style
;
59 m_modalShowing
= FALSE
;
64 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));
68 wxTopLevelWindows
.Append(this);
70 if (parent
) parent
->AddChild(this);
73 m_windowId
= (int)NewControlId();
93 ::SetRect(&theBoundsRect
, m_x
, m_y
, m_x
+ m_width
, m_y
+ m_height
);
94 m_macWindowData
= new MacWindowData() ;
96 WindowClass wclass
= kMovableModalWindowClass
;
97 WindowAttributes attr
= kWindowNoAttributes
;
99 if ( ( m_windowStyle
& wxMINIMIZE_BOX
) || ( m_windowStyle
& wxMAXIMIZE_BOX
) )
101 attr
|= kWindowFullZoomAttribute
;
102 attr
|= kWindowResizableAttribute
;
105 UMACreateNewWindow( wclass
, attr
, &theBoundsRect
, &m_macWindowData
->m_macWindow
) ;
106 wxAssociateWinWithMacWindow( m_macWindowData
->m_macWindow
, this ) ;
108 if( wxApp::s_macDefaultEncodingIsPC
)
109 label
= wxMacMakeMacStringFromPC( title
) ;
112 UMASetWTitleC( m_macWindowData
->m_macWindow
, label
) ;
113 m_macWindowData
->m_macWindowBackgroundTheme
= kThemeBrushDialogBackgroundActive
;
114 UMACreateRootControl( m_macWindowData
->m_macWindow
, &m_macWindowData
->m_macRootControl
) ;
115 m_macWindowData
->m_macFocus
= NULL
;
119 void wxDialog::SetModal(bool flag
)
122 m_windowStyle
|= wxDIALOG_MODAL
;
124 if ( m_windowStyle
& wxDIALOG_MODAL
)
125 m_windowStyle
-= wxDIALOG_MODAL
;
127 wxModelessWindows
.DeleteObject(this);
129 wxModelessWindows
.Append(this);
132 wxDialog::~wxDialog()
134 m_isBeingDeleted
= TRUE
;
135 wxTopLevelWindows
.DeleteObject(this);
137 m_modalShowing
= FALSE
;
139 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
140 wxModelessWindows
.DeleteObject(this);
142 // If this is the last top-level window, exit.
143 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
145 wxTheApp
->SetTopWindow(NULL
);
147 if (wxTheApp
->GetExitOnFrameDelete())
149 wxTheApp
->ExitMainLoop() ;
154 // By default, pressing escape cancels the dialog
155 void wxDialog::OnCharHook(wxKeyEvent
& event
)
157 if (event
.m_keyCode
== WXK_ESCAPE
)
159 // Behaviour changed in 2.0: we'll send a Cancel message
160 // to the dialog instead of Close.
161 wxCommandEvent
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
162 cancelEvent
.SetEventObject( this );
163 GetEventHandler()->ProcessEvent(cancelEvent
);
167 // We didn't process this event.
171 void wxDialog::Iconize(bool WXUNUSED(iconize
))
173 // mac dialogs cannot be iconized
176 bool wxDialog::IsIconized() const
178 // mac dialogs cannot be iconized
182 void wxDialog::DoSetClientSize(int width
, int height
)
184 wxWindow::DoSetClientSize( width
, height
) ;
187 void wxDialog::GetPosition(int *x
, int *y
) const
189 DoGetPosition( x
, y
) ;
192 bool wxDialog::IsShown() const
197 bool wxDialog::IsModal() const
199 return wxModalDialogs
.Find((wxDialog
*)this) != 0; // const_cast
203 extern bool s_macIsInModalLoop
;
205 bool wxDialog::Show(bool show
)
212 bool modal
= ((GetWindowStyleFlag() & wxDIALOG_MODAL
) == wxDIALOG_MODAL
) ;
214 #if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
219 if (!wxModelessWindows
.Find(this))
220 wxModelessWindows
.Append(this);
223 wxModelessWindows
.DeleteObject(this);
227 if (!wxTopLevelWindows
.Find(this))
228 wxTopLevelWindows
.Append(this);
231 wxTopLevelWindows
.DeleteObject(this);
236 s_macIsInModalLoop
= true ;
241 // BringWindowToTop((HWND) GetHWND());
245 m_modalShowing
= TRUE
;
246 // if we don't do it, some window might be deleted while we have pointers
247 // to them in our disabledWindows list and the program will crash when it
248 // will try to reenable them after the modal dialog end
249 wxTheApp
->DeletePendingObjects();
251 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
252 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
254 if (!wxModalDialogs
.Member(this))
255 wxModalDialogs
.Append(this);
257 while (wxModalDialogs
.Member(this) )
259 wxTheApp
->MacDoOneEvent() ;
264 wxModalDialogs
.DeleteObject(this);
265 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
267 s_macIsInModalLoop
= false ;
273 UMAShowWindow( m_macWindowData
->m_macWindow
) ;
274 UMASelectWindow( m_macWindowData
->m_macWindow
) ;
278 UMAHideWindow( m_macWindowData
->m_macWindow
) ;
284 void wxDialog::SetTitle(const wxString
& title
)
286 wxWindow::SetTitle( title
) ;
289 wxString
wxDialog::GetTitle() const
291 return wxWindow::GetTitle() ;
294 void wxDialog::Centre(int direction
)
296 int x_offset
,y_offset
;
297 int display_width
, display_height
;
298 int width
, height
, x
, y
;
299 wxWindow
*parent
= GetParent();
300 if ((direction
& wxCENTER_FRAME
) && parent
)
302 parent
->GetPosition(&x_offset
,&y_offset
) ;
303 parent
->GetSize(&display_width
,&display_height
) ;
307 wxDisplaySize(&display_width
, &display_height
);
312 GetSize(&width
, &height
);
315 if (direction
& wxHORIZONTAL
)
316 x
= (int)((display_width
- width
)/2);
317 if (direction
& wxVERTICAL
)
318 y
= (int)((display_height
- height
)/2);
320 SetSize(x
+x_offset
, y
+y_offset
, width
, height
);
323 // Replacement for Show(TRUE) for modal dialogs - returns return code
324 int wxDialog::ShowModal()
326 m_windowStyle
|= wxDIALOG_MODAL
;
328 return GetReturnCode();
331 void wxDialog::EndModal(int retCode
)
333 SetReturnCode(retCode
);
338 void wxDialog::OnOK(wxCommandEvent
& event
)
340 if ( Validate() && TransferDataFromWindow() )
346 SetReturnCode(wxID_OK
);
352 void wxDialog::OnApply(wxCommandEvent
& event
)
355 TransferDataFromWindow();
356 // TODO probably need to disable the Apply button until things change again
359 void wxDialog::OnCancel(wxCommandEvent
& event
)
362 EndModal(wxID_CANCEL
);
365 SetReturnCode(wxID_CANCEL
);
370 void wxDialog::OnPaint(wxPaintEvent
& event
)
372 // No: if you call the default procedure, it makes
373 // the following painting code not work.
374 // wxWindow::OnPaint(event);
377 void wxDialog::OnCloseWindow(wxCloseEvent
& event
)
379 // We'll send a Cancel message by default,
380 // which may close the dialog.
381 // Check for looping if the Cancel event handler calls Close().
383 // Note that if a cancel button and handler aren't present in the dialog,
384 // nothing will happen when you close the dialog via the window manager, or
386 // We wouldn't want to destroy the dialog by default, since the dialog may have been
387 // created on the stack.
388 // However, this does mean that calling dialog->Close() won't delete the dialog
389 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
390 // sure to destroy the dialog.
391 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
393 static wxList closing
;
395 if ( closing
.Member(this) )
398 closing
.Append(this);
400 wxCommandEvent
cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
);
401 cancelEvent
.SetEventObject( this );
402 GetEventHandler()->ProcessEvent(cancelEvent
); // This may close the dialog
404 closing
.DeleteObject(this);
407 // Destroy the window (delayed, if a managed window)
408 bool wxDialog::Destroy()
410 if (!wxPendingDelete
.Member(this))
411 wxPendingDelete
.Append(this);
415 void wxDialog::OnSize(wxSizeEvent
& WXUNUSED(event
))
417 // if we're using constraints - do use them
418 #if wxUSE_CONSTRAINTS
419 if ( GetAutoLayout() )
426 void wxDialog::OnSysColourChanged(wxSysColourChangedEvent
& event
)
428 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
));