KiCad PCB EDA Suite
grid_icon_text_helpers.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 (C) 2018 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, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
25 
26 #include <wx/textctrl.h>
27 #include <wx/dc.h>
28 
29 
30 //---- Grid helpers: custom wxGridCellRenderer that renders icon and a label ------------
31 
32 
33 GRID_CELL_ICON_TEXT_RENDERER::GRID_CELL_ICON_TEXT_RENDERER( const std::vector<BITMAP_DEF>& icons,
34  const wxArrayString& names ) :
35  m_icons( icons ),
36  m_names( names )
37 {
38 }
39 
40 void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
41  const wxRect& aRect, int aRow, int aCol,
42  bool isSelected )
43 {
44  wxString value = aGrid.GetCellValue( aRow, aCol );
45  wxBitmap bitmap;
46 
47  wxRect rect = aRect;
48  rect.Inflate( -1 );
49 
50  // erase background
51  wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected );
52 
53  // draw the icon
54  // note that the set of icons might be smaller than the set of labels if the last
55  // label is <...>.
56  auto position = m_names.Index( value );
57  if( position < (int) m_icons.size() && position != wxNOT_FOUND )
58  {
59  bitmap = KiBitmap( (BITMAP_DEF) m_icons[ position ] );
60  aDC.DrawBitmap( bitmap, rect.GetLeft() + 3, rect.GetTop() + 2, true );
61  }
62  // still need a bitmap to fetch the width
63  else
64  bitmap = KiBitmap( (BITMAP_DEF) m_icons[ 0 ] );
65 
66  // draw the text
67  rect.SetLeft( rect.GetLeft() + bitmap.GetWidth() + 7 );
68  SetTextColoursAndFont( aGrid, aAttr, aDC, isSelected );
69  aGrid.DrawTextRectangle( aDC, value, rect, wxALIGN_LEFT, wxALIGN_CENTRE );
70 }
71 
72 //---- Grid helpers: custom wxGridCellRenderer that renders just an icon ----------------
73 //
74 // Note: this renderer is supposed to be used with read only cells
75 
76 GRID_CELL_ICON_RENDERER::GRID_CELL_ICON_RENDERER(const wxBitmap& icon) : m_icon( icon )
77 {
78 }
79 
80 
81 void GRID_CELL_ICON_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
82  const wxRect& aRect, int aRow, int aCol, bool isSelected )
83 {
84  wxRect rect = aRect;
85  rect.Inflate( -1 );
86 
87  // erase background
88  wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected );
89 
90  // Draw icon
91  if( m_icon.IsOk() )
92  {
93  aDC.DrawBitmap( m_icon,
94  rect.GetLeft() + ( rect.GetWidth() - m_icon.GetWidth() ) / 2,
95  rect.GetTop() + ( rect.GetHeight() - m_icon.GetHeight() ) / 2,
96  true );
97  }
98 }
99 
100 
101 wxSize GRID_CELL_ICON_RENDERER::GetBestSize( wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col )
102 {
103  return wxSize( m_icon.GetWidth() + 6, m_icon.GetHeight() + 4 );
104 }
105 
106 
107 wxGridCellRenderer* GRID_CELL_ICON_RENDERER::Clone() const
108 {
109  return new GRID_CELL_ICON_RENDERER( m_icon );
110 }
111 
112 
113 //---- Grid helpers: custom wxGridCellEditor ------------------------------------------
114 //
115 // Note: this implementation is an adaptation of wxGridCellChoiceEditor
116 
117 
118 GRID_CELL_ICON_TEXT_POPUP::GRID_CELL_ICON_TEXT_POPUP( const std::vector<BITMAP_DEF>& icons,
119  const wxArrayString& names ) :
120  m_icons( icons ),
121  m_names( names )
122 {
123 }
124 
125 
126 wxGridCellEditor* GRID_CELL_ICON_TEXT_POPUP::Clone() const
127 {
129 }
130 
131 
132 void GRID_CELL_ICON_TEXT_POPUP::Create( wxWindow* aParent, wxWindowID aId,
133  wxEvtHandler* aEventHandler )
134 {
135  m_control = new wxBitmapComboBox(
136  aParent, aId, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL,
137  wxCB_READONLY | wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxBORDER_NONE );
138 
139  for( unsigned i = 0; i < m_names.size(); ++i )
140  {
141  // note that the set of icons might be smaller than the set of labels if
142  // the last label is <...>.
143  if( i < m_icons.size() )
144  Combo()->Append( m_names[ i ], KiBitmap( m_icons[ i ] ) );
145  else
146  Combo()->Append( m_names[ i ] );
147  }
148 
149  wxGridCellEditor::Create(aParent, aId, aEventHandler);
150 }
151 
153 {
154  return Combo()->GetValue();
155 }
156 
157 void GRID_CELL_ICON_TEXT_POPUP::SetSize( const wxRect& aRect )
158 {
159  wxRect rect( aRect );
160  rect.Inflate( -1 );
161 
162 #if !defined( __WXMSW__ ) && !defined( __WXGTK20__ )
163  // Only implemented in generic wxBitmapComboBox; MSW and GTK use native controls
164  Combo()->SetButtonPosition( 0, 0, wxRIGHT, 2 );
165 #endif
166 
167 #if defined( __WXMAC__ )
168  rect.Inflate( 3 ); // no FOCUS_RING, even on Mac
169 #endif
170 
171  Combo()->SetSize( rect, wxSIZE_ALLOW_MINUS_ONE );
172 }
173 
174 
175 void GRID_CELL_ICON_TEXT_POPUP::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
176 {
177  auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
178 
179  // Don't immediately end if we get a kill focus event within BeginEdit
180  evtHandler->SetInSetFocus( true );
181 
182  m_value = aGrid->GetTable()->GetValue( aRow, aCol );
183 
184  Combo()->SetSelection( Combo()->FindString( m_value ) );
185  Combo()->SetFocus();
186 
187 #ifdef __WXOSX_COCOA__
188  // This is a work around for the combobox being simply dismissed when a
189  // choice is made in it under OS X. The bug is almost certainly due to a
190  // problem in focus events generation logic but it's not obvious to fix and
191  // for now this at least allows to use wxGrid.
192  Combo()->Popup();
193 #endif
194 
195  // When dropping down the menu, a kill focus event
196  // happens after this point, so we can't reset the flag yet.
197 #if !defined(__WXGTK20__)
198  evtHandler->SetInSetFocus( false );
199 #endif
200 }
201 
202 
203 bool GRID_CELL_ICON_TEXT_POPUP::EndEdit( int , int , const wxGrid* , const wxString& ,
204  wxString *aNewVal )
205 {
206  const wxString value = Combo()->GetValue();
207 
208  if( value == m_value )
209  return false;
210 
211  m_value = value;
212 
213  if( aNewVal )
214  *aNewVal = value;
215 
216  return true;
217 }
218 
219 
220 void GRID_CELL_ICON_TEXT_POPUP::ApplyEdit( int aRow, int aCol, wxGrid* aGrid )
221 {
222  aGrid->GetTable()->SetValue( aRow, aCol, m_value );
223 }
224 
225 
227 {
228  Combo()->SetSelection( Combo()->FindString( m_value ) );
229 }
230 
231 
GRID_CELL_ICON_TEXT_RENDERER(const std::vector< BITMAP_DEF > &icons, const wxArrayString &names)
wxBitmapComboBox * Combo() const
wxGridCellRenderer * Clone() const override
wxGridCellEditor * Clone() const override
wxString GetValue() const override
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
const std::vector< BITMAP_DEF > & m_icons
const wxArrayString & m_names
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
bool EndEdit(int, int, const wxGrid *, const wxString &, wxString *aNewVal) override
void Draw(wxGrid &aGrid, wxGridCellAttr &aAttr, wxDC &aDC, const wxRect &aRect, int aRow, int aCol, bool isSelected) override
void ApplyEdit(int aRow, int aCol, wxGrid *aGrid) override
GRID_CELL_ICON_TEXT_POPUP(const std::vector< BITMAP_DEF > &icons, const wxArrayString &names)
void SetSize(const wxRect &aRect) override
const std::vector< BITMAP_DEF > & m_icons
void BeginEdit(int aRow, int aCol, wxGrid *aGrid) override
GRID_CELL_ICON_RENDERER(const wxBitmap &icon)
size_t i
Definition: json11.cpp:597
wxSize GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col) override
void Draw(wxGrid &aGrid, wxGridCellAttr &aAttr, wxDC &aDC, const wxRect &aRect, int aRow, int aCol, bool isSelected) override