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