]>
Commit | Line | Data |
---|---|---|
a3ef8eb5 VZ |
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 | ||
add6e919 VZ |
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 | ||
a3ef8eb5 VZ |
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; | |
82edfbe7 | 114 | if ( m_grid->CanDragColSize(m_col) ) |
a3ef8eb5 VZ |
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 | ||
4a07d706 VZ |
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 | ||
a3ef8eb5 VZ |
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 | |
4a07d706 VZ |
211 | GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx, |
212 | GetDummyMouseEvent()); | |
a3ef8eb5 VZ |
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 | { | |
4a07d706 VZ |
226 | GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_CLICK, |
227 | -1, event.GetColumn(), | |
228 | GetDummyMouseEvent()); | |
229 | ||
a3ef8eb5 VZ |
230 | GetOwner()->DoColHeaderClick(event.GetColumn()); |
231 | } | |
232 | ||
4a07d706 VZ |
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 | ||
a3ef8eb5 VZ |
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 | { | |
27bb2c8c VZ |
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); | |
a3ef8eb5 VZ |
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 | ||
6c5cc8a0 VZ |
308 | virtual wxWindow *GetMainWindowOfCompositeControl() { return m_owner; } |
309 | ||
a3ef8eb5 VZ |
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 | ||
a3ef8eb5 VZ |
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 | |
f71adb50 | 553 | virtual int GetLineAt(const wxGrid *grid, int pos) const = 0; |
a3ef8eb5 | 554 | |
8770af49 VZ |
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 | ||
e75ceab0 | 560 | // Return the index of the line just before the given one or wxNOT_FOUND. |
f71adb50 | 561 | virtual int GetLineBefore(const wxGrid* grid, int line) const = 0; |
a3ef8eb5 VZ |
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); } | |
a3ef8eb5 | 624 | virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const |
82edfbe7 | 625 | { grid->SetDefaultRowSize(size, resizeExisting); } |
a3ef8eb5 | 626 | |
2c6d6dfe VZ |
627 | virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int pos) const |
628 | { return pos; } // TODO: implement row reordering | |
8770af49 VZ |
629 | virtual int GetLinePos(const wxGrid * WXUNUSED(grid), int line) const |
630 | { return line; } // TODO: implement row reordering | |
a3ef8eb5 | 631 | |
f71adb50 | 632 | virtual int GetLineBefore(const wxGrid* WXUNUSED(grid), int line) const |
e75ceab0 | 633 | { return line - 1; } |
f71adb50 | 634 | |
a3ef8eb5 VZ |
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); } | |
a3ef8eb5 | 690 | virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const |
82edfbe7 | 691 | { grid->SetDefaultColSize(size, resizeExisting); } |
a3ef8eb5 | 692 | |
2c6d6dfe VZ |
693 | virtual int GetLineAt(const wxGrid *grid, int pos) const |
694 | { return grid->GetColAt(pos); } | |
8770af49 VZ |
695 | virtual int GetLinePos(const wxGrid *grid, int line) const |
696 | { return grid->GetColPos(line); } | |
a3ef8eb5 | 697 | |
f71adb50 | 698 | virtual int GetLineBefore(const wxGrid* grid, int line) const |
7c99eaa1 VZ |
699 | { |
700 | int posBefore = grid->GetColPos(line) - 1; | |
701 | return posBefore >= 0 ? grid->GetColAt(posBefore) : wxNOT_FOUND; | |
702 | } | |
f71adb50 | 703 | |
a3ef8eb5 VZ |
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 | |
8770af49 VZ |
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. | |
a3ef8eb5 VZ |
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) | |
8770af49 VZ |
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. | |
a3ef8eb5 VZ |
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: | |
8770af49 VZ |
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 | ||
b64bb3ca VZ |
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 | ||
8770af49 | 778 | |
a3ef8eb5 VZ |
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 | ||
b64bb3ca VZ |
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; | |
a3ef8eb5 VZ |
810 | } |
811 | ||
812 | virtual void Advance(wxGridCellCoords& coords) const | |
813 | { | |
b64bb3ca VZ |
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 | } | |
a3ef8eb5 VZ |
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 | ||
b64bb3ca VZ |
836 | // Please refer to the comments above when reading this class code, it's |
837 | // absolutely symmetrical to wxGridBackwardOperations. | |
a3ef8eb5 VZ |
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 | ||
b64bb3ca VZ |
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; | |
a3ef8eb5 VZ |
860 | } |
861 | ||
862 | virtual void Advance(wxGridCellCoords& coords) const | |
863 | { | |
b64bb3ca VZ |
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 | } | |
a3ef8eb5 VZ |
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 | ||
a3ef8eb5 VZ |
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_ |