grid.h 31 KB

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