Added DECLARE_VARIANT_OBJECT macros for easy conversion

from and to wxVariant using the shift left operator.
  Use the for GDI classes and wxImage.
  Document it.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41532 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling 2006-09-30 15:37:52 +00:00
parent cdd8d745c4
commit 3f90a3994d
3 changed files with 127 additions and 8 deletions

View File

@ -31,10 +31,48 @@ type-safety checks at runtime.
This class is useful for reducing the programming for certain tasks, such as an editor
for different data types, or a remote procedure call protocol.
An optional name member is associated with a wxVariant. This might be used, for example, in CORBA
or OLE automation classes, where named parameters are required.
An optional name member is associated with a wxVariant. This might be used, for example,
in CORBA or OLE automation classes, where named parameters are required.
Note that as of wxWidgets 2.7.1, wxVariant is reference counted.
Note that as of wxWidgets 2.7.1, wxVariant is reference counted. Additionly, the
conveniance macros {\bf DECLARE\_VARIANT\_OBJECT} and {\bf IMPLEMENT\_VARIANT\_OBJECT}
were added so that adding (limited) support for conversion to and from wxVariant
can be very easily implemented without modifiying either the wxVariant or the class
to be stored by wxVariant. Since assignement operators cannot be declared outside
the class, the shift left operators are used like this:
\begin{verbatim}
// in the header file
DECLARE_VARIANT_OBJECT(MyClass)
// in the implementation file
IMPLMENT_VARIANT_OBJECT(MyClass)
// in the user code
wxVariant variant;
MyClass value;
variant << value;
// or
value << variant;
\end{verbatim}
For this to work, MyClass must derive from \helpref{wxObject}{wxobject}, implement
the \helpref{wxWidgets RTTI system}{runtimeclassoverview}
and support the assignment operator and equality operator for itself. Ideally, it
should also be reference counted to make copying operations cheap and fast. This
can be most easily implemented using the reference counting support offered by
\helpref{wxObject}{wxobject} itself. By default, wxWidgets already implements
the shift operator conversion for a few of its drawing related classes:
\begin{verbatim}
IMPLEMENT_VARIANT_OBJECT(wxColour)
IMPLEMENT_VARIANT_OBJECT(wxPen)
IMPLEMENT_VARIANT_OBJECT(wxBrush)
IMPLEMENT_VARIANT_OBJECT(wxImage)
IMPLEMENT_VARIANT_OBJECT(wxIcon)
IMPLEMENT_VARIANT_OBJECT(wxBitmap)
\end{verbatim}
\wxheading{Derived from}

View File

@ -316,9 +316,86 @@ private:
DECLARE_DYNAMIC_CLASS(wxVariant)
};
//Since we want type safety wxVariant we need to fetch and dynamic_cast
//in a seemingly safe way so the compiler can check, so we define
//a dynamic_cast /wxDynamicCast analogue.
#define DECLARE_VARIANT_OBJECT(classname) \
classname& operator << ( classname &object, const wxVariant &variant ); \
wxVariant& operator << ( wxVariant &variant, const classname &object );
#define IMPLEMENT_VARIANT_OBJECT(classname) \
class classname##VariantData: public wxVariantData \
{ \
public:\
classname##VariantData() {} \
classname##VariantData( const classname &value ) { m_value = value; } \
\
classname &GetValue() { return m_value; } \
\
virtual bool Eq(wxVariantData& data) const; \
\
virtual wxString GetType() const; \
virtual wxClassInfo* GetValueClassInfo(); \
\
protected:\
classname m_value; \
\
private: \
DECLARE_CLASS(classname##VariantData) \
};\
\
IMPLEMENT_CLASS(classname##VariantData, wxVariantData)\
\
bool classname##VariantData::Eq(wxVariantData& data) const \
{\
wxASSERT( wxIsKindOf((&data), classname##VariantData) );\
\
classname##VariantData & otherData = (classname##VariantData &) data;\
\
return (otherData.m_value == m_value);\
}\
\
wxString classname##VariantData::GetType() const\
{\
return m_value.GetClassInfo()->GetClassName();\
}\
\
wxClassInfo* classname##VariantData::GetValueClassInfo()\
{\
return m_value.GetClassInfo();\
}\
\
classname& operator << ( classname &value, const wxVariant &variant )\
{\
wxASSERT( wxIsKindOf( variant.GetData(), classname##VariantData ) );\
\
classname##VariantData *data = (classname##VariantData*) variant.GetData();\
value = data->GetValue();\
return value;\
}\
\
wxVariant& operator << ( wxVariant &variant, const classname &value )\
{\
classname##VariantData *data = new classname##VariantData( value );\
variant.SetData( data );\
return variant;\
}
#include "wx/colour.h"
#include "wx/pen.h"
#include "wx/brush.h"
#include "wx/image.h"
#include "wx/icon.h"
#include "wx/bitmap.h"
DECLARE_VARIANT_OBJECT(wxColour)
DECLARE_VARIANT_OBJECT(wxPen)
DECLARE_VARIANT_OBJECT(wxBrush)
DECLARE_VARIANT_OBJECT(wxImage)
DECLARE_VARIANT_OBJECT(wxIcon)
DECLARE_VARIANT_OBJECT(wxBitmap)
// Since we want type safety wxVariant we need to fetch and dynamic_cast
// in a seemingly safe way so the compiler can check, so we define
// a dynamic_cast /wxDynamicCast analogue.
#define wxGetVariantCast(var,classname) \
((classname*)(var.IsValueKindOf(&classname::ms_classInfo) ?\

View File

@ -2026,7 +2026,11 @@ bool wxVariant::Convert(wxDateTime* value) const
}
#endif // wxUSE_DATETIME
IMPLEMENT_VARIANT_OBJECT(wxColour)
IMPLEMENT_VARIANT_OBJECT(wxPen)
IMPLEMENT_VARIANT_OBJECT(wxBrush)
IMPLEMENT_VARIANT_OBJECT(wxImage)
IMPLEMENT_VARIANT_OBJECT(wxIcon)
IMPLEMENT_VARIANT_OBJECT(wxBitmap)
#endif // wxUSE_VARIANT