From 52ae67ef86cbc7644107191606687c26e8d1d1d4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Jan 2020 03:47:23 +0100 Subject: [PATCH] Replace dynamic casts with virtual wxWindow::WXGetTextEntry() Instead of checking for all text-like controls one by one in wxCommandEvent::GetString(), call a virtual function checking for this. This is simpler, less error-prone and faster -- at the cost of increasing the vtbl size of all wxWindow-derived classes. Closes https://github.com/wxWidgets/wxWidgets/pull/1696 --- include/wx/gtk/combobox.h | 2 ++ include/wx/gtk1/combobox.h | 2 ++ include/wx/motif/combobox.h | 2 ++ include/wx/msw/combobox.h | 2 ++ include/wx/osx/combobox.h | 2 ++ include/wx/qt/combobox.h | 2 ++ include/wx/srchctrl.h | 4 ++++ include/wx/textctrl.h | 2 ++ include/wx/univ/combobox.h | 2 ++ include/wx/window.h | 3 +++ src/common/event.cpp | 37 ++++++++++--------------------------- 11 files changed, 33 insertions(+), 27 deletions(-) diff --git a/include/wx/gtk/combobox.h b/include/wx/gtk/combobox.h index cb64c7aaf6..1daf836a4a 100644 --- a/include/wx/gtk/combobox.h +++ b/include/wx/gtk/combobox.h @@ -128,6 +128,8 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + protected: // From wxWindowGTK: virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; diff --git a/include/wx/gtk1/combobox.h b/include/wx/gtk1/combobox.h index 55a828207c..8c54feb568 100644 --- a/include/wx/gtk1/combobox.h +++ b/include/wx/gtk1/combobox.h @@ -157,6 +157,8 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); + virtual const wxTextEntry* WXGetTextEntry() const { return this; } + protected: virtual int DoInsertItems(const wxArrayStringsAdapter& items, unsigned int pos, diff --git a/include/wx/motif/combobox.h b/include/wx/motif/combobox.h index 4eb14d5342..7179a01dc0 100644 --- a/include/wx/motif/combobox.h +++ b/include/wx/motif/combobox.h @@ -108,6 +108,8 @@ public: virtual void Popup() { wxFAIL_MSG( wxT("Not implemented") ); } virtual void Dismiss() { wxFAIL_MSG( wxT("Not implemented") ); } + virtual const wxTextEntry* WXGetTextEntry() const { return this; } + protected: virtual wxSize DoGetBestSize() const; virtual void DoSetSize(int x, int y, diff --git a/include/wx/msw/combobox.h b/include/wx/msw/combobox.h index 027b7c277e..1e0a6e6182 100644 --- a/include/wx/msw/combobox.h +++ b/include/wx/msw/combobox.h @@ -128,6 +128,8 @@ public: virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE; + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + protected: #if wxUSE_TOOLTIPS virtual void DoSetToolTip(wxToolTip *tip) wxOVERRIDE; diff --git a/include/wx/osx/combobox.h b/include/wx/osx/combobox.h index ab85a712bd..3d00efd9b8 100644 --- a/include/wx/osx/combobox.h +++ b/include/wx/osx/combobox.h @@ -102,6 +102,8 @@ class WXDLLIMPEXP_CORE wxComboBox : #endif // wxOSX_USE_COCOA + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + // osx specific event handling common for all osx-ports virtual bool OSXHandleClicked(double timestampsec) wxOVERRIDE; diff --git a/include/wx/qt/combobox.h b/include/wx/qt/combobox.h index 75e8ee8852..d0f60b6863 100644 --- a/include/wx/qt/combobox.h +++ b/include/wx/qt/combobox.h @@ -80,6 +80,8 @@ public: virtual void Popup(); virtual void Dismiss(); + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + virtual bool QtHandleFocusEvent(QWidget *handler, QFocusEvent *event) wxOVERRIDE; protected: diff --git a/include/wx/srchctrl.h b/include/wx/srchctrl.h index 30253cfca8..bd46a27e2f 100644 --- a/include/wx/srchctrl.h +++ b/include/wx/srchctrl.h @@ -82,6 +82,10 @@ public: virtual void SetDescriptiveText(const wxString& text) = 0; virtual wxString GetDescriptiveText() const = 0; +#if wxUSE_NATIVE_SEARCH_CONTROL + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } +#endif // wxUSE_NATIVE_SEARCH_CONTROL + private: // implement wxTextEntry pure virtual method virtual wxWindow *GetEditableWindow() wxOVERRIDE { return this; } diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h index 22792af375..283e6d6c5d 100644 --- a/include/wx/textctrl.h +++ b/include/wx/textctrl.h @@ -759,6 +759,8 @@ public: return GetCompositeControlsDefaultAttributes(variant); } + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + protected: // Override wxEvtHandler method to check for a common problem of binding // wxEVT_TEXT_ENTER to a control without wxTE_PROCESS_ENTER style, which is diff --git a/include/wx/univ/combobox.h b/include/wx/univ/combobox.h index 13283906e6..2eff8cfb6c 100644 --- a/include/wx/univ/combobox.h +++ b/include/wx/univ/combobox.h @@ -161,6 +161,8 @@ public: virtual wxClientDataType GetClientDataType() const wxOVERRIDE; virtual void SetClientDataType(wxClientDataType clientDataItemsType) wxOVERRIDE; + virtual const wxTextEntry* WXGetTextEntry() const wxOVERRIDE { return this; } + protected: virtual int DoInsertItems(const wxArrayStringsAdapter& items, unsigned int pos, diff --git a/include/wx/window.h b/include/wx/window.h index c08ffa7712..20e8ec5119 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -58,6 +58,7 @@ class WXDLLIMPEXP_FWD_CORE wxDC; class WXDLLIMPEXP_FWD_CORE wxDropTarget; class WXDLLIMPEXP_FWD_CORE wxLayoutConstraints; class WXDLLIMPEXP_FWD_CORE wxSizer; +class WXDLLIMPEXP_FWD_CORE wxTextEntry; class WXDLLIMPEXP_FWD_CORE wxToolTip; class WXDLLIMPEXP_FWD_CORE wxWindowBase; class WXDLLIMPEXP_FWD_CORE wxWindow; @@ -1582,6 +1583,8 @@ public: return false; } + // This is an internal helper function implemented by text-like controls. + virtual const wxTextEntry* WXGetTextEntry() const { return NULL; } protected: // helper for the derived class Create() methods: the first overload, with diff --git a/src/common/event.cpp b/src/common/event.cpp index bf62ab8593..83820b54b4 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -37,20 +37,14 @@ #if wxUSE_GUI #include "wx/window.h" - #include "wx/combobox.h" #include "wx/control.h" #include "wx/dc.h" - #include "wx/srchctrl.h" #include "wx/spinbutt.h" - #include "wx/textctrl.h" + #include "wx/textentry.h" #include "wx/validate.h" #endif // wxUSE_GUI #endif -#if wxUSE_GUI - #include "wx/srchctrl.h" -#endif // wxUSE_GUI - #include "wx/thread.h" #if wxUSE_BASE @@ -448,28 +442,17 @@ wxString wxCommandEvent::GetString() const { // This is part of the hack retrieving the event string from the control // itself only when/if it's really needed to avoid copying potentially huge - // strings coming from multiline text controls. For consistency we also do - // it for combo boxes, even though there are no real performance advantages - // in doing this for them. + // strings coming from multiline text controls. if (m_eventType == wxEVT_TEXT && m_eventObject) { -#if wxUSE_TEXTCTRL - wxTextCtrl *txt = wxDynamicCast(m_eventObject, wxTextCtrl); - if ( txt ) - return txt->GetValue(); -#endif // wxUSE_TEXTCTRL - -#if wxUSE_COMBOBOX - wxComboBox* combo = wxDynamicCast(m_eventObject, wxComboBox); - if ( combo ) - return combo->GetValue(); -#endif // wxUSE_COMBOBOX - -#if wxUSE_SEARCHCTRL - wxSearchCtrl* search = wxDynamicCast(m_eventObject, wxSearchCtrl); - if ( search ) - return search->GetValue(); -#endif // wxUSE_SEARCHCTRL + // Only windows generate wxEVT_TEXT events, so this cast should really + // succeed, but err on the side of caution just in case somebody + // created a bogus event of this type. + if ( wxWindow* const w = wxDynamicCast(m_eventObject, wxWindow) ) + { + if ( const wxTextEntry* const entry = w->WXGetTextEntry() ) + return entry->GetValue(); + } } return m_cmdString;