X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c9b9e020cab11094582a2b921bf9943f8f5d4e6f..5a410e4453e28ee77ee3ad7a407ca71692f9f30f:/src/os2/dialog.cpp diff --git a/src/os2/dialog.cpp b/src/os2/dialog.cpp index edc04a0d24..6d46d6022f 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,8 +33,6 @@ #define wxDIALOG_DEFAULT_WIDTH 500 #define wxDIALOG_DEFAULT_HEIGHT 500 -wxWindowList wxModalDialogs; - IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow) BEGIN_EVENT_TABLE(wxDialog, wxDialogBase) @@ -44,11 +44,47 @@ BEGIN_EVENT_TABLE(wxDialog, wxDialogBase) 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 @@ -169,7 +205,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() @@ -181,7 +217,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(); @@ -200,26 +235,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). @@ -243,13 +277,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(); } // @@ -265,6 +302,14 @@ 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 // @@ -295,14 +340,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