]> git.saurik.com Git - wxWidgets.git/blame - src/os2/dialog.cpp
attempts at making modal dialogs without parent work - failed
[wxWidgets.git] / src / os2 / dialog.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: dialog.cpp
3// Purpose: wxDialog class
fb46a9a6 4// Author: David Webster
0e320a79 5// Modified by:
fb46a9a6 6// Created: 10/14/99
0e320a79 7// RCS-ID: $Id$
fb46a9a6
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
27476f73
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
27476f73 15#ifndef WX_PRECOMP
0e320a79
DW
16#include "wx/dialog.h"
17#include "wx/utils.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/settings.h"
27476f73
DW
21#include "wx/intl.h"
22#include "wx/log.h"
23#endif
24
25#include "wx/os2/private.h"
26#include "wx/log.h"
27
27476f73
DW
28#define wxDIALOG_DEFAULT_X 300
29#define wxDIALOG_DEFAULT_Y 300
0e320a79
DW
30
31// Lists to keep track of windows, so we can disable/enable them
32// for modal dialogs
27476f73
DW
33wxWindowList wxModalDialogs;
34wxWindowList wxModelessWindows; // Frames and modeless dialogs
35extern wxList WXDLLEXPORT wxPendingDelete;
0e320a79 36
27476f73
DW
37 IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
38
39 BEGIN_EVENT_TABLE(wxDialog, wxPanel)
40 EVT_SIZE(wxDialog::OnSize)
41 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
42 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
43 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
44 EVT_CHAR_HOOK(wxDialog::OnCharHook)
45 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
46 EVT_CLOSE(wxDialog::OnCloseWindow)
47 END_EVENT_TABLE()
0e320a79
DW
48
49wxDialog::wxDialog()
50{
27476f73
DW
51 m_isShown = FALSE;
52 m_modalShowing = FALSE;
53
0e320a79
DW
54 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
55}
56
57bool wxDialog::Create(wxWindow *parent, wxWindowID id,
58 const wxString& title,
59 const wxPoint& pos,
60 const wxSize& size,
61 long style,
62 const wxString& name)
63{
27476f73
DW
64#if wxUSE_TOOLTIPS
65 m_hwndToolTip = 0;
66#endif
0e320a79 67
27476f73
DW
68 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
69 SetName(name);
0e320a79 70
27476f73
DW
71 if (!parent)
72 wxTopLevelWindows.Append(this);
0e320a79 73
27476f73 74 if (parent) parent->AddChild(this);
0e320a79 75
27476f73
DW
76 if ( id == -1 )
77 m_windowId = (int)NewControlId();
78 else
79 m_windowId = id;
80
81 int x = pos.x;
82 int y = pos.y;
83 int width = size.x;
84 int height = size.y;
85
86 if (x < 0) x = wxDIALOG_DEFAULT_X;
87 if (y < 0) y = wxDIALOG_DEFAULT_Y;
88
89 m_windowStyle = style;
90
91 m_isShown = FALSE;
92 m_modalShowing = FALSE;
93
94 if (width < 0)
95 width = 500;
96 if (height < 0)
97 height = 500;
98
99 // TODO: convert below to OS/2 PM code
100
101 // All dialogs should really have this style
102// m_windowStyle |= wxTAB_TRAVERSAL;
103//
104// WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle);
105// if (m_windowStyle & wxSTAY_ON_TOP)
106// extendedStyle |= WS_EX_TOPMOST;
107//
108 // Allows creation of dialogs with & without captions under MSWindows,
109 // resizeable or not (but a resizeable dialog always has caption -
110 // otherwise it would look too strange)
111// const wxChar *dlg;
112// if ( style & wxRESIZE_BORDER )
223d09f6 113// dlg = wxT("wxResizeableDialog");
27476f73 114// else if ( style & wxCAPTION )
223d09f6 115// dlg = wxT("wxCaptionDialog");
27476f73 116// else
223d09f6 117// dlg = wxT("wxNoCaptionDialog");
27476f73
DW
118// MSWCreate(m_windowId, parent, NULL, this, NULL,
119// x, y, width, height,
120// 0, // style is not used if we have dlg template
121// dlg,
122// extendedStyle);
123//
124// HWND hwnd = (HWND)GetHWND();
125//
126// if ( !hwnd )
127// {
223d09f6 128// wxLogError(wxT("Failed to create dialog."));
27476f73
DW
129//
130// return FALSE;
131// }
132//
133// SubclassWin(GetHWND());
134//
135// SetWindowText(hwnd, title);
136// SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
137//
138 return TRUE;
0e320a79
DW
139}
140
141void wxDialog::SetModal(bool flag)
142{
27476f73
DW
143 if ( flag )
144 m_windowStyle |= wxDIALOG_MODAL ;
145 else if ( m_windowStyle & wxDIALOG_MODAL )
146 m_windowStyle -= wxDIALOG_MODAL ;
147
148 wxModelessWindows.DeleteObject(this);
149 if (!flag)
150 wxModelessWindows.Append(this);
0e320a79
DW
151}
152
153wxDialog::~wxDialog()
154{
27476f73
DW
155 m_isBeingDeleted = TRUE;
156
0e320a79
DW
157 wxTopLevelWindows.DeleteObject(this);
158
27476f73
DW
159 Show(FALSE);
160
161 if (m_modalShowing)
162 {
163 if (GetParent() && GetParent()->GetHWND())
164 // TODO: bring the parent to the top
165 return;
166 }
167
168 m_modalShowing = FALSE;
0e320a79 169 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
27476f73
DW
170 wxModelessWindows.DeleteObject(this);
171
0e320a79
DW
172
173 // If this is the last top-level window, exit.
174 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
175 {
176 wxTheApp->SetTopWindow(NULL);
177
178 if (wxTheApp->GetExitOnFrameDelete())
179 {
180 // TODO: exit
181 }
182 }
183}
184
185// By default, pressing escape cancels the dialog
186void wxDialog::OnCharHook(wxKeyEvent& event)
187{
27476f73
DW
188 if (GetHWND())
189 {
190 if (event.m_keyCode == WXK_ESCAPE)
191 {
192 // Behaviour changed in 2.0: we'll send a Cancel message
193 // to the dialog instead of Close.
194 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
195 cancelEvent.SetEventObject( this );
196 GetEventHandler()->ProcessEvent(cancelEvent);
0e320a79 197
27476f73
DW
198 return;
199 }
200 }
201 // We didn't process this event.
202 event.Skip();
203}
204
205void wxDialog::OnPaint(wxPaintEvent& event)
206{
207 // No: if you call the default procedure, it makes
208 // the following painting code not work.
209// wxWindow::OnPaint(event);
210}
211
212void wxDialog::Fit()
213{
214 wxWindow::Fit();
0e320a79
DW
215}
216
217void wxDialog::Iconize(bool WXUNUSED(iconize))
218{
27476f73 219 // Windows dialog boxes can't be iconized
0e320a79
DW
220}
221
222bool wxDialog::IsIconized() const
223{
0e320a79
DW
224 return FALSE;
225}
226
27476f73
DW
227void wxDialog::DoSetClientSize(int width, int height)
228{
229 // TODO: Convert the below to OS/2 PM code
230
231// HWND hWnd = (HWND) GetHWND();
232// RECT rect;
233// ::GetClientRect(hWnd, &rect);
234//
235// RECT rect2;
236// GetWindowRect(hWnd, &rect2);
237//
238 // Find the difference between the entire window (title bar and all)
239 // and the client area; add this to the new client size to move the
240 // window
241// int actual_width = rect2.right - rect2.left - rect.right + width;
242// int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
243
244// MoveWindow(hWnd, rect2.left, rect2.top, actual_width, actual_height, TRUE);
245//
246// wxSizeEvent event(wxSize(actual_width, actual_height), m_windowId);
247// event.SetEventObject( this );
248// GetEventHandler()->ProcessEvent(event);
249}
0e320a79
DW
250void wxDialog::GetPosition(int *x, int *y) const
251{
27476f73
DW
252 // TODO: Convert
253// HWND hWnd = (HWND) GetHWND();
254// RECT rect;
255// GetWindowRect(hWnd, &rect);
256
257// *x = rect.left;
258// *y = rect.top;
259}
260
261bool wxDialog::IsShown() const
262{
263 return m_isShown;
264}
265
266bool wxDialog::IsModal() const
267{
268 return wxModalDialogs.Find((wxDialog *)this) != 0; // const_cast
0e320a79
DW
269}
270
271bool wxDialog::Show(bool show)
272{
27476f73 273 // TODO: This is involved code, look at msw port for details
0e320a79
DW
274 return FALSE;
275}
276
277void wxDialog::SetTitle(const wxString& title)
278{
27476f73 279 ::WinSetWindowText((HWND) GetHWND(), title.c_str());
0e320a79
DW
280}
281
282wxString wxDialog::GetTitle() const
283{
27476f73
DW
284 ::WinQueryWindowText((HWND) GetHWND(), 1000, wxBuffer);
285 return wxString(wxBuffer);
0e320a79
DW
286}
287
288void wxDialog::Centre(int direction)
289{
290 int x_offset,y_offset ;
291 int display_width, display_height;
292 int width, height, x, y;
293 wxWindow *parent = GetParent();
294 if ((direction & wxCENTER_FRAME) && parent)
295 {
296 parent->GetPosition(&x_offset,&y_offset) ;
297 parent->GetSize(&display_width,&display_height) ;
298 }
299 else
300 {
301 wxDisplaySize(&display_width, &display_height);
302 x_offset = 0 ;
303 y_offset = 0 ;
304 }
305
306 GetSize(&width, &height);
307 GetPosition(&x, &y);
308
309 if (direction & wxHORIZONTAL)
310 x = (int)((display_width - width)/2);
311 if (direction & wxVERTICAL)
312 y = (int)((display_height - height)/2);
313
314 SetSize(x+x_offset, y+y_offset, width, height);
315}
316
317// Replacement for Show(TRUE) for modal dialogs - returns return code
318int wxDialog::ShowModal()
319{
320 m_windowStyle |= wxDIALOG_MODAL;
27476f73
DW
321 Show(TRUE);
322 return GetReturnCode();
0e320a79
DW
323}
324
325void wxDialog::EndModal(int retCode)
326{
27476f73 327 SetReturnCode(retCode);
0e320a79 328 // TODO modal un-showing
27476f73 329 Show(FALSE);
0e320a79
DW
330}
331
27476f73
DW
332// Define for each class of dialog and control
333WXHBRUSH wxDialog::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
334 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
335{
336 return 0;
337}
0e320a79
DW
338// Standard buttons
339void wxDialog::OnOK(wxCommandEvent& event)
340{
27476f73
DW
341 if ( Validate() && TransferDataFromWindow() )
342 {
0e320a79
DW
343 if ( IsModal() )
344 EndModal(wxID_OK);
345 else
346 {
27476f73
DW
347 SetReturnCode(wxID_OK);
348 this->Show(FALSE);
0e320a79 349 }
27476f73 350 }
0e320a79
DW
351}
352
353void wxDialog::OnApply(wxCommandEvent& event)
354{
27476f73
DW
355 if (Validate())
356 TransferDataFromWindow();
357 // TODO probably need to disable the Apply button until things change again
0e320a79
DW
358}
359
360void wxDialog::OnCancel(wxCommandEvent& event)
361{
362 if ( IsModal() )
363 EndModal(wxID_CANCEL);
364 else
365 {
366 SetReturnCode(wxID_CANCEL);
27476f73 367 this->Show(FALSE);
0e320a79
DW
368 }
369}
370
371void wxDialog::OnCloseWindow(wxCloseEvent& event)
372{
373 // We'll send a Cancel message by default,
374 // which may close the dialog.
375 // Check for looping if the Cancel event handler calls Close().
376
377 // Note that if a cancel button and handler aren't present in the dialog,
378 // nothing will happen when you close the dialog via the window manager, or
379 // via Close().
380 // We wouldn't want to destroy the dialog by default, since the dialog may have been
381 // created on the stack.
382 // However, this does mean that calling dialog->Close() won't delete the dialog
383 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
384 // sure to destroy the dialog.
385 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
386
387 static wxList closing;
c3d43472 388
0e320a79
DW
389 if ( closing.Member(this) )
390 return;
c3d43472 391
0e320a79 392 closing.Append(this);
c3d43472 393
0e320a79
DW
394 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
395 cancelEvent.SetEventObject( this );
396 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
397
398 closing.DeleteObject(this);
399}
400
401// Destroy the window (delayed, if a managed window)
402bool wxDialog::Destroy()
403{
27476f73
DW
404 if (!wxPendingDelete.Member(this))
405 wxPendingDelete.Append(this);
406 return TRUE;
407}
408
409void wxDialog::OnSize(wxSizeEvent& WXUNUSED(event))
410{
411 // if we're using constraints - do use them
412 #if wxUSE_CONSTRAINTS
413 if ( GetAutoLayout() )
414 {
415 Layout();
416 }
417 #endif
0e320a79
DW
418}
419
420void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event)
421{
422 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
423 Refresh();
424}
425
a885d89a 426MRESULT wxDialog::OS2WindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
0e320a79 427{
27476f73
DW
428 MRESULT rc = 0;
429 bool processed = FALSE;
430
431 switch ( message )
432 {
433 case WM_CLOSE:
434 // if we can't close, tell the system that we processed the
435 // message - otherwise it would close us
436 processed = !Close();
437 break;
438 }
439
440 if ( !processed )
a885d89a 441 rc = wxWindow::OS2WindowProc(message, wParam, lParam);
27476f73
DW
442
443 return rc;
0e320a79 444}
27476f73 445