KiCad PCB EDA Suite
Loading...
Searching...
No Matches
grid_combobox.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22
23//-------- Renderer ---------------------------------------------------------------------
24// None required; just render as normal text.
25
26
27
28//-------- Editor -----------------------------------------------------------------------
29//
30// Note: this implementation is an adaptation of wxGridCellChoiceEditor
31
32
33GRID_CELL_COMBOBOX::GRID_CELL_COMBOBOX( const wxArrayString& names ) :
34 m_names( names )
35{
36}
37
38
40
41
42wxGridCellEditor* GRID_CELL_COMBOBOX::Clone() const
43{
44 return new GRID_CELL_COMBOBOX( m_names );
45}
46
47
48void GRID_CELL_COMBOBOX::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
49{
50 m_control = new wxComboBox( aParent, wxID_ANY, wxEmptyString,
51 wxDefaultPosition, wxDefaultSize, m_names );
52
53 wxGridCellEditor::Create(aParent, aId, aEventHandler);
54}
55
56
58{
59 return Combo()->GetValue();
60}
61
62
63void GRID_CELL_COMBOBOX::SetSize( const wxRect& aRect )
64{
65 wxRect rect( aRect );
66 rect.Inflate( -1 );
67
68#if defined( __WXMAC__ )
69 rect.Inflate( 3 ); // no FOCUS_RING, even on Mac
70#endif
71
72 Combo()->SetSize( rect, wxSIZE_ALLOW_MINUS_ONE );
73}
74
75
76void GRID_CELL_COMBOBOX::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
77{
78 auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
79
80 // Don't immediately end if we get a kill focus event within BeginEdit
81 evtHandler->SetInSetFocus( true );
82
83 // These event handlers are needed to properly dismiss the editor when the popup is closed
84 m_control->Bind(wxEVT_COMBOBOX_DROPDOWN, &GRID_CELL_COMBOBOX::onComboDropDown, this);
85 m_control->Bind(wxEVT_COMBOBOX_CLOSEUP, &GRID_CELL_COMBOBOX::onComboCloseUp, this);
86
87 m_value = aGrid->GetTable()->GetValue( aRow, aCol );
88
89 Combo()->SetFocus();
90
91 // Work around a wxWidgets bug where the drop-down is the wrong width on the first drop.
92 Combo()->Set( Combo()->GetStrings() );
93
94 Combo()->ChangeValue( m_value );
95 Combo()->SelectAll();
96
97#ifdef __WXOSX_COCOA__
98 // This is a work around for the combobox being simply dismissed when a
99 // choice is made in it under OS X. The bug is almost certainly due to a
100 // problem in focus events generation logic but it's not obvious to fix and
101 // for now this at least allows one to use wxGrid.
102 Combo()->Popup();
103#endif
104
105 // When dropping down the menu, a kill focus event
106 // happens after this point, so we can't reset the flag yet.
107#if !defined(__WXGTK__)
108 evtHandler->SetInSetFocus( false );
109#endif
110}
111
112
113bool GRID_CELL_COMBOBOX::EndEdit( int , int , const wxGrid* , const wxString& , wxString *aNewVal )
114{
115 const wxString value = Combo()->GetValue();
116
117 if( value == m_value )
118 return false;
119
120 m_value = value;
121
122 if( aNewVal )
123 *aNewVal = value;
124
125 return true;
126}
127
128
129void GRID_CELL_COMBOBOX::ApplyEdit( int aRow, int aCol, wxGrid* aGrid )
130{
131 aGrid->GetTable()->SetValue( aRow, aCol, m_value );
132}
133
134
138
139
140void GRID_CELL_COMBOBOX::onComboDropDown( wxCommandEvent& aEvent )
141{
142 auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
143
144 // Once the combobox is dropped, reset the flag to allow the focus-loss handler
145 // to function and close the editor.
146 evtHandler->SetInSetFocus( false );
147}
148
149
150void GRID_CELL_COMBOBOX::onComboCloseUp( wxCommandEvent& aEvent )
151{
152 auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
153
154 // Forward the combobox close up event to the cell event handler as a focus kill event
155 // so that the grid editor is dismissed when the combox closes, otherwise it leaves the
156 // dropdown arrow visible in the cell.
157 wxFocusEvent event( wxEVT_KILL_FOCUS, m_control->GetId() );
158 event.SetEventObject( m_control );
159 evtHandler->ProcessEvent( event );
160}
bool EndEdit(int aRow, int aCol, const wxGrid *, const wxString &, wxString *aNewVal) override
void onComboDropDown(wxCommandEvent &aEvent)
GRID_CELL_COMBOBOX(const wxArrayString &names)
~GRID_CELL_COMBOBOX() override
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
void onComboCloseUp(wxCommandEvent &aEvent)
wxString GetValue() const override
void BeginEdit(int aRow, int aCol, wxGrid *aGrid) override
wxArrayString m_names
wxComboBox * Combo() const
void SetSize(const wxRect &aRect) override
void Reset() override
void ApplyEdit(int aRow, int aCol, wxGrid *aGrid) override
wxGridCellEditor * Clone() const override