From a216806c996ab6e42f73a821857542774a9c1f79 Mon Sep 17 00:00:00 2001 From: Igor Korot Date: Wed, 24 Feb 2016 20:07:34 +0100 Subject: [PATCH] Allow modifying wxComboBox from its CLOSEUP handler with wxGTK2 Doing this resulted in GTK errors about invalid iterators, so postpone the generation of the CLOSEUP event for slightly later to allow changing the combobox contents from it with GTK+ 2 (this is not necessary with GTK+ 3). Also add a demon of a dynamic combobox, creating and destroying its items on the fly, to the widgets sample. Closes #17223. --- interface/wx/combobox.h | 3 +-- samples/widgets/combobox.cpp | 34 ++++++++++++++++++++++++++++++++-- src/gtk/combobox.cpp | 14 +++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/interface/wx/combobox.h b/interface/wx/combobox.h index 2ba41dca3b..b2bf2579f3 100644 --- a/interface/wx/combobox.h +++ b/interface/wx/combobox.h @@ -67,8 +67,7 @@ Process a @c wxEVT_COMBOBOX_CLOSEUP event, which is generated when the list box of the combo box disappears (closes up). This event is only generated for the same platforms as - @c wxEVT_COMBOBOX_DROPDOWN above. Also note that only wxMSW and - wxOSX/Cocoa support adding or deleting items in this event. + @c wxEVT_COMBOBOX_DROPDOWN above. @endEventTable @library{wxcore} diff --git a/samples/widgets/combobox.cpp b/samples/widgets/combobox.cpp index ab9947173b..e0f0312334 100644 --- a/samples/widgets/combobox.cpp +++ b/samples/widgets/combobox.cpp @@ -74,7 +74,8 @@ enum ComboPage_SetValue, ComboPage_SetValueText, ComboPage_Combo, - ComboPage_ContainerTests + ComboPage_ContainerTests, + ComboPage_Dynamic }; // kinds of comboboxes @@ -121,6 +122,8 @@ protected: void OnDropdown(wxCommandEvent& event); void OnCloseup(wxCommandEvent& event); + void OnPopup(wxCommandEvent &event); + void OnDismiss(wxCommandEvent &event); void OnComboBox(wxCommandEvent& event); void OnComboText(wxCommandEvent& event); void OnComboTextPasted(wxClipboardTextEvent& event); @@ -155,7 +158,7 @@ protected: *m_chkProcessEnter; // the combobox itself and the sizer it is in - wxComboBox *m_combobox; + wxComboBox *m_combobox, *m_combobox1; wxSizer *m_sizerCombo; // the text entries for "Add/change string" and "Delete" buttons @@ -380,6 +383,13 @@ void ComboboxWidgetsPage::CreateContent() 0, NULL, 0); sizerRight->Add(m_combobox, 0, wxGROW | wxALL, 5); + m_combobox1 = new wxComboBox( this, ComboPage_Dynamic ); + m_combobox1->Append( "Dynamic ComboBox Test - Click me!" ); + m_combobox1->SetSelection( 0 ); + sizerRight->Add( 20, 20, 0, wxEXPAND, 0 ); + sizerRight->Add( m_combobox1, 0, wxGROW | wxALL, 5 ); + m_combobox1->Bind( wxEVT_COMBOBOX_DROPDOWN, &ComboboxWidgetsPage::OnPopup, this ); + m_combobox1->Bind( wxEVT_COMBOBOX_CLOSEUP, &ComboboxWidgetsPage::OnDismiss, this ); sizerRight->SetMinSize(150, 0); m_sizerCombo = sizerRight; // save it to modify it later @@ -699,4 +709,24 @@ void ComboboxWidgetsPage::OnCloseup(wxCommandEvent& WXUNUSED(event)) wxLogMessage(wxT("Combobox closed up")); } +void ComboboxWidgetsPage::OnPopup(wxCommandEvent &WXUNUSED(event)) +{ + m_combobox1->Clear(); + m_combobox1->Append( "Selection 1" ); + m_combobox1->Append( "Selection 2" ); + m_combobox1->Append( "Selection 3" ); + wxLogMessage("The number of items is %d", m_combobox1->GetCount()); +} + +void ComboboxWidgetsPage::OnDismiss(wxCommandEvent &WXUNUSED(event)) +{ + if ( m_combobox1->GetSelection() == wxNOT_FOUND ) + { + m_combobox1->Clear(); + m_combobox1->Append( "Dynamic ComboBox Test - Click me!" ); + m_combobox1->SetSelection( 0 ); + } + wxLogMessage("The number of items is %d", m_combobox1->GetCount()); +} + #endif // wxUSE_COMBOBOX diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp index 9c96133c79..6782de03f5 100644 --- a/src/gtk/combobox.cpp +++ b/src/gtk/combobox.cpp @@ -55,7 +55,19 @@ gtkcombobox_popupshown_callback(GObject *WXUNUSED(gobject), : wxEVT_COMBOBOX_CLOSEUP, combo->GetId() ); event.SetEventObject( combo ); - combo->HandleWindowEvent( event ); + +#ifndef __WXGTK3__ + // Process the close up event once the combobox is already closed with GTK+ + // 2, otherwise changing the combobox from its handler result in errors. + if ( !isShown ) + { + combo->GetEventHandler()->AddPendingEvent( event ); + } + else +#endif // GTK+ < 3 + { + combo->HandleWindowEvent( event ); + } } }