]>
Commit | Line | Data |
---|---|---|
29efc6e4 FM |
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() ) | |
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 | GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx); | |
199 | } | |
200 | ||
201 | // overridden to react to the columns order changes in the customization | |
202 | // dialog | |
203 | virtual void UpdateColumnsOrder(const wxArrayInt& order) | |
204 | { | |
205 | GetOwner()->SetColumnsOrder(order); | |
206 | } | |
207 | ||
208 | ||
209 | // event handlers forwarding wxHeaderCtrl events to wxGrid | |
210 | void OnClick(wxHeaderCtrlEvent& event) | |
211 | { | |
212 | GetOwner()->DoColHeaderClick(event.GetColumn()); | |
213 | } | |
214 | ||
215 | void OnBeginResize(wxHeaderCtrlEvent& event) | |
216 | { | |
217 | GetOwner()->DoStartResizeCol(event.GetColumn()); | |
218 | ||
219 | event.Skip(); | |
220 | } | |
221 | ||
222 | void OnResizing(wxHeaderCtrlEvent& event) | |
223 | { | |
224 | GetOwner()->DoUpdateResizeColWidth(event.GetWidth()); | |
225 | } | |
226 | ||
227 | void OnEndResize(wxHeaderCtrlEvent& event) | |
228 | { | |
229 | GetOwner()->DoEndDragResizeCol(); | |
230 | ||
231 | event.Skip(); | |
232 | } | |
233 | ||
234 | void OnBeginReorder(wxHeaderCtrlEvent& event) | |
235 | { | |
236 | GetOwner()->DoStartMoveCol(event.GetColumn()); | |
237 | } | |
238 | ||
239 | void OnEndReorder(wxHeaderCtrlEvent& event) | |
240 | { | |
241 | GetOwner()->DoEndMoveCol(event.GetNewOrder()); | |
242 | } | |
243 | ||
244 | wxVector<wxGridHeaderColumn> m_columns; | |
245 | ||
246 | DECLARE_EVENT_TABLE() | |
247 | DECLARE_NO_COPY_CLASS(wxGridHeaderCtrl) | |
248 | }; | |
249 | ||
250 | // common base class for various grid subwindows | |
251 | class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow | |
252 | { | |
253 | public: | |
254 | wxGridSubwindow(wxGrid *owner, | |
255 | int additionalStyle = 0, | |
256 | const wxString& name = wxPanelNameStr) | |
257 | : wxWindow(owner, wxID_ANY, | |
258 | wxDefaultPosition, wxDefaultSize, | |
259 | wxBORDER_NONE | additionalStyle, | |
260 | name) | |
261 | { | |
262 | m_owner = owner; | |
263 | } | |
264 | ||
265 | virtual bool AcceptsFocus() const { return false; } | |
266 | ||
267 | wxGrid *GetOwner() { return m_owner; } | |
268 | ||
269 | protected: | |
270 | void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); | |
271 | ||
272 | wxGrid *m_owner; | |
273 | ||
274 | DECLARE_EVENT_TABLE() | |
275 | DECLARE_NO_COPY_CLASS(wxGridSubwindow) | |
276 | }; | |
277 | ||
278 | class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow | |
279 | { | |
280 | public: | |
281 | wxGridRowLabelWindow(wxGrid *parent) | |
282 | : wxGridSubwindow(parent) | |
283 | { | |
284 | } | |
285 | ||
286 | ||
287 | private: | |
288 | void OnPaint( wxPaintEvent& event ); | |
289 | void OnMouseEvent( wxMouseEvent& event ); | |
290 | void OnMouseWheel( wxMouseEvent& event ); | |
291 | ||
292 | DECLARE_EVENT_TABLE() | |
293 | DECLARE_NO_COPY_CLASS(wxGridRowLabelWindow) | |
294 | }; | |
295 | ||
296 | ||
297 | class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow | |
298 | { | |
299 | public: | |
300 | wxGridColLabelWindow(wxGrid *parent) | |
301 | : wxGridSubwindow(parent) | |
302 | { | |
303 | } | |
304 | ||
305 | ||
306 | private: | |
307 | void OnPaint( wxPaintEvent& event ); | |
308 | void OnMouseEvent( wxMouseEvent& event ); | |
309 | void OnMouseWheel( wxMouseEvent& event ); | |
310 | ||
311 | DECLARE_EVENT_TABLE() | |
312 | DECLARE_NO_COPY_CLASS(wxGridColLabelWindow) | |
313 | }; | |
314 | ||
315 | ||
316 | class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow | |
317 | { | |
318 | public: | |
319 | wxGridCornerLabelWindow(wxGrid *parent) | |
320 | : wxGridSubwindow(parent) | |
321 | { | |
322 | } | |
323 | ||
324 | private: | |
325 | void OnMouseEvent( wxMouseEvent& event ); | |
326 | void OnMouseWheel( wxMouseEvent& event ); | |
327 | void OnPaint( wxPaintEvent& event ); | |
328 | ||
329 | DECLARE_EVENT_TABLE() | |
330 | DECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow) | |
331 | }; | |
332 | ||
333 | class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow | |
334 | { | |
335 | public: | |
336 | wxGridWindow(wxGrid *parent) | |
337 | : wxGridSubwindow(parent, | |
338 | wxWANTS_CHARS | wxCLIP_CHILDREN, | |
339 | "GridWindow") | |
340 | { | |
341 | } | |
342 | ||
343 | ||
344 | virtual void ScrollWindow( int dx, int dy, const wxRect *rect ); | |
345 | ||
346 | virtual bool AcceptsFocus() const { return true; } | |
347 | ||
348 | private: | |
349 | void OnPaint( wxPaintEvent &event ); | |
350 | void OnMouseWheel( wxMouseEvent& event ); | |
351 | void OnMouseEvent( wxMouseEvent& event ); | |
352 | void OnKeyDown( wxKeyEvent& ); | |
353 | void OnKeyUp( wxKeyEvent& ); | |
354 | void OnChar( wxKeyEvent& ); | |
355 | void OnEraseBackground( wxEraseEvent& ); | |
356 | void OnFocus( wxFocusEvent& ); | |
357 | ||
358 | DECLARE_EVENT_TABLE() | |
359 | DECLARE_NO_COPY_CLASS(wxGridWindow) | |
360 | }; | |
361 | ||
362 | // ---------------------------------------------------------------------------- | |
363 | // the internal data representation used by wxGridCellAttrProvider | |
364 | // ---------------------------------------------------------------------------- | |
365 | ||
366 | // this class stores attributes set for cells | |
367 | class WXDLLIMPEXP_ADV wxGridCellAttrData | |
368 | { | |
369 | public: | |
370 | void SetAttr(wxGridCellAttr *attr, int row, int col); | |
371 | wxGridCellAttr *GetAttr(int row, int col) const; | |
372 | void UpdateAttrRows( size_t pos, int numRows ); | |
373 | void UpdateAttrCols( size_t pos, int numCols ); | |
374 | ||
375 | private: | |
376 | // searches for the attr for given cell, returns wxNOT_FOUND if not found | |
377 | int FindIndex(int row, int col) const; | |
378 | ||
379 | wxGridCellWithAttrArray m_attrs; | |
380 | }; | |
381 | ||
382 | // this class stores attributes set for rows or columns | |
383 | class WXDLLIMPEXP_ADV wxGridRowOrColAttrData | |
384 | { | |
385 | public: | |
386 | // empty ctor to suppress warnings | |
387 | wxGridRowOrColAttrData() {} | |
388 | ~wxGridRowOrColAttrData(); | |
389 | ||
390 | void SetAttr(wxGridCellAttr *attr, int rowOrCol); | |
391 | wxGridCellAttr *GetAttr(int rowOrCol) const; | |
392 | void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols ); | |
393 | ||
394 | private: | |
395 | wxArrayInt m_rowsOrCols; | |
396 | wxArrayAttrs m_attrs; | |
397 | }; | |
398 | ||
399 | // NB: this is just a wrapper around 3 objects: one which stores cell | |
400 | // attributes, and 2 others for row/col ones | |
401 | class WXDLLIMPEXP_ADV wxGridCellAttrProviderData | |
402 | { | |
403 | public: | |
404 | wxGridCellAttrData m_cellAttrs; | |
405 | wxGridRowOrColAttrData m_rowAttrs, | |
406 | m_colAttrs; | |
407 | }; | |
408 | ||
409 | // ---------------------------------------------------------------------------- | |
410 | // operations classes abstracting the difference between operating on rows and | |
411 | // columns | |
412 | // ---------------------------------------------------------------------------- | |
413 | ||
414 | // This class allows to write a function only once because by using its methods | |
415 | // it will apply to both columns and rows. | |
416 | // | |
417 | // This is an abstract interface definition, the two concrete implementations | |
418 | // below should be used when working with rows and columns respectively. | |
419 | class wxGridOperations | |
420 | { | |
421 | public: | |
422 | // Returns the operations in the other direction, i.e. wxGridRowOperations | |
423 | // if this object is a wxGridColumnOperations and vice versa. | |
424 | virtual wxGridOperations& Dual() const = 0; | |
425 | ||
426 | // Return the number of rows or columns. | |
427 | virtual int GetNumberOfLines(const wxGrid *grid) const = 0; | |
428 | ||
429 | // Return the selection mode which allows selecting rows or columns. | |
430 | virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0; | |
431 | ||
432 | // Make a wxGridCellCoords from the given components: thisDir is row or | |
433 | // column and otherDir is column or row | |
434 | virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0; | |
435 | ||
436 | // Calculate the scrolled position of the given abscissa or ordinate. | |
437 | virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0; | |
438 | ||
439 | // Selects the horizontal or vertical component from the given object. | |
440 | virtual int Select(const wxGridCellCoords& coords) const = 0; | |
441 | virtual int Select(const wxPoint& pt) const = 0; | |
442 | virtual int Select(const wxSize& sz) const = 0; | |
443 | virtual int Select(const wxRect& r) const = 0; | |
444 | virtual int& Select(wxRect& r) const = 0; | |
445 | ||
446 | // Returns width or height of the rectangle | |
447 | virtual int& SelectSize(wxRect& r) const = 0; | |
448 | ||
449 | // Make a wxSize such that Select() applied to it returns first component | |
450 | virtual wxSize MakeSize(int first, int second) const = 0; | |
451 | ||
452 | // Sets the row or column component of the given cell coordinates | |
453 | virtual void Set(wxGridCellCoords& coords, int line) const = 0; | |
454 | ||
455 | ||
456 | // Draws a line parallel to the row or column, i.e. horizontal or vertical: | |
457 | // pos is the horizontal or vertical position of the line and start and end | |
458 | // are the coordinates of the line extremities in the other direction | |
459 | virtual void | |
460 | DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0; | |
461 | ||
462 | // Draw a horizontal or vertical line across the given rectangle | |
463 | // (this is implemented in terms of above and uses Select() to extract | |
464 | // start and end from the given rectangle) | |
465 | void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const | |
466 | { | |
467 | const int posStart = Select(rect.GetPosition()); | |
468 | DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos); | |
469 | } | |
470 | ||
471 | ||
472 | // Return the index of the row or column at the given pixel coordinate. | |
473 | virtual int | |
474 | PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0; | |
475 | ||
476 | // Get the top/left position, in pixels, of the given row or column | |
477 | virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0; | |
478 | ||
479 | // Get the bottom/right position, in pixels, of the given row or column | |
480 | virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0; | |
481 | ||
482 | // Get the height/width of the given row/column | |
483 | virtual int GetLineSize(const wxGrid *grid, int line) const = 0; | |
484 | ||
485 | // Get wxGrid::m_rowBottoms/m_colRights array | |
486 | virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0; | |
487 | ||
488 | // Get default height row height or column width | |
489 | virtual int GetDefaultLineSize(const wxGrid *grid) const = 0; | |
490 | ||
491 | // Return the minimal acceptable row height or column width | |
492 | virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0; | |
493 | ||
494 | // Return the minimal row height or column width | |
495 | virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0; | |
496 | ||
497 | // Set the row height or column width | |
498 | virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0; | |
499 | ||
500 | // True if rows/columns can be resized by user | |
501 | virtual bool CanResizeLines(const wxGrid *grid) const = 0; | |
502 | ||
503 | ||
504 | // Return the index of the line at the given position | |
505 | // | |
506 | // NB: currently this is always identity for the rows as reordering is only | |
507 | // implemented for the lines | |
508 | virtual int GetLineAt(const wxGrid *grid, int line) const = 0; | |
509 | ||
510 | ||
511 | // Get the row or column label window | |
512 | virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0; | |
513 | ||
514 | // Get the width or height of the row or column label window | |
515 | virtual int GetHeaderWindowSize(wxGrid *grid) const = 0; | |
516 | ||
517 | ||
518 | // This class is never used polymorphically but give it a virtual dtor | |
519 | // anyhow to suppress g++ complaints about it | |
520 | virtual ~wxGridOperations() { } | |
521 | }; | |
522 | ||
523 | class wxGridRowOperations : public wxGridOperations | |
524 | { | |
525 | public: | |
526 | virtual wxGridOperations& Dual() const; | |
527 | ||
528 | virtual int GetNumberOfLines(const wxGrid *grid) const | |
529 | { return grid->GetNumberRows(); } | |
530 | ||
531 | virtual wxGrid::wxGridSelectionModes GetSelectionMode() const | |
532 | { return wxGrid::wxGridSelectRows; } | |
533 | ||
534 | virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const | |
535 | { return wxGridCellCoords(thisDir, otherDir); } | |
536 | ||
537 | virtual int CalcScrolledPosition(wxGrid *grid, int pos) const | |
538 | { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; } | |
539 | ||
540 | virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); } | |
541 | virtual int Select(const wxPoint& pt) const { return pt.x; } | |
542 | virtual int Select(const wxSize& sz) const { return sz.x; } | |
543 | virtual int Select(const wxRect& r) const { return r.x; } | |
544 | virtual int& Select(wxRect& r) const { return r.x; } | |
545 | virtual int& SelectSize(wxRect& r) const { return r.width; } | |
546 | virtual wxSize MakeSize(int first, int second) const | |
547 | { return wxSize(first, second); } | |
548 | virtual void Set(wxGridCellCoords& coords, int line) const | |
549 | { coords.SetRow(line); } | |
550 | ||
551 | virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const | |
552 | { dc.DrawLine(start, pos, end, pos); } | |
553 | ||
554 | virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const | |
555 | { return grid->YToRow(pos, clip); } | |
556 | virtual int GetLineStartPos(const wxGrid *grid, int line) const | |
557 | { return grid->GetRowTop(line); } | |
558 | virtual int GetLineEndPos(const wxGrid *grid, int line) const | |
559 | { return grid->GetRowBottom(line); } | |
560 | virtual int GetLineSize(const wxGrid *grid, int line) const | |
561 | { return grid->GetRowHeight(line); } | |
562 | virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const | |
563 | { return grid->m_rowBottoms; } | |
564 | virtual int GetDefaultLineSize(const wxGrid *grid) const | |
565 | { return grid->GetDefaultRowSize(); } | |
566 | virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const | |
567 | { return grid->GetRowMinimalAcceptableHeight(); } | |
568 | virtual int GetMinimalLineSize(const wxGrid *grid, int line) const | |
569 | { return grid->GetRowMinimalHeight(line); } | |
570 | virtual void SetLineSize(wxGrid *grid, int line, int size) const | |
571 | { grid->SetRowSize(line, size); } | |
572 | virtual bool CanResizeLines(const wxGrid *grid) const | |
573 | { return grid->CanDragRowSize(); } | |
574 | ||
575 | virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int line) const | |
576 | { return line; } // TODO: implement row reordering | |
577 | ||
578 | virtual wxWindow *GetHeaderWindow(wxGrid *grid) const | |
579 | { return grid->GetGridRowLabelWindow(); } | |
580 | virtual int GetHeaderWindowSize(wxGrid *grid) const | |
581 | { return grid->GetRowLabelSize(); } | |
582 | }; | |
583 | ||
584 | class wxGridColumnOperations : public wxGridOperations | |
585 | { | |
586 | public: | |
587 | virtual wxGridOperations& Dual() const; | |
588 | ||
589 | virtual int GetNumberOfLines(const wxGrid *grid) const | |
590 | { return grid->GetNumberCols(); } | |
591 | ||
592 | virtual wxGrid::wxGridSelectionModes GetSelectionMode() const | |
593 | { return wxGrid::wxGridSelectColumns; } | |
594 | ||
595 | virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const | |
596 | { return wxGridCellCoords(otherDir, thisDir); } | |
597 | ||
598 | virtual int CalcScrolledPosition(wxGrid *grid, int pos) const | |
599 | { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; } | |
600 | ||
601 | virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); } | |
602 | virtual int Select(const wxPoint& pt) const { return pt.y; } | |
603 | virtual int Select(const wxSize& sz) const { return sz.y; } | |
604 | virtual int Select(const wxRect& r) const { return r.y; } | |
605 | virtual int& Select(wxRect& r) const { return r.y; } | |
606 | virtual int& SelectSize(wxRect& r) const { return r.height; } | |
607 | virtual wxSize MakeSize(int first, int second) const | |
608 | { return wxSize(second, first); } | |
609 | virtual void Set(wxGridCellCoords& coords, int line) const | |
610 | { coords.SetCol(line); } | |
611 | ||
612 | virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const | |
613 | { dc.DrawLine(pos, start, pos, end); } | |
614 | ||
615 | virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const | |
616 | { return grid->XToCol(pos, clip); } | |
617 | virtual int GetLineStartPos(const wxGrid *grid, int line) const | |
618 | { return grid->GetColLeft(line); } | |
619 | virtual int GetLineEndPos(const wxGrid *grid, int line) const | |
620 | { return grid->GetColRight(line); } | |
621 | virtual int GetLineSize(const wxGrid *grid, int line) const | |
622 | { return grid->GetColWidth(line); } | |
623 | virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const | |
624 | { return grid->m_colRights; } | |
625 | virtual int GetDefaultLineSize(const wxGrid *grid) const | |
626 | { return grid->GetDefaultColSize(); } | |
627 | virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const | |
628 | { return grid->GetColMinimalAcceptableWidth(); } | |
629 | virtual int GetMinimalLineSize(const wxGrid *grid, int line) const | |
630 | { return grid->GetColMinimalWidth(line); } | |
631 | virtual void SetLineSize(wxGrid *grid, int line, int size) const | |
632 | { grid->SetColSize(line, size); } | |
633 | virtual bool CanResizeLines(const wxGrid *grid) const | |
634 | { return grid->CanDragColSize(); } | |
635 | ||
636 | virtual int GetLineAt(const wxGrid *grid, int line) const | |
637 | { return grid->GetColAt(line); } | |
638 | ||
639 | virtual wxWindow *GetHeaderWindow(wxGrid *grid) const | |
640 | { return grid->GetGridColLabelWindow(); } | |
641 | virtual int GetHeaderWindowSize(wxGrid *grid) const | |
642 | { return grid->GetColLabelSize(); } | |
643 | }; | |
644 | ||
645 | // This class abstracts the difference between operations going forward | |
646 | // (down/right) and backward (up/left) and allows to use the same code for | |
647 | // functions which differ only in the direction of grid traversal | |
648 | // | |
649 | // Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike | |
650 | // it, this is a normal object and not just a function dispatch table and has a | |
651 | // non-default ctor. | |
652 | // | |
653 | // Note: the explanation of this discrepancy is the existence of (very useful) | |
654 | // Dual() method in wxGridOperations which forces us to make wxGridOperations a | |
655 | // function dispatcher only. | |
656 | class wxGridDirectionOperations | |
657 | { | |
658 | public: | |
659 | // The oper parameter to ctor selects whether we work with rows or columns | |
660 | wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper) | |
661 | : m_grid(grid), | |
662 | m_oper(oper) | |
663 | { | |
664 | } | |
665 | ||
666 | // Check if the component of this point in our direction is at the | |
667 | // boundary, i.e. is the first/last row/column | |
668 | virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0; | |
669 | ||
670 | // Increment the component of this point in our direction | |
671 | virtual void Advance(wxGridCellCoords& coords) const = 0; | |
672 | ||
673 | // Find the line at the given distance, in pixels, away from this one | |
674 | // (this uses clipping, i.e. anything after the last line is counted as the | |
675 | // last one and anything before the first one as 0) | |
676 | virtual int MoveByPixelDistance(int line, int distance) const = 0; | |
677 | ||
678 | // This class is never used polymorphically but give it a virtual dtor | |
679 | // anyhow to suppress g++ complaints about it | |
680 | virtual ~wxGridDirectionOperations() { } | |
681 | ||
682 | protected: | |
683 | wxGrid * const m_grid; | |
684 | const wxGridOperations& m_oper; | |
685 | }; | |
686 | ||
687 | class wxGridBackwardOperations : public wxGridDirectionOperations | |
688 | { | |
689 | public: | |
690 | wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper) | |
691 | : wxGridDirectionOperations(grid, oper) | |
692 | { | |
693 | } | |
694 | ||
695 | virtual bool IsAtBoundary(const wxGridCellCoords& coords) const | |
696 | { | |
697 | wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" ); | |
698 | ||
699 | return m_oper.Select(coords) == 0; | |
700 | } | |
701 | ||
702 | virtual void Advance(wxGridCellCoords& coords) const | |
703 | { | |
704 | wxASSERT( !IsAtBoundary(coords) ); | |
705 | ||
706 | m_oper.Set(coords, m_oper.Select(coords) - 1); | |
707 | } | |
708 | ||
709 | virtual int MoveByPixelDistance(int line, int distance) const | |
710 | { | |
711 | int pos = m_oper.GetLineStartPos(m_grid, line); | |
712 | return m_oper.PosToLine(m_grid, pos - distance + 1, true); | |
713 | } | |
714 | }; | |
715 | ||
716 | class wxGridForwardOperations : public wxGridDirectionOperations | |
717 | { | |
718 | public: | |
719 | wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper) | |
720 | : wxGridDirectionOperations(grid, oper), | |
721 | m_numLines(oper.GetNumberOfLines(grid)) | |
722 | { | |
723 | } | |
724 | ||
725 | virtual bool IsAtBoundary(const wxGridCellCoords& coords) const | |
726 | { | |
727 | wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" ); | |
728 | ||
729 | return m_oper.Select(coords) == m_numLines - 1; | |
730 | } | |
731 | ||
732 | virtual void Advance(wxGridCellCoords& coords) const | |
733 | { | |
734 | wxASSERT( !IsAtBoundary(coords) ); | |
735 | ||
736 | m_oper.Set(coords, m_oper.Select(coords) + 1); | |
737 | } | |
738 | ||
739 | virtual int MoveByPixelDistance(int line, int distance) const | |
740 | { | |
741 | int pos = m_oper.GetLineStartPos(m_grid, line); | |
742 | return m_oper.PosToLine(m_grid, pos + distance, true); | |
743 | } | |
744 | ||
745 | private: | |
746 | const int m_numLines; | |
747 | }; | |
748 | ||
749 | // ---------------------------------------------------------------------------- | |
750 | // private helpers | |
751 | // ---------------------------------------------------------------------------- | |
752 | ||
753 | namespace | |
754 | { | |
755 | ||
756 | // ensure that first is less or equal to second, swapping the values if | |
757 | // necessary | |
758 | void EnsureFirstLessThanSecond(int& first, int& second) | |
759 | { | |
760 | if ( first > second ) | |
761 | wxSwap(first, second); | |
762 | } | |
763 | ||
764 | } // anonymous namespace | |
765 | ||
766 | // ---------------------------------------------------------------------------- | |
767 | // data structures used for the data type registry | |
768 | // ---------------------------------------------------------------------------- | |
769 | ||
770 | struct wxGridDataTypeInfo | |
771 | { | |
772 | wxGridDataTypeInfo(const wxString& typeName, | |
773 | wxGridCellRenderer* renderer, | |
774 | wxGridCellEditor* editor) | |
775 | : m_typeName(typeName), m_renderer(renderer), m_editor(editor) | |
776 | {} | |
777 | ||
778 | ~wxGridDataTypeInfo() | |
779 | { | |
780 | wxSafeDecRef(m_renderer); | |
781 | wxSafeDecRef(m_editor); | |
782 | } | |
783 | ||
784 | wxString m_typeName; | |
785 | wxGridCellRenderer* m_renderer; | |
786 | wxGridCellEditor* m_editor; | |
787 | ||
788 | DECLARE_NO_COPY_CLASS(wxGridDataTypeInfo) | |
789 | }; | |
790 | ||
791 | ||
792 | WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray, | |
793 | class WXDLLIMPEXP_ADV); | |
794 | ||
795 | ||
796 | class WXDLLIMPEXP_ADV wxGridTypeRegistry | |
797 | { | |
798 | public: | |
799 | wxGridTypeRegistry() {} | |
800 | ~wxGridTypeRegistry(); | |
801 | ||
802 | void RegisterDataType(const wxString& typeName, | |
803 | wxGridCellRenderer* renderer, | |
804 | wxGridCellEditor* editor); | |
805 | ||
806 | // find one of already registered data types | |
807 | int FindRegisteredDataType(const wxString& typeName); | |
808 | ||
809 | // try to FindRegisteredDataType(), if this fails and typeName is one of | |
810 | // standard typenames, register it and return its index | |
811 | int FindDataType(const wxString& typeName); | |
812 | ||
813 | // try to FindDataType(), if it fails see if it is not one of already | |
814 | // registered data types with some params in which case clone the | |
815 | // registered data type and set params for it | |
816 | int FindOrCloneDataType(const wxString& typeName); | |
817 | ||
818 | wxGridCellRenderer* GetRenderer(int index); | |
819 | wxGridCellEditor* GetEditor(int index); | |
820 | ||
821 | private: | |
822 | wxGridDataTypeInfoArray m_typeinfo; | |
823 | }; | |
824 | ||
825 | #endif // wxUSE_GRID | |
826 | #endif // _WX_GENERIC_GRID_PRIVATE_H_ |