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:
lucian-rotariu 2019-07-03 23:07:30 +03:00 committed by Vadim Zeitlin
parent f61b58bba3
commit 04f7f1fd32
6 changed files with 1477 additions and 409 deletions

View File

@ -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,

View File

@ -158,9 +158,9 @@ protected:
return m_columns[idx];
}
private:
wxGrid *GetOwner() const { return static_cast<wxGrid *>(GetParent()); }
private:
static wxMouseEvent GetDummyMouseEvent()
{
// make up a dummy event for the grid event to use -- unfortunately we
@ -327,6 +327,7 @@ public:
{
}
virtual bool IsFrozen() const { return false; }
private:
void OnPaint( wxPaintEvent& event );
@ -338,6 +339,18 @@ private:
};
class wxGridRowFrozenLabelWindow : public wxGridRowLabelWindow
{
public:
wxGridRowFrozenLabelWindow(wxGrid *parent)
: wxGridRowLabelWindow(parent)
{
}
virtual bool IsFrozen() const { return true; }
};
class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow
{
public:
@ -346,6 +359,7 @@ public:
{
}
virtual bool IsFrozen() const { return false; }
private:
void OnPaint( wxPaintEvent& event );
@ -357,6 +371,18 @@ private:
};
class wxGridColFrozenLabelWindow : public wxGridColLabelWindow
{
public:
wxGridColFrozenLabelWindow(wxGrid *parent)
: wxGridColLabelWindow(parent)
{
}
virtual bool IsFrozen() const { return true; }
};
class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow
{
public:
@ -377,10 +403,21 @@ private:
class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow
{
public:
wxGridWindow(wxGrid *parent)
// grid window variants for scrolling possibilities
enum wxGridWindowType
{
wxGridWindowNormal = 0,
wxGridWindowFrozenCol = 1,
wxGridWindowFrozenRow = 2,
wxGridWindowFrozenCorner = wxGridWindowFrozenCol |
wxGridWindowFrozenRow
};
wxGridWindow(wxGrid *parent, wxGridWindowType type)
: wxGridSubwindow(parent,
wxWANTS_CHARS | wxCLIP_CHILDREN,
"GridWindow")
"GridWindow"),
m_type(type)
{
}
@ -389,7 +426,11 @@ public:
virtual bool AcceptsFocus() const wxOVERRIDE { return true; }
wxGridWindowType GetType() const { return m_type; }
private:
const wxGridWindowType m_type;
void OnPaint( wxPaintEvent &event );
void OnMouseWheel( wxMouseEvent& event );
void OnMouseEvent( wxMouseEvent& event );
@ -467,8 +508,14 @@ public:
// if this object is a wxGridColumnOperations and vice versa.
virtual wxGridOperations& Dual() const = 0;
// Return the number of rows or columns.
virtual int GetNumberOfLines(const wxGrid *grid) const = 0;
// Return the total number of rows or columns.
virtual int GetTotalNumberOfLines(const wxGrid *grid) const = 0;
// Return the current number of rows or columns of a grid window.
virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const = 0;
// Return the first line for this grid type.
virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const = 0;
// Return the selection mode which allows selecting rows or columns.
virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0;
@ -515,7 +562,7 @@ public:
// Return the index of the row or column at the given pixel coordinate.
virtual int
PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0;
PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow, bool clip = false) const = 0;
// Get the top/left position, in pixels, of the given row or column
virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0;
@ -565,6 +612,8 @@ public:
// Get the width or height of the row or column label window
virtual int GetHeaderWindowSize(wxGrid *grid) const = 0;
// Get the row or column frozen grid window
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const = 0;
// This class is never used polymorphically but give it a virtual dtor
// anyhow to suppress g++ complaints about it
@ -576,9 +625,13 @@ class wxGridRowOperations : public wxGridOperations
public:
virtual wxGridOperations& Dual() const wxOVERRIDE;
virtual int GetNumberOfLines(const wxGrid *grid) const wxOVERRIDE
virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
{ return grid->GetNumberRows(); }
virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
virtual wxGrid::wxGridSelectionModes GetSelectionMode() const wxOVERRIDE
{ return wxGrid::wxGridSelectRows; }
@ -602,8 +655,8 @@ public:
virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const wxOVERRIDE
{ dc.DrawLine(start, pos, end, pos); }
virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const wxOVERRIDE
{ return grid->YToRow(pos, clip); }
virtual int PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow , bool clip = false) const wxOVERRIDE
{ return grid->YToRow(pos, clip, gridWindow); }
virtual int GetLineStartPos(const wxGrid *grid, int line) const wxOVERRIDE
{ return grid->GetRowTop(line); }
virtual int GetLineEndPos(const wxGrid *grid, int line) const wxOVERRIDE
@ -635,6 +688,9 @@ public:
{ return grid->GetGridRowLabelWindow(); }
virtual int GetHeaderWindowSize(wxGrid *grid) const wxOVERRIDE
{ return grid->GetRowLabelSize(); }
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
{ return (wxGridWindow*)grid->GetFrozenRowGridWindow(); }
};
class wxGridColumnOperations : public wxGridOperations
@ -642,9 +698,13 @@ class wxGridColumnOperations : public wxGridOperations
public:
virtual wxGridOperations& Dual() const wxOVERRIDE;
virtual int GetNumberOfLines(const wxGrid *grid) const wxOVERRIDE
virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
{ return grid->GetNumberCols(); }
virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
virtual wxGrid::wxGridSelectionModes GetSelectionMode() const wxOVERRIDE
{ return wxGrid::wxGridSelectColumns; }
@ -668,8 +728,8 @@ public:
virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const wxOVERRIDE
{ dc.DrawLine(pos, start, pos, end); }
virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const wxOVERRIDE
{ return grid->XToCol(pos, clip); }
virtual int PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow, bool clip = false) const wxOVERRIDE
{ return grid->XToCol(pos, clip, gridWindow); }
virtual int GetLineStartPos(const wxGrid *grid, int line) const wxOVERRIDE
{ return grid->GetColLeft(line); }
virtual int GetLineEndPos(const wxGrid *grid, int line) const wxOVERRIDE
@ -704,6 +764,9 @@ public:
{ return grid->GetGridColLabelWindow(); }
virtual int GetHeaderWindowSize(wxGrid *grid) const wxOVERRIDE
{ return grid->GetColLabelSize(); }
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
{ return (wxGridWindow*)grid->GetFrozenColGridWindow(); }
};
// This class abstracts the difference between operations going forward
@ -828,7 +891,7 @@ public:
virtual int MoveByPixelDistance(int line, int distance) const wxOVERRIDE
{
int pos = m_oper.GetLineStartPos(m_grid, line);
return m_oper.PosToLine(m_grid, pos - distance + 1, true);
return m_oper.PosToLine(m_grid, pos - distance + 1, NULL, true);
}
};
@ -839,7 +902,7 @@ class wxGridForwardOperations : public wxGridDirectionOperations
public:
wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper)
: wxGridDirectionOperations(grid, oper),
m_numLines(oper.GetNumberOfLines(grid))
m_numLines(oper.GetTotalNumberOfLines(grid))
{
}
@ -878,7 +941,7 @@ public:
virtual int MoveByPixelDistance(int line, int distance) const wxOVERRIDE
{
int pos = m_oper.GetLineStartPos(m_grid, line);
return m_oper.PosToLine(m_grid, pos + distance, true);
return m_oper.PosToLine(m_grid, pos + distance, NULL, true);
}
private:

View File

@ -2687,8 +2687,13 @@ public:
Also note that currently @c wxEVT_GRID_LABEL_RIGHT_DCLICK event is not
generated for the column labels if the native columns header is used
(but this limitation could possibly be lifted in the future).
Finally, please note that using the native control is currently
incompatible with freezing columns in the grid (see FreezeTo()) and
this function will return @false, without doing anything, if it's
called on a grid in which any columns are frozen.
*/
void UseNativeColHeader(bool native = true);
bool UseNativeColHeader(bool native = true);
//@}
@ -3767,8 +3772,14 @@ public:
/**
Enables or disables column moving by dragging with the mouse.
Note that reordering columns by dragging them is currently not
supported when the grid has any frozen columns (see FreezeTo()) and if
this method is called with @a enable equal to @true in this situation,
it returns @false without doing anything. Otherwise it returns @true to
indicate that it was successful.
*/
void EnableDragColMove(bool enable = true);
bool EnableDragColMove(bool enable = true);
/**
Enables or disables column sizing by dragging with the mouse.
@ -4280,10 +4291,13 @@ public:
limited by @a topLeft and @a bottomRight cell in device coords and
clipped to the client size of the grid window.
@since 3.1.3 Parameter @a gridWindow has been added.
@see CellToRect()
*/
wxRect BlockToDeviceRect(const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight) const;
const wxGridCellCoords& bottomRight,
const wxGridWindow *gridWindow = NULL) const;
/**
Return the rectangle corresponding to the grid cell's size and position
@ -4301,7 +4315,78 @@ public:
wxRect CellToRect(const wxGridCellCoords& coords) const;
/**
Returns the column at the given pixel position.
Returns the grid window that contains the cell.
In a grid without frozen rows or columns (see FreezeTo()), this will
always return the same window as GetGridWindow(), however if some parts
of the grid are frozen, this function returns the window containing the
given cell.
@since 3.1.3
*/
wxGridWindow* CellToGridWindow( int row, int col ) const;
/// @overload
wxGridWindow* CellToGridWindow( const wxGridCellCoords& coords ) const
/**
Returns the grid window that includes the input coordinates.
@since 3.1.3
*/
wxGridWindow* DevicePosToGridWindow(wxPoint pos) const;
/// @overload
wxGridWindow* DevicePosToGridWindow(int x, int y) const;
/**
Returns the grid window's offset from the grid starting position taking
into account the frozen cells.
If there are no frozen cells, returns (0, 0).
@since 3.1.3
@see FreezeTo()
*/
void GetGridWindowOffset(const wxGridWindow *gridWindow, int &x, int &y) const;
/// @overload
wxPoint GetGridWindowOffset(const wxGridWindow *gridWindow) const;
/**
Translates the device coordinates to the logical ones, taking into
account the grid window type.
@since 3.1.3
@see wxScrolled::CalcUnscrolledPosition()
*/
void CalcGridWindowUnscrolledPosition(int x, int y,
int *xx, int *yy,
const wxGridWindow *gridWindow) const;
/// @overload
wxPoint CalcGridWindowUnscrolledPosition(const wxPoint& pt,
const wxGridWindow *gridWindow) const;
/**
Translates the logical coordinates to the device ones, taking into
account the grid window type.
@since 3.1.3
@see wxScrolled::CalcScrolledPosition()
*/
void CalcGridWindowScrolledPosition(int x, int y,
int *xx, int *yy,
const wxGridWindow *gridWindow) const;
/// @overload
wxPoint CalcGridWindowScrolledPosition(const wxPoint& pt,
const wxGridWindow *gridWindow) const;
/**
Returns the column at the given pixel position depending on the window.
@param x
The x position to evaluate.
@ -4309,10 +4394,15 @@ public:
If @true, rather than returning @c wxNOT_FOUND, it returns either
the first or last column depending on whether @a x is too far to
the left or right respectively.
@param gridWindow
The associated grid window that limits the search (note that this
parameter is only available since wxWidgets 3.1.3).
If @a gridWindow is @NULL, it will consider all the cells, no matter
which grid they belong to.
@return
The column index or @c wxNOT_FOUND.
*/
int XToCol(int x, bool clipToMinMax = false) const;
int XToCol(int x, bool clipToMinMax = false, wxGridWindow *gridWindow = NULL) const;
/**
Returns the column whose right hand edge is close to the given logical
@ -4330,20 +4420,22 @@ public:
the mouse position, which is expressed in device coordinates, to
logical ones.
@see XToCol(), YToRow()
*/
wxGridCellCoords XYToCell(int x, int y) const;
/**
Translates logical pixel coordinates to the grid cell coordinates.
The parameter @a gridWindow is new since wxWidgets 3.1.3. If it is
specified, i.e. non-@NULL, the coordinates must be in this window
coordinate system and only the cells of this window are considered,
i.e. the function returns @c wxNOT_FOUND if the coordinates are out of
bounds.
Notice that this function expects logical coordinates on input so if
you use this function in a mouse event handler you need to translate
the mouse position, which is expressed in device coordinates, to
logical ones.
If @a gridWindow is @NULL, coordinates are relative to the main grid
window and all cells are considered.
@see XToCol(), YToRow()
*/
wxGridCellCoords XYToCell(const wxPoint& pos) const;
wxGridCellCoords XYToCell(int x, int y, wxGridWindow *gridWindow = NULL) const;
/// @overload
wxGridCellCoords XYToCell(const wxPoint& pos, wxGridWindow *gridWindow = NULL) const;
// XYToCell(int, int, wxGridCellCoords&) overload is intentionally
// undocumented, using it is ugly and non-const reference parameters are
// not used in wxWidgets API
@ -4359,9 +4451,16 @@ public:
/**
Returns the grid row that corresponds to the logical @a y coordinate.
Returns @c wxNOT_FOUND if there is no row at the @a y position.
The parameter @a gridWindow is new since wxWidgets 3.1.3. If it is
specified, i.e. non-@NULL, only the cells of this window are
considered, i.e. the function returns @c wxNOT_FOUND if @a y is out of
bounds.
If @a gridWindow is @NULL, the function returns @c wxNOT_FOUND only if
there is no row at all at the @a y position.
*/
int YToRow(int y, bool clipToMinMax = false) const;
int YToRow(int y, bool clipToMinMax = false, wxGridWindow *gridWindow = NULL) const;
//@}
@ -4489,6 +4588,31 @@ public:
*/
bool DeleteRows(int pos = 0, int numRows = 1, bool updateLabels = true);
/**
Sets or resets the frozen columns and rows.
@param row
The number of rows to freeze, 0 means to unfreeze all rows.
@param col
The number of columns to freeze, 0 means to unfreeze all columns.
@return @true on success or @false if it failed.
Note that this method doesn't do anything, and returns @false, if any
of the following conditions are true:
- Either @a row or @a col are out of range
- Size of the frozen area would be bigger than the current viewing area
- There are any merged cells in the area to be frozen
- Grid uses a native header control (see UseNativeColHeader())
(some of these limitations could be lifted in the future).
@since 3.1.3
*/
bool FreezeTo(unsigned row, unsigned col);
/// @overload
bool FreezeTo(const wxGridCellCoords& coords);
/**
Decrements the grid's batch count.
@ -4535,6 +4659,28 @@ public:
*/
int GetNumberRows() const;
/**
Returns the number of frozen grid columns.
If there are no frozen columns, returns 0.
@since 3.1.3
@see FreezeTo()
*/
int GetNumberFrozenCols() const;
/**
Returns the number of frozen grid rows.
If there are no frozen rows, returns 0.
@since 3.1.3
@see FreezeTo()
*/
int GetNumberFrozenRows() const;
/**
Returns the attribute for the given cell creating one if necessary.
@ -4693,9 +4839,12 @@ public:
void SetRowAttr(int row, wxGridCellAttr* attr);
wxArrayInt CalcRowLabelsExposed( const wxRegion& reg );
wxArrayInt CalcColLabelsExposed( const wxRegion& reg );
wxGridCellCoordsArray CalcCellsExposed( const wxRegion& reg );
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;
//@}
@ -4776,15 +4925,19 @@ public:
Return the various child windows of wxGrid.
wxGrid is an empty parent window for 4 children representing the column
labels window (top), the row labels window (left), the corner window
(top left) and the main grid window. It may be necessary to use these
individual windows and not the wxGrid window itself if you need to
handle events for them (this can be done using wxEvtHandler::Connect()
or wxWindow::PushEventHandler()) or do something else requiring the use
of the correct window pointer. Notice that you should not, however,
change these windows (e.g. reposition them or draw over them) because
they are managed by wxGrid itself.
wxGrid is an empty parent window for at least 4 children representing
the column labels window (top), the row labels window (left), the
corner window (top left) and the main grid window. It may be necessary
to use these individual windows and not the wxGrid window itself if you
need to handle events for them (using wxEvtHandler::Bind()) or do
something else requiring the use of the correct window pointer. Notice
that you should not, however, change these windows (e.g. reposition
them or draw over them) because they are managed by wxGrid itself.
When parts of the grid are frozen using FreezeTo() function, the main
grid window contains only the unfrozen part and additional windows are
used for the parts containing frozen rows and/or columns and the corner
window if both some rows and some columns are frozen.
*/
//@{
@ -4795,6 +4948,33 @@ public:
*/
wxWindow *GetGridWindow() const;
/**
Return the corner grid window containing frozen cells.
This window is shown only when there are frozen rows and columns.
@since 3.1.3
*/
wxWindow* GetFrozenCornerGridWindow() const;
/**
Return the rows grid window containing row frozen cells.
This window is shown only when there are frozen rows.
@since 3.1.3
*/
wxWindow* GetFrozenRowGridWindow() const;
/**
Return the columns grid window containing column frozen cells.
This window is shown only when there are frozen columns.
@since 3.1.3
*/
wxWindow* GetFrozenColGridWindow() const;
/**
Return the row labels window.
@ -4864,6 +5044,8 @@ public:
void SetCellHighlightColour( const wxColour& );
void SetCellHighlightPenWidth(int width);
void SetCellHighlightROPenWidth(int width);
void SetGridFrozenBorderColour( const wxColour& );
void SetGridFrozenBorderPenWidth( int width );
protected:

View File

@ -189,6 +189,8 @@ wxBEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_SELCOLS, GridFrame::SelectCols )
EVT_MENU( ID_SELROWSORCOLS, GridFrame::SelectRowsOrCols )
EVT_MENU( ID_FREEZE_OR_THAW, GridFrame::FreezeOrThaw )
EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
@ -370,6 +372,8 @@ GridFrame::GridFrame()
editMenu->Append( ID_CLEARGRID, "Cl&ear grid cell contents" );
editMenu->Append( ID_SETCORNERLABEL, "&Set corner label..." );
editMenu->AppendCheckItem( ID_FREEZE_OR_THAW, "Freeze up to cursor\tCtrl-F" );
wxMenu *selectMenu = new wxMenu;
selectMenu->Append( ID_SELECT_UNSELECT, "Add new cells to the selection",
"When off, old selection is deselected before "
@ -573,10 +577,10 @@ GridFrame::GridFrame()
"This takes two cells",
"Another choice",
};
grid->SetCellEditor(4, 0, new wxGridCellChoiceEditor(WXSIZEOF(choices), choices));
grid->SetCellSize(4, 0, 1, 2);
grid->SetCellValue(4, 0, choices[0]);
grid->SetCellOverflow(4, 0, false);
grid->SetCellEditor(4, 2, new wxGridCellChoiceEditor(WXSIZEOF(choices), choices));
grid->SetCellSize(4, 2, 1, 2);
grid->SetCellValue(4, 2, choices[0]);
grid->SetCellOverflow(4, 2, false);
grid->SetCellSize(7, 1, 3, 4);
grid->SetCellAlignment(7, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
@ -1209,6 +1213,30 @@ void GridFrame::SelectRowsOrCols( wxCommandEvent& WXUNUSED(ev) )
grid->SetSelectionMode( wxGrid::wxGridSelectRowsOrColumns );
}
void GridFrame::FreezeOrThaw(wxCommandEvent& ev)
{
if ( ev.IsChecked() )
{
if ( !grid->FreezeTo(grid->GetGridCursorCoords()) )
{
wxLogMessage("Failed to freeze the grid.");
GetMenuBar()->Check(ID_FREEZE_OR_THAW, false);
return;
}
wxLogMessage("Grid is now frozen");
}
else
{
// This never fails.
grid->FreezeTo(0, 0);
wxLogMessage("Grid is now thawed");
}
GetMenuBar()->Enable( ID_TOGGLECOLMOVING, !grid->IsFrozen() );
}
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);

View File

@ -75,6 +75,8 @@ class GridFrame : public wxFrame
void SelectCols( wxCommandEvent& );
void SelectRowsOrCols( wxCommandEvent& );
void FreezeOrThaw( wxCommandEvent& );
void DeselectCell(wxCommandEvent& event);
void DeselectCol(wxCommandEvent& event);
void DeselectRow(wxCommandEvent& event);
@ -204,6 +206,8 @@ public:
ID_SIZE_LABELS_ROW,
ID_SIZE_GRID,
ID_FREEZE_OR_THAW,
ID_SET_HIGHLIGHT_WIDTH,
ID_SET_RO_HIGHLIGHT_WIDTH,

File diff suppressed because it is too large Load Diff