X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a756f210019dd5b51331b7181c816d3882146a30..6f28211af2258ce0c052e5b5c1d862e7bbc8de27:/src/os2/dialog.cpp diff --git a/src/os2/dialog.cpp b/src/os2/dialog.cpp index e503f93cc8..fb4e903b07 100644 --- a/src/os2/dialog.cpp +++ b/src/os2/dialog.cpp @@ -24,6 +24,8 @@ #include "wx/os2/private.h" #include "wx/log.h" +#include "wx/evtloop.h" +#include "wx/ptr_scpd.h" #define wxDIALOG_DEFAULT_X 300 #define wxDIALOG_DEFAULT_Y 300 @@ -31,11 +33,9 @@ #define wxDIALOG_DEFAULT_WIDTH 500 #define wxDIALOG_DEFAULT_HEIGHT 500 -wxWindowList wxModalDialogs; - IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow) -BEGIN_EVENT_TABLE(wxDialog, wxTopLevelWindow) +BEGIN_EVENT_TABLE(wxDialog, wxDialogBase) EVT_BUTTON(wxID_OK, wxDialog::OnOK) EVT_BUTTON(wxID_APPLY, wxDialog::OnApply) EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel) @@ -44,11 +44,47 @@ BEGIN_EVENT_TABLE(wxDialog, wxTopLevelWindow) EVT_CLOSE(wxDialog::OnCloseWindow) END_EVENT_TABLE() +// ---------------------------------------------------------------------------- +// wxDialogModalData +// ---------------------------------------------------------------------------- + +// this is simply a container for any data we need to implement modality which +// allows us to avoid changing wxDialog each time the implementation changes +class wxDialogModalData +{ +public: + wxDialogModalData(wxDialog *dialog) : m_evtLoop(dialog) { } + + void RunLoop() + { + m_evtLoop.Run(); + } + + void ExitLoop() + { + m_evtLoop.Exit(); + } + +private: + wxModalEventLoop m_evtLoop; +}; + +wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxDialog construction +// ---------------------------------------------------------------------------- + void wxDialog::Init() { m_pOldFocus = (wxWindow *)NULL; m_isShown = FALSE; m_pWindowDisabler = (wxWindowDisabler *)NULL; + m_modalData = NULL; SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); } // end of wxDialog::Init @@ -62,14 +98,6 @@ bool wxDialog::Create( , const wxString& rsName ) { - long lX = rPos.x; - long lY = rPos.y; - long lWidth = rSize.x; - long lHeight = rSize.y; - const char* zDlg; - WXDWORD dwExtendedStyle = 0L; - HWND hWnd; - Init(); SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG); @@ -93,6 +121,12 @@ bool wxDialog::Create( )) return FALSE; SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + + // + // Must defer setting the title until after dialog is created and sized + // + if (!rsTitle.IsNull()) + SetTitle(rsTitle); return TRUE; } // end of wxDialog::Create @@ -163,7 +197,7 @@ bool wxDialog::IsModal() const bool wxDialog::IsModalShowing() const { - return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast + return m_modalData != NULL; // const_cast } // end of wxDialog::IsModalShowing void wxDialog::DoShowModal() @@ -175,7 +209,6 @@ void wxDialog::DoShowModal() wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") ); - wxModalDialogs.Append(this); if (pOldFocus) hWndOldFocus = (HWND)pOldFocus->GetHWND(); @@ -194,26 +227,25 @@ void wxDialog::DoShowModal() // wxASSERT_MSG(!m_pWindowDisabler, _T("disabling windows twice?")); - m_pWindowDisabler = new wxWindowDisabler(this); - // - // Enter the modal loop + // Before entering the modal loop, reset the "is in OnIdle()" flag (see + // comment in app.cpp) // - while ( IsModalShowing() ) - { -#if wxUSE_THREADS - wxMutexGuiLeaveOrEnter(); -#endif // wxUSE_THREADS + extern bool gbInOnIdle; + bool bWasInOnIdle = gbInOnIdle; - while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() ) - ; + gbInOnIdle = FALSE; - // a message came or no more idle processing to do - wxTheApp->DoMessage(); + // enter the modal loop + { + wxDialogModalDataTiedPtr modalData(&m_modalData, + new wxDialogModalData(this)); + modalData->RunLoop(); } + gbInOnIdle = bWasInOnIdle; // - // Snd restore focus + // and restore focus // Note that this code MUST NOT access the dialog object's data // in case the object has been deleted (which will be the case // for a modal dialog that has been destroyed before calling EndModal). @@ -237,13 +269,16 @@ bool wxDialog::Show( // // If we had disabled other app windows, reenable them back now because // if they stay disabled Windows will activate another window (one - // which is enabled, anyhow) and we will lose activation + // which is enabled, anyhow) and we will lose activation. We really don't + // do this in OS/2 since PM does this for us. // if (m_pWindowDisabler) { delete m_pWindowDisabler; m_pWindowDisabler = NULL; } + if ( m_modalData ) + m_modalData->ExitLoop(); } // @@ -259,12 +294,22 @@ bool wxDialog::Show( if (bShow) { + // dialogs don't get WM_SIZE message after creation unlike most (all?) + // other windows and so could start their life non laid out correctly + // if we didn't call Layout() from here + // + // NB: normally we should call it just the first time but doing it + // every time is simpler than keeping a flag +// Layout(); + // // Usually will result in TransferDataToWindow() being called // InitDialog(); } + if (GetTitle().c_str()) + ::WinSetWindowText((HWND)GetHwnd(), GetTitle().c_str()); if (IsModal()) { if (bShow) @@ -287,14 +332,6 @@ bool wxDialog::Show( } DoShowModal(); } - else // end of modal dialog - { - // - // This will cause IsModalShowing() return FALSE and our local - // message loop will terminate - // - wxModalDialogs.DeleteObject(this); - } } return TRUE; } // end of wxDialog::Show