From b3098689305ce9ab1e07bce85d521a6dd32e7759 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 30 May 2019 19:34:09 +0200 Subject: [PATCH] Fix implementation of wxScrolled wxControl::Create() has a different signature than wxWindow::Create() (its 6-th parameter is of const wxValidator& type instead of const wxString&) so it cannot be invoked from the the general template of wxScrolled::Create() method. We need to move a call to T::Create() function to a dedicated template function wxCreateScrolled() responsible for actual creation of the scrolled window and overload it for custom classes if necessary. This has to be done for wxControl and from this overloaded function wxControl::Create() can be called with rearranged parameters. --- include/wx/scrolwin.h | 25 ++++++++++++++++++++++++- interface/wx/scrolwin.h | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index 029b0cb4b9..c7a858feea 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -11,6 +11,7 @@ #ifndef _WX_SCROLWIN_H_BASE_ #define _WX_SCROLWIN_H_BASE_ +#include "wx/control.h" #include "wx/panel.h" class WXDLLIMPEXP_FWD_CORE wxScrollHelperEvtHandler; @@ -378,6 +379,28 @@ struct WXDLLIMPEXP_CORE wxScrolledT_Helper // Scrollable window base on window type T. This used to be wxScrolledWindow, // but wxScrolledWindow includes wxControlContainer functionality and that's // not always desirable. +template +bool wxCreateScrolled(T* self, + wxWindow *parent, wxWindowID winid, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name) +{ + return self->Create(parent, winid, pos, size, style, name); +} + +#if wxUSE_CONTROLS +// For wxControl we have to provide overloaded wxCreateScrolled() +// because wxControl::Create() has 7 parameters and therefore base +// template expecting 6-parameter T::Create() cannot be used. +inline bool wxCreateScrolled(wxControl* self, + wxWindow *parent, wxWindowID winid, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name) +{ + return self->Create(parent, winid, pos, size, style, wxDefaultValidator, name); +} +#endif // wxUSE_CONTROLS + template class wxScrolled : public T, public wxScrollHelper, @@ -415,7 +438,7 @@ public: if ( !(style & (wxHSCROLL | wxVSCROLL)) ) style |= wxHSCROLL | wxVSCROLL; - return T::Create(parent, winid, pos, size, style, name); + return wxCreateScrolled((T*)this, parent, winid, pos, size, style, name); } #ifdef __WXMSW__ diff --git a/interface/wx/scrolwin.h b/interface/wx/scrolwin.h index 177ce0545a..fc62e085b6 100644 --- a/interface/wx/scrolwin.h +++ b/interface/wx/scrolwin.h @@ -33,6 +33,9 @@ enum wxScrollbarVisibility so doesn't handle children specially. This is suitable e.g. for implementing scrollable controls such as tree or list controls. + @note + See wxScrolled::Create() if you want to use wxScrolled with a custom class. + Starting from version 2.4 of wxWidgets, there are several ways to use a ::wxScrolledWindow (and now wxScrolled). In particular, there are three ways to set the size of the scrolling area: @@ -231,8 +234,13 @@ public: /** Creates the window for two-step construction. Derived classes - should call or replace this function. See wxScrolled::wxScrolled() - for details. + should call or replace this function. If it is not replaced, + bear in mind that it calls T::Create() through the global function + wxCreateScrolled() so if T::Create() has a different signature + than wxScrolled::Create() you should implement overloaded + wxCreateScrolled() which would call T::Create() in the correct manner. + + @see wxScrolled::wxScrolled() and wxCreateScrolled() for details. */ bool Create(wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, @@ -590,6 +598,32 @@ protected: virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size); }; +/** + Helper function which is called from wxScrolled::Create() to actually create + a scrolled window. By default it just passes the call to the base class Create(): + @code + self->Create(parent, winid, pos, size, style, name); + @endcode + + You should provide overloaded implementation of this function for the custom + base class if this class is created in a different manner, like it is e.g. + done for wxControl: + @code + bool wxCreateScrolled(wxControl* self, + wxWindow *parent, wxWindowID winid, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name) + { + return self->Create(parent, winid, pos, size, style, wxDefaultValidator, name); + } + @endcode + + @since 3.1.3 +*/ +bool wxCreateScrolled(T* self, + wxWindow *parent, wxWindowID winid, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name); /** Scrolled window derived from wxPanel.