allow handling events in a function taking the base class of the event class corresponding to the event type and not exactly the event class itself: this is more flexible (while still being safe) and incidentally fixes compatibility issues with existing code using explicit casts to wxObjectEventFunction (see #10477)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58690 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -23,19 +23,21 @@
|
||||
// test events and their handlers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const wxEventType EVT_LEGACY = wxNewEventType();
|
||||
const wxEventType LegacyEventType = wxNewEventType();
|
||||
|
||||
class MyEvent;
|
||||
wxDEFINE_EVENT( EVT_MYEVENT, MyEvent )
|
||||
wxDEFINE_EVENT( MyEventType, MyEvent )
|
||||
|
||||
class MyEvent : public wxEvent
|
||||
{
|
||||
public:
|
||||
MyEvent() : wxEvent(0, EVT_MYEVENT) { }
|
||||
MyEvent() : wxEvent(0, MyEventType) { }
|
||||
|
||||
virtual wxEvent *Clone() const { return new MyEvent; }
|
||||
};
|
||||
|
||||
#define EVT_MYEVENT(func) wx__DECLARE_EVT0(MyEventType, &func)
|
||||
|
||||
class AnotherEvent : public wxEvent
|
||||
{
|
||||
};
|
||||
@@ -100,6 +102,7 @@ public:
|
||||
struct MySink
|
||||
{
|
||||
void OnMyEvent(MyEvent&) { g_called.method = true; }
|
||||
void OnEvent(wxEvent&) { g_called.method = true; }
|
||||
void OnIdle(wxIdleEvent&) { g_called.method = true; }
|
||||
};
|
||||
|
||||
@@ -119,7 +122,11 @@ private:
|
||||
BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
|
||||
EVT_IDLE(MyClassWithEventTable::OnIdle)
|
||||
|
||||
EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
|
||||
EVT_MYEVENT(MyClassWithEventTable::OnEvent)
|
||||
|
||||
// this shouldn't compile:
|
||||
//EVT_MYEVENT(MyClassWithEventTable::OnIdle)
|
||||
//EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -144,6 +151,7 @@ private:
|
||||
CPPUNIT_TEST( ConnectStaticMethod );
|
||||
CPPUNIT_TEST( ConnectFunctor );
|
||||
CPPUNIT_TEST( ConnectMethod );
|
||||
CPPUNIT_TEST( ConnectMethodUsingBaseEvent );
|
||||
CPPUNIT_TEST( ConnectMethodWithSink );
|
||||
CPPUNIT_TEST( ConnectNonHandler );
|
||||
CPPUNIT_TEST( StaticConnect );
|
||||
@@ -158,6 +166,7 @@ private:
|
||||
void ConnectStaticMethod();
|
||||
void ConnectFunctor();
|
||||
void ConnectMethod();
|
||||
void ConnectMethodUsingBaseEvent();
|
||||
void ConnectMethodWithSink();
|
||||
void ConnectNonHandler();
|
||||
void StaticConnect();
|
||||
@@ -187,6 +196,11 @@ void EvtHandlerTestCase::BuiltinConnect()
|
||||
handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
|
||||
handler.Disconnect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
|
||||
|
||||
// using casts like this is even uglier than using wxIdleEventHandler but
|
||||
// it should still continue to work for compatibility
|
||||
handler.Connect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
|
||||
handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
|
||||
|
||||
#if !wxEVENTS_COMPATIBILITY_2_8
|
||||
handler.Connect(wxEVT_IDLE, GlobalOnIdle);
|
||||
handler.Disconnect(wxEVT_IDLE, GlobalOnIdle);
|
||||
@@ -205,22 +219,22 @@ void EvtHandlerTestCase::BuiltinConnect()
|
||||
|
||||
void EvtHandlerTestCase::LegacyConnect()
|
||||
{
|
||||
handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Connect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
|
||||
handler.Disconnect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Disconnect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||
|
||||
|
||||
handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Connect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
|
||||
handler.Disconnect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Disconnect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||
}
|
||||
|
||||
#if !wxEVENTS_COMPATIBILITY_2_8
|
||||
@@ -228,40 +242,40 @@ void EvtHandlerTestCase::LegacyConnect()
|
||||
void EvtHandlerTestCase::ConnectFunction()
|
||||
{
|
||||
// function tests
|
||||
handler.Connect( EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Connect( MyEventType, GlobalOnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.function );
|
||||
handler.Disconnect( EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Disconnect( MyEventType, GlobalOnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
|
||||
|
||||
handler.Connect( 0, EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Disconnect( 0, EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Connect( 0, MyEventType, GlobalOnMyEvent );
|
||||
handler.Disconnect( 0, MyEventType, GlobalOnMyEvent );
|
||||
|
||||
handler.Connect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Disconnect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
|
||||
handler.Connect( 0, 0, MyEventType, GlobalOnMyEvent );
|
||||
handler.Disconnect( 0, 0, MyEventType, GlobalOnMyEvent );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectStaticMethod()
|
||||
{
|
||||
// static method tests (this is same as functions but still test it just in
|
||||
// case we hit some strange compiler bugs)
|
||||
handler.Connect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Connect( MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.smethod );
|
||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Disconnect( MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.smethod );
|
||||
|
||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Connect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
handler.Disconnect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
|
||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
||||
handler.Connect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
handler.Disconnect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectFunctor()
|
||||
@@ -269,50 +283,71 @@ void EvtHandlerTestCase::ConnectFunctor()
|
||||
// generalized functor tests
|
||||
MyFunctor functor;
|
||||
|
||||
handler.Connect( EVT_MYEVENT, functor );
|
||||
handler.Connect( MyEventType, functor );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.functor );
|
||||
handler.Disconnect( EVT_MYEVENT, functor );
|
||||
handler.Disconnect( MyEventType, functor );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.functor );
|
||||
|
||||
handler.Connect( 0, EVT_MYEVENT, functor );
|
||||
handler.Disconnect( 0, EVT_MYEVENT, functor );
|
||||
handler.Connect( 0, MyEventType, functor );
|
||||
handler.Disconnect( 0, MyEventType, functor );
|
||||
|
||||
handler.Connect( 0, 0, EVT_MYEVENT, functor );
|
||||
handler.Disconnect( 0, 0, EVT_MYEVENT, functor );
|
||||
handler.Connect( 0, 0, MyEventType, functor );
|
||||
handler.Disconnect( 0, 0, MyEventType, functor );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectMethod()
|
||||
{
|
||||
// class method tests
|
||||
handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Connect( MyEventType, &MyHandler::OnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.method );
|
||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.method );
|
||||
|
||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent );
|
||||
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent );
|
||||
|
||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
||||
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent );
|
||||
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectMethodUsingBaseEvent()
|
||||
{
|
||||
// test connecting a method taking just wxEvent and not MyEvent: this
|
||||
// should work too if we don't need any MyEvent-specific information in the
|
||||
// handler
|
||||
handler.Connect( MyEventType, &MyHandler::OnEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.method );
|
||||
handler.Disconnect( MyEventType, &MyHandler::OnEvent );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.method );
|
||||
|
||||
handler.Connect( 0, MyEventType, &MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, MyEventType, &MyHandler::OnEvent );
|
||||
|
||||
handler.Connect( 0, 0, MyEventType, &MyHandler::OnEvent );
|
||||
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnEvent );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectMethodWithSink()
|
||||
{
|
||||
handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Connect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
|
||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::ConnectNonHandler()
|
||||
@@ -320,11 +355,11 @@ void EvtHandlerTestCase::ConnectNonHandler()
|
||||
// class method tests for class not derived from wxEvtHandler
|
||||
MySink sink;
|
||||
|
||||
handler.Connect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
|
||||
handler.Connect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( g_called.method );
|
||||
handler.Disconnect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
|
||||
handler.Disconnect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
|
||||
g_called.Reset();
|
||||
handler.ProcessEvent(e);
|
||||
CPPUNIT_ASSERT( !g_called.method );
|
||||
@@ -332,13 +367,13 @@ void EvtHandlerTestCase::ConnectNonHandler()
|
||||
|
||||
void EvtHandlerTestCase::StaticConnect()
|
||||
{
|
||||
wxEvtHandler::Connect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Connect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Connect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Connect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Connect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Connect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
|
||||
wxEvtHandler::Disconnect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Disconnect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Disconnect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Disconnect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Disconnect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
wxEvtHandler::Disconnect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||
}
|
||||
|
||||
void EvtHandlerTestCase::InvalidConnect()
|
||||
@@ -346,10 +381,10 @@ void EvtHandlerTestCase::InvalidConnect()
|
||||
// these calls shouldn't compile but we unfortunately can't check this
|
||||
// automatically, you need to uncomment them manually and test that
|
||||
// compilation does indeed fail
|
||||
//handler.Connect(EVT_MYEVENT, GlobalOnAnotherEvent);
|
||||
//IdleFunctor f; handler.Connect(EVT_MYEVENT, f);
|
||||
//handler.Connect(EVT_MYEVENT, &MyHandler::StaticOnAnotherEvent);
|
||||
//handler.Connect(EVT_MYEVENT, &MyHandler::OnAnotherEvent);
|
||||
//handler.Connect(MyEventType, GlobalOnAnotherEvent);
|
||||
//IdleFunctor f; handler.Connect(MyEventType, f);
|
||||
//handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent);
|
||||
//handler.Connect(MyEventType, &MyHandler::OnAnotherEvent);
|
||||
}
|
||||
|
||||
#endif // !wxEVENTS_COMPATIBILITY_2_8
|
||||
|
Reference in New Issue
Block a user