fix compuation of dirty cells when the columns are reordered, this didn't work at all before

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57291 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-12-12 17:34:13 +00:00
parent 8ad170cb85
commit cd4f6f5f8f
2 changed files with 89 additions and 41 deletions

View File

@@ -1313,6 +1313,12 @@ public:
wxGridCellCoords XYToCell(const wxPoint& pos) const wxGridCellCoords XYToCell(const wxPoint& pos) const
{ return XYToCell(pos.x, pos.y); } { return XYToCell(pos.x, pos.y); }
// these functions return the index of the row/columns corresponding to the
// given logical position in pixels
//
// 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 YToRow( int y, bool clipToMinMax = false ) const;
int XToCol( int x, bool clipToMinMax = false ) const; int XToCol( int x, bool clipToMinMax = false ) const;
@@ -1505,33 +1511,48 @@ public:
void SetColSize( int col, int width ); void SetColSize( int col, int width );
//Column positions // columns index <-> positions mapping: by default, the position of the
int GetColAt( int colPos ) const // column is the same as its index, but the columns can also be reordered
// (either by calling SetColPos() explicitly or by the user dragging the
// columns around) in which case their indices don't correspond to their
// positions on display any longer
//
// internally we always work with indices except for the functions which
// have "Pos" in their names (and which work with columns, not pixels) and
// only the display and hit testing code really cares about display
// positions at all
// return the column index corresponding to the given (valid) position
int GetColAt(int pos) const
{ {
if ( m_colAt.IsEmpty() ) return m_colAt.empty() ? pos : m_colAt[pos];
return colPos;
else
return m_colAt[colPos];
} }
void SetColPos( int colID, int newPos ); // reorder the columns so that the column with the given index is now shown
// as the position pos
void SetColPos(int idx, int pos);
int GetColPos( int colID ) const // return the position at which the column with the given index is
// displayed: notice that this is a slow operation as we don't maintain the
// reverse mapping currently
int GetColPos(int idx) const
{ {
if ( m_colAt.IsEmpty() ) if ( m_colAt.IsEmpty() )
return colID; return idx;
else
for ( int i = 0; i < m_numCols; i++ )
{ {
for ( int i = 0; i < m_numCols; i++ ) if ( m_colAt[i] == idx )
{ return i;
if ( m_colAt[i] == colID )
return i;
}
} }
return -1; wxFAIL_MSG( "invalid column index" );
return wxNOT_FOUND;
} }
// automatically size the column or row to fit to its contents, if // automatically size the column or row to fit to its contents, if
// setAsMin is true, this optimal width will also be set as minimal width // setAsMin is true, this optimal width will also be set as minimal width
// for this column // for this column
@@ -2225,6 +2246,14 @@ private:
void DoClipGridLines(bool& var, bool clip); void DoClipGridLines(bool& var, bool clip);
// return the position (not index) of the column at the given logical pixel
// position
//
// 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;
// event handlers and their helpers // event handlers and their helpers
// -------------------------------- // --------------------------------
@@ -2273,8 +2302,10 @@ private:
// common implementations of methods defined for both rows and columns // common implementations of methods defined for both rows and columns
void DeselectLine(int line, const wxGridOperations& oper); void DeselectLine(int line, const wxGridOperations& oper);
void DoEndDragResizeLine(const wxGridOperations& oper); void DoEndDragResizeLine(const wxGridOperations& oper);
int PosToLine(int pos, bool clipToMinMax, int PosToLinePos(int pos, bool clipToMinMax,
const wxGridOperations& oper) const; const wxGridOperations& oper) const;
int PosToLine(int pos, bool clipToMinMax,
const wxGridOperations& oper) const;
int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const; int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const;
bool DoMoveCursor(bool expandSelection, bool DoMoveCursor(bool expandSelection,

View File

@@ -616,7 +616,7 @@ public:
} }
// Return the row or column at the given pixel coordinate. // Return the index of the row or column at the given pixel coordinate.
virtual int virtual int
PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0; PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0;
@@ -5602,9 +5602,8 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg ) const
CalcUnscrolledPosition( r.GetRight(), r.GetBottom(), &right, &bottom ); CalcUnscrolledPosition( r.GetRight(), r.GetBottom(), &right, &bottom );
// find the cells within these bounds // find the cells within these bounds
// wxArrayInt cols;
int row, col; for ( int row = internalYToRow(top); row < m_numRows; row++ )
for ( row = internalYToRow(top); row < m_numRows; row++ )
{ {
if ( GetRowBottom(row) <= top ) if ( GetRowBottom(row) <= top )
continue; continue;
@@ -5612,19 +5611,23 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg ) const
if ( GetRowTop(row) > bottom ) if ( GetRowTop(row) > bottom )
break; break;
int colPos; // add all dirty cells in this row: notice that the columns which
for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ ) // are dirty don't depend on the row so we compute them only once
// for the first dirty row and then reuse for all the next ones
if ( cols.empty() )
{ {
col = GetColAt( colPos ); // do determine the dirty columns
for ( int pos = XToPos(left); pos <= XToPos(right); pos++ )
cols.push_back(GetColAt(pos));
if ( GetColRight(col) <= left ) // if there are no dirty columns at all, nothing to do
continue; if ( cols.empty() )
if ( GetColLeft(col) > right )
break; break;
cellsExposed.Add( wxGridCellCoords( row, col ) );
} }
const size_t count = cols.size();
for ( size_t n = 0; n < count; n++ )
cellsExposed.Add(wxGridCellCoords(row, cols[n]));
} }
++iter; ++iter;
@@ -8737,15 +8740,14 @@ wxGridCellCoords wxGrid::XYToCell(int x, int y) const
// m_defaultRowHeight/m_defaultColWidth or binary search on array of // m_defaultRowHeight/m_defaultColWidth or binary search on array of
// m_rowBottoms/m_colRights to do it quickly (linear search shouldn't be used // m_rowBottoms/m_colRights to do it quickly (linear search shouldn't be used
// for large grids) // for large grids)
int int wxGrid::PosToLinePos(int coord,
wxGrid::PosToLine(int coord, bool clipToMinMax,
bool clipToMinMax, const wxGridOperations& oper) const
const wxGridOperations& oper) const
{ {
const int numLines = oper.GetNumberOfLines(this); const int numLines = oper.GetNumberOfLines(this);
if ( coord < 0 ) if ( coord < 0 )
return clipToMinMax && numLines > 0 ? oper.GetLineAt(this, 0) : -1; return clipToMinMax && numLines > 0 ? 0 : wxNOT_FOUND;
const int defaultLineSize = oper.GetDefaultLineSize(this); const int defaultLineSize = oper.GetDefaultLineSize(this);
wxCHECK_MSG( defaultLineSize, -1, "can't have 0 default line size" ); wxCHECK_MSG( defaultLineSize, -1, "can't have 0 default line size" );
@@ -8789,12 +8791,12 @@ wxGrid::PosToLine(int coord,
// check if the position is beyond the last column // check if the position is beyond the last column
const int lineAtMaxPos = oper.GetLineAt(this, maxPos); const int lineAtMaxPos = oper.GetLineAt(this, maxPos);
if ( coord >= lineEnds[lineAtMaxPos] ) if ( coord >= lineEnds[lineAtMaxPos] )
return clipToMinMax ? lineAtMaxPos : -1; return clipToMinMax ? maxPos : -1;
// or before the first one // or before the first one
const int lineAt0 = oper.GetLineAt(this, 0); const int lineAt0 = oper.GetLineAt(this, 0);
if ( coord < lineEnds[lineAt0] ) if ( coord < lineEnds[lineAt0] )
return lineAt0; return 0;
// finally do perform the binary search // finally do perform the binary search
@@ -8803,10 +8805,10 @@ wxGrid::PosToLine(int coord,
wxCHECK_MSG( lineEnds[oper.GetLineAt(this, minPos)] <= coord && wxCHECK_MSG( lineEnds[oper.GetLineAt(this, minPos)] <= coord &&
coord < lineEnds[oper.GetLineAt(this, maxPos)], coord < lineEnds[oper.GetLineAt(this, maxPos)],
-1, -1,
"wxGrid: internal error in PosToLine()" ); "wxGrid: internal error in PosToLinePos()" );
if ( coord >= lineEnds[oper.GetLineAt(this, maxPos - 1)] ) if ( coord >= lineEnds[oper.GetLineAt(this, maxPos - 1)] )
return oper.GetLineAt(this, maxPos); return maxPos;
else else
maxPos--; maxPos--;
@@ -8817,7 +8819,17 @@ wxGrid::PosToLine(int coord,
minPos = median; minPos = median;
} }
return oper.GetLineAt(this, maxPos); return maxPos;
}
int
wxGrid::PosToLine(int coord,
bool clipToMinMax,
const wxGridOperations& oper) const
{
int pos = PosToLinePos(coord, clipToMinMax, oper);
return pos == wxNOT_FOUND ? wxNOT_FOUND : oper.GetLineAt(this, pos);
} }
int wxGrid::YToRow(int y, bool clipToMinMax) const int wxGrid::YToRow(int y, bool clipToMinMax) const
@@ -8830,6 +8842,11 @@ int wxGrid::XToCol(int x, bool clipToMinMax) const
return PosToLine(x, clipToMinMax, wxGridColumnOperations()); return PosToLine(x, clipToMinMax, wxGridColumnOperations());
} }
int wxGrid::XToPos(int x) const
{
return PosToLinePos(x, true /* clip */, wxGridColumnOperations());
}
// return the row number that that the y coord is near the edge of, or -1 if // return the row number that that the y coord is near the edge of, or -1 if
// not near an edge. // not near an edge.
// //