diff --git a/include/wx/xrc/xh_sizer.h b/include/wx/xrc/xh_sizer.h index 5d57d7ea66..5c941dea97 100644 --- a/include/wx/xrc/xh_sizer.h +++ b/include/wx/xrc/xh_sizer.h @@ -27,13 +27,16 @@ public: virtual wxObject *DoCreateResource(); virtual bool CanHandle(wxXmlNode *node); +protected: + virtual wxSizer* DoCreateSizer(const wxString& name); + virtual bool IsSizerNode(wxXmlNode *node) const; + private: bool m_isInside; bool m_isGBS; wxSizer *m_parentSizer; - bool IsSizerNode(wxXmlNode *node); wxObject* Handle_sizeritem(); wxObject* Handle_spacer(); diff --git a/interface/wx/xrc/xh_sizer.h b/interface/wx/xrc/xh_sizer.h new file mode 100644 index 0000000000..2690a0d8e2 --- /dev/null +++ b/interface/wx/xrc/xh_sizer.h @@ -0,0 +1,106 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: xrc/xh_sizer.h +// Purpose: XML resource handler for wxSizer +// Author: Kinaou Hervé +// Created: 2010-10-24 +// Copyright: (c) 2010 wxWidgets development team +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +/** + @class wxSizerXmlHandler + + @class wxXmlResourceHandler + + wxSizerXmlHandler is a class for resource handlers capable of creating + a wxSizer object from an XML node. + + @see wxXmlResourceHandler, wxSizer + + @library{wxxrc} + @category{xrc} +*/ +class wxSizerXmlHandler : public wxXmlResourceHandler +{ +public: + /** + Constructor. + Initializes the attributes and adds the supported styles. + */ + wxSizerXmlHandler(); + + /** + Creates a sizer, sizeritem or spacer object, depending on + the current handled node. + @see wxXmlResourceHandler::DoCreateResource(). + */ + virtual wxObject *DoCreateResource(); + + /** + Returns @true if the given node can be handled by this class. + If the node concerns a sizer object, the method IsSizerNode is called + to know if the class is managed or not. + If the node concerns a sizer item or a spacer, @true is returned. + Otherwise @false is returned. + @see wxXmlResourceHandler::CanHandle(). + */ + virtual bool CanHandle(wxXmlNode *node); + +protected: + /** + Creates an object of type wxSizer from the XML node content. + + This virtual method can be overridden to add support for custom sizer + classes to the derived handler. + + Notice that if you override this method you would typically overload + IsSizerNode() as well. + + Example of use of this method: + @code + class MySizerXmlHandler : public wxSizerXmlHandler + { + ... + + prottected: + bool IsSizerNode(wxXmlNode *node) const + { + return IsOfClass(node, "MySizer") || + wxSizerXmlHandler::IsSizerNode(node)); + } + + void DoCreateSizer(const wxString& name) + { + if ( name == "MySizer" ) + return Handle_MySizer(); + else + return wxSizerXmlHandler::DoCreateSizer(name); + } + + private: + wxSizer* Handle_MySizer() + { + // Create your own sizer here from XRC content (see + // wxXmlResource methods) and return the instance. + } + }; + @endcode + + @since 2.9.2 + */ + virtual wxSizer* DoCreateSizer(const wxString& name); + + /** + Used by CanHandle() to know if the given node contains a sizer + supported by this class. + + This method should be overridden to allow this handler to be used for + the custom sizer types. + + See the example in DoCreateSizer() description for how it can be used. + + @since 2.9.2 + */ + virtual bool IsSizerNode(wxXmlNode *node) const; + +}; diff --git a/src/xrc/xh_sizer.cpp b/src/xrc/xh_sizer.cpp index 30a1175b00..9e3d23d2ff 100644 --- a/src/xrc/xh_sizer.cpp +++ b/src/xrc/xh_sizer.cpp @@ -115,9 +115,40 @@ wxObject* wxSizerXmlHandler::DoCreateResource() } +wxSizer* wxSizerXmlHandler::DoCreateSizer(const wxString& name) +{ + if (name == wxT("wxBoxSizer")) + return Handle_wxBoxSizer(); +#if wxUSE_STATBOX + else if (name == wxT("wxStaticBoxSizer")) + return Handle_wxStaticBoxSizer(); +#endif + else if (name == wxT("wxGridSizer")) + { + if ( !ValidateGridSizerChildren() ) + return NULL; + return Handle_wxGridSizer(); + } + else if (name == wxT("wxFlexGridSizer")) + { + return Handle_wxFlexGridSizer(); + } + else if (name == wxT("wxGridBagSizer")) + { + return Handle_wxGridBagSizer(); + } + else if (name == wxT("wxWrapSizer")) + { + return Handle_wxWrapSizer(); + } + + ReportError(wxString::Format("unknown sizer class \"%s\"", name)); + return NULL; +} -bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node) + +bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node) const { return (IsOfClass(node, wxT("wxBoxSizer"))) || (IsOfClass(node, wxT("wxStaticBoxSizer"))) || @@ -195,9 +226,6 @@ wxObject* wxSizerXmlHandler::Handle_spacer() wxObject* wxSizerXmlHandler::Handle_sizer() { - wxSizer *sizer = NULL; - wxFlexGridSizer *flexsizer = NULL; - wxXmlNode *parentNode = m_node->GetParent(); if ( !m_parentSizer && @@ -208,36 +236,8 @@ wxObject* wxSizerXmlHandler::Handle_sizer() return NULL; } - if (m_class == wxT("wxBoxSizer")) - sizer = Handle_wxBoxSizer(); -#if wxUSE_STATBOX - else if (m_class == wxT("wxStaticBoxSizer")) - sizer = Handle_wxStaticBoxSizer(); -#endif - else if (m_class == wxT("wxGridSizer")) - { - if ( !ValidateGridSizerChildren() ) - return NULL; - sizer = Handle_wxGridSizer(); - } - else if (m_class == wxT("wxFlexGridSizer")) - { - flexsizer = Handle_wxFlexGridSizer(); - sizer = flexsizer; - } - else if (m_class == wxT("wxGridBagSizer")) - { - flexsizer = Handle_wxGridBagSizer(); - sizer = flexsizer; - } - else if (m_class == wxT("wxWrapSizer")) - { - sizer = Handle_wxWrapSizer(); - } - else - { - ReportError(wxString::Format("unknown sizer class \"%s\"", m_class)); - } + // Create the sizer of the appropriate class. + wxSizer * const sizer = DoCreateSizer(m_class); // creation of sizer failed for some (already reported) reason, so exit: if ( !sizer ) @@ -259,7 +259,7 @@ wxObject* wxSizerXmlHandler::Handle_sizer() CreateChildren(m_parent, true/*only this handler*/); // set growable rows and cols for sizers which support this - if ( flexsizer ) + if ( wxFlexGridSizer *flexsizer = wxDynamicCast(sizer, wxFlexGridSizer) ) { SetGrowables(flexsizer, wxT("growablerows"), true); SetGrowables(flexsizer, wxT("growablecols"), false);