improvements to wxEventFunctor classes; use wxHAS_EVENT_BIND instead of wxEVENTS_COMPATIBILITY_2_8 (see #10653)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2009-05-02 12:52:54 +00:00
parent 1ba0367603
commit 890d70ebea
17 changed files with 329 additions and 273 deletions

View File

@ -682,13 +682,6 @@ WX_ARG_ENABLE_PARAM(universal_binary, [[ --enable-universal_binary create Mac
WX_ARG_ENABLE(compat26, [ --enable-compat26 enable wxWidgets 2.6 compatibility], WXWIN_COMPATIBILITY_2_6)
WX_ARG_DISABLE(compat28, [ --disable-compat28 disable wxWidgets 2.8 compatibility], WXWIN_COMPATIBILITY_2_8)
dnl currently we don't provide a switch for disabling it as it shouldn't be
dnl necessary to do it unless the compiler doesn't support the new events and
dnl this should be tested for by configure itself (but also isn't done yet
dnl because there are no known examples of such compilers among the currently
dnl supported ones)
AC_DEFINE(wxEVENTS_COMPATIBILITY_2_8, 0)
WX_ARG_DISABLE(rpath, [ --disable-rpath disable use of rpath for uninstalled builds], wxUSE_RPATH)
WX_ARG_ENABLE(objc_uniquifying,[ --enable-objc_uniquifying enable Objective-C class name uniquifying], wxUSE_OBJC_UNIQUIFYING)

View File

@ -27,7 +27,7 @@
#include "wx/thread.h"
#include "wx/tracker.h"
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
#include "wx/meta/convertible.h"
#endif
@ -101,7 +101,7 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
// New macros to create templatized event types:
#if wxEVENTS_COMPATIBILITY_2_8
#ifndef wxHAS_EVENT_BIND
// Define/Declare a wxEventType-based event type:
@ -126,7 +126,8 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
#define wxDECLARE_EVENT( name, type ) \
wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type )
#else
#else // wxHAS_EVENT_BIND
// Define/Declare a templatized event type with the corresponding event as
// a nested typedef:
@ -151,16 +152,15 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
#define wxDECLARE_EVENT( name, type ) \
wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type )
#endif
#endif // wxHAS_EVENT_BIND
// Try to cast the given event handler to the correct handler type:
#define wxEVENT_HANDLER_CAST( functype, func ) \
( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
// Template which associates the correct event object with the event type
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
// The tag is a type associated to the event type (which is an integer itself,
// in spite of its name) value. It exists in order to be used as a template
@ -184,7 +184,7 @@ private:
wxEventType m_type;
};
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
// These are needed for the functor definitions
typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
@ -199,6 +199,15 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
typedef wxEventFunction wxObjectEventFunction;
// wxEventFunctorClassInfo is used as a unique identifier for wxEventFunctor-
// derived classes; it is more light weight than wxClassInfo and can be used in
// template classes
typedef void (*wxEventFunctorClassInfo)();
// this macro must be used in wxEventFunctor-derived classes
#define wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( classInfoName ) \
static void classInfoName() {}
// The event functor which is stored in the static and dynamic event tables:
class WXDLLIMPEXP_BASE wxEventFunctor
{
@ -209,54 +218,74 @@ public:
virtual void operator()(wxEvtHandler *, wxEvent&) = 0;
// this function tests whether this functor is matched, for the purpose of
// finding it in an event table in Disconnect(), by the given func
virtual bool Matches(const wxEventFunctor& func) const = 0;
// finding it in an event table in Unbind(), by the given functor:
virtual bool IsMatching(const wxEventFunctor& functor) const = 0;
// these functions are used for functors comparison in Matches()
virtual void *GetHandler() const { return GetEvtHandler(); }
virtual wxEventFunction GetMethod() const { return NULL; }
// Test whether the given class info is the same as from this functor. This
// allows us in IsMatching to safely downcast the given wxEventFunctor without
// the usage of dynamic_cast<>().
virtual bool IsSameClass(wxEventFunctorClassInfo classInfo) const = 0;
// this one is also used elsewhere in the code and should be overridden to
// return non-NULL if we are indeed associated with an wxEvtHandler
virtual wxEvtHandler *GetEvtHandler() const { return NULL; }
// If the functor holds an wxEvtHandler, then get access to it and track
// its lifetime with wxEventConnectionRef:
virtual wxEvtHandler *GetEvtHandler() const
{ return NULL; }
// This is only used to maintain backward compatibility in
// wxAppConsoleBase::CallEventHandler and ensures that an overwritten
// wxAppConsoleBase::HandleEvent is still called for functors which hold an
// wxEventFunction:
virtual wxEventFunction GetEvtMethod() const
{ return NULL; }
};
// A plain method functor: notice that it is used even with the new events as
// it is reused as a specialization of wxEventFunctorMethod for legacy untyped
// event types
// A plain method functor for the untyped legacy event types:
class WXDLLIMPEXP_BASE wxObjectEventFunctor : public wxEventFunctor
{
public:
wxObjectEventFunctor(wxObjectEventFunction method, wxEvtHandler *handler)
: m_handler( handler ), m_method( method )
{ }
virtual void operator()(wxEvtHandler *handler, wxEvent& event)
{
m_handler = handler;
m_method = method;
wxEvtHandler * const realHandler = m_handler ? m_handler : handler;
(realHandler->*m_method)(event);
}
virtual void operator()(wxEvtHandler *handler, wxEvent& event);
virtual bool Matches(const wxEventFunctor& func) const
virtual bool IsMatching(const wxEventFunctor& functor) const
{
void * const handler = func.GetHandler();
if ( handler && GetHandler() != handler )
if ( functor.IsSameClass( sm_classInfo ))
{
const wxObjectEventFunctor &other =
static_cast< const wxObjectEventFunctor & >( functor );
// FIXME-VC6: amazing but true: replacing "method == NULL" here
// with "!method" makes VC6 crash with an ICE in DLL build (only!)
return ( m_method == other.m_method || other.m_method == NULL ) &&
( m_handler == other.m_handler || other.m_handler == NULL );
}
else
return false;
const wxEventFunction method = GetMethod();
// FIXME-VC6: amazing but true: replacing "method == NULL" here with
// "!method" makes VC6 crash with an ICE in DLL build (only!)
return method == NULL || GetMethod() == method;
}
virtual wxEvtHandler *GetEvtHandler() const { return m_handler; }
virtual wxEventFunction GetMethod() const { return m_method; }
virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
{ return sm_classInfo == otherClassInfo; }
virtual wxEvtHandler *GetEvtHandler() const
{ return m_handler; }
virtual wxEventFunction GetEvtMethod() const
{ return m_method; }
private:
wxEvtHandler *m_handler;
wxEventFunction m_method;
};
#if wxEVENTS_COMPATIBILITY_2_8
wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
};
// Create a functor for the legacy events: used by Connect()
inline wxObjectEventFunctor *
@ -283,40 +312,7 @@ wxMakeEventFunctor(const wxEventType& WXUNUSED(evtType),
return wxObjectEventFunctor(method, handler);
}
#else // !wxEVENTS_COMPATIBILITY_2_8
// functor forwarding the event to anything callable (function, static method,
// generalized functor...)
template <typename EventTag, typename Functor>
class wxEventFunctorFunction : public wxEventFunctor
{
public:
typedef typename EventTag::EventClass EventArg;
wxEventFunctorFunction(Functor handler)
{
m_handler = handler;
}
virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event)
{
m_handler(static_cast<EventArg&>(event));
}
virtual bool Matches(const wxEventFunctor& WXUNUSED(func)) const
{
// we have no way to compare arbitrary functors so just consider them
// to be equal: this means that disconnecting a functor will always
// find the last functor connected which in turn implies that it's
// probably a bad idea to connect more than one functor if you plan to
// disconnect them but this limitation doesn't seem very important in
// practice
return true;
}
private:
Functor m_handler;
};
#ifdef wxHAS_EVENT_BIND
namespace wxPrivate
{
@ -356,7 +352,7 @@ struct HandlerImpl<T, A, true>
{ return static_cast<T *>(p); }
static wxEvtHandler *ConvertToEvtHandler(T *p)
{ return p; }
static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&))
static wxEventFunction ConvertToEvtMethod(void (T::*f)(A&))
{ return static_cast<wxEventFunction>(
reinterpret_cast<void (T::*)(wxEvent&)>(f)); }
};
@ -371,7 +367,7 @@ struct HandlerImpl<T, A, false>
{ return NULL; }
static wxEvtHandler *ConvertToEvtHandler(T *)
{ return NULL; }
static wxEventFunction ConvertToEvtFunction(void (T::*)(A&))
static wxEventFunction ConvertToEvtMethod(void (T::*)(A&))
{ return NULL; }
};
@ -406,6 +402,7 @@ public:
wxEventFunctorMethod(void (Class::*method)(EventArg&), EventHandler *handler)
: m_handler( handler ), m_method( method )
{
wxASSERT_MSG( handler || this->IsEvtHandler(),
"handlers defined in non-wxEvtHandler-derived classes "
@ -415,9 +412,6 @@ public:
// 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_method = method;
}
virtual void operator()(wxEvtHandler *handler, wxEvent& event)
@ -437,60 +431,179 @@ public:
(realHandler->*m_method)(static_cast<EventArg&>(event));
}
virtual bool Matches(const wxEventFunctor& func) const
virtual bool IsMatching(const wxEventFunctor& functor) const
{
void * const handler = func.GetHandler();
if ( handler && GetHandler() != handler )
if ( !functor.IsSameClass(sm_classInfo) )
return false;
const wxEventFunction method = GetMethod();
return !method || GetMethod() == method;
typedef wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>
ThisFunctor;
// the cast is valid because IsSameClass() returned true above
const ThisFunctor& other = static_cast<const ThisFunctor &>(functor);
return (m_method == other.m_method || other.m_method == NULL) &&
(m_handler == other.m_handler || other.m_handler == NULL);
}
virtual void *GetHandler() const
{
return m_handler;
}
virtual wxEventFunction GetMethod() const
{
return this->ConvertToEvtFunction(m_method);
}
virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
{ return sm_classInfo == otherClassInfo; }
virtual wxEvtHandler *GetEvtHandler() const
{
return this->ConvertToEvtHandler(m_handler);
}
{ return this->ConvertToEvtHandler(m_handler); }
virtual wxEventFunction GetEvtMethod() const
{ return this->ConvertToEvtMethod(m_method); }
private:
EventHandler *m_handler;
void (Class::*m_method)(EventArg&);
wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
};
// functor forwarding the event to function (function, static method)
template <typename EventTag, typename EventArg>
class wxEventFunctorFunction : public wxEventFunctor
{
private:
static void CheckHandlerArgument(EventArg *) { }
public:
// the event class associated with the given event tag
typedef typename wxPrivate::EventClassOf<EventTag>::type EventClass;
wxEventFunctorFunction( void ( *handler )( EventArg & ))
: m_handler( handler )
{
// 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));
}
virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event)
{
// If you get an error here like "must use .* or ->* to call
// pointer-to-member function" then you probably tried to call
// Bind/Unbind with a method pointer but without a handler pointer or
// NULL as a handler e.g.:
// Unbind( wxEVT_XXX, &EventHandler::method );
// or
// Unbind( wxEVT_XXX, &EventHandler::method, NULL )
m_handler(static_cast<EventArg&>(event));
}
virtual bool IsMatching(const wxEventFunctor &functor) const
{
if ( !functor.IsSameClass(sm_classInfo) )
return false;
typedef wxEventFunctorFunction<EventTag, EventArg> ThisFunctor;
const ThisFunctor& other = static_cast<const ThisFunctor&>( functor );
return m_handler == other.m_handler;
}
virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
{ return sm_classInfo == otherClassInfo; }
private:
void (*m_handler)(EventArg&);
wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
};
template <typename EventTag, typename Functor>
class wxEventFunctorFunctor : public wxEventFunctor
{
public:
typedef typename EventTag::EventClass EventArg;
wxEventFunctorFunctor(Functor& handler)
: m_handler(handler), m_handlerAddr(&handler)
{ }
virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event)
{
// If you get an error here like "must use '.*' or '->*' to call
// pointer-to-member function" then you probably tried to call
// Bind/Unbind with a method pointer but without a handler pointer or
// NULL as a handler e.g.:
// Unbind( wxEVT_XXX, &EventHandler::method );
// or
// Unbind( wxEVT_XXX, &EventHandler::method, NULL )
m_handler(static_cast<EventArg&>(event));
}
virtual bool IsMatching(const wxEventFunctor &functor) const
{
if ( !functor.IsSameClass(sm_classInfo) )
return false;
typedef wxEventFunctorFunctor<EventTag, Functor> FunctorThis;
const FunctorThis& other = static_cast<const FunctorThis&>(functor);
// The only reliable/portable way to compare two functors is by
// identity:
return m_handlerAddr == other.m_handlerAddr;
}
virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
{ return sm_classInfo == otherClassInfo; }
private:
// Store a copy of the functor to prevent using/calling an already
// destroyed instance:
Functor m_handler;
// Use the address of the original functor for comparison in IsMatching:
const void *m_handlerAddr;
wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
};
// Create functors for the templatized events, either allocated on the heap for
// wxNewXXX() variants (this is needed in wxEvtHandler::Bind<>() to store them
// in dynamic event table) or just by returning them as temporary objects (this
// in dynamic event table) or just by returning them as a temporary objects (this
// is enough for Unbind<>() and we avoid unnecessary heap allocation like this).
// Create functors wrapping other functors (including functions):
template <typename EventTag, typename Functor>
inline wxEventFunctorFunction<EventTag, Functor> *
wxNewEventFunctor(const EventTag&, Functor func)
// Create functors wrapping functions:
template <typename EventTag, typename EventArg>
inline wxEventFunctorFunction<EventTag, EventArg> *
wxNewEventFunctor(const EventTag&, void (*func)(EventArg &))
{
return new wxEventFunctorFunction<EventTag, Functor>(func);
return new wxEventFunctorFunction<EventTag, EventArg>(func);
}
template <typename EventTag, typename EventArg>
inline wxEventFunctorFunction<EventTag, EventArg>
wxMakeEventFunctor(const EventTag&, void (*func)(EventArg &))
{
return wxEventFunctorFunction<EventTag, EventArg>(func);
}
// Create functors wrapping other functors:
template <typename EventTag, typename Functor>
inline wxEventFunctorFunctor<EventTag, Functor> *
wxNewEventFunctor(const EventTag&, Functor &func)
{
return new wxEventFunctorFunctor<EventTag, Functor>(func);
}
template <typename EventTag, typename Functor>
inline wxEventFunctorFunction<EventTag, Functor>
wxMakeEventFunctor(const EventTag&, Functor func)
inline wxEventFunctorFunctor<EventTag, Functor>
wxMakeEventFunctor(const EventTag&, Functor &func)
{
return wxEventFunctorFunction<EventTag, Functor>(func);
return wxEventFunctorFunctor<EventTag, Functor>(func);
}
// Create functors for methods:
// Create functors wrapping methods:
template
<typename EventTag, typename Class, typename EventArg, typename EventHandler>
inline wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler> *
@ -524,7 +637,7 @@ wxNewEventTableFunctor(const EventTag&, void (Class::*method)(EventArg&))
method, NULL);
}
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
// many, but not all, standard event types
@ -2871,7 +2984,7 @@ public:
wxObject *userData = NULL,
wxEvtHandler *eventSink = NULL)
{
DoConnect(winid, lastId, eventType,
DoBind(winid, lastId, eventType,
wxNewEventFunctor(eventType, func, eventSink),
userData);
}
@ -2898,7 +3011,7 @@ public:
wxObject *userData = NULL,
wxEvtHandler *eventSink = NULL)
{
return DoDisconnect(winid, lastId, eventType,
return DoUnbind(winid, lastId, eventType,
wxMakeEventFunctor(eventType, func, eventSink),
userData );
}
@ -2916,16 +3029,42 @@ public:
wxEvtHandler *eventSink = NULL)
{ return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
#if !wxEVENTS_COMPATIBILITY_2_8
// Bind arbitrary functor (including just a function) to an event:
template <typename EventTag, typename Functor>
#ifdef wxHAS_EVENT_BIND
// Bind functions to an event:
template <typename EventTag, typename EventArg>
void Bind(const EventTag& eventType,
Functor functor,
void (*function)(EventArg &),
int winid = wxID_ANY,
int lastId = wxID_ANY,
wxObject *userData = NULL)
{
DoConnect(winid, lastId, eventType,
DoBind(winid, lastId, eventType,
wxNewEventFunctor(eventType, function),
userData);
}
template <typename EventTag, typename EventArg>
bool Unbind(const EventTag& eventType,
void (*function)(EventArg &),
int winid = wxID_ANY,
int lastId = wxID_ANY,
wxObject *userData = NULL)
{
return DoUnbind(winid, lastId, eventType,
wxMakeEventFunctor(eventType, function),
userData);
}
// Bind functors to an event:
template <typename EventTag, typename Functor>
void Bind(const EventTag& eventType,
Functor &functor,
int winid = wxID_ANY,
int lastId = wxID_ANY,
wxObject *userData = NULL)
{
DoBind(winid, lastId, eventType,
wxNewEventFunctor(eventType, functor),
userData);
}
@ -2933,12 +3072,12 @@ public:
template <typename EventTag, typename Functor>
bool Unbind(const EventTag& eventType,
Functor functor,
Functor &functor,
int winid = wxID_ANY,
int lastId = wxID_ANY,
wxObject *userData = NULL)
{
return DoDisconnect(winid, lastId, eventType,
return DoUnbind(winid, lastId, eventType,
wxMakeEventFunctor(eventType, functor),
userData);
}
@ -2955,7 +3094,7 @@ public:
int lastId = wxID_ANY,
wxObject *userData = NULL)
{
DoConnect(winid, lastId, eventType,
DoBind(winid, lastId, eventType,
wxNewEventFunctor(eventType, method, handler),
userData);
}
@ -2968,11 +3107,11 @@ public:
int lastId = wxID_ANY,
wxObject *userData = NULL )
{
return DoDisconnect(winid, lastId, eventType,
return DoUnbind(winid, lastId, eventType,
wxMakeEventFunctor(eventType, method, handler),
userData);
}
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
wxList* GetDynamicEventTable() const { return m_dynamicEvents ; }
@ -3014,13 +3153,13 @@ public:
private:
void DoConnect(int winid,
void DoBind(int winid,
int lastId,
wxEventType eventType,
wxEventFunctor *func,
wxObject* userData = NULL);
bool DoDisconnect(int winid,
bool DoUnbind(int winid,
int lastId,
wxEventType eventType,
const wxEventFunctor& func,
@ -3155,13 +3294,6 @@ private:
wxDECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef);
};
inline void wxObjectEventFunctor::operator()(wxEvtHandler *handler, wxEvent& event)
{
wxEvtHandler * const realHandler = m_handler ? m_handler : handler;
(realHandler->*m_method)(event);
}
// Post a message to the given event handler which will be processed during the
// next event loop iteration.
//
@ -3771,17 +3903,17 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
// (and not in a private header) because the base class must be visible from
// other public headers, please do NOT use this in your code, it will be
// removed from future wx versions without warning.
#if wxEVENTS_COMPATIBILITY_2_8
#ifndef wxHAS_EVENT_BIND
#define wxBIND_OR_CONNECT_HACK_BASE_CLASS public wxEvtHandler,
#define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS : public wxEvtHandler
#define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \
win->Connect(evt, handler(func), NULL, obj)
#else // wxEVENTS_COMPATIBILITY_2_8
#else // wxHAS_EVENT_BIND
#define wxBIND_OR_CONNECT_HACK_BASE_CLASS
#define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
#define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \
win->Bind(evt, &func, obj)
#endif // wxEVENTS_COMPATIBILITY_2_8/!wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
#if wxUSE_GUI

View File

@ -99,5 +99,13 @@
#define wxHAVE_RAW_BITMAP
#endif
/*
If this is defined, wxEvtHandler::Bind<>() is available (not all compilers
have the required template support for this and in particular under Windows
where only g++ and MSVC >= 7 currently support it, for the others it will be
undefined in wx/chkconf.h).
*/
#define wxHAS_EVENT_BIND
#endif /* _WX_FEATURES_H_ */

View File

@ -47,19 +47,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -415,10 +415,9 @@
Currently only recent MSVC compilers can build the new events code under
Windows.
*/
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
# if !wxCHECK_VISUALC_VERSION(7)
# undef wxEVENTS_COMPATIBILITY_2_8
# define wxEVENTS_COMPATIBILITY_2_8 1
# undef wxHAS_EVENT_BIND
# endif
#endif

View File

@ -47,19 +47,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -47,19 +47,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -47,19 +47,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -48,19 +48,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -47,19 +47,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -43,19 +43,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -46,19 +46,6 @@
// Recommended setting: 0 (please update your code)
#define WXWIN_COMPATIBILITY_2_8 1
// Use the 2.8-compatible events and Connect(): this is set to 0 by default as
// the new events bring significant benefits in compile-time safety and
// flexibility but can be disabled to somewhat reduce the compilation time and,
// especially, to still allow building if the compiler template support is too
// bad to compile the new code.
//
// Default is 0 but this is set to 1 automatically in wx/chkconf.h for the
// compilers which can't build the new code (currently only g++ and MSVC >= 8
// can)
//
// Recommended setting: 0
#define wxEVENTS_COMPATIBILITY_2_8 0
// MSW-only: Set to 0 for accurate dialog units, else 1 for old behaviour when
// default system font is used for wxWindow::GetCharWidth/Height() instead of
// the current font.

View File

@ -77,9 +77,9 @@ public:
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
void OnBind(wxCommandEvent& event);
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
void OnConnect(wxCommandEvent& event);
void OnDynamic(wxCommandEvent& event);
void OnPushEventHandler(wxCommandEvent& event);
@ -177,9 +177,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Event_Quit, MyFrame::OnQuit)
EVT_MENU(Event_About, MyFrame::OnAbout)
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
EVT_MENU(Event_Bind, MyFrame::OnBind)
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
EVT_MENU(Event_Connect, MyFrame::OnConnect)
EVT_MENU(Event_Custom, MyFrame::OnFireCustom)
@ -257,10 +257,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
menuFile->Append(Event_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
wxMenu *menuEvent = new wxMenu;
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
menuEvent->AppendCheckItem(Event_Bind, "&Bind\tCtrl-B",
"Bind or unbind a dynamic event handler");
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
menuEvent->AppendCheckItem(Event_Connect, _T("&Connect\tCtrl-C"),
_T("Connect or disconnect the dynamic event handler"));
menuEvent->Append(Event_Dynamic, _T("&Dynamic event\tCtrl-D"),
@ -352,7 +352,7 @@ void MyFrame::OnDynamic(wxCommandEvent& event)
);
}
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
void MyFrame::OnBind(wxCommandEvent& event)
{
@ -379,7 +379,7 @@ void MyFrame::OnBind(wxCommandEvent& event)
UpdateDynamicStatus(event.IsChecked());
}
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
void MyFrame::OnConnect(wxCommandEvent& event)
{

View File

@ -152,8 +152,6 @@
#define WXWIN_COMPATIBILITY_2_8 0
#define wxEVENTS_COMPATIBILITY_2_8 0
#define wxDIALOG_UNIT_COMPATIBILITY 0

View File

@ -503,7 +503,7 @@ void wxAppConsoleBase::CallEventHandler(wxEvtHandler *handler,
{
// If the functor holds a method then, for backward compatibility, call
// HandleEvent():
wxEventFunction eventFunction = functor.GetMethod();
wxEventFunction eventFunction = functor.GetEvtMethod();
if ( eventFunction )
HandleEvent(handler, eventFunction, event);

View File

@ -1415,11 +1415,11 @@ bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
return false;
}
void wxEvtHandler::DoConnect(int id,
int lastId,
wxEventType eventType,
wxEventFunctor *func,
wxObject *userData)
void wxEvtHandler::DoBind(int id,
int lastId,
wxEventType eventType,
wxEventFunctor *func,
wxObject *userData)
{
wxDynamicEventTableEntry *entry =
new wxDynamicEventTableEntry(eventType, id, lastId, func, userData);
@ -1443,11 +1443,11 @@ void wxEvtHandler::DoConnect(int id,
}
bool
wxEvtHandler::DoDisconnect(int id,
int lastId,
wxEventType eventType,
const wxEventFunctor& func,
wxObject *userData)
wxEvtHandler::DoUnbind(int id,
int lastId,
wxEventType eventType,
const wxEventFunctor& func,
wxObject *userData)
{
if (!m_dynamicEvents)
return false;
@ -1469,7 +1469,7 @@ wxEvtHandler::DoDisconnect(int id,
if ((entry->m_id == id) &&
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
entry->m_fn->Matches(func) &&
entry->m_fn->IsMatching(func) &&
((entry->m_callbackUserData == userData) || !userData))
{
delete entry->m_callbackUserData;

View File

@ -37,7 +37,7 @@ public:
};
typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
#if wxEVENTS_COMPATIBILITY_2_8
#ifndef wxHAS_EVENT_BIND
#define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
#else
#define MyEventHandler(func) &func
@ -75,6 +75,11 @@ void GlobalOnMyEvent(MyEvent&)
g_called.function = true;
}
void GlobalOnEvent(wxEvent&)
{
g_called.function = true;
}
void GlobalOnAnotherEvent(AnotherEvent&);
void GlobalOnIdle(wxIdleEvent&)
@ -130,7 +135,7 @@ BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
EVT_IDLE(MyClassWithEventTable::OnIdle)
EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
EVT_MYEVENT(MyClassWithEventTable::OnEvent)
#endif
@ -155,28 +160,30 @@ private:
CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
CPPUNIT_TEST( BuiltinConnect );
CPPUNIT_TEST( LegacyConnect );
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
CPPUNIT_TEST( BindFunction );
CPPUNIT_TEST( BindStaticMethod );
CPPUNIT_TEST( BindFunctor );
CPPUNIT_TEST( BindMethod );
CPPUNIT_TEST( BindMethodUsingBaseEvent );
CPPUNIT_TEST( BindFunctionUsingBaseEvent );
CPPUNIT_TEST( BindNonHandler );
CPPUNIT_TEST( InvalidBind );
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
CPPUNIT_TEST_SUITE_END();
void BuiltinConnect();
void LegacyConnect();
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
void BindFunction();
void BindStaticMethod();
void BindFunctor();
void BindMethod();
void BindMethodUsingBaseEvent();
void BindFunctionUsingBaseEvent();
void BindNonHandler();
void InvalidBind();
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
// these member variables exceptionally don't use "m_" prefix because
@ -206,7 +213,7 @@ void EvtHandlerTestCase::BuiltinConnect()
handler.Connect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
handler.Bind(wxEVT_IDLE, GlobalOnIdle);
handler.Unbind(wxEVT_IDLE, GlobalOnIdle);
@ -219,7 +226,7 @@ void EvtHandlerTestCase::BuiltinConnect()
handler.Bind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
handler.Unbind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND
}
void EvtHandlerTestCase::LegacyConnect()
@ -242,7 +249,7 @@ void EvtHandlerTestCase::LegacyConnect()
handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
}
#if !wxEVENTS_COMPATIBILITY_2_8
#ifdef wxHAS_EVENT_BIND
void EvtHandlerTestCase::BindFunction()
{
@ -345,6 +352,29 @@ void EvtHandlerTestCase::BindMethodUsingBaseEvent()
}
void EvtHandlerTestCase::BindFunctionUsingBaseEvent()
{
// test connecting a function taking just wxEvent and not MyEvent: this
// should work too if we don't need any MyEvent-specific information in the
// handler
handler.Bind( MyEventType, GlobalOnEvent );
g_called.Reset();
handler.ProcessEvent(e);
CPPUNIT_ASSERT( g_called.function );
handler.Unbind( MyEventType, GlobalOnEvent );
g_called.Reset();
handler.ProcessEvent(e);
CPPUNIT_ASSERT( !g_called.function );
handler.Bind( MyEventType, GlobalOnEvent, 0 );
handler.Unbind( MyEventType, GlobalOnEvent, 0 );
handler.Bind( MyEventType, GlobalOnEvent, 0, 0 );
handler.Unbind( MyEventType, GlobalOnEvent, 0, 0 );
}
void EvtHandlerTestCase::BindNonHandler()
{
// class method tests for class not derived from wxEvtHandler
@ -402,4 +432,4 @@ void EvtHandlerTestCase::InvalidBind()
#endif
}
#endif // !wxEVENTS_COMPATIBILITY_2_8
#endif // wxHAS_EVENT_BIND