From: Robert Roebling Date: Mon, 6 Dec 2004 12:47:06 +0000 (+0000) Subject: Apply choice patch for proper handling of clearing X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/16edee16a7c3d346b9eab1672a4c696cb0cf6e24?ds=inline Apply choice patch for proper handling of clearing wxChoice (it reported a selection value of 0) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30873 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h index 8732297d19..70fea3819b 100644 --- a/include/wx/gtk/choice.h +++ b/include/wx/gtk/choice.h @@ -104,6 +104,10 @@ private: // allocate it if it's needed (hence using pointer) wxSortedArrayString *m_strings; + // this circumvents a GTK+ 2.0 bug so that the selection is + // invalidated properly + int m_selection_hack; + DECLARE_DYNAMIC_CLASS(wxChoice) }; diff --git a/include/wx/gtk1/choice.h b/include/wx/gtk1/choice.h index 8732297d19..70fea3819b 100644 --- a/include/wx/gtk1/choice.h +++ b/include/wx/gtk1/choice.h @@ -104,6 +104,10 @@ private: // allocate it if it's needed (hence using pointer) wxSortedArrayString *m_strings; + // this circumvents a GTK+ 2.0 bug so that the selection is + // invalidated properly + int m_selection_hack; + DECLARE_DYNAMIC_CLASS(wxChoice) }; diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index 08a2f642b3..39c259f1e5 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -111,6 +111,9 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, m_strings = new wxSortedArrayString; } + // begin with no selection + m_selection_hack = wxNOT_FOUND; + GtkWidget *menu = gtk_menu_new(); for (int i = 0; i < n; i++) @@ -154,6 +157,13 @@ int wxChoice::DoInsert( const wxString &item, int pos ) GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); + // if the item to insert is at or before the selection, and the selection is valid + if ((pos <= m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) + { + // move the selection forward one + m_selection_hack++; + } + return GtkAddHelper(menu, pos, item); } @@ -224,6 +234,9 @@ void wxChoice::Clear() if ( m_strings ) m_strings->Clear(); + + // begin with no selection + m_selection_hack = wxNOT_FOUND; } void wxChoice::Delete( int n ) @@ -237,6 +250,18 @@ void wxChoice::Delete( int n ) wxCHECK_RET( n >= 0 && n < count, _T("invalid index in wxChoice::Delete") ); + // if the item to delete is before the selection, and the selection is valid + if ((n < m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) + { + // move the selection back one + m_selection_hack--; + } + else if (n == m_selection_hack) + { + // invalidate the selection + m_selection_hack = wxNOT_FOUND; + } + const bool hasClientData = m_clientDataItemsType != wxClientData_None; const bool hasObjectData = m_clientDataItemsType == wxClientData_Object; @@ -329,6 +354,10 @@ int wxChoice::GetSelection() const { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") ); + // this has the same (if not better) behaviour as the following commented code + return m_selection_hack; + + /* #ifdef __WXGTK20__ return gtk_option_menu_get_history( GTK_OPTION_MENU(m_widget) ); @@ -348,6 +377,7 @@ int wxChoice::GetSelection() const return -1; #endif + */ } void wxChoice::SetString( int n, const wxString& str ) @@ -435,6 +465,24 @@ void wxChoice::SetSelection( int n ) int tmp = n; gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp ); + + // set the local selection variable manually + if ((n >= 0) && (n < GetCount())) + { + // a valid selection has been made + m_selection_hack = n; + } + else if ((n == wxNOT_FOUND) || (GetCount() == 0)) + { + // invalidates the selection if there are no items + // or if it is specifically set to wxNOT_FOUND + m_selection_hack = wxNOT_FOUND; + } + else + { + // this selects the first item by default if the selection is out of bounds + m_selection_hack = 0; + } } void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style) diff --git a/src/gtk1/choice.cpp b/src/gtk1/choice.cpp index 08a2f642b3..39c259f1e5 100644 --- a/src/gtk1/choice.cpp +++ b/src/gtk1/choice.cpp @@ -111,6 +111,9 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, m_strings = new wxSortedArrayString; } + // begin with no selection + m_selection_hack = wxNOT_FOUND; + GtkWidget *menu = gtk_menu_new(); for (int i = 0; i < n; i++) @@ -154,6 +157,13 @@ int wxChoice::DoInsert( const wxString &item, int pos ) GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); + // if the item to insert is at or before the selection, and the selection is valid + if ((pos <= m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) + { + // move the selection forward one + m_selection_hack++; + } + return GtkAddHelper(menu, pos, item); } @@ -224,6 +234,9 @@ void wxChoice::Clear() if ( m_strings ) m_strings->Clear(); + + // begin with no selection + m_selection_hack = wxNOT_FOUND; } void wxChoice::Delete( int n ) @@ -237,6 +250,18 @@ void wxChoice::Delete( int n ) wxCHECK_RET( n >= 0 && n < count, _T("invalid index in wxChoice::Delete") ); + // if the item to delete is before the selection, and the selection is valid + if ((n < m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) + { + // move the selection back one + m_selection_hack--; + } + else if (n == m_selection_hack) + { + // invalidate the selection + m_selection_hack = wxNOT_FOUND; + } + const bool hasClientData = m_clientDataItemsType != wxClientData_None; const bool hasObjectData = m_clientDataItemsType == wxClientData_Object; @@ -329,6 +354,10 @@ int wxChoice::GetSelection() const { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") ); + // this has the same (if not better) behaviour as the following commented code + return m_selection_hack; + + /* #ifdef __WXGTK20__ return gtk_option_menu_get_history( GTK_OPTION_MENU(m_widget) ); @@ -348,6 +377,7 @@ int wxChoice::GetSelection() const return -1; #endif + */ } void wxChoice::SetString( int n, const wxString& str ) @@ -435,6 +465,24 @@ void wxChoice::SetSelection( int n ) int tmp = n; gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp ); + + // set the local selection variable manually + if ((n >= 0) && (n < GetCount())) + { + // a valid selection has been made + m_selection_hack = n; + } + else if ((n == wxNOT_FOUND) || (GetCount() == 0)) + { + // invalidates the selection if there are no items + // or if it is specifically set to wxNOT_FOUND + m_selection_hack = wxNOT_FOUND; + } + else + { + // this selects the first item by default if the selection is out of bounds + m_selection_hack = 0; + } } void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style)