From 40730ad17db78193611389a3d12db772b28eac31 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2010 14:33:58 +0000 Subject: [PATCH] Make it easier to define custom wxSizerXmlHandler subclasses. No real changes but refactor wxSizerXmlHandler to make it easier to derive from it by adding virtual IsSizerNode() and DoCreateSizer() methods. To add support for a custom sizer class you only need to override them in wxSizerXmlHandler subclass now. Also document wxSizerXmlHandler which was not documented at all previously. Closes #11845. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/xrc/xh_sizer.h | 5 +- interface/wx/xrc/xh_sizer.h | 106 ++++++++++++++++++++++++++++++++++++ src/xrc/xh_sizer.cpp | 70 ++++++++++++------------ 3 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 interface/wx/xrc/xh_sizer.h 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); -- 2.45.2