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