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:
@@ -321,11 +321,32 @@ private:
|
|||||||
Functor m_handler;
|
Functor m_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper class defining operations different for method functors using an
|
|
||||||
// object of wxEvtHandler-derived class as handler and the others
|
|
||||||
namespace wxPrivate
|
namespace wxPrivate
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// helper template defining nested "type" typedef as the event class
|
||||||
|
// corresponding to the given event type
|
||||||
|
template <typename T> struct EventClassOf;
|
||||||
|
|
||||||
|
// the typed events provide the information about the class of the events they
|
||||||
|
// carry themselves:
|
||||||
|
template <typename T>
|
||||||
|
struct EventClassOf< wxEventTypeTag<T> >
|
||||||
|
{
|
||||||
|
typedef typename wxEventTypeTag<T>::EventClass type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// for the old untyped events we don't have information about the exact event
|
||||||
|
// class carried by them
|
||||||
|
template <>
|
||||||
|
struct EventClassOf<wxEventType>
|
||||||
|
{
|
||||||
|
typedef wxEvent type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// helper class defining operations different for method functors using an
|
||||||
|
// object of wxEvtHandler-derived class as handler and the others
|
||||||
template <typename T, typename A, bool> struct HandlerImpl;
|
template <typename T, typename A, bool> struct HandlerImpl;
|
||||||
|
|
||||||
// specialization for handlers deriving from wxEvtHandler
|
// specialization for handlers deriving from wxEvtHandler
|
||||||
@@ -339,7 +360,8 @@ struct HandlerImpl<T, A, true>
|
|||||||
static wxEvtHandler *ConvertToEvtHandler(T *p)
|
static wxEvtHandler *ConvertToEvtHandler(T *p)
|
||||||
{ return p; }
|
{ return p; }
|
||||||
static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&))
|
static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&))
|
||||||
{ return reinterpret_cast<wxEventFunction>(f); }
|
{ return static_cast<wxEventFunction>(
|
||||||
|
reinterpret_cast<void (T::*)(wxEvent&)>(f)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// specialization for handlers not deriving from wxEvtHandler
|
// specialization for handlers not deriving from wxEvtHandler
|
||||||
@@ -362,18 +384,29 @@ struct HandlerImpl<T, A, false>
|
|||||||
//
|
//
|
||||||
// notice that the object class may be different from the class in which the
|
// notice that the object class may be different from the class in which the
|
||||||
// method is defined but it must be convertible to this class
|
// method is defined but it must be convertible to this class
|
||||||
template <typename EventTag, typename Class, typename ObjClass>
|
//
|
||||||
|
// also, the type of the handler parameter doesn't need to be exactly the same
|
||||||
|
// as EventTag::EventClass but it must be its base class -- this is explicitly
|
||||||
|
// allowed to handle different events in the same handler taking wxEvent&, for
|
||||||
|
// example
|
||||||
|
template
|
||||||
|
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
||||||
class wxEventFunctorMethod
|
class wxEventFunctorMethod
|
||||||
: public wxEventFunctor,
|
: public wxEventFunctor,
|
||||||
private wxPrivate::HandlerImpl
|
private wxPrivate::HandlerImpl
|
||||||
<
|
<
|
||||||
Class,
|
Class,
|
||||||
typename EventTag::EventClass,
|
EventArg,
|
||||||
wxConvertibleTo<Class, wxEvtHandler>::value
|
wxConvertibleTo<Class, wxEvtHandler>::value
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
static void CheckHandlerArgument(EventArg *) { }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename EventTag::EventClass EventArg;
|
// the event class associated with the given event tag
|
||||||
|
typedef typename wxPrivate::EventClassOf<EventTag>::type EventClass;
|
||||||
|
|
||||||
|
|
||||||
wxEventFunctorMethod(void (Class::*method)(EventArg&), ObjClass *handler)
|
wxEventFunctorMethod(void (Class::*method)(EventArg&), ObjClass *handler)
|
||||||
{
|
{
|
||||||
@@ -381,6 +414,11 @@ public:
|
|||||||
"handlers defined in non-wxEvtHandler-derived classes "
|
"handlers defined in non-wxEvtHandler-derived classes "
|
||||||
"must be connected with a valid sink object" );
|
"must be connected with a valid sink object" );
|
||||||
|
|
||||||
|
// if you get an error here it means that the signature of the handler
|
||||||
|
// you're trying to use is not compatible with (i.e. is not the same as
|
||||||
|
// or a base class of) the real event class used for this event type
|
||||||
|
CheckHandlerArgument(static_cast<EventClass *>(NULL));
|
||||||
|
|
||||||
m_handler = handler;
|
m_handler = handler;
|
||||||
m_method = method;
|
m_method = method;
|
||||||
}
|
}
|
||||||
@@ -396,6 +434,9 @@ public:
|
|||||||
wxCHECK_RET( realHandler, "invalid event handler" );
|
wxCHECK_RET( realHandler, "invalid event handler" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the real (run-time) type of event is EventClass and we checked in
|
||||||
|
// the ctor that EventClass can be converted to EventArg, so this cast
|
||||||
|
// is always valid
|
||||||
(realHandler->*m_method)(static_cast<EventArg&>(event));
|
(realHandler->*m_method)(static_cast<EventArg&>(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,18 +470,6 @@ private:
|
|||||||
void (Class::*m_method)(EventArg&);
|
void (Class::*m_method)(EventArg&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// partial specialization for legacy event types
|
|
||||||
template <typename ObjClass>
|
|
||||||
class wxEventFunctorMethod<wxEventType, wxEvtHandler, ObjClass>
|
|
||||||
: public wxObjectEventFunctor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
wxEventFunctorMethod(wxObjectEventFunction method, ObjClass *handler)
|
|
||||||
: wxObjectEventFunctor(method, handler)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create functors for the templatized events, either allocated on the heap for
|
// Create functors for the templatized events, either allocated on the heap for
|
||||||
@@ -469,39 +498,43 @@ wxMakeEventFunctor(const EventTag&, Functor func)
|
|||||||
// Create functors for methods:
|
// Create functors for methods:
|
||||||
template
|
template
|
||||||
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
||||||
inline wxEventFunctorMethod<EventTag, Class, ObjClass> *
|
inline wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass> *
|
||||||
wxNewEventFunctor(const EventTag&,
|
wxNewEventFunctor(const EventTag&,
|
||||||
void (Class::*method)(EventArg&),
|
void (Class::*method)(EventArg&),
|
||||||
ObjClass *handler)
|
ObjClass *handler)
|
||||||
{
|
{
|
||||||
return new wxEventFunctorMethod<EventTag, Class, ObjClass>(method, handler);
|
return new wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>(
|
||||||
|
method, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
template
|
template
|
||||||
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
||||||
inline wxEventFunctorMethod<EventTag, Class, ObjClass>
|
inline wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>
|
||||||
wxMakeEventFunctor(const EventTag&,
|
wxMakeEventFunctor(const EventTag&,
|
||||||
void (Class::*method)(EventArg&),
|
void (Class::*method)(EventArg&),
|
||||||
ObjClass *handler)
|
ObjClass *handler)
|
||||||
{
|
{
|
||||||
return wxEventFunctorMethod<EventTag, Class, ObjClass>(method, handler);
|
return wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>(
|
||||||
|
method, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for the wxNewEventFunctor() calls used inside the event table
|
// Special case for the wxNewEventFunctor() calls used inside the event table
|
||||||
// macros: they don't specify the handler so ObjClass can't be deduced
|
// macros: they don't specify the handler so ObjClass can't be deduced
|
||||||
template <typename EventTag, typename Class, typename EventArg>
|
template <typename EventTag, typename Class, typename EventArg>
|
||||||
inline wxEventFunctorMethod<EventTag, Class, Class> *
|
inline wxEventFunctorMethod<EventTag, Class, EventArg, Class> *
|
||||||
wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
|
wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
|
||||||
{
|
{
|
||||||
return new wxEventFunctorMethod<EventTag, Class, Class>(method, NULL);
|
return new wxEventFunctorMethod<EventTag, Class, EventArg, Class>(
|
||||||
|
method, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
template
|
template
|
||||||
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
<typename EventTag, typename Class, typename EventArg, typename ObjClass>
|
||||||
inline wxEventFunctorMethod<EventTag, Class, Class>
|
inline wxEventFunctorMethod<EventTag, Class, EventArg, Class>
|
||||||
wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
|
wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
|
||||||
{
|
{
|
||||||
return wxEventFunctorMethod<EventTag, Class, Class>(method, NULL);
|
return wxEventFunctorMethod<EventTag, Class, EventArg, Class>(
|
||||||
|
method, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !wxEVENTS_COMPATIBILITY_2_8
|
#endif // !wxEVENTS_COMPATIBILITY_2_8
|
||||||
|
@@ -23,19 +23,21 @@
|
|||||||
// test events and their handlers
|
// test events and their handlers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
const wxEventType EVT_LEGACY = wxNewEventType();
|
const wxEventType LegacyEventType = wxNewEventType();
|
||||||
|
|
||||||
class MyEvent;
|
class MyEvent;
|
||||||
wxDEFINE_EVENT( EVT_MYEVENT, MyEvent )
|
wxDEFINE_EVENT( MyEventType, MyEvent )
|
||||||
|
|
||||||
class MyEvent : public wxEvent
|
class MyEvent : public wxEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MyEvent() : wxEvent(0, EVT_MYEVENT) { }
|
MyEvent() : wxEvent(0, MyEventType) { }
|
||||||
|
|
||||||
virtual wxEvent *Clone() const { return new MyEvent; }
|
virtual wxEvent *Clone() const { return new MyEvent; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define EVT_MYEVENT(func) wx__DECLARE_EVT0(MyEventType, &func)
|
||||||
|
|
||||||
class AnotherEvent : public wxEvent
|
class AnotherEvent : public wxEvent
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@@ -100,6 +102,7 @@ public:
|
|||||||
struct MySink
|
struct MySink
|
||||||
{
|
{
|
||||||
void OnMyEvent(MyEvent&) { g_called.method = true; }
|
void OnMyEvent(MyEvent&) { g_called.method = true; }
|
||||||
|
void OnEvent(wxEvent&) { g_called.method = true; }
|
||||||
void OnIdle(wxIdleEvent&) { g_called.method = true; }
|
void OnIdle(wxIdleEvent&) { g_called.method = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,7 +122,11 @@ private:
|
|||||||
BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
|
BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
|
||||||
EVT_IDLE(MyClassWithEventTable::OnIdle)
|
EVT_IDLE(MyClassWithEventTable::OnIdle)
|
||||||
|
|
||||||
|
EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
|
||||||
|
EVT_MYEVENT(MyClassWithEventTable::OnEvent)
|
||||||
|
|
||||||
// this shouldn't compile:
|
// this shouldn't compile:
|
||||||
|
//EVT_MYEVENT(MyClassWithEventTable::OnIdle)
|
||||||
//EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
|
//EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -144,6 +151,7 @@ private:
|
|||||||
CPPUNIT_TEST( ConnectStaticMethod );
|
CPPUNIT_TEST( ConnectStaticMethod );
|
||||||
CPPUNIT_TEST( ConnectFunctor );
|
CPPUNIT_TEST( ConnectFunctor );
|
||||||
CPPUNIT_TEST( ConnectMethod );
|
CPPUNIT_TEST( ConnectMethod );
|
||||||
|
CPPUNIT_TEST( ConnectMethodUsingBaseEvent );
|
||||||
CPPUNIT_TEST( ConnectMethodWithSink );
|
CPPUNIT_TEST( ConnectMethodWithSink );
|
||||||
CPPUNIT_TEST( ConnectNonHandler );
|
CPPUNIT_TEST( ConnectNonHandler );
|
||||||
CPPUNIT_TEST( StaticConnect );
|
CPPUNIT_TEST( StaticConnect );
|
||||||
@@ -158,6 +166,7 @@ private:
|
|||||||
void ConnectStaticMethod();
|
void ConnectStaticMethod();
|
||||||
void ConnectFunctor();
|
void ConnectFunctor();
|
||||||
void ConnectMethod();
|
void ConnectMethod();
|
||||||
|
void ConnectMethodUsingBaseEvent();
|
||||||
void ConnectMethodWithSink();
|
void ConnectMethodWithSink();
|
||||||
void ConnectNonHandler();
|
void ConnectNonHandler();
|
||||||
void StaticConnect();
|
void StaticConnect();
|
||||||
@@ -187,6 +196,11 @@ void EvtHandlerTestCase::BuiltinConnect()
|
|||||||
handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
|
handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
|
||||||
handler.Disconnect(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
|
#if !wxEVENTS_COMPATIBILITY_2_8
|
||||||
handler.Connect(wxEVT_IDLE, GlobalOnIdle);
|
handler.Connect(wxEVT_IDLE, GlobalOnIdle);
|
||||||
handler.Disconnect(wxEVT_IDLE, GlobalOnIdle);
|
handler.Disconnect(wxEVT_IDLE, GlobalOnIdle);
|
||||||
@@ -205,22 +219,22 @@ void EvtHandlerTestCase::BuiltinConnect()
|
|||||||
|
|
||||||
void EvtHandlerTestCase::LegacyConnect()
|
void EvtHandlerTestCase::LegacyConnect()
|
||||||
{
|
{
|
||||||
handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Connect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
|
|
||||||
handler.Disconnect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Disconnect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
|
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
|
||||||
|
|
||||||
|
|
||||||
handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||||
handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||||
handler.Connect( 0, 0, EVT_LEGACY, (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( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||||
handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||||
handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !wxEVENTS_COMPATIBILITY_2_8
|
#if !wxEVENTS_COMPATIBILITY_2_8
|
||||||
@@ -228,40 +242,40 @@ void EvtHandlerTestCase::LegacyConnect()
|
|||||||
void EvtHandlerTestCase::ConnectFunction()
|
void EvtHandlerTestCase::ConnectFunction()
|
||||||
{
|
{
|
||||||
// function tests
|
// function tests
|
||||||
handler.Connect( EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Connect( MyEventType, GlobalOnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( g_called.function );
|
CPPUNIT_ASSERT( g_called.function );
|
||||||
handler.Disconnect( EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Disconnect( MyEventType, GlobalOnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
|
CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
|
||||||
|
|
||||||
handler.Connect( 0, EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Connect( 0, MyEventType, GlobalOnMyEvent );
|
||||||
handler.Disconnect( 0, EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Disconnect( 0, MyEventType, GlobalOnMyEvent );
|
||||||
|
|
||||||
handler.Connect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Connect( 0, 0, MyEventType, GlobalOnMyEvent );
|
||||||
handler.Disconnect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
|
handler.Disconnect( 0, 0, MyEventType, GlobalOnMyEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvtHandlerTestCase::ConnectStaticMethod()
|
void EvtHandlerTestCase::ConnectStaticMethod()
|
||||||
{
|
{
|
||||||
// static method tests (this is same as functions but still test it just in
|
// static method tests (this is same as functions but still test it just in
|
||||||
// case we hit some strange compiler bugs)
|
// case we hit some strange compiler bugs)
|
||||||
handler.Connect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Connect( MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( g_called.smethod );
|
CPPUNIT_ASSERT( g_called.smethod );
|
||||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Disconnect( MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( !g_called.smethod );
|
CPPUNIT_ASSERT( !g_called.smethod );
|
||||||
|
|
||||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Connect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Disconnect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
|
|
||||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Connect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
|
handler.Disconnect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvtHandlerTestCase::ConnectFunctor()
|
void EvtHandlerTestCase::ConnectFunctor()
|
||||||
@@ -269,50 +283,71 @@ void EvtHandlerTestCase::ConnectFunctor()
|
|||||||
// generalized functor tests
|
// generalized functor tests
|
||||||
MyFunctor functor;
|
MyFunctor functor;
|
||||||
|
|
||||||
handler.Connect( EVT_MYEVENT, functor );
|
handler.Connect( MyEventType, functor );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( g_called.functor );
|
CPPUNIT_ASSERT( g_called.functor );
|
||||||
handler.Disconnect( EVT_MYEVENT, functor );
|
handler.Disconnect( MyEventType, functor );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( !g_called.functor );
|
CPPUNIT_ASSERT( !g_called.functor );
|
||||||
|
|
||||||
handler.Connect( 0, EVT_MYEVENT, functor );
|
handler.Connect( 0, MyEventType, functor );
|
||||||
handler.Disconnect( 0, EVT_MYEVENT, functor );
|
handler.Disconnect( 0, MyEventType, functor );
|
||||||
|
|
||||||
handler.Connect( 0, 0, EVT_MYEVENT, functor );
|
handler.Connect( 0, 0, MyEventType, functor );
|
||||||
handler.Disconnect( 0, 0, EVT_MYEVENT, functor );
|
handler.Disconnect( 0, 0, MyEventType, functor );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvtHandlerTestCase::ConnectMethod()
|
void EvtHandlerTestCase::ConnectMethod()
|
||||||
{
|
{
|
||||||
// class method tests
|
// class method tests
|
||||||
handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent );
|
handler.Connect( MyEventType, &MyHandler::OnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( g_called.method );
|
CPPUNIT_ASSERT( g_called.method );
|
||||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent );
|
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( !g_called.method );
|
CPPUNIT_ASSERT( !g_called.method );
|
||||||
|
|
||||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent );
|
||||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent );
|
||||||
|
|
||||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
|
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent );
|
||||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &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()
|
void EvtHandlerTestCase::ConnectMethodWithSink()
|
||||||
{
|
{
|
||||||
handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Connect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
|
|
||||||
handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Disconnect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvtHandlerTestCase::ConnectNonHandler()
|
void EvtHandlerTestCase::ConnectNonHandler()
|
||||||
@@ -320,11 +355,11 @@ void EvtHandlerTestCase::ConnectNonHandler()
|
|||||||
// class method tests for class not derived from wxEvtHandler
|
// class method tests for class not derived from wxEvtHandler
|
||||||
MySink sink;
|
MySink sink;
|
||||||
|
|
||||||
handler.Connect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
|
handler.Connect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( g_called.method );
|
CPPUNIT_ASSERT( g_called.method );
|
||||||
handler.Disconnect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
|
handler.Disconnect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
|
||||||
g_called.Reset();
|
g_called.Reset();
|
||||||
handler.ProcessEvent(e);
|
handler.ProcessEvent(e);
|
||||||
CPPUNIT_ASSERT( !g_called.method );
|
CPPUNIT_ASSERT( !g_called.method );
|
||||||
@@ -332,13 +367,13 @@ void EvtHandlerTestCase::ConnectNonHandler()
|
|||||||
|
|
||||||
void EvtHandlerTestCase::StaticConnect()
|
void EvtHandlerTestCase::StaticConnect()
|
||||||
{
|
{
|
||||||
wxEvtHandler::Connect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
wxEvtHandler::Connect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
wxEvtHandler::Connect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
wxEvtHandler::Connect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
wxEvtHandler::Connect( &handler, 0, 0, EVT_MYEVENT, &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, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
wxEvtHandler::Disconnect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
wxEvtHandler::Disconnect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
wxEvtHandler::Disconnect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
|
wxEvtHandler::Disconnect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvtHandlerTestCase::InvalidConnect()
|
void EvtHandlerTestCase::InvalidConnect()
|
||||||
@@ -346,10 +381,10 @@ void EvtHandlerTestCase::InvalidConnect()
|
|||||||
// these calls shouldn't compile but we unfortunately can't check this
|
// these calls shouldn't compile but we unfortunately can't check this
|
||||||
// automatically, you need to uncomment them manually and test that
|
// automatically, you need to uncomment them manually and test that
|
||||||
// compilation does indeed fail
|
// compilation does indeed fail
|
||||||
//handler.Connect(EVT_MYEVENT, GlobalOnAnotherEvent);
|
//handler.Connect(MyEventType, GlobalOnAnotherEvent);
|
||||||
//IdleFunctor f; handler.Connect(EVT_MYEVENT, f);
|
//IdleFunctor f; handler.Connect(MyEventType, f);
|
||||||
//handler.Connect(EVT_MYEVENT, &MyHandler::StaticOnAnotherEvent);
|
//handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent);
|
||||||
//handler.Connect(EVT_MYEVENT, &MyHandler::OnAnotherEvent);
|
//handler.Connect(MyEventType, &MyHandler::OnAnotherEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !wxEVENTS_COMPATIBILITY_2_8
|
#endif // !wxEVENTS_COMPATIBILITY_2_8
|
||||||
|
Reference in New Issue
Block a user