Add support for freezing columns and/or rows of wxGrid
Add wxGrid::FreezeTo() method which allows to freeze the given number of columns and/or rows at the beginning of the grid, i.e. keep them pinned in place while the rest of the grid is scrolled. The main wxGridWindow (m_gridWin) now corresponds to the non-frozen part of the grid, with up to 3 new similar windows for the frozen rows/columns and the frozen corner cells (which only exist if both rows and columns are frozen) being additionally used. Doing this involved adding "wxGridWindow*" parameter to many functions that previously only worked with m_gridWin itself and addressing additional complications, such as mouse events that can now cross different windows. See https://github.com/wxWidgets/wxWidgets/pull/952 for the original version of the changes.
This commit is contained in:
committed by
Vadim Zeitlin
parent
f61b58bba3
commit
04f7f1fd32
@@ -1021,14 +1021,19 @@ public:
|
||||
int GetNumberRows() const { return m_numRows; }
|
||||
int GetNumberCols() const { return m_numCols; }
|
||||
|
||||
int GetNumberFrozenRows() const { return m_numFrozenRows; }
|
||||
int GetNumberFrozenCols() const { return m_numFrozenCols; }
|
||||
|
||||
// ------ display update functions
|
||||
//
|
||||
wxArrayInt CalcRowLabelsExposed( const wxRegion& reg ) const;
|
||||
|
||||
wxArrayInt CalcColLabelsExposed( const wxRegion& reg ) const;
|
||||
wxGridCellCoordsArray CalcCellsExposed( const wxRegion& reg ) const;
|
||||
wxArrayInt CalcRowLabelsExposed( const wxRegion& reg,
|
||||
wxGridWindow *gridWindow = NULL) const;
|
||||
wxArrayInt CalcColLabelsExposed( const wxRegion& reg,
|
||||
wxGridWindow *gridWindow = NULL) const;
|
||||
wxGridCellCoordsArray CalcCellsExposed( const wxRegion& reg,
|
||||
wxGridWindow *gridWindow = NULL) const;
|
||||
|
||||
void PrepareDCFor(wxDC &dc, wxGridWindow *gridWindow);
|
||||
|
||||
void ClearGrid();
|
||||
bool InsertRows(int pos = 0, int numRows = 1, bool updateLabels = true)
|
||||
@@ -1062,12 +1067,24 @@ public:
|
||||
pos, numCols, updateLabels);
|
||||
}
|
||||
|
||||
bool FreezeTo(int row, int col);
|
||||
bool FreezeTo(const wxGridCellCoords& coords)
|
||||
{
|
||||
return FreezeTo(coords.GetRow(), coords.GetCol());
|
||||
}
|
||||
|
||||
bool IsFrozen() const;
|
||||
|
||||
void DrawGridCellArea( wxDC& dc , const wxGridCellCoordsArray& cells );
|
||||
void DrawGridSpace( wxDC& dc );
|
||||
void DrawGridSpace( wxDC& dc, wxGridWindow *gridWindow );
|
||||
void DrawCellBorder( wxDC& dc, const wxGridCellCoords& );
|
||||
void DrawAllGridLines( wxDC& dc, const wxRegion & reg );
|
||||
void DrawAllGridLines();
|
||||
void DrawAllGridWindowLines( wxDC& dc, const wxRegion & reg , wxGridWindow *gridWindow);
|
||||
void DrawCell( wxDC& dc, const wxGridCellCoords& );
|
||||
void DrawHighlight(wxDC& dc, const wxGridCellCoordsArray& cells);
|
||||
void DrawFrozenBorder( wxDC& dc, wxGridWindow *gridWindow );
|
||||
void DrawLabelFrozenBorder( wxDC& dc, wxWindow *window, bool isRow );
|
||||
|
||||
void ScrollWindow( int dx, int dy, const wxRect *rect ) wxOVERRIDE;
|
||||
|
||||
void UpdateGridWindows() const;
|
||||
@@ -1165,11 +1182,15 @@ public:
|
||||
// grid cells and labels so you will need to convert from device
|
||||
// coordinates for mouse events etc.
|
||||
//
|
||||
wxGridCellCoords XYToCell(int x, int y) const;
|
||||
void XYToCell(int x, int y, wxGridCellCoords& coords) const
|
||||
{ coords = XYToCell(x, y); }
|
||||
wxGridCellCoords XYToCell(const wxPoint& pos) const
|
||||
{ return XYToCell(pos.x, pos.y); }
|
||||
wxGridCellCoords XYToCell(int x, int y, wxGridWindow *gridWindow = NULL) const;
|
||||
void XYToCell(int x, int y,
|
||||
wxGridCellCoords& coords,
|
||||
wxGridWindow *gridWindow = NULL) const
|
||||
{ coords = XYToCell(x, y, gridWindow); }
|
||||
|
||||
wxGridCellCoords XYToCell(const wxPoint& pos,
|
||||
wxGridWindow *gridWindow = NULL) const
|
||||
{ return XYToCell(pos.x, pos.y, gridWindow); }
|
||||
|
||||
// these functions return the index of the row/columns corresponding to the
|
||||
// given logical position in pixels
|
||||
@@ -1177,8 +1198,8 @@ public:
|
||||
// if clipToMinMax is false (default, wxNOT_FOUND is returned if the
|
||||
// position is outside any row/column, otherwise the first/last element is
|
||||
// returned in this case
|
||||
int YToRow( int y, bool clipToMinMax = false ) const;
|
||||
int XToCol( int x, bool clipToMinMax = false ) const;
|
||||
int YToRow( int y, bool clipToMinMax = false, wxGridWindow *gridWindow = NULL ) const;
|
||||
int XToCol( int x, bool clipToMinMax = false, wxGridWindow *gridWindow = NULL ) const;
|
||||
|
||||
int YToEdgeOfRow( int y ) const;
|
||||
int XToEdgeOfCol( int x ) const;
|
||||
@@ -1187,12 +1208,32 @@ public:
|
||||
wxRect CellToRect( const wxGridCellCoords& coords ) const
|
||||
{ return CellToRect( coords.GetRow(), coords.GetCol() ); }
|
||||
|
||||
wxGridWindow* CellToGridWindow( int row, int col ) const;
|
||||
wxGridWindow* CellToGridWindow( const wxGridCellCoords& coords ) const
|
||||
{ return CellToGridWindow( coords.GetRow(), coords.GetCol() ); }
|
||||
|
||||
const wxGridCellCoords& GetGridCursorCoords() const
|
||||
{ return m_currentCellCoords; }
|
||||
|
||||
int GetGridCursorRow() const { return m_currentCellCoords.GetRow(); }
|
||||
int GetGridCursorCol() const { return m_currentCellCoords.GetCol(); }
|
||||
|
||||
void GetGridWindowOffset(const wxGridWindow *gridWindow, int &x, int &y) const;
|
||||
wxPoint GetGridWindowOffset(const wxGridWindow *gridWindow) const;
|
||||
|
||||
wxGridWindow* DevicePosToGridWindow(wxPoint pos) const;
|
||||
wxGridWindow* DevicePosToGridWindow(int x, int y) const;
|
||||
|
||||
void CalcGridWindowUnscrolledPosition(int x, int y, int *xx, int *yy,
|
||||
const wxGridWindow *gridWindow) const;
|
||||
wxPoint CalcGridWindowUnscrolledPosition(const wxPoint& pt,
|
||||
const wxGridWindow *gridWindow) const;
|
||||
|
||||
void CalcGridWindowScrolledPosition(int x, int y, int *xx, int *yy,
|
||||
const wxGridWindow *gridWindow) const;
|
||||
wxPoint CalcGridWindowScrolledPosition(const wxPoint& pt,
|
||||
const wxGridWindow *gridWindow) const;
|
||||
|
||||
// check to see if a cell is either wholly visible (the default arg) or
|
||||
// at least partially visible in the grid window
|
||||
//
|
||||
@@ -1256,9 +1297,11 @@ public:
|
||||
wxColour GetCellHighlightColour() const { return m_cellHighlightColour; }
|
||||
int GetCellHighlightPenWidth() const { return m_cellHighlightPenWidth; }
|
||||
int GetCellHighlightROPenWidth() const { return m_cellHighlightROPenWidth; }
|
||||
wxColor GetGridFrozenBorderColour() const { return m_gridFrozenBorderColour; }
|
||||
int GetGridFrozenBorderPenWidth() const { return m_gridFrozenBorderPenWidth; }
|
||||
|
||||
// this one will use wxHeaderCtrl for the column labels
|
||||
void UseNativeColHeader(bool native = true);
|
||||
bool UseNativeColHeader(bool native = true);
|
||||
|
||||
// this one will still draw them manually but using the native renderer
|
||||
// instead of using the same appearance as for the row labels
|
||||
@@ -1280,9 +1323,10 @@ public:
|
||||
void SetColLabelValue( int col, const wxString& );
|
||||
void SetCornerLabelValue( const wxString& );
|
||||
void SetCellHighlightColour( const wxColour& );
|
||||
void SetCellHighlightPenWidth(int width);
|
||||
void SetCellHighlightROPenWidth(int width);
|
||||
|
||||
void SetCellHighlightPenWidth( int width );
|
||||
void SetCellHighlightROPenWidth( int width );
|
||||
void SetGridFrozenBorderColour( const wxColour& );
|
||||
void SetGridFrozenBorderPenWidth( int width );
|
||||
|
||||
// interactive grid mouse operations control
|
||||
// -----------------------------------------
|
||||
@@ -1309,7 +1353,7 @@ public:
|
||||
{ return m_canDragColSize && DoCanResizeLine(col, m_setFixedCols); }
|
||||
|
||||
// interactive column reordering (disabled by default)
|
||||
void EnableDragColMove( bool enable = true );
|
||||
bool EnableDragColMove( bool enable = true );
|
||||
void DisableDragColMove() { EnableDragColMove( false ); }
|
||||
bool CanDragColMove() const { return m_canDragColMove; }
|
||||
|
||||
@@ -1635,7 +1679,8 @@ public:
|
||||
// to the client size of the grid window.
|
||||
//
|
||||
wxRect BlockToDeviceRect( const wxGridCellCoords & topLeft,
|
||||
const wxGridCellCoords & bottomRight ) const;
|
||||
const wxGridCellCoords & bottomRight,
|
||||
const wxGridWindow *gridWindow = NULL) const;
|
||||
|
||||
// Access or update the selection fore/back colours
|
||||
wxColour GetSelectionBackground() const
|
||||
@@ -1671,6 +1716,9 @@ public:
|
||||
|
||||
// Accessors for component windows
|
||||
wxWindow* GetGridWindow() const { return (wxWindow*)m_gridWin; }
|
||||
wxWindow* GetFrozenCornerGridWindow()const { return (wxWindow*)m_frozenCornerGridWin; }
|
||||
wxWindow* GetFrozenRowGridWindow() const { return (wxWindow*)m_frozenRowGridWin; }
|
||||
wxWindow* GetFrozenColGridWindow() const { return (wxWindow*)m_frozenColGridWin; }
|
||||
wxWindow* GetGridRowLabelWindow() const { return (wxWindow*)m_rowLabelWin; }
|
||||
wxWindow* GetGridColLabelWindow() const { return m_colLabelWin; }
|
||||
wxWindow* GetGridCornerLabelWindow() const { return (wxWindow*)m_cornerLabelWin; }
|
||||
@@ -1904,13 +1952,18 @@ protected:
|
||||
bool m_created;
|
||||
|
||||
wxGridWindow *m_gridWin;
|
||||
wxGridWindow *m_frozenColGridWin;
|
||||
wxGridWindow *m_frozenRowGridWin;
|
||||
wxGridWindow *m_frozenCornerGridWin;
|
||||
wxGridCornerLabelWindow *m_cornerLabelWin;
|
||||
wxGridRowLabelWindow *m_rowLabelWin;
|
||||
wxGridRowLabelWindow *m_rowFrozenLabelWin;
|
||||
|
||||
// the real type of the column window depends on m_useNativeHeader value:
|
||||
// if it is true, its dynamic type is wxHeaderCtrl, otherwise it is
|
||||
// wxGridColLabelWindow, use accessors below when the real type matters
|
||||
wxWindow *m_colLabelWin;
|
||||
wxWindow *m_colFrozenLabelWin;
|
||||
|
||||
wxGridColLabelWindow *GetColLabelWindow() const
|
||||
{
|
||||
@@ -1925,6 +1978,10 @@ protected:
|
||||
int m_numRows;
|
||||
int m_numCols;
|
||||
|
||||
// Number of frozen rows/columns in the beginning of the grid, 0 if none.
|
||||
int m_numFrozenRows;
|
||||
int m_numFrozenCols;
|
||||
|
||||
wxGridCellCoords m_currentCellCoords;
|
||||
|
||||
// the corners of the block being currently selected or wxGridNoCellCoords
|
||||
@@ -2014,7 +2071,8 @@ protected:
|
||||
wxColour m_cellHighlightColour;
|
||||
int m_cellHighlightPenWidth;
|
||||
int m_cellHighlightROPenWidth;
|
||||
|
||||
wxColour m_gridFrozenBorderColour;
|
||||
int m_gridFrozenBorderPenWidth;
|
||||
|
||||
// common part of AutoSizeColumn/Row() and GetBestSize()
|
||||
int SetOrCalcColumnSizes(bool calcOnly, bool setAsMin = true);
|
||||
@@ -2200,6 +2258,9 @@ protected:
|
||||
{ UpdateBlockBeingSelected(topLeft.GetRow(), topLeft.GetCol(),
|
||||
bottomRight.GetRow(), bottomRight.GetCol()); }
|
||||
|
||||
virtual bool ShouldScrollToChildOnFocus(wxWindow* WXUNUSED(win)) wxOVERRIDE
|
||||
{ return false; }
|
||||
|
||||
friend class WXDLLIMPEXP_FWD_CORE wxGridSelection;
|
||||
friend class wxGridRowOperations;
|
||||
friend class wxGridColumnOperations;
|
||||
@@ -2218,6 +2279,10 @@ private:
|
||||
// implement wxScrolledWindow method to return m_gridWin size
|
||||
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size) wxOVERRIDE;
|
||||
|
||||
// depending on the values of m_numFrozenRows and m_numFrozenCols, it will
|
||||
// create and initialize or delete the frozen windows
|
||||
void InitializeFrozenWindows();
|
||||
|
||||
// redraw the grid lines, should be called after changing their attributes
|
||||
void RedrawGridLines();
|
||||
|
||||
@@ -2265,8 +2330,7 @@ private:
|
||||
//
|
||||
// this always returns a valid position, even if the coordinate is out of
|
||||
// bounds (in which case first/last column is returned)
|
||||
int XToPos(int x) const;
|
||||
|
||||
int XToPos(int x, wxGridWindow *gridWindow) const;
|
||||
|
||||
// event handlers and their helpers
|
||||
// --------------------------------
|
||||
@@ -2277,14 +2341,27 @@ private:
|
||||
bool isFirstDrag);
|
||||
|
||||
// process row/column resizing drag event
|
||||
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
|
||||
void DoGridLineDrag(int pos,
|
||||
const wxGridOperations& oper,
|
||||
wxGridWindow* gridWindow);
|
||||
|
||||
// process mouse drag event in the grid window, return false if starting
|
||||
// dragging was vetoed by the user-defined wxEVT_GRID_CELL_BEGIN_DRAG
|
||||
// handler
|
||||
bool DoGridDragEvent(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
bool isFirstDrag);
|
||||
bool isFirstDrag,
|
||||
wxGridWindow* gridWindow);
|
||||
|
||||
void DrawGridDragLine(wxPoint position,
|
||||
const wxGridOperations& oper,
|
||||
wxGridWindow* gridWindow);
|
||||
|
||||
// return the current grid windows involved in the drag process
|
||||
void GetDragGridWindows(int pos,
|
||||
const wxGridOperations& oper,
|
||||
wxGridWindow*& firstGridWindow,
|
||||
wxGridWindow*& secondGridWindow);
|
||||
|
||||
// process different clicks on grid cells
|
||||
void DoGridCellLeftDown(wxMouseEvent& event,
|
||||
@@ -2293,30 +2370,38 @@ private:
|
||||
void DoGridCellLeftDClick(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos);
|
||||
void DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords);
|
||||
void DoGridCellLeftUp(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
wxGridWindow* gridWindow);
|
||||
|
||||
// process movement (but not dragging) event in the grid cell area
|
||||
void DoGridMouseMoveEvent(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos);
|
||||
const wxPoint& pos,
|
||||
wxGridWindow* gridWindow);
|
||||
|
||||
// process mouse events in the grid window
|
||||
void ProcessGridCellMouseEvent(wxMouseEvent& event);
|
||||
void ProcessGridCellMouseEvent(wxMouseEvent& event, wxGridWindow* gridWindow);
|
||||
|
||||
// process mouse events in the row/column labels/corner windows
|
||||
void ProcessRowLabelMouseEvent(wxMouseEvent& event);
|
||||
void ProcessColLabelMouseEvent(wxMouseEvent& event);
|
||||
void ProcessRowLabelMouseEvent(wxMouseEvent& event,
|
||||
wxGridRowLabelWindow* rowLabelWin);
|
||||
void ProcessColLabelMouseEvent(wxMouseEvent& event,
|
||||
wxGridColLabelWindow* colLabelWin);
|
||||
void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
|
||||
|
||||
void DoColHeaderClick(int col);
|
||||
|
||||
void DoStartResizeCol(int col);
|
||||
void DoUpdateResizeCol(int x);
|
||||
void DoUpdateResizeColWidth(int w);
|
||||
void DoStartMoveCol(int col);
|
||||
|
||||
void DoEndDragResizeRow(const wxMouseEvent& event);
|
||||
void DoEndDragResizeCol(const wxMouseEvent& event);
|
||||
void DoEndDragResizeRow(const wxMouseEvent& event, wxGridWindow *gridWindow);
|
||||
void DoEndDragResizeCol(const wxMouseEvent& event, wxGridWindow *gridWindow);
|
||||
void DoEndDragResizeCol(const wxMouseEvent& event)
|
||||
{
|
||||
DoEndDragResizeCol(event, m_gridWin);
|
||||
}
|
||||
void DoEndMoveCol(int pos);
|
||||
|
||||
// process a TAB keypress
|
||||
@@ -2324,11 +2409,13 @@ private:
|
||||
|
||||
// common implementations of methods defined for both rows and columns
|
||||
void DeselectLine(int line, const wxGridOperations& oper);
|
||||
bool DoEndDragResizeLine(const wxGridOperations& oper);
|
||||
bool DoEndDragResizeLine(const wxGridOperations& oper, wxGridWindow *gridWindow);
|
||||
int PosToLinePos(int pos, bool clipToMinMax,
|
||||
const wxGridOperations& oper) const;
|
||||
const wxGridOperations& oper,
|
||||
wxGridWindow *gridWindow) const;
|
||||
int PosToLine(int pos, bool clipToMinMax,
|
||||
const wxGridOperations& oper) const;
|
||||
const wxGridOperations& oper,
|
||||
wxGridWindow *gridWindow) const;
|
||||
int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const;
|
||||
|
||||
bool DoMoveCursor(bool expandSelection,
|
||||
|
Reference in New Issue
Block a user