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