Properly dismiss the grid combobox editor when it loses focus

The old way of checking for focus loss caused GTK to be unable to
even open the combobox. This way checks for the event sent when the
list closes and uses that to close the grid editor.

Fixes https://gitlab.com/kicad/code/kicad/issues/4617
This commit is contained in:
Ian McInerney 2020-07-09 20:35:45 +01:00
parent bb596ac139
commit af24a5d5a7
7 changed files with 32 additions and 14 deletions

View File

@ -30,6 +30,7 @@
#include <grid_tricks.h> #include <grid_tricks.h>
#include <panel_setup_netclasses.h> #include <panel_setup_netclasses.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <widgets/grid_combobox.h>
#include <widgets/wx_grid.h> #include <widgets/wx_grid.h>
#include <kicad_string.h> #include <kicad_string.h>
#include <widgets/grid_color_swatch_helpers.h> #include <widgets/grid_color_swatch_helpers.h>
@ -311,7 +312,7 @@ void PANEL_SETUP_NETCLASSES::rebuildNetclassDropdowns()
} }
wxGridCellAttr* attr = new wxGridCellAttr; wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( netclassNames ) ); attr->SetEditor( new GRID_CELL_COMBOBOX( netclassNames ) );
m_membershipGrid->SetColAttr( 1, attr ); m_membershipGrid->SetColAttr( 1, attr );
m_assignNetClass->Set( netclassNames ); m_assignNetClass->Set( netclassNames );
@ -510,12 +511,6 @@ void PANEL_SETUP_NETCLASSES::OnSizeNetclassGrid( wxSizeEvent& event )
} }
void PANEL_SETUP_NETCLASSES::OnMembershipKillFocus( wxFocusEvent& event )
{
m_membershipGrid->CommitPendingChanges();
}
void PANEL_SETUP_NETCLASSES::AdjustMembershipGridColumns( int aWidth ) void PANEL_SETUP_NETCLASSES::AdjustMembershipGridColumns( int aWidth )
{ {
// Account for scroll bars // Account for scroll bars

View File

@ -50,7 +50,6 @@ private:
void OnSizeMembershipGrid( wxSizeEvent& event ) override; void OnSizeMembershipGrid( wxSizeEvent& event ) override;
void OnUpdateUI( wxUpdateUIEvent &event ) override; void OnUpdateUI( wxUpdateUIEvent &event ) override;
void OnNetclassGridCellChanging( wxGridEvent& event ); void OnNetclassGridCellChanging( wxGridEvent& event );
void OnMembershipKillFocus( wxFocusEvent& event ) override;
void OnShowAll( wxCommandEvent& event ) override { doApplyFilters( true ); } void OnShowAll( wxCommandEvent& event ) override { doApplyFilters( true ); }
void OnApplyFilters( wxCommandEvent& event ) override { doApplyFilters( false ); } void OnApplyFilters( wxCommandEvent& event ) override { doApplyFilters( false ); }
void OnAssignAll( wxCommandEvent& event ) override { doAssignments( true ); } void OnAssignAll( wxCommandEvent& event ) override { doAssignments( true ); }

View File

@ -245,7 +245,6 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
m_filterNetsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); m_filterNetsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this );
m_assignAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this ); m_assignAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this );
m_assignSelectedButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this ); m_assignSelectedButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this );
m_membershipGrid->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnMembershipKillFocus ), NULL, this );
m_membershipGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this ); m_membershipGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this );
} }
@ -260,7 +259,6 @@ PANEL_SETUP_NETCLASSES_BASE::~PANEL_SETUP_NETCLASSES_BASE()
m_filterNetsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this ); m_filterNetsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnApplyFilters ), NULL, this );
m_assignAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this ); m_assignAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignAll ), NULL, this );
m_assignSelectedButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this ); m_assignSelectedButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnAssignSelected ), NULL, this );
m_membershipGrid->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnMembershipKillFocus ), NULL, this );
m_membershipGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this ); m_membershipGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnSizeMembershipGrid ), NULL, this );
} }

View File

@ -1325,7 +1325,6 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style">wxBORDER_DEFAULT</property> <property name="window_style">wxBORDER_DEFAULT</property>
<event name="OnKillFocus">OnMembershipKillFocus</event>
<event name="OnSize">OnSizeMembershipGrid</event> <event name="OnSize">OnSizeMembershipGrid</event>
</object> </object>
</object> </object>

View File

@ -66,7 +66,6 @@ class PANEL_SETUP_NETCLASSES_BASE : public wxPanel
virtual void OnApplyFilters( wxCommandEvent& event ) { event.Skip(); } virtual void OnApplyFilters( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAssignAll( wxCommandEvent& event ) { event.Skip(); } virtual void OnAssignAll( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAssignSelected( wxCommandEvent& event ) { event.Skip(); } virtual void OnAssignSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMembershipKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSizeMembershipGrid( wxSizeEvent& event ) { event.Skip(); } virtual void OnSizeMembershipGrid( wxSizeEvent& event ) { event.Skip(); }

View File

@ -79,6 +79,10 @@ void GRID_CELL_COMBOBOX::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
// Don't immediately end if we get a kill focus event within BeginEdit // Don't immediately end if we get a kill focus event within BeginEdit
evtHandler->SetInSetFocus( true ); evtHandler->SetInSetFocus( true );
// These event handlers are needed to properly dismiss the editor when the popup is closed
m_control->Bind(wxEVT_COMBOBOX_DROPDOWN, &GRID_CELL_COMBOBOX::onComboDropDown, this);
m_control->Bind(wxEVT_COMBOBOX_CLOSEUP, &GRID_CELL_COMBOBOX::onComboCloseUp, this);
m_value = aGrid->GetTable()->GetValue( aRow, aCol ); m_value = aGrid->GetTable()->GetValue( aRow, aCol );
Combo()->SetFocus(); Combo()->SetFocus();
@ -126,3 +130,24 @@ void GRID_CELL_COMBOBOX::Reset()
} }
void GRID_CELL_COMBOBOX::onComboDropDown( wxCommandEvent& aEvent )
{
auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
// Once the combobox is dropped, reset the flag to allow the focus-loss handler
// to function and close the editor.
evtHandler->SetInSetFocus( false );
}
void GRID_CELL_COMBOBOX::onComboCloseUp( wxCommandEvent& aEvent )
{
auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
// Forward the combobox close up event to the cell event handler as a focus kill event
// so that the grid editor is dismissed when the combox closes, otherwise it leaves the
// dropdown arrow visible in the cell.
wxFocusEvent event( wxEVT_KILL_FOCUS, m_control->GetId() );
event.SetEventObject( m_control );
evtHandler->ProcessEvent( event );
}

View File

@ -52,8 +52,11 @@ public:
protected: protected:
wxComboBox* Combo() const { return static_cast<wxComboBox*>( m_control ); } wxComboBox* Combo() const { return static_cast<wxComboBox*>( m_control ); }
const wxArrayString& m_names; void onComboCloseUp( wxCommandEvent& aEvent );
wxString m_value; void onComboDropDown( wxCommandEvent& aEvent );
wxArrayString m_names;
wxString m_value;
wxDECLARE_NO_COPY_CLASS( GRID_CELL_COMBOBOX ); wxDECLARE_NO_COPY_CLASS( GRID_CELL_COMBOBOX );
}; };