From 3f90a3994d2dcdbbebbaa83fdbe879c9dbdec962 Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
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.50.0

