KiCad PCB EDA Suite
GRIDCELL_AUTOWRAP_STRINGRENDERER Class Reference
Inheritance diagram for GRIDCELL_AUTOWRAP_STRINGRENDERER:

Public Member Functions

int GetHeight (wxDC &aDC, wxGrid *aGrid, int aRow, int aCol)
 
wxGridCellRenderer * Clone () const override
 

Private Member Functions

wxArrayString GetTextLines (wxGrid &grid, wxDC &dc, const wxGridCellAttr &attr, const wxRect &rect, int row, int col)
 
void BreakLine (wxDC &dc, const wxString &logicalLine, wxCoord maxWidth, wxArrayString &lines)
 
wxCoord BreakWord (wxDC &dc, const wxString &word, wxCoord maxWidth, wxArrayString &lines, wxString &line)
 

Detailed Description

Definition at line 50 of file dialog_edit_components_libid.cpp.

Member Function Documentation

◆ BreakLine()

void GRIDCELL_AUTOWRAP_STRINGRENDERER::BreakLine ( wxDC &  dc,
const wxString &  logicalLine,
wxCoord  maxWidth,
wxArrayString &  lines 
)
private

Definition at line 134 of file dialog_edit_components_libid.cpp.

138 {
139  wxCoord lineWidth = 0;
140  wxString line;
141 
142  // For each word
143  wxStringTokenizer wordTokenizer(logicalLine, wxS(" \t"), wxTOKEN_RET_DELIMS);
144  while ( wordTokenizer.HasMoreTokens() )
145  {
146  const wxString word = wordTokenizer.GetNextToken();
147  const wxCoord wordWidth = dc.GetTextExtent(word).x;
148  if ( lineWidth + wordWidth < maxWidth )
149  {
150  // Word fits, just add it to this line.
151  line += word;
152  lineWidth += wordWidth;
153  }
154  else
155  {
156  // Word does not fit, check whether the word is itself wider that
157  // available width
158  if ( wordWidth < maxWidth )
159  {
160  // Word can fit in a new line, put it at the beginning
161  // of the new line.
162  lines.push_back(line);
163  line = word;
164  lineWidth = wordWidth;
165  }
166  else // Word cannot fit in available width at all.
167  {
168  if ( !line.empty() )
169  {
170  lines.push_back(line);
171  line.clear();
172  lineWidth = 0;
173  }
174 
175  // Break it up in several lines.
176  lineWidth = BreakWord(dc, word, maxWidth, lines, line);
177  }
178  }
179  }
180 
181  if ( !line.empty() )
182  lines.push_back(line);
183 }
wxCoord BreakWord(wxDC &dc, const wxString &word, wxCoord maxWidth, wxArrayString &lines, wxString &line)

References BreakWord().

Referenced by GetTextLines().

◆ BreakWord()

wxCoord GRIDCELL_AUTOWRAP_STRINGRENDERER::BreakWord ( wxDC &  dc,
const wxString &  word,
wxCoord  maxWidth,
wxArrayString &  lines,
wxString &  line 
)
private

Definition at line 188 of file dialog_edit_components_libid.cpp.

193 {
194  wxArrayInt widths;
195  dc.GetPartialTextExtents(word, widths);
196 
197  // TODO: Use binary search to find the first element > maxWidth.
198  const unsigned count = widths.size();
199  unsigned n;
200  for ( n = 0; n < count; n++ )
201  {
202  if ( widths[n] > maxWidth )
203  break;
204  }
205 
206  if ( n == 0 )
207  {
208  // This is a degenerate case: the first character of the word is
209  // already wider than the available space, so we just can't show it
210  // completely and have to put the first character in this line.
211  n = 1;
212  }
213 
214  lines.push_back(word.substr(0, n));
215 
216  // Check if the remainder of the string fits in one line.
217  //
218  // Unfortunately we can't use the existing partial text extents as the
219  // extent of the remainder may be different when it's rendered in a
220  // separate line instead of as part of the same one, so we have to
221  // recompute it.
222  const wxString rest = word.substr(n);
223  const wxCoord restWidth = dc.GetTextExtent(rest).x;
224  if ( restWidth <= maxWidth )
225  {
226  line = rest;
227  return restWidth;
228  }
229 
230  // Break the rest of the word into lines.
231  //
232  // TODO: Perhaps avoid recursion? The code is simpler like this but using a
233  // loop in this function would probably be more efficient.
234  return BreakWord(dc, rest, maxWidth, lines, line);
235 }
wxCoord BreakWord(wxDC &dc, const wxString &word, wxCoord maxWidth, wxArrayString &lines, wxString &line)

Referenced by BreakLine().

◆ Clone()

wxGridCellRenderer* GRIDCELL_AUTOWRAP_STRINGRENDERER::Clone ( ) const
inlineoverride

◆ GetHeight()

int GRIDCELL_AUTOWRAP_STRINGRENDERER::GetHeight ( wxDC &  aDC,
wxGrid *  aGrid,
int  aRow,
int  aCol 
)

Definition at line 240 of file dialog_edit_components_libid.cpp.

241 {
242  wxGridCellAttr* attr = aGrid->GetOrCreateCellAttr( aRow, aCol );
243  wxRect rect;
244 
245  aDC.SetFont( attr->GetFont() );
246  rect.SetWidth( aGrid->GetColSize( aCol ) - ( 2 * GRID_CELL_MARGIN ) );
247 
248  const size_t numLines = GetTextLines( *aGrid, aDC, *attr, rect, aRow, aCol ).size();
249  const int textHeight = numLines *aDC.GetCharHeight();
250 
251  attr->DecRef();
252 
253  return textHeight + ( 2 * GRID_CELL_MARGIN );
254 }
wxArrayString GetTextLines(wxGrid &grid, wxDC &dc, const wxGridCellAttr &attr, const wxRect &rect, int row, int col)
#define GRID_CELL_MARGIN

References GetTextLines(), and GRID_CELL_MARGIN.

Referenced by DIALOG_EDIT_COMPONENTS_LIBID::AddRowToGrid(), and DIALOG_EDIT_COMPONENTS_LIBID::OnSizeGrid().

◆ GetTextLines()

wxArrayString GRIDCELL_AUTOWRAP_STRINGRENDERER::GetTextLines ( wxGrid &  grid,
wxDC &  dc,
const wxGridCellAttr &  attr,
const wxRect &  rect,
int  row,
int  col 
)
private

Definition at line 92 of file dialog_edit_components_libid.cpp.

97 {
98  dc.SetFont(attr.GetFont());
99  const wxCoord maxWidth = rect.GetWidth();
100 
101  // Transform logical lines into physical ones, wrapping the longer ones.
102  const wxArrayString
103  logicalLines = wxSplit(grid.GetCellValue(row, col), '\n', '\0');
104 
105  // Trying to do anything if the column is hidden anyhow doesn't make sense
106  // and we run into problems in BreakLine() in this case.
107  if ( maxWidth <= 0 )
108  return logicalLines;
109 
110  wxArrayString physicalLines;
111  for ( wxArrayString::const_iterator it = logicalLines.begin();
112  it != logicalLines.end();
113  ++it )
114  {
115  const wxString& line = *it;
116 
117  if ( dc.GetTextExtent(line).x > maxWidth )
118  {
119  // Line does not fit, break it up.
120  BreakLine(dc, line, maxWidth, physicalLines);
121  }
122  else // The entire line fits as is
123  {
124  physicalLines.push_back(line);
125  }
126  }
127 
128  return physicalLines;
129 }
void BreakLine(wxDC &dc, const wxString &logicalLine, wxCoord maxWidth, wxArrayString &lines)

References BreakLine().

Referenced by GetHeight().


The documentation for this class was generated from the following file: