]> git.saurik.com Git - wxWidgets.git/blob - include/wx/generic/private/grid.h
Make wxLog::EnableLogging() and wxLogNull thread-specific.
[wxWidgets.git] / include / wx / generic / private / grid.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/generic/private/grid.h
3 // Purpose: Private wxGrid structures
4 // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
5 // Modified by: Santiago Palacios
6 // Created: 1/08/1999
7 // RCS-ID: $Id$
8 // Copyright: (c) Michael Bedward
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_GENERIC_GRID_PRIVATE_H_
13 #define _WX_GENERIC_GRID_PRIVATE_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_GRID
18
19 // ----------------------------------------------------------------------------
20 // array classes
21 // ----------------------------------------------------------------------------
22
23 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs,
24 class WXDLLIMPEXP_ADV);
25
26 struct wxGridCellWithAttr
27 {
28 wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_)
29 : coords(row, col), attr(attr_)
30 {
31 wxASSERT( attr );
32 }
33
34 wxGridCellWithAttr(const wxGridCellWithAttr& other)
35 : coords(other.coords),
36 attr(other.attr)
37 {
38 attr->IncRef();
39 }
40
41 wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other)
42 {
43 coords = other.coords;
44 if (attr != other.attr)
45 {
46 attr->DecRef();
47 attr = other.attr;
48 attr->IncRef();
49 }
50 return *this;
51 }
52
53 void ChangeAttr(wxGridCellAttr* new_attr)
54 {
55 if (attr != new_attr)
56 {
57 // "Delete" (i.e. DecRef) the old attribute.
58 attr->DecRef();
59 attr = new_attr;
60 // Take ownership of the new attribute, i.e. no IncRef.
61 }
62 }
63
64 ~wxGridCellWithAttr()
65 {
66 attr->DecRef();
67 }
68
69 wxGridCellCoords coords;
70 wxGridCellAttr *attr;
71 };
72
73 WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray,
74 class WXDLLIMPEXP_ADV);
75
76
77 // ----------------------------------------------------------------------------
78 // private classes
79 // ----------------------------------------------------------------------------
80
81 // header column providing access to the column information stored in wxGrid
82 // via wxHeaderColumn interface
83 class wxGridHeaderColumn : public wxHeaderColumn
84 {
85 public:
86 wxGridHeaderColumn(wxGrid *grid, int col)
87 : m_grid(grid),
88 m_col(col)
89 {
90 }
91
92 virtual wxString GetTitle() const { return m_grid->GetColLabelValue(m_col); }
93 virtual wxBitmap GetBitmap() const { return wxNullBitmap; }
94 virtual int GetWidth() const { return m_grid->GetColSize(m_col); }
95 virtual int GetMinWidth() const { return 0; }
96 virtual wxAlignment GetAlignment() const
97 {
98 int horz,
99 vert;
100 m_grid->GetColLabelAlignment(&horz, &vert);
101
102 return static_cast<wxAlignment>(horz);
103 }
104
105 virtual int GetFlags() const
106 {
107 // we can't know in advance whether we can sort by this column or not
108 // with wxGrid API so suppose we can by default
109 int flags = wxCOL_SORTABLE;
110 if ( m_grid->CanDragColSize(m_col) )
111 flags |= wxCOL_RESIZABLE;
112 if ( m_grid->CanDragColMove() )
113 flags |= wxCOL_REORDERABLE;
114 if ( GetWidth() == 0 )
115 flags |= wxCOL_HIDDEN;
116
117 return flags;
118 }
119
120 virtual bool IsSortKey() const
121 {
122 return m_grid->IsSortingBy(m_col);
123 }
124
125 virtual bool IsSortOrderAscending() const
126 {
127 return m_grid->IsSortOrderAscending();
128 }
129
130 private:
131 // these really should be const but are not because the column needs to be
132 // assignable to be used in a wxVector (in STL build, in non-STL build we
133 // avoid the need for this)
134 wxGrid *m_grid;
135 int m_col;
136 };
137
138 // header control retreiving column information from the grid
139 class wxGridHeaderCtrl : public wxHeaderCtrl
140 {
141 public:
142 wxGridHeaderCtrl(wxGrid *owner)
143 : wxHeaderCtrl(owner,
144 wxID_ANY,
145 wxDefaultPosition,
146 wxDefaultSize,
147 wxHD_ALLOW_HIDE |
148 (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
149 {
150 }
151
152 protected:
153 virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
154 {
155 return m_columns[idx];
156 }
157
158 private:
159 wxGrid *GetOwner() const { return static_cast<wxGrid *>(GetParent()); }
160
161 // override the base class method to update our m_columns array
162 virtual void OnColumnCountChanging(unsigned int count)
163 {
164 const unsigned countOld = m_columns.size();
165 if ( count < countOld )
166 {
167 // just discard the columns which don't exist any more (notice that
168 // we can't use resize() here as it would require the vector
169 // value_type, i.e. wxGridHeaderColumn to be default constructible,
170 // which it is not)
171 m_columns.erase(m_columns.begin() + count, m_columns.end());
172 }
173 else // new columns added
174 {
175 // add columns for the new elements
176 for ( unsigned n = countOld; n < count; n++ )
177 m_columns.push_back(wxGridHeaderColumn(GetOwner(), n));
178 }
179 }
180
181 // override to implement column auto sizing
182 virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
183 {
184 // TODO: currently grid doesn't support computing the column best width
185 // from its contents so we just use the best label width as is
186 GetOwner()->SetColSize(idx, widthTitle);
187
188 return true;
189 }
190
191 // overridden to react to the actions using the columns popup menu
192 virtual void UpdateColumnVisibility(unsigned int idx, bool show)
193 {
194 GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
195
196 // as this is done by the user we should notify the main program about
197 // it
198
199 // make up a dummy event for the grid event to use -- unfortunately we
200 // can't do anything else here
201 wxMouseEvent e;
202 e.SetState(wxGetMouseState());
203 GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx, e);
204 }
205
206 // overridden to react to the columns order changes in the customization
207 // dialog
208 virtual void UpdateColumnsOrder(const wxArrayInt& order)
209 {
210 GetOwner()->SetColumnsOrder(order);
211 }
212
213
214 // event handlers forwarding wxHeaderCtrl events to wxGrid
215 void OnClick(wxHeaderCtrlEvent& event)
216 {
217 GetOwner()->DoColHeaderClick(event.GetColumn());
218 }
219
220 void OnBeginResize(wxHeaderCtrlEvent& event)
221 {
222 GetOwner()->DoStartResizeCol(event.GetColumn());
223
224 event.Skip();
225 }
226
227 void OnResizing(wxHeaderCtrlEvent& event)
228 {
229 GetOwner()->DoUpdateResizeColWidth(event.GetWidth());
230 }
231
232 void OnEndResize(wxHeaderCtrlEvent& event)
233 {
234 // we again need to pass a mouse event to be used for the grid event
235 // generation but we don't have it here so use a dummy one as in
236 // UpdateColumnVisibility()
237 wxMouseEvent e;
238 e.SetState(wxGetMouseState());
239 GetOwner()->DoEndDragResizeCol(e);
240
241 event.Skip();
242 }
243
244 void OnBeginReorder(wxHeaderCtrlEvent& event)
245 {
246 GetOwner()->DoStartMoveCol(event.GetColumn());
247 }
248
249 void OnEndReorder(wxHeaderCtrlEvent& event)
250 {
251 GetOwner()->DoEndMoveCol(event.GetNewOrder());
252 }
253
254 wxVector<wxGridHeaderColumn> m_columns;
255
256 DECLARE_EVENT_TABLE()
257 wxDECLARE_NO_COPY_CLASS(wxGridHeaderCtrl);
258 };
259
260 // common base class for various grid subwindows
261 class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow
262 {
263 public:
264 wxGridSubwindow(wxGrid *owner,
265 int additionalStyle = 0,
266 const wxString& name = wxPanelNameStr)
267 : wxWindow(owner, wxID_ANY,
268 wxDefaultPosition, wxDefaultSize,
269 wxBORDER_NONE | additionalStyle,
270 name)
271 {
272 m_owner = owner;
273 }
274
275 virtual bool AcceptsFocus() const { return false; }
276
277 wxGrid *GetOwner() { return m_owner; }
278
279 protected:
280 void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
281
282 wxGrid *m_owner;
283
284 DECLARE_EVENT_TABLE()
285 wxDECLARE_NO_COPY_CLASS(wxGridSubwindow);
286 };
287
288 class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow
289 {
290 public:
291 wxGridRowLabelWindow(wxGrid *parent)
292 : wxGridSubwindow(parent)
293 {
294 }
295
296
297 private:
298 void OnPaint( wxPaintEvent& event );
299 void OnMouseEvent( wxMouseEvent& event );
300 void OnMouseWheel( wxMouseEvent& event );
301
302 DECLARE_EVENT_TABLE()
303 wxDECLARE_NO_COPY_CLASS(wxGridRowLabelWindow);
304 };
305
306
307 class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow
308 {
309 public:
310 wxGridColLabelWindow(wxGrid *parent)
311 : wxGridSubwindow(parent)
312 {
313 }
314
315
316 private:
317 void OnPaint( wxPaintEvent& event );
318 void OnMouseEvent( wxMouseEvent& event );
319 void OnMouseWheel( wxMouseEvent& event );
320
321 DECLARE_EVENT_TABLE()
322 wxDECLARE_NO_COPY_CLASS(wxGridColLabelWindow);
323 };
324
325
326 class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow
327 {
328 public:
329 wxGridCornerLabelWindow(wxGrid *parent)
330 : wxGridSubwindow(parent)
331 {
332 }
333
334 private:
335 void OnMouseEvent( wxMouseEvent& event );
336 void OnMouseWheel( wxMouseEvent& event );
337 void OnPaint( wxPaintEvent& event );
338
339 DECLARE_EVENT_TABLE()
340 wxDECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow);
341 };
342
343 class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow
344 {
345 public:
346 wxGridWindow(wxGrid *parent)
347 : wxGridSubwindow(parent,
348 wxWANTS_CHARS | wxCLIP_CHILDREN,
349 "GridWindow")
350 {
351 }
352
353
354 virtual void ScrollWindow( int dx, int dy, const wxRect *rect );
355
356 virtual bool AcceptsFocus() const { return true; }
357
358 private:
359 void OnPaint( wxPaintEvent &event );
360 void OnMouseWheel( wxMouseEvent& event );
361 void OnMouseEvent( wxMouseEvent& event );
362 void OnKeyDown( wxKeyEvent& );
363 void OnKeyUp( wxKeyEvent& );
364 void OnChar( wxKeyEvent& );
365 void OnEraseBackground( wxEraseEvent& );
366 void OnFocus( wxFocusEvent& );
367
368 DECLARE_EVENT_TABLE()
369 wxDECLARE_NO_COPY_CLASS(wxGridWindow);
370 };
371
372 // ----------------------------------------------------------------------------
373 // the internal data representation used by wxGridCellAttrProvider
374 // ----------------------------------------------------------------------------
375
376 // this class stores attributes set for cells
377 class WXDLLIMPEXP_ADV wxGridCellAttrData
378 {
379 public:
380 void SetAttr(wxGridCellAttr *attr, int row, int col);
381 wxGridCellAttr *GetAttr(int row, int col) const;
382 void UpdateAttrRows( size_t pos, int numRows );
383 void UpdateAttrCols( size_t pos, int numCols );
384
385 private:
386 // searches for the attr for given cell, returns wxNOT_FOUND if not found
387 int FindIndex(int row, int col) const;
388
389 wxGridCellWithAttrArray m_attrs;
390 };
391
392 // this class stores attributes set for rows or columns
393 class WXDLLIMPEXP_ADV wxGridRowOrColAttrData
394 {
395 public:
396 // empty ctor to suppress warnings
397 wxGridRowOrColAttrData() {}
398 ~wxGridRowOrColAttrData();
399
400 void SetAttr(wxGridCellAttr *attr, int rowOrCol);
401 wxGridCellAttr *GetAttr(int rowOrCol) const;
402 void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols );
403
404 private:
405 wxArrayInt m_rowsOrCols;
406 wxArrayAttrs m_attrs;
407 };
408
409 // NB: this is just a wrapper around 3 objects: one which stores cell
410 // attributes, and 2 others for row/col ones
411 class WXDLLIMPEXP_ADV wxGridCellAttrProviderData
412 {
413 public:
414 wxGridCellAttrData m_cellAttrs;
415 wxGridRowOrColAttrData m_rowAttrs,
416 m_colAttrs;
417 };
418
419 // ----------------------------------------------------------------------------
420 // operations classes abstracting the difference between operating on rows and
421 // columns
422 // ----------------------------------------------------------------------------
423
424 // This class allows to write a function only once because by using its methods
425 // it will apply to both columns and rows.
426 //
427 // This is an abstract interface definition, the two concrete implementations
428 // below should be used when working with rows and columns respectively.
429 class wxGridOperations
430 {
431 public:
432 // Returns the operations in the other direction, i.e. wxGridRowOperations
433 // if this object is a wxGridColumnOperations and vice versa.
434 virtual wxGridOperations& Dual() const = 0;
435
436 // Return the number of rows or columns.
437 virtual int GetNumberOfLines(const wxGrid *grid) const = 0;
438
439 // Return the selection mode which allows selecting rows or columns.
440 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0;
441
442 // Make a wxGridCellCoords from the given components: thisDir is row or
443 // column and otherDir is column or row
444 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0;
445
446 // Calculate the scrolled position of the given abscissa or ordinate.
447 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0;
448
449 // Selects the horizontal or vertical component from the given object.
450 virtual int Select(const wxGridCellCoords& coords) const = 0;
451 virtual int Select(const wxPoint& pt) const = 0;
452 virtual int Select(const wxSize& sz) const = 0;
453 virtual int Select(const wxRect& r) const = 0;
454 virtual int& Select(wxRect& r) const = 0;
455
456 // Returns width or height of the rectangle
457 virtual int& SelectSize(wxRect& r) const = 0;
458
459 // Make a wxSize such that Select() applied to it returns first component
460 virtual wxSize MakeSize(int first, int second) const = 0;
461
462 // Sets the row or column component of the given cell coordinates
463 virtual void Set(wxGridCellCoords& coords, int line) const = 0;
464
465
466 // Draws a line parallel to the row or column, i.e. horizontal or vertical:
467 // pos is the horizontal or vertical position of the line and start and end
468 // are the coordinates of the line extremities in the other direction
469 virtual void
470 DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
471
472 // Draw a horizontal or vertical line across the given rectangle
473 // (this is implemented in terms of above and uses Select() to extract
474 // start and end from the given rectangle)
475 void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
476 {
477 const int posStart = Select(rect.GetPosition());
478 DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
479 }
480
481
482 // Return the index of the row or column at the given pixel coordinate.
483 virtual int
484 PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0;
485
486 // Get the top/left position, in pixels, of the given row or column
487 virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0;
488
489 // Get the bottom/right position, in pixels, of the given row or column
490 virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0;
491
492 // Get the height/width of the given row/column
493 virtual int GetLineSize(const wxGrid *grid, int line) const = 0;
494
495 // Get wxGrid::m_rowBottoms/m_colRights array
496 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0;
497
498 // Get default height row height or column width
499 virtual int GetDefaultLineSize(const wxGrid *grid) const = 0;
500
501 // Return the minimal acceptable row height or column width
502 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0;
503
504 // Return the minimal row height or column width
505 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0;
506
507 // Set the row height or column width
508 virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0;
509
510 // Set the row default height or column default width
511 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
512
513
514 // Return the index of the line at the given position
515 //
516 // NB: currently this is always identity for the rows as reordering is only
517 // implemented for the lines
518 virtual int GetLineAt(const wxGrid *grid, int line) const = 0;
519
520
521 // Get the row or column label window
522 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0;
523
524 // Get the width or height of the row or column label window
525 virtual int GetHeaderWindowSize(wxGrid *grid) const = 0;
526
527
528 // This class is never used polymorphically but give it a virtual dtor
529 // anyhow to suppress g++ complaints about it
530 virtual ~wxGridOperations() { }
531 };
532
533 class wxGridRowOperations : public wxGridOperations
534 {
535 public:
536 virtual wxGridOperations& Dual() const;
537
538 virtual int GetNumberOfLines(const wxGrid *grid) const
539 { return grid->GetNumberRows(); }
540
541 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
542 { return wxGrid::wxGridSelectRows; }
543
544 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
545 { return wxGridCellCoords(thisDir, otherDir); }
546
547 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
548 { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; }
549
550 virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); }
551 virtual int Select(const wxPoint& pt) const { return pt.x; }
552 virtual int Select(const wxSize& sz) const { return sz.x; }
553 virtual int Select(const wxRect& r) const { return r.x; }
554 virtual int& Select(wxRect& r) const { return r.x; }
555 virtual int& SelectSize(wxRect& r) const { return r.width; }
556 virtual wxSize MakeSize(int first, int second) const
557 { return wxSize(first, second); }
558 virtual void Set(wxGridCellCoords& coords, int line) const
559 { coords.SetRow(line); }
560
561 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
562 { dc.DrawLine(start, pos, end, pos); }
563
564 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
565 { return grid->YToRow(pos, clip); }
566 virtual int GetLineStartPos(const wxGrid *grid, int line) const
567 { return grid->GetRowTop(line); }
568 virtual int GetLineEndPos(const wxGrid *grid, int line) const
569 { return grid->GetRowBottom(line); }
570 virtual int GetLineSize(const wxGrid *grid, int line) const
571 { return grid->GetRowHeight(line); }
572 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
573 { return grid->m_rowBottoms; }
574 virtual int GetDefaultLineSize(const wxGrid *grid) const
575 { return grid->GetDefaultRowSize(); }
576 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
577 { return grid->GetRowMinimalAcceptableHeight(); }
578 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
579 { return grid->GetRowMinimalHeight(line); }
580 virtual void SetLineSize(wxGrid *grid, int line, int size) const
581 { grid->SetRowSize(line, size); }
582 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
583 { grid->SetDefaultRowSize(size, resizeExisting); }
584
585 virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int line) const
586 { return line; } // TODO: implement row reordering
587
588 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
589 { return grid->GetGridRowLabelWindow(); }
590 virtual int GetHeaderWindowSize(wxGrid *grid) const
591 { return grid->GetRowLabelSize(); }
592 };
593
594 class wxGridColumnOperations : public wxGridOperations
595 {
596 public:
597 virtual wxGridOperations& Dual() const;
598
599 virtual int GetNumberOfLines(const wxGrid *grid) const
600 { return grid->GetNumberCols(); }
601
602 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
603 { return wxGrid::wxGridSelectColumns; }
604
605 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
606 { return wxGridCellCoords(otherDir, thisDir); }
607
608 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
609 { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; }
610
611 virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); }
612 virtual int Select(const wxPoint& pt) const { return pt.y; }
613 virtual int Select(const wxSize& sz) const { return sz.y; }
614 virtual int Select(const wxRect& r) const { return r.y; }
615 virtual int& Select(wxRect& r) const { return r.y; }
616 virtual int& SelectSize(wxRect& r) const { return r.height; }
617 virtual wxSize MakeSize(int first, int second) const
618 { return wxSize(second, first); }
619 virtual void Set(wxGridCellCoords& coords, int line) const
620 { coords.SetCol(line); }
621
622 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
623 { dc.DrawLine(pos, start, pos, end); }
624
625 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
626 { return grid->XToCol(pos, clip); }
627 virtual int GetLineStartPos(const wxGrid *grid, int line) const
628 { return grid->GetColLeft(line); }
629 virtual int GetLineEndPos(const wxGrid *grid, int line) const
630 { return grid->GetColRight(line); }
631 virtual int GetLineSize(const wxGrid *grid, int line) const
632 { return grid->GetColWidth(line); }
633 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
634 { return grid->m_colRights; }
635 virtual int GetDefaultLineSize(const wxGrid *grid) const
636 { return grid->GetDefaultColSize(); }
637 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
638 { return grid->GetColMinimalAcceptableWidth(); }
639 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
640 { return grid->GetColMinimalWidth(line); }
641 virtual void SetLineSize(wxGrid *grid, int line, int size) const
642 { grid->SetColSize(line, size); }
643 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
644 { grid->SetDefaultColSize(size, resizeExisting); }
645
646 virtual int GetLineAt(const wxGrid *grid, int line) const
647 { return grid->GetColAt(line); }
648
649 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
650 { return grid->GetGridColLabelWindow(); }
651 virtual int GetHeaderWindowSize(wxGrid *grid) const
652 { return grid->GetColLabelSize(); }
653 };
654
655 // This class abstracts the difference between operations going forward
656 // (down/right) and backward (up/left) and allows to use the same code for
657 // functions which differ only in the direction of grid traversal
658 //
659 // Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike
660 // it, this is a normal object and not just a function dispatch table and has a
661 // non-default ctor.
662 //
663 // Note: the explanation of this discrepancy is the existence of (very useful)
664 // Dual() method in wxGridOperations which forces us to make wxGridOperations a
665 // function dispatcher only.
666 class wxGridDirectionOperations
667 {
668 public:
669 // The oper parameter to ctor selects whether we work with rows or columns
670 wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper)
671 : m_grid(grid),
672 m_oper(oper)
673 {
674 }
675
676 // Check if the component of this point in our direction is at the
677 // boundary, i.e. is the first/last row/column
678 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0;
679
680 // Increment the component of this point in our direction
681 virtual void Advance(wxGridCellCoords& coords) const = 0;
682
683 // Find the line at the given distance, in pixels, away from this one
684 // (this uses clipping, i.e. anything after the last line is counted as the
685 // last one and anything before the first one as 0)
686 virtual int MoveByPixelDistance(int line, int distance) const = 0;
687
688 // This class is never used polymorphically but give it a virtual dtor
689 // anyhow to suppress g++ complaints about it
690 virtual ~wxGridDirectionOperations() { }
691
692 protected:
693 wxGrid * const m_grid;
694 const wxGridOperations& m_oper;
695 };
696
697 class wxGridBackwardOperations : public wxGridDirectionOperations
698 {
699 public:
700 wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper)
701 : wxGridDirectionOperations(grid, oper)
702 {
703 }
704
705 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
706 {
707 wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" );
708
709 return m_oper.Select(coords) == 0;
710 }
711
712 virtual void Advance(wxGridCellCoords& coords) const
713 {
714 wxASSERT( !IsAtBoundary(coords) );
715
716 m_oper.Set(coords, m_oper.Select(coords) - 1);
717 }
718
719 virtual int MoveByPixelDistance(int line, int distance) const
720 {
721 int pos = m_oper.GetLineStartPos(m_grid, line);
722 return m_oper.PosToLine(m_grid, pos - distance + 1, true);
723 }
724 };
725
726 class wxGridForwardOperations : public wxGridDirectionOperations
727 {
728 public:
729 wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper)
730 : wxGridDirectionOperations(grid, oper),
731 m_numLines(oper.GetNumberOfLines(grid))
732 {
733 }
734
735 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
736 {
737 wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" );
738
739 return m_oper.Select(coords) == m_numLines - 1;
740 }
741
742 virtual void Advance(wxGridCellCoords& coords) const
743 {
744 wxASSERT( !IsAtBoundary(coords) );
745
746 m_oper.Set(coords, m_oper.Select(coords) + 1);
747 }
748
749 virtual int MoveByPixelDistance(int line, int distance) const
750 {
751 int pos = m_oper.GetLineStartPos(m_grid, line);
752 return m_oper.PosToLine(m_grid, pos + distance, true);
753 }
754
755 private:
756 const int m_numLines;
757 };
758
759 // ----------------------------------------------------------------------------
760 // private helpers
761 // ----------------------------------------------------------------------------
762
763 namespace
764 {
765
766 // ensure that first is less or equal to second, swapping the values if
767 // necessary
768 void EnsureFirstLessThanSecond(int& first, int& second)
769 {
770 if ( first > second )
771 wxSwap(first, second);
772 }
773
774 } // anonymous namespace
775
776 // ----------------------------------------------------------------------------
777 // data structures used for the data type registry
778 // ----------------------------------------------------------------------------
779
780 struct wxGridDataTypeInfo
781 {
782 wxGridDataTypeInfo(const wxString& typeName,
783 wxGridCellRenderer* renderer,
784 wxGridCellEditor* editor)
785 : m_typeName(typeName), m_renderer(renderer), m_editor(editor)
786 {}
787
788 ~wxGridDataTypeInfo()
789 {
790 wxSafeDecRef(m_renderer);
791 wxSafeDecRef(m_editor);
792 }
793
794 wxString m_typeName;
795 wxGridCellRenderer* m_renderer;
796 wxGridCellEditor* m_editor;
797
798 wxDECLARE_NO_COPY_CLASS(wxGridDataTypeInfo);
799 };
800
801
802 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray,
803 class WXDLLIMPEXP_ADV);
804
805
806 class WXDLLIMPEXP_ADV wxGridTypeRegistry
807 {
808 public:
809 wxGridTypeRegistry() {}
810 ~wxGridTypeRegistry();
811
812 void RegisterDataType(const wxString& typeName,
813 wxGridCellRenderer* renderer,
814 wxGridCellEditor* editor);
815
816 // find one of already registered data types
817 int FindRegisteredDataType(const wxString& typeName);
818
819 // try to FindRegisteredDataType(), if this fails and typeName is one of
820 // standard typenames, register it and return its index
821 int FindDataType(const wxString& typeName);
822
823 // try to FindDataType(), if it fails see if it is not one of already
824 // registered data types with some params in which case clone the
825 // registered data type and set params for it
826 int FindOrCloneDataType(const wxString& typeName);
827
828 wxGridCellRenderer* GetRenderer(int index);
829 wxGridCellEditor* GetEditor(int index);
830
831 private:
832 wxGridDataTypeInfoArray m_typeinfo;
833 };
834
835 #endif // wxUSE_GRID
836 #endif // _WX_GENERIC_GRID_PRIVATE_H_