]> git.saurik.com Git - wxWidgets.git/blob - include/wx/generic/private/grid.h
3b21325aa0a95b0297b0256faa8a77906a22196a
[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 static wxMouseEvent GetDummyMouseEvent()
162 {
163 // make up a dummy event for the grid event to use -- unfortunately we
164 // can't do anything else here
165 wxMouseEvent e;
166 e.SetState(wxGetMouseState());
167 return e;
168 }
169
170 // override the base class method to update our m_columns array
171 virtual void OnColumnCountChanging(unsigned int count)
172 {
173 const unsigned countOld = m_columns.size();
174 if ( count < countOld )
175 {
176 // just discard the columns which don't exist any more (notice that
177 // we can't use resize() here as it would require the vector
178 // value_type, i.e. wxGridHeaderColumn to be default constructible,
179 // which it is not)
180 m_columns.erase(m_columns.begin() + count, m_columns.end());
181 }
182 else // new columns added
183 {
184 // add columns for the new elements
185 for ( unsigned n = countOld; n < count; n++ )
186 m_columns.push_back(wxGridHeaderColumn(GetOwner(), n));
187 }
188 }
189
190 // override to implement column auto sizing
191 virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
192 {
193 // TODO: currently grid doesn't support computing the column best width
194 // from its contents so we just use the best label width as is
195 GetOwner()->SetColSize(idx, widthTitle);
196
197 return true;
198 }
199
200 // overridden to react to the actions using the columns popup menu
201 virtual void UpdateColumnVisibility(unsigned int idx, bool show)
202 {
203 GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
204
205 // as this is done by the user we should notify the main program about
206 // it
207 GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx,
208 GetDummyMouseEvent());
209 }
210
211 // overridden to react to the columns order changes in the customization
212 // dialog
213 virtual void UpdateColumnsOrder(const wxArrayInt& order)
214 {
215 GetOwner()->SetColumnsOrder(order);
216 }
217
218
219 // event handlers forwarding wxHeaderCtrl events to wxGrid
220 void OnClick(wxHeaderCtrlEvent& event)
221 {
222 GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_CLICK,
223 -1, event.GetColumn(),
224 GetDummyMouseEvent());
225
226 GetOwner()->DoColHeaderClick(event.GetColumn());
227 }
228
229 void OnDoubleClick(wxHeaderCtrlEvent& event)
230 {
231 if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_DCLICK,
232 -1, event.GetColumn(),
233 GetDummyMouseEvent()) )
234 {
235 event.Skip();
236 }
237 }
238
239 void OnRightClick(wxHeaderCtrlEvent& event)
240 {
241 if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_RIGHT_CLICK,
242 -1, event.GetColumn(),
243 GetDummyMouseEvent()) )
244 {
245 event.Skip();
246 }
247 }
248
249 void OnBeginResize(wxHeaderCtrlEvent& event)
250 {
251 GetOwner()->DoStartResizeCol(event.GetColumn());
252
253 event.Skip();
254 }
255
256 void OnResizing(wxHeaderCtrlEvent& event)
257 {
258 GetOwner()->DoUpdateResizeColWidth(event.GetWidth());
259 }
260
261 void OnEndResize(wxHeaderCtrlEvent& event)
262 {
263 // we again need to pass a mouse event to be used for the grid event
264 // generation but we don't have it here so use a dummy one as in
265 // UpdateColumnVisibility()
266 wxMouseEvent e;
267 e.SetState(wxGetMouseState());
268 GetOwner()->DoEndDragResizeCol(e);
269
270 event.Skip();
271 }
272
273 void OnBeginReorder(wxHeaderCtrlEvent& event)
274 {
275 GetOwner()->DoStartMoveCol(event.GetColumn());
276 }
277
278 void OnEndReorder(wxHeaderCtrlEvent& event)
279 {
280 GetOwner()->DoEndMoveCol(event.GetNewOrder());
281 }
282
283 wxVector<wxGridHeaderColumn> m_columns;
284
285 DECLARE_EVENT_TABLE()
286 wxDECLARE_NO_COPY_CLASS(wxGridHeaderCtrl);
287 };
288
289 // common base class for various grid subwindows
290 class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow
291 {
292 public:
293 wxGridSubwindow(wxGrid *owner,
294 int additionalStyle = 0,
295 const wxString& name = wxPanelNameStr)
296 : wxWindow(owner, wxID_ANY,
297 wxDefaultPosition, wxDefaultSize,
298 wxBORDER_NONE | additionalStyle,
299 name)
300 {
301 m_owner = owner;
302 }
303
304 virtual wxWindow *GetMainWindowOfCompositeControl() { return m_owner; }
305
306 virtual bool AcceptsFocus() const { return false; }
307
308 wxGrid *GetOwner() { return m_owner; }
309
310 protected:
311 void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
312
313 wxGrid *m_owner;
314
315 DECLARE_EVENT_TABLE()
316 wxDECLARE_NO_COPY_CLASS(wxGridSubwindow);
317 };
318
319 class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow
320 {
321 public:
322 wxGridRowLabelWindow(wxGrid *parent)
323 : wxGridSubwindow(parent)
324 {
325 }
326
327
328 private:
329 void OnPaint( wxPaintEvent& event );
330 void OnMouseEvent( wxMouseEvent& event );
331 void OnMouseWheel( wxMouseEvent& event );
332
333 DECLARE_EVENT_TABLE()
334 wxDECLARE_NO_COPY_CLASS(wxGridRowLabelWindow);
335 };
336
337
338 class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow
339 {
340 public:
341 wxGridColLabelWindow(wxGrid *parent)
342 : wxGridSubwindow(parent)
343 {
344 }
345
346
347 private:
348 void OnPaint( wxPaintEvent& event );
349 void OnMouseEvent( wxMouseEvent& event );
350 void OnMouseWheel( wxMouseEvent& event );
351
352 DECLARE_EVENT_TABLE()
353 wxDECLARE_NO_COPY_CLASS(wxGridColLabelWindow);
354 };
355
356
357 class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow
358 {
359 public:
360 wxGridCornerLabelWindow(wxGrid *parent)
361 : wxGridSubwindow(parent)
362 {
363 }
364
365 private:
366 void OnMouseEvent( wxMouseEvent& event );
367 void OnMouseWheel( wxMouseEvent& event );
368 void OnPaint( wxPaintEvent& event );
369
370 DECLARE_EVENT_TABLE()
371 wxDECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow);
372 };
373
374 class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow
375 {
376 public:
377 wxGridWindow(wxGrid *parent)
378 : wxGridSubwindow(parent,
379 wxWANTS_CHARS | wxCLIP_CHILDREN,
380 "GridWindow")
381 {
382 }
383
384
385 virtual void ScrollWindow( int dx, int dy, const wxRect *rect );
386
387 virtual bool AcceptsFocus() const { return true; }
388
389 private:
390 void OnPaint( wxPaintEvent &event );
391 void OnMouseWheel( wxMouseEvent& event );
392 void OnMouseEvent( wxMouseEvent& event );
393 void OnKeyDown( wxKeyEvent& );
394 void OnKeyUp( wxKeyEvent& );
395 void OnChar( wxKeyEvent& );
396 void OnEraseBackground( wxEraseEvent& );
397 void OnFocus( wxFocusEvent& );
398
399 DECLARE_EVENT_TABLE()
400 wxDECLARE_NO_COPY_CLASS(wxGridWindow);
401 };
402
403 // ----------------------------------------------------------------------------
404 // the internal data representation used by wxGridCellAttrProvider
405 // ----------------------------------------------------------------------------
406
407 // this class stores attributes set for cells
408 class WXDLLIMPEXP_ADV wxGridCellAttrData
409 {
410 public:
411 void SetAttr(wxGridCellAttr *attr, int row, int col);
412 wxGridCellAttr *GetAttr(int row, int col) const;
413 void UpdateAttrRows( size_t pos, int numRows );
414 void UpdateAttrCols( size_t pos, int numCols );
415
416 private:
417 // searches for the attr for given cell, returns wxNOT_FOUND if not found
418 int FindIndex(int row, int col) const;
419
420 wxGridCellWithAttrArray m_attrs;
421 };
422
423 // this class stores attributes set for rows or columns
424 class WXDLLIMPEXP_ADV wxGridRowOrColAttrData
425 {
426 public:
427 // empty ctor to suppress warnings
428 wxGridRowOrColAttrData() {}
429 ~wxGridRowOrColAttrData();
430
431 void SetAttr(wxGridCellAttr *attr, int rowOrCol);
432 wxGridCellAttr *GetAttr(int rowOrCol) const;
433 void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols );
434
435 private:
436 wxArrayInt m_rowsOrCols;
437 wxArrayAttrs m_attrs;
438 };
439
440 // NB: this is just a wrapper around 3 objects: one which stores cell
441 // attributes, and 2 others for row/col ones
442 class WXDLLIMPEXP_ADV wxGridCellAttrProviderData
443 {
444 public:
445 wxGridCellAttrData m_cellAttrs;
446 wxGridRowOrColAttrData m_rowAttrs,
447 m_colAttrs;
448 };
449
450 // ----------------------------------------------------------------------------
451 // operations classes abstracting the difference between operating on rows and
452 // columns
453 // ----------------------------------------------------------------------------
454
455 // This class allows to write a function only once because by using its methods
456 // it will apply to both columns and rows.
457 //
458 // This is an abstract interface definition, the two concrete implementations
459 // below should be used when working with rows and columns respectively.
460 class wxGridOperations
461 {
462 public:
463 // Returns the operations in the other direction, i.e. wxGridRowOperations
464 // if this object is a wxGridColumnOperations and vice versa.
465 virtual wxGridOperations& Dual() const = 0;
466
467 // Return the number of rows or columns.
468 virtual int GetNumberOfLines(const wxGrid *grid) const = 0;
469
470 // Return the selection mode which allows selecting rows or columns.
471 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0;
472
473 // Make a wxGridCellCoords from the given components: thisDir is row or
474 // column and otherDir is column or row
475 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0;
476
477 // Calculate the scrolled position of the given abscissa or ordinate.
478 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0;
479
480 // Selects the horizontal or vertical component from the given object.
481 virtual int Select(const wxGridCellCoords& coords) const = 0;
482 virtual int Select(const wxPoint& pt) const = 0;
483 virtual int Select(const wxSize& sz) const = 0;
484 virtual int Select(const wxRect& r) const = 0;
485 virtual int& Select(wxRect& r) const = 0;
486
487 // Returns width or height of the rectangle
488 virtual int& SelectSize(wxRect& r) const = 0;
489
490 // Make a wxSize such that Select() applied to it returns first component
491 virtual wxSize MakeSize(int first, int second) const = 0;
492
493 // Sets the row or column component of the given cell coordinates
494 virtual void Set(wxGridCellCoords& coords, int line) const = 0;
495
496
497 // Draws a line parallel to the row or column, i.e. horizontal or vertical:
498 // pos is the horizontal or vertical position of the line and start and end
499 // are the coordinates of the line extremities in the other direction
500 virtual void
501 DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
502
503 // Draw a horizontal or vertical line across the given rectangle
504 // (this is implemented in terms of above and uses Select() to extract
505 // start and end from the given rectangle)
506 void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
507 {
508 const int posStart = Select(rect.GetPosition());
509 DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
510 }
511
512
513 // Return the index of the row or column at the given pixel coordinate.
514 virtual int
515 PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0;
516
517 // Get the top/left position, in pixels, of the given row or column
518 virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0;
519
520 // Get the bottom/right position, in pixels, of the given row or column
521 virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0;
522
523 // Get the height/width of the given row/column
524 virtual int GetLineSize(const wxGrid *grid, int line) const = 0;
525
526 // Get wxGrid::m_rowBottoms/m_colRights array
527 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0;
528
529 // Get default height row height or column width
530 virtual int GetDefaultLineSize(const wxGrid *grid) const = 0;
531
532 // Return the minimal acceptable row height or column width
533 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0;
534
535 // Return the minimal row height or column width
536 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0;
537
538 // Set the row height or column width
539 virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0;
540
541 // Set the row default height or column default width
542 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
543
544
545 // Return the index of the line at the given position
546 //
547 // NB: currently this is always identity for the rows as reordering is only
548 // implemented for the lines
549 virtual int GetLineAt(const wxGrid *grid, int pos) const = 0;
550
551 // Return the display position of the line with the given index.
552 //
553 // NB: As GetLineAt(), currently this is always identity for rows.
554 virtual int GetLinePos(const wxGrid *grid, int line) const = 0;
555
556 // Return the index of the line just before the given one or wxNOT_FOUND.
557 virtual int GetLineBefore(const wxGrid* grid, int line) const = 0;
558
559 // Get the row or column label window
560 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0;
561
562 // Get the width or height of the row or column label window
563 virtual int GetHeaderWindowSize(wxGrid *grid) const = 0;
564
565
566 // This class is never used polymorphically but give it a virtual dtor
567 // anyhow to suppress g++ complaints about it
568 virtual ~wxGridOperations() { }
569 };
570
571 class wxGridRowOperations : public wxGridOperations
572 {
573 public:
574 virtual wxGridOperations& Dual() const;
575
576 virtual int GetNumberOfLines(const wxGrid *grid) const
577 { return grid->GetNumberRows(); }
578
579 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
580 { return wxGrid::wxGridSelectRows; }
581
582 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
583 { return wxGridCellCoords(thisDir, otherDir); }
584
585 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
586 { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; }
587
588 virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); }
589 virtual int Select(const wxPoint& pt) const { return pt.x; }
590 virtual int Select(const wxSize& sz) const { return sz.x; }
591 virtual int Select(const wxRect& r) const { return r.x; }
592 virtual int& Select(wxRect& r) const { return r.x; }
593 virtual int& SelectSize(wxRect& r) const { return r.width; }
594 virtual wxSize MakeSize(int first, int second) const
595 { return wxSize(first, second); }
596 virtual void Set(wxGridCellCoords& coords, int line) const
597 { coords.SetRow(line); }
598
599 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
600 { dc.DrawLine(start, pos, end, pos); }
601
602 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
603 { return grid->YToRow(pos, clip); }
604 virtual int GetLineStartPos(const wxGrid *grid, int line) const
605 { return grid->GetRowTop(line); }
606 virtual int GetLineEndPos(const wxGrid *grid, int line) const
607 { return grid->GetRowBottom(line); }
608 virtual int GetLineSize(const wxGrid *grid, int line) const
609 { return grid->GetRowHeight(line); }
610 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
611 { return grid->m_rowBottoms; }
612 virtual int GetDefaultLineSize(const wxGrid *grid) const
613 { return grid->GetDefaultRowSize(); }
614 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
615 { return grid->GetRowMinimalAcceptableHeight(); }
616 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
617 { return grid->GetRowMinimalHeight(line); }
618 virtual void SetLineSize(wxGrid *grid, int line, int size) const
619 { grid->SetRowSize(line, size); }
620 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
621 { grid->SetDefaultRowSize(size, resizeExisting); }
622
623 virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int pos) const
624 { return pos; } // TODO: implement row reordering
625 virtual int GetLinePos(const wxGrid * WXUNUSED(grid), int line) const
626 { return line; } // TODO: implement row reordering
627
628 virtual int GetLineBefore(const wxGrid* WXUNUSED(grid), int line) const
629 { return line - 1; }
630
631 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
632 { return grid->GetGridRowLabelWindow(); }
633 virtual int GetHeaderWindowSize(wxGrid *grid) const
634 { return grid->GetRowLabelSize(); }
635 };
636
637 class wxGridColumnOperations : public wxGridOperations
638 {
639 public:
640 virtual wxGridOperations& Dual() const;
641
642 virtual int GetNumberOfLines(const wxGrid *grid) const
643 { return grid->GetNumberCols(); }
644
645 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
646 { return wxGrid::wxGridSelectColumns; }
647
648 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
649 { return wxGridCellCoords(otherDir, thisDir); }
650
651 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
652 { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; }
653
654 virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); }
655 virtual int Select(const wxPoint& pt) const { return pt.y; }
656 virtual int Select(const wxSize& sz) const { return sz.y; }
657 virtual int Select(const wxRect& r) const { return r.y; }
658 virtual int& Select(wxRect& r) const { return r.y; }
659 virtual int& SelectSize(wxRect& r) const { return r.height; }
660 virtual wxSize MakeSize(int first, int second) const
661 { return wxSize(second, first); }
662 virtual void Set(wxGridCellCoords& coords, int line) const
663 { coords.SetCol(line); }
664
665 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
666 { dc.DrawLine(pos, start, pos, end); }
667
668 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
669 { return grid->XToCol(pos, clip); }
670 virtual int GetLineStartPos(const wxGrid *grid, int line) const
671 { return grid->GetColLeft(line); }
672 virtual int GetLineEndPos(const wxGrid *grid, int line) const
673 { return grid->GetColRight(line); }
674 virtual int GetLineSize(const wxGrid *grid, int line) const
675 { return grid->GetColWidth(line); }
676 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
677 { return grid->m_colRights; }
678 virtual int GetDefaultLineSize(const wxGrid *grid) const
679 { return grid->GetDefaultColSize(); }
680 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
681 { return grid->GetColMinimalAcceptableWidth(); }
682 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
683 { return grid->GetColMinimalWidth(line); }
684 virtual void SetLineSize(wxGrid *grid, int line, int size) const
685 { grid->SetColSize(line, size); }
686 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
687 { grid->SetDefaultColSize(size, resizeExisting); }
688
689 virtual int GetLineAt(const wxGrid *grid, int pos) const
690 { return grid->GetColAt(pos); }
691 virtual int GetLinePos(const wxGrid *grid, int line) const
692 { return grid->GetColPos(line); }
693
694 virtual int GetLineBefore(const wxGrid* grid, int line) const
695 {
696 int posBefore = grid->GetColPos(line) - 1;
697 return posBefore >= 0 ? grid->GetColAt(posBefore) : wxNOT_FOUND;
698 }
699
700 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
701 { return grid->GetGridColLabelWindow(); }
702 virtual int GetHeaderWindowSize(wxGrid *grid) const
703 { return grid->GetColLabelSize(); }
704 };
705
706 // This class abstracts the difference between operations going forward
707 // (down/right) and backward (up/left) and allows to use the same code for
708 // functions which differ only in the direction of grid traversal.
709 //
710 // Notice that all operations in this class work with display positions and not
711 // internal indices which can be different if the columns were reordered.
712 //
713 // Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike
714 // it, this is a normal object and not just a function dispatch table and has a
715 // non-default ctor.
716 //
717 // Note: the explanation of this discrepancy is the existence of (very useful)
718 // Dual() method in wxGridOperations which forces us to make wxGridOperations a
719 // function dispatcher only.
720 class wxGridDirectionOperations
721 {
722 public:
723 // The oper parameter to ctor selects whether we work with rows or columns
724 wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper)
725 : m_grid(grid),
726 m_oper(oper)
727 {
728 }
729
730 // Check if the component of this point in our direction is at the
731 // boundary, i.e. is the first/last row/column
732 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0;
733
734 // Increment the component of this point in our direction
735 virtual void Advance(wxGridCellCoords& coords) const = 0;
736
737 // Find the line at the given distance, in pixels, away from this one
738 // (this uses clipping, i.e. anything after the last line is counted as the
739 // last one and anything before the first one as 0)
740 //
741 // TODO: Implementation of this method currently doesn't support column
742 // reordering as it mixes up indices and positions. But this doesn't
743 // really matter as it's only called for rows (Page Up/Down only work
744 // vertically) and row reordering is not currently supported. We'd
745 // need to fix it if this ever changes however.
746 virtual int MoveByPixelDistance(int line, int distance) const = 0;
747
748 // This class is never used polymorphically but give it a virtual dtor
749 // anyhow to suppress g++ complaints about it
750 virtual ~wxGridDirectionOperations() { }
751
752 protected:
753 // Get the position of the row or column from the given coordinates pair.
754 //
755 // This is just a shortcut to avoid repeating m_oper and m_grid multiple
756 // times in the derived classes code.
757 int GetLinePos(const wxGridCellCoords& coords) const
758 {
759 return m_oper.GetLinePos(m_grid, m_oper.Select(coords));
760 }
761
762 // Get the index of the row or column from the position.
763 int GetLineAt(int pos) const
764 {
765 return m_oper.GetLineAt(m_grid, pos);
766 }
767
768 // Check if the given line is visible, i.e. has non 0 size.
769 bool IsLineVisible(int line) const
770 {
771 return m_oper.GetLineSize(m_grid, line) != 0;
772 }
773
774
775 wxGrid * const m_grid;
776 const wxGridOperations& m_oper;
777 };
778
779 class wxGridBackwardOperations : public wxGridDirectionOperations
780 {
781 public:
782 wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper)
783 : wxGridDirectionOperations(grid, oper)
784 {
785 }
786
787 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
788 {
789 wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" );
790
791 int pos = GetLinePos(coords);
792 while ( pos )
793 {
794 // Check the previous line.
795 int line = GetLineAt(--pos);
796 if ( IsLineVisible(line) )
797 {
798 // There is another visible line before this one, hence it's
799 // not at boundary.
800 return false;
801 }
802 }
803
804 // We reached the boundary without finding any visible lines.
805 return true;
806 }
807
808 virtual void Advance(wxGridCellCoords& coords) const
809 {
810 int pos = GetLinePos(coords);
811 for ( ;; )
812 {
813 // This is not supposed to happen if IsAtBoundary() returned false.
814 wxCHECK_RET( pos, "can't advance when already at boundary" );
815
816 int line = GetLineAt(--pos);
817 if ( IsLineVisible(line) )
818 {
819 m_oper.Set(coords, line);
820 break;
821 }
822 }
823 }
824
825 virtual int MoveByPixelDistance(int line, int distance) const
826 {
827 int pos = m_oper.GetLineStartPos(m_grid, line);
828 return m_oper.PosToLine(m_grid, pos - distance + 1, true);
829 }
830 };
831
832 // Please refer to the comments above when reading this class code, it's
833 // absolutely symmetrical to wxGridBackwardOperations.
834 class wxGridForwardOperations : public wxGridDirectionOperations
835 {
836 public:
837 wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper)
838 : wxGridDirectionOperations(grid, oper),
839 m_numLines(oper.GetNumberOfLines(grid))
840 {
841 }
842
843 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
844 {
845 wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" );
846
847 int pos = GetLinePos(coords);
848 while ( pos < m_numLines - 1 )
849 {
850 int line = GetLineAt(++pos);
851 if ( IsLineVisible(line) )
852 return false;
853 }
854
855 return true;
856 }
857
858 virtual void Advance(wxGridCellCoords& coords) const
859 {
860 int pos = GetLinePos(coords);
861 for ( ;; )
862 {
863 wxCHECK_RET( pos < m_numLines - 1,
864 "can't advance when already at boundary" );
865
866 int line = GetLineAt(++pos);
867 if ( IsLineVisible(line) )
868 {
869 m_oper.Set(coords, line);
870 break;
871 }
872 }
873 }
874
875 virtual int MoveByPixelDistance(int line, int distance) const
876 {
877 int pos = m_oper.GetLineStartPos(m_grid, line);
878 return m_oper.PosToLine(m_grid, pos + distance, true);
879 }
880
881 private:
882 const int m_numLines;
883 };
884
885 // ----------------------------------------------------------------------------
886 // data structures used for the data type registry
887 // ----------------------------------------------------------------------------
888
889 struct wxGridDataTypeInfo
890 {
891 wxGridDataTypeInfo(const wxString& typeName,
892 wxGridCellRenderer* renderer,
893 wxGridCellEditor* editor)
894 : m_typeName(typeName), m_renderer(renderer), m_editor(editor)
895 {}
896
897 ~wxGridDataTypeInfo()
898 {
899 wxSafeDecRef(m_renderer);
900 wxSafeDecRef(m_editor);
901 }
902
903 wxString m_typeName;
904 wxGridCellRenderer* m_renderer;
905 wxGridCellEditor* m_editor;
906
907 wxDECLARE_NO_COPY_CLASS(wxGridDataTypeInfo);
908 };
909
910
911 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray,
912 class WXDLLIMPEXP_ADV);
913
914
915 class WXDLLIMPEXP_ADV wxGridTypeRegistry
916 {
917 public:
918 wxGridTypeRegistry() {}
919 ~wxGridTypeRegistry();
920
921 void RegisterDataType(const wxString& typeName,
922 wxGridCellRenderer* renderer,
923 wxGridCellEditor* editor);
924
925 // find one of already registered data types
926 int FindRegisteredDataType(const wxString& typeName);
927
928 // try to FindRegisteredDataType(), if this fails and typeName is one of
929 // standard typenames, register it and return its index
930 int FindDataType(const wxString& typeName);
931
932 // try to FindDataType(), if it fails see if it is not one of already
933 // registered data types with some params in which case clone the
934 // registered data type and set params for it
935 int FindOrCloneDataType(const wxString& typeName);
936
937 wxGridCellRenderer* GetRenderer(int index);
938 wxGridCellEditor* GetEditor(int index);
939
940 private:
941 wxGridDataTypeInfoArray m_typeinfo;
942 };
943
944 #endif // wxUSE_GRID
945 #endif // _WX_GENERIC_GRID_PRIVATE_H_