Add lambda-friendly wxDialog::ShowWindowModalThenDo().

Add a convenience ShowWindowModalThenDo() variant of ShowWindowModal()
that takes a functor argument and calls it when the dialog is closed.

This is, of course, particularly useful when the argument is a C++11
lambda, especially when having more than one window-modal dialog invoked
from the same window, which can get messy quickly with all the
wxEVT_WINDOW_MODAL_DIALOG_CLOSED handlers.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74775 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2013-09-06 17:09:20 +00:00
parent c80d4c1e20
commit c5d4360fc9
2 changed files with 83 additions and 2 deletions

View File

@@ -79,6 +79,11 @@ public:
virtual void ShowWindowModal () ; virtual void ShowWindowModal () ;
virtual void SendWindowModalDialogEvent ( wxEventType type ); virtual void SendWindowModalDialogEvent ( wxEventType type );
#ifdef wxHAS_EVENT_BIND
template<typename Functor>
void ShowWindowModalThenDo(const Functor& onEndModal);
#endif // wxHAS_EVENT_BIND
// Modal dialogs have a return code - usually the id of the last // Modal dialogs have a return code - usually the id of the last
// pressed button // pressed button
void SetReturnCode(int returnCode) { m_returnCode = returnCode; } void SetReturnCode(int returnCode) { m_returnCode = returnCode; }
@@ -391,5 +396,40 @@ typedef void (wxEvtHandler::*wxWindowModalDialogEventFunction)(wxWindowModalDial
#define EVT_WINDOW_MODAL_DIALOG_CLOSED(winid, func) \ #define EVT_WINDOW_MODAL_DIALOG_CLOSED(winid, func) \
wx__DECLARE_EVT1(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, winid, wxWindowModalDialogEventHandler(func)) wx__DECLARE_EVT1(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, winid, wxWindowModalDialogEventHandler(func))
#ifdef wxHAS_EVENT_BIND
template<typename Functor>
class wxWindowModalDialogEventFunctor
{
public:
wxWindowModalDialogEventFunctor(const Functor& f)
: m_f(f), m_wasCalled(false)
{}
void operator()(wxWindowModalDialogEvent& event)
{
if ( m_wasCalled )
{
event.Skip();
return;
}
m_wasCalled = true;
m_f(event.GetReturnCode());
}
private:
Functor m_f;
bool m_wasCalled;
};
template<typename Functor>
void wxDialogBase::ShowWindowModalThenDo(const Functor& onEndModal)
{
Bind(wxEVT_WINDOW_MODAL_DIALOG_CLOSED,
wxWindowModalDialogEventFunctor<Functor>(onEndModal));
ShowWindowModal();
};
#endif // wxHAS_EVENT_BIND
#endif #endif
// _WX_DIALOG_H_BASE_ // _WX_DIALOG_H_BASE_

View File

@@ -596,7 +596,8 @@ public:
@return The value set with SetReturnCode(). @return The value set with SetReturnCode().
@see ShowWindowModal(), EndModal(), GetReturnCode(), SetReturnCode() @see ShowWindowModal(), ShowWindowModalThenDo(),
EndModal(), GetReturnCode(), SetReturnCode()
*/ */
virtual int ShowModal(); virtual int ShowModal();
@@ -614,11 +615,51 @@ public:
the other platforms it behaves like ShowModal() (but also sends the the other platforms it behaves like ShowModal() (but also sends the
above mentioned event). above mentioned event).
@see wxWindowModalDialogEvent @see wxWindowModalDialogEvent, ShowWindowModalThenDo()
@since 2.9.0 @since 2.9.0
*/ */
void ShowWindowModal(); void ShowWindowModal();
/**
Shows a dialog modal to the parent top level window only and call a
functor after the dialog is closed.
Same as the other ShowWindowModal() overload, but calls the functor
passed as the argument upon completion, instead of generating the
wxEVT_WINDOW_MODAL_DIALOG_CLOSED event.
This form is particularly useful in combination with C++11 lambdas,
when it allows writing window-modal very similarly to how ShowModal()
is used (with the notable exception of not being able to create
the dialog on stack):
@code
wxWindowPtr<wxDialog> dlg(new wxMessageDialog(this, "Hello!"));
dlg->ShowWindowModalThenDo([this,dlg](int retcode){
if ( retcode == wxID_OK )
DoSomething();
// dlg is implicitly destroyed here, because the pointer was
// explicitly captured by the lambda
});
@endcode
@param onEndModal Function object to call when the dialog is
closed. The functor is called with a single
integer argument, dialog's return code.
@note The dialog instance must not be destroyed until @a onEndModal
is called. The best way to ensure thay is to use wxWindowPtr
to hold a pointer and include it in the lambda's capture,
by value (not reference!), as shown in the example above.
@since 3.0
@see wxWindowPtr<T>
*/
template<typename Functor>
void ShowWindowModalThenDo(const Functor& onEndModal);
}; };