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 49 of file dialog_edit_components_libid.cpp.

Member Function Documentation

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

Definition at line 133 of file dialog_edit_components_libid.cpp.

References BreakWord().

Referenced by Clone(), and GetTextLines().

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

Definition at line 187 of file dialog_edit_components_libid.cpp.

Referenced by BreakLine(), and Clone().

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

Definition at line 239 of file dialog_edit_components_libid.cpp.

References GetTextLines(), and GRID_CELL_MARGIN.

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

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

Definition at line 91 of file dialog_edit_components_libid.cpp.

References BreakLine().

Referenced by Clone(), and GetHeight().

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

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