]> git.saurik.com Git - wxWidgets.git/blame - src/generic/gridctrl.cpp
missing commit, see #10269
[wxWidgets.git] / src / generic / gridctrl.cpp
CommitLineData
d10f4bf9 1///////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/generic/gridctrl.cpp
d10f4bf9
VZ
3// Purpose: wxGrid controls
4// Author: Paul Gammans, Roger Gammans
5// Modified by:
6// Created: 11/04/2001
7// RCS-ID: $Id$
8// Copyright: (c) The Computer Surgery (paul@compsurg.co.uk)
65571936 9// Licence: wxWindows licence
d10f4bf9
VZ
10/////////////////////////////////////////////////////////////////////////////
11
d10f4bf9
VZ
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
f7556ff0 18#if wxUSE_GRID
b53dc7d6 19
df9fac6d 20#include "wx/generic/gridctrl.h"
29efc6e4 21#include "wx/generic/grideditors.h"
df9fac6d 22
7ac05a91
VZ
23#ifndef WX_PRECOMP
24 #include "wx/textctrl.h"
25 #include "wx/dc.h"
df9fac6d 26 #include "wx/combobox.h"
03647350 27 #include "wx/settings.h"
85fe9f6f
FM
28 #include "wx/log.h"
29 #include "wx/checkbox.h"
7ac05a91
VZ
30#endif // WX_PRECOMP
31
d10f4bf9 32#include "wx/tokenzr.h"
29efc6e4 33#include "wx/renderer.h"
d10f4bf9 34
f8d0234d
FM
35
36// ----------------------------------------------------------------------------
37// wxGridCellRenderer
38// ----------------------------------------------------------------------------
39
40void wxGridCellRenderer::Draw(wxGrid& grid,
41 wxGridCellAttr& attr,
42 wxDC& dc,
43 const wxRect& rect,
44 int WXUNUSED(row), int WXUNUSED(col),
45 bool isSelected)
46{
47 dc.SetBackgroundMode( wxBRUSHSTYLE_SOLID );
48
49 wxColour clr;
01a65e7c 50 if ( grid.IsThisEnabled() )
f8d0234d
FM
51 {
52 if ( isSelected )
53 {
54 if ( grid.HasFocus() )
55 clr = grid.GetSelectionBackground();
56 else
57 clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
58 }
59 else
60 {
61 clr = attr.GetBackgroundColour();
62 }
63 }
64 else // grey out fields if the grid is disabled
65 {
66 clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
67 }
68
69 dc.SetBrush(clr);
70 dc.SetPen( *wxTRANSPARENT_PEN );
71 dc.DrawRectangle(rect);
72}
73
74
d10f4bf9
VZ
75// ----------------------------------------------------------------------------
76// wxGridCellDateTimeRenderer
77// ----------------------------------------------------------------------------
78
e2b87f38
VZ
79#if wxUSE_DATETIME
80
90e572f1 81// Enables a grid cell to display a formatted date and or time
d10f4bf9 82
fbfb8bcc 83wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
d10f4bf9
VZ
84{
85 m_iformat = informat;
86 m_oformat = outformat;
87 m_tz = wxDateTime::Local;
88 m_dateDef = wxDefaultDateTime;
89}
90
91wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
92{
93 wxGridCellDateTimeRenderer *renderer = new wxGridCellDateTimeRenderer;
94 renderer->m_iformat = m_iformat;
95 renderer->m_oformat = m_oformat;
96 renderer->m_dateDef = m_dateDef;
97 renderer->m_tz = m_tz;
98
99 return renderer;
100}
101
fbfb8bcc 102wxString wxGridCellDateTimeRenderer::GetString(const wxGrid& grid, int row, int col)
d10f4bf9
VZ
103{
104 wxGridTableBase *table = grid.GetTable();
105
ca65c044 106 bool hasDatetime = false;
d10f4bf9
VZ
107 wxDateTime val;
108 wxString text;
109 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
110 {
111 void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
112
6a147dfe
VZ
113 if (tempval)
114 {
d10f4bf9 115 val = *((wxDateTime *)tempval);
ca65c044 116 hasDatetime = true;
d10f4bf9
VZ
117 delete (wxDateTime *)tempval;
118 }
119
120 }
121
122 if (!hasDatetime )
123 {
124 text = table->GetValue(row, col);
6a147dfe
VZ
125 const char * const end = val.ParseFormat(text, m_iformat, m_dateDef);
126 hasDatetime = end && !*end;
d10f4bf9
VZ
127 }
128
129 if ( hasDatetime )
130 text = val.Format(m_oformat, m_tz );
131
6a147dfe 132 // If we failed to parse string just show what we where given?
d10f4bf9
VZ
133 return text;
134}
135
136void wxGridCellDateTimeRenderer::Draw(wxGrid& grid,
137 wxGridCellAttr& attr,
138 wxDC& dc,
139 const wxRect& rectCell,
140 int row, int col,
141 bool isSelected)
142{
143 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
144
145 SetTextColoursAndFont(grid, attr, dc, isSelected);
146
147 // draw the text right aligned by default
cfbc15ee
VZ
148 int hAlign = wxALIGN_RIGHT,
149 vAlign = wxALIGN_INVALID;
150 attr.GetNonDefaultAlignment(&hAlign, &vAlign);
d10f4bf9
VZ
151
152 wxRect rect = rectCell;
153 rect.Inflate(-1);
154
155 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
156}
157
158wxSize wxGridCellDateTimeRenderer::GetBestSize(wxGrid& grid,
159 wxGridCellAttr& attr,
160 wxDC& dc,
161 int row, int col)
162{
163 return DoGetBestSize(attr, dc, GetString(grid, row, col));
164}
165
7448de8d
WS
166void wxGridCellDateTimeRenderer::SetParameters(const wxString& params)
167{
168 if (!params.empty())
d10f4bf9
VZ
169 m_oformat=params;
170}
171
e2b87f38
VZ
172#endif // wxUSE_DATETIME
173
d10f4bf9 174// ----------------------------------------------------------------------------
db890987 175// wxGridCellEnumRenderer
d10f4bf9
VZ
176// ----------------------------------------------------------------------------
177// Renders a number as a textual equivalent.
178// eg data in cell is 0,1,2 ... n the cell could be rendered as "John","Fred"..."Bob"
179
180
181wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
182{
7448de8d 183 if (!choices.empty())
d10f4bf9
VZ
184 SetParameters(choices);
185}
186
187wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
188{
189 wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
190 renderer->m_choices = m_choices;
191 return renderer;
192}
193
fbfb8bcc 194wxString wxGridCellEnumRenderer::GetString(const wxGrid& grid, int row, int col)
d10f4bf9
VZ
195{
196 wxGridTableBase *table = grid.GetTable();
197 wxString text;
198 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
199 {
200 int choiceno = table->GetValueAsLong(row, col);
9a83f860 201 text.Printf(wxT("%s"), m_choices[ choiceno ].c_str() );
d10f4bf9
VZ
202 }
203 else
204 {
205 text = table->GetValue(row, col);
206 }
207
208
209 //If we faild to parse string just show what we where given?
210 return text;
211}
212
213void wxGridCellEnumRenderer::Draw(wxGrid& grid,
214 wxGridCellAttr& attr,
215 wxDC& dc,
216 const wxRect& rectCell,
217 int row, int col,
218 bool isSelected)
219{
220 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
221
222 SetTextColoursAndFont(grid, attr, dc, isSelected);
223
224 // draw the text right aligned by default
cfbc15ee
VZ
225 int hAlign = wxALIGN_RIGHT,
226 vAlign = wxALIGN_INVALID;
227 attr.GetNonDefaultAlignment(&hAlign, &vAlign);
d10f4bf9
VZ
228
229 wxRect rect = rectCell;
230 rect.Inflate(-1);
231
232 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
233}
234
235wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid,
236 wxGridCellAttr& attr,
237 wxDC& dc,
238 int row, int col)
239{
240 return DoGetBestSize(attr, dc, GetString(grid, row, col));
241}
242
243void wxGridCellEnumRenderer::SetParameters(const wxString& params)
244{
245 if ( !params )
246 {
247 // what can we do?
248 return;
249 }
250
251 m_choices.Empty();
252
9a83f860 253 wxStringTokenizer tk(params, wxT(','));
d10f4bf9
VZ
254 while ( tk.HasMoreTokens() )
255 {
256 m_choices.Add(tk.GetNextToken());
257 }
258}
259
3a8c693a 260
d10f4bf9 261// ----------------------------------------------------------------------------
29efc6e4 262// wxGridCellAutoWrapStringRenderer
d10f4bf9 263// ----------------------------------------------------------------------------
3a8c693a 264
d10f4bf9
VZ
265
266void
267wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid,
268 wxGridCellAttr& attr,
269 wxDC& dc,
270 const wxRect& rectCell,
271 int row, int col,
272 bool isSelected) {
273
274
275 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
276
277 // now we only have to draw the text
278 SetTextColoursAndFont(grid, attr, dc, isSelected);
279
280 int horizAlign, vertAlign;
281 attr.GetAlignment(&horizAlign, &vertAlign);
282
283 wxRect rect = rectCell;
284 rect.Inflate(-1);
285
286 grid.DrawTextRectangle(dc, GetTextLines(grid,dc,attr,rect,row,col),
287 rect, horizAlign, vertAlign);
288}
289
290
291wxArrayString
292wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
293 wxDC& dc,
fbfb8bcc 294 const wxGridCellAttr& attr,
d10f4bf9
VZ
295 const wxRect& rect,
296 int row, int col)
297{
298 wxString data = grid.GetCellValue(row, col);
299
300 wxArrayString lines;
301 dc.SetFont(attr.GetFont());
302
303 //Taken from wxGrid again!
304 wxCoord x = 0, y = 0, curr_x = 0;
305 wxCoord max_x = rect.GetWidth();
306
307 dc.SetFont(attr.GetFont());
9a83f860 308 wxStringTokenizer tk(data , wxT(" \n\t\r"));
ca65c044 309 wxString thisline = wxEmptyString;
d10f4bf9
VZ
310
311 while ( tk.HasMoreTokens() )
312 {
313 wxString tok = tk.GetNextToken();
d13b34d3 314 //FIXME: this causes us to print an extra unnecessary
7448de8d
WS
315 // space at the end of the line. But it
316 // is invisible , simplifies the size calculation
317 // and ensures tokens are separated in the display
9a83f860 318 tok += wxT(" ");
d10f4bf9
VZ
319
320 dc.GetTextExtent(tok, &x, &y);
7448de8d
WS
321 if ( curr_x + x > max_x)
322 {
5c3a7f71
VZ
323 if ( curr_x == 0 )
324 {
325 // this means that a single token is wider than the maximal
326 // width -- still use it as is as we need to show at least the
327 // part of it which fits
328 lines.Add(tok);
329 }
330 else
331 {
332 lines.Add(thisline);
333 thisline = tok;
334 curr_x = x;
335 }
7448de8d
WS
336 }
337 else
338 {
d10f4bf9 339 thisline+= tok;
7448de8d
WS
340 curr_x += x;
341 }
d10f4bf9
VZ
342 }
343 //Add last line
344 lines.Add( wxString(thisline) );
345
346 return lines;
347}
348
349
350wxSize
351wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
352 wxGridCellAttr& attr,
353 wxDC& dc,
354 int row, int col)
355{
86647b53
SN
356 wxCoord x,y, height , width = grid.GetColSize(col) -20;
357 // for width, subtract 20 because ColSize includes a magin of 10 pixels
358 // that we do not want here and because we always start with an increment
359 // by 10 in the loop below.
d10f4bf9
VZ
360 int count = 250; //Limit iterations..
361
362 wxRect rect(0,0,width,10);
363
364 // M is a nice large character 'y' gives descender!.
8dd8f875 365 dc.GetTextExtent(wxT("My"), &x, &y);
d10f4bf9
VZ
366
367 do
368 {
369 width+=10;
370 rect.SetWidth(width);
4a10ea8b 371 height = y * (wx_truncate_cast(wxCoord, GetTextLines(grid,dc,attr,rect,row,col).GetCount()));
d10f4bf9
VZ
372 count--;
373 // Search for a shape no taller than the golden ratio.
374 } while (count && (width < (height*1.68)) );
375
376
377 return wxSize(width,height);
378}
379
29efc6e4 380
29efc6e4
FM
381// ----------------------------------------------------------------------------
382// wxGridCellStringRenderer
383// ----------------------------------------------------------------------------
384
385void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid,
386 const wxGridCellAttr& attr,
387 wxDC& dc,
388 bool isSelected)
389{
390 dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT );
391
392 // TODO some special colours for attr.IsReadOnly() case?
393
394 // different coloured text when the grid is disabled
01a65e7c 395 if ( grid.IsThisEnabled() )
29efc6e4
FM
396 {
397 if ( isSelected )
398 {
399 wxColour clr;
400 if ( grid.HasFocus() )
401 clr = grid.GetSelectionBackground();
402 else
403 clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
404 dc.SetTextBackground( clr );
405 dc.SetTextForeground( grid.GetSelectionForeground() );
406 }
407 else
408 {
409 dc.SetTextBackground( attr.GetBackgroundColour() );
410 dc.SetTextForeground( attr.GetTextColour() );
411 }
412 }
413 else
414 {
415 dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
416 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
417 }
418
419 dc.SetFont( attr.GetFont() );
420}
421
422wxSize wxGridCellStringRenderer::DoGetBestSize(const wxGridCellAttr& attr,
423 wxDC& dc,
424 const wxString& text)
425{
426 wxCoord x = 0, y = 0, max_x = 0;
427 dc.SetFont(attr.GetFont());
9a83f860 428 wxStringTokenizer tk(text, wxT('\n'));
29efc6e4
FM
429 while ( tk.HasMoreTokens() )
430 {
431 dc.GetTextExtent(tk.GetNextToken(), &x, &y);
432 max_x = wxMax(max_x, x);
433 }
434
435 y *= 1 + text.Freq(wxT('\n')); // multiply by the number of lines.
436
437 return wxSize(max_x, y);
438}
439
440wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid,
441 wxGridCellAttr& attr,
442 wxDC& dc,
443 int row, int col)
444{
445 return DoGetBestSize(attr, dc, grid.GetCellValue(row, col));
446}
447
448void wxGridCellStringRenderer::Draw(wxGrid& grid,
449 wxGridCellAttr& attr,
450 wxDC& dc,
451 const wxRect& rectCell,
452 int row, int col,
453 bool isSelected)
454{
455 wxRect rect = rectCell;
456 rect.Inflate(-1);
457
458 // erase only this cells background, overflow cells should have been erased
459 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
460
461 int hAlign, vAlign;
462 attr.GetAlignment(&hAlign, &vAlign);
463
464 int overflowCols = 0;
465
466 if (attr.GetOverflow())
467 {
468 int cols = grid.GetNumberCols();
469 int best_width = GetBestSize(grid,attr,dc,row,col).GetWidth();
470 int cell_rows, cell_cols;
471 attr.GetSize( &cell_rows, &cell_cols ); // shouldn't get here if <= 0
472 if ((best_width > rectCell.width) && (col < cols) && grid.GetTable())
473 {
474 int i, c_cols, c_rows;
475 for (i = col+cell_cols; i < cols; i++)
476 {
477 bool is_empty = true;
478 for (int j=row; j < row + cell_rows; j++)
479 {
480 // check w/ anchor cell for multicell block
481 grid.GetCellSize(j, i, &c_rows, &c_cols);
482 if (c_rows > 0)
483 c_rows = 0;
484 if (!grid.GetTable()->IsEmptyCell(j + c_rows, i))
485 {
486 is_empty = false;
487 break;
488 }
489 }
490
491 if (is_empty)
492 {
493 rect.width += grid.GetColSize(i);
494 }
495 else
496 {
497 i--;
498 break;
499 }
500
501 if (rect.width >= best_width)
502 break;
503 }
504
505 overflowCols = i - col - cell_cols + 1;
506 if (overflowCols >= cols)
507 overflowCols = cols - 1;
508 }
509
510 if (overflowCols > 0) // redraw overflow cells w/ proper hilight
511 {
512 hAlign = wxALIGN_LEFT; // if oveflowed then it's left aligned
513 wxRect clip = rect;
514 clip.x += rectCell.width;
515 // draw each overflow cell individually
516 int col_end = col + cell_cols + overflowCols;
517 if (col_end >= grid.GetNumberCols())
518 col_end = grid.GetNumberCols() - 1;
519 for (int i = col + cell_cols; i <= col_end; i++)
520 {
521 clip.width = grid.GetColSize(i) - 1;
522 dc.DestroyClippingRegion();
523 dc.SetClippingRegion(clip);
524
525 SetTextColoursAndFont(grid, attr, dc,
526 grid.IsInSelection(row,i));
527
528 grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
529 rect, hAlign, vAlign);
530 clip.x += grid.GetColSize(i) - 1;
531 }
532
533 rect = rectCell;
534 rect.Inflate(-1);
535 rect.width++;
536 dc.DestroyClippingRegion();
537 }
538 }
539
540 // now we only have to draw the text
541 SetTextColoursAndFont(grid, attr, dc, isSelected);
542
543 grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
544 rect, hAlign, vAlign);
545}
546
547// ----------------------------------------------------------------------------
548// wxGridCellNumberRenderer
549// ----------------------------------------------------------------------------
550
551wxString wxGridCellNumberRenderer::GetString(const wxGrid& grid, int row, int col)
552{
553 wxGridTableBase *table = grid.GetTable();
554 wxString text;
555 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
556 {
9a83f860 557 text.Printf(wxT("%ld"), table->GetValueAsLong(row, col));
29efc6e4
FM
558 }
559 else
560 {
561 text = table->GetValue(row, col);
562 }
563
564 return text;
565}
566
567void wxGridCellNumberRenderer::Draw(wxGrid& grid,
568 wxGridCellAttr& attr,
569 wxDC& dc,
570 const wxRect& rectCell,
571 int row, int col,
572 bool isSelected)
573{
574 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
575
576 SetTextColoursAndFont(grid, attr, dc, isSelected);
577
578 // draw the text right aligned by default
cfbc15ee
VZ
579 int hAlign = wxALIGN_RIGHT,
580 vAlign = wxALIGN_INVALID;
581 attr.GetNonDefaultAlignment(&hAlign, &vAlign);
29efc6e4
FM
582
583 wxRect rect = rectCell;
584 rect.Inflate(-1);
585
586 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
587}
588
589wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid,
590 wxGridCellAttr& attr,
591 wxDC& dc,
592 int row, int col)
593{
594 return DoGetBestSize(attr, dc, GetString(grid, row, col));
595}
596
597// ----------------------------------------------------------------------------
598// wxGridCellFloatRenderer
599// ----------------------------------------------------------------------------
600
1d8d3cc5
VZ
601wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width,
602 int precision,
603 int format)
29efc6e4
FM
604{
605 SetWidth(width);
606 SetPrecision(precision);
1d8d3cc5 607 SetFormat(format);
29efc6e4
FM
608}
609
610wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const
611{
612 wxGridCellFloatRenderer *renderer = new wxGridCellFloatRenderer;
613 renderer->m_width = m_width;
614 renderer->m_precision = m_precision;
1d8d3cc5 615 renderer->m_style = m_style;
29efc6e4
FM
616 renderer->m_format = m_format;
617
618 return renderer;
619}
620
621wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col)
622{
623 wxGridTableBase *table = grid.GetTable();
624
625 bool hasDouble;
626 double val;
627 wxString text;
628 if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
629 {
630 val = table->GetValueAsDouble(row, col);
631 hasDouble = true;
632 }
633 else
634 {
635 text = table->GetValue(row, col);
636 hasDouble = text.ToDouble(&val);
637 }
638
639 if ( hasDouble )
640 {
641 if ( !m_format )
642 {
643 if ( m_width == -1 )
644 {
645 if ( m_precision == -1 )
646 {
647 // default width/precision
1d8d3cc5 648 m_format = wxT("%");
29efc6e4
FM
649 }
650 else
651 {
1d8d3cc5 652 m_format.Printf(wxT("%%.%d"), m_precision);
29efc6e4
FM
653 }
654 }
655 else if ( m_precision == -1 )
656 {
657 // default precision
1d8d3cc5 658 m_format.Printf(wxT("%%%d."), m_width);
29efc6e4
FM
659 }
660 else
661 {
1d8d3cc5 662 m_format.Printf(wxT("%%%d.%d"), m_width, m_precision);
29efc6e4 663 }
1d8d3cc5
VZ
664
665 bool isUpper = ( ( m_style & wxGRID_FLOAT_FORMAT_UPPER ) == wxGRID_FLOAT_FORMAT_UPPER);
666 if ( ( m_style & wxGRID_FLOAT_FORMAT_SCIENTIFIC ) == wxGRID_FLOAT_FORMAT_SCIENTIFIC)
667 m_format += isUpper ? wxT('E') : wxT('e');
668 else if ( ( m_style & wxGRID_FLOAT_FORMAT_COMPACT ) == wxGRID_FLOAT_FORMAT_COMPACT)
669 m_format += isUpper ? wxT('G') : wxT('g');
670 else
671 m_format += wxT('f');
29efc6e4
FM
672 }
673
674 text.Printf(m_format, val);
675
676 }
677 //else: text already contains the string
678
679 return text;
680}
681
682void wxGridCellFloatRenderer::Draw(wxGrid& grid,
683 wxGridCellAttr& attr,
684 wxDC& dc,
685 const wxRect& rectCell,
686 int row, int col,
687 bool isSelected)
688{
689 wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
690
691 SetTextColoursAndFont(grid, attr, dc, isSelected);
692
693 // draw the text right aligned by default
cfbc15ee
VZ
694 int hAlign = wxALIGN_RIGHT,
695 vAlign = wxALIGN_INVALID;
696 attr.GetNonDefaultAlignment(&hAlign, &vAlign);
29efc6e4
FM
697
698 wxRect rect = rectCell;
699 rect.Inflate(-1);
700
701 grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
702}
703
704wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid,
705 wxGridCellAttr& attr,
706 wxDC& dc,
707 int row, int col)
708{
709 return DoGetBestSize(attr, dc, GetString(grid, row, col));
710}
711
712void wxGridCellFloatRenderer::SetParameters(const wxString& params)
713{
714 if ( !params )
715 {
716 // reset to defaults
717 SetWidth(-1);
718 SetPrecision(-1);
1d8d3cc5 719 SetFormat(wxGRID_FLOAT_FORMAT_DEFAULT);
29efc6e4
FM
720 }
721 else
722 {
1d8d3cc5
VZ
723 wxString rest;
724 wxString tmp = params.BeforeFirst(wxT(','), &rest);
29efc6e4
FM
725 if ( !tmp.empty() )
726 {
727 long width;
728 if ( tmp.ToLong(&width) )
729 {
730 SetWidth((int)width);
731 }
732 else
733 {
9a83f860 734 wxLogDebug(wxT("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str());
29efc6e4
FM
735 }
736 }
737
1d8d3cc5 738 tmp = rest.BeforeFirst(wxT(','));
29efc6e4
FM
739 if ( !tmp.empty() )
740 {
741 long precision;
742 if ( tmp.ToLong(&precision) )
743 {
744 SetPrecision((int)precision);
745 }
746 else
747 {
9a83f860 748 wxLogDebug(wxT("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str());
29efc6e4
FM
749 }
750 }
1d8d3cc5
VZ
751
752 tmp = rest.AfterFirst(wxT(','));
753 if ( !tmp.empty() )
754 {
755 if ( tmp[0] == wxT('f') )
756 {
757 SetFormat(wxGRID_FLOAT_FORMAT_FIXED);
758 }
759 else if ( tmp[0] == wxT('e') )
760 {
761 SetFormat(wxGRID_FLOAT_FORMAT_SCIENTIFIC);
762 }
763 else if ( tmp[0] == wxT('g') )
764 {
765 SetFormat(wxGRID_FLOAT_FORMAT_COMPACT);
766 }
767 else if ( tmp[0] == wxT('E') )
768 {
769 SetFormat(wxGRID_FLOAT_FORMAT_SCIENTIFIC |
770 wxGRID_FLOAT_FORMAT_UPPER);
771 }
772 else if ( tmp[0] == wxT('F') )
773 {
774 SetFormat(wxGRID_FLOAT_FORMAT_FIXED |
775 wxGRID_FLOAT_FORMAT_UPPER);
776 }
777 else if ( tmp[0] == wxT('G') )
778 {
779 SetFormat(wxGRID_FLOAT_FORMAT_COMPACT |
780 wxGRID_FLOAT_FORMAT_UPPER);
781 }
782 else
783 {
784 wxLogDebug("Invalid wxGridCellFloatRenderer format "
785 "parameter string '%s ignored", params);
786 }
787 }
29efc6e4
FM
788 }
789}
790
791// ----------------------------------------------------------------------------
792// wxGridCellBoolRenderer
793// ----------------------------------------------------------------------------
794
795wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
796
191e43fd 797wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
29efc6e4
FM
798 wxGridCellAttr& WXUNUSED(attr),
799 wxDC& WXUNUSED(dc),
800 int WXUNUSED(row),
801 int WXUNUSED(col))
802{
803 // compute it only once (no locks for MT safeness in GUI thread...)
804 if ( !ms_sizeCheckMark.x )
805 {
191e43fd 806 ms_sizeCheckMark = wxRendererNative::Get().GetCheckBoxSize(&grid);
29efc6e4
FM
807 }
808
809 return ms_sizeCheckMark;
810}
811
812void wxGridCellBoolRenderer::Draw(wxGrid& grid,
813 wxGridCellAttr& attr,
814 wxDC& dc,
815 const wxRect& rect,
816 int row, int col,
817 bool isSelected)
818{
819 wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
820
821 // draw a check mark in the centre (ignoring alignment - TODO)
822 wxSize size = GetBestSize(grid, attr, dc, row, col);
823
824 // don't draw outside the cell
825 wxCoord minSize = wxMin(rect.width, rect.height);
826 if ( size.x >= minSize || size.y >= minSize )
827 {
828 // and even leave (at least) 1 pixel margin
829 size.x = size.y = minSize;
830 }
831
832 // draw a border around checkmark
833 int vAlign, hAlign;
834 attr.GetAlignment(&hAlign, &vAlign);
835
836 wxRect rectBorder;
837 if (hAlign == wxALIGN_CENTRE)
838 {
839 rectBorder.x = rect.x + rect.width / 2 - size.x / 2;
840 rectBorder.y = rect.y + rect.height / 2 - size.y / 2;
841 rectBorder.width = size.x;
842 rectBorder.height = size.y;
843 }
844 else if (hAlign == wxALIGN_LEFT)
845 {
846 rectBorder.x = rect.x + 2;
847 rectBorder.y = rect.y + rect.height / 2 - size.y / 2;
848 rectBorder.width = size.x;
849 rectBorder.height = size.y;
850 }
851 else if (hAlign == wxALIGN_RIGHT)
852 {
853 rectBorder.x = rect.x + rect.width - size.x - 2;
854 rectBorder.y = rect.y + rect.height / 2 - size.y / 2;
855 rectBorder.width = size.x;
856 rectBorder.height = size.y;
857 }
858
859 bool value;
860 if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
861 {
862 value = grid.GetTable()->GetValueAsBool(row, col);
863 }
864 else
865 {
866 wxString cellval( grid.GetTable()->GetValue(row, col) );
867 value = wxGridCellBoolEditor::IsTrueValue(cellval);
868 }
869
870 int flags = 0;
871 if (value)
872 flags |= wxCONTROL_CHECKED;
873
874 wxRendererNative::Get().DrawCheckBox( &grid, dc, rectBorder, flags );
875}
876
3a8c693a
VZ
877#endif // wxUSE_GRID
878