From 3f90a3994d2dcdbbebbaa83fdbe879c9dbdec962 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sat, 30 Sep 2006 15:37:52 +0000 Subject: [PATCH] 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 --- docs/latex/wx/variant.tex | 46 ++++++++++++++++++++-- include/wx/variant.h | 83 +++++++++++++++++++++++++++++++++++++-- src/common/variant.cpp | 8 +++- 3 files changed, 128 insertions(+), 9 deletions(-) diff --git a/docs/latex/wx/variant.tex b/docs/latex/wx/variant.tex index a6cd0b1a1c..11c574c389 100644 --- a/docs/latex/wx/variant.tex +++ b/docs/latex/wx/variant.tex @@ -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. - -Note that as of wxWidgets 2.7.1, wxVariant is reference counted. +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. 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} diff --git a/include/wx/variant.h b/include/wx/variant.h index 10a8fa896e..8f36485474 100644 --- a/include/wx/variant.h +++ b/include/wx/variant.h @@ -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) ?\ diff --git a/src/common/variant.cpp b/src/common/variant.cpp index df261de03f..308965606b 100644 --- a/src/common/variant.cpp +++ b/src/common/variant.cpp @@ -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 -- 2.45.2