]> git.saurik.com Git - wxWidgets.git/commitdiff
fix compuation of dirty cells when the columns are reordered, this didn't work at...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 12 Dec 2008 17:34:13 +0000 (17:34 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 12 Dec 2008 17:34:13 +0000 (17:34 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57291 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
src/generic/grid.cpp

index 1e0e44b01c090aff860002f81cdf1842873efb3e..ec0043baf711af09a720a9c1bd88a37a5bafcaae 100644 (file)
@@ -1313,6 +1313,12 @@ public:
     wxGridCellCoords XYToCell(const wxPoint& pos) const
         { 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  XToCol( int x, bool clipToMinMax = false ) const;
 
@@ -1505,33 +1511,48 @@ public:
 
     void     SetColSize( int col, int width );
 
-    //Column positions
-    int GetColAt( int colPos ) const
+    // columns index <-> positions mapping: by default, the position of the
+    // 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 colPos;
-        else
-            return m_colAt[colPos];
+        return m_colAt.empty() ? pos : m_colAt[pos];
     }
 
-    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() )
-            return colID;
-        else
+            return idx;
+
+        for ( int i = 0; i < m_numCols; i++ )
         {
-            for ( int i = 0; i < m_numCols; i++ )
-            {
-                if ( m_colAt[i] == colID )
-                    return i;
-            }
+            if ( m_colAt[i] == idx )
+                return i;
         }
 
-        return -1;
+        wxFAIL_MSG( "invalid column index" );
+
+        return wxNOT_FOUND;
     }
 
+
+
     // 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
     // for this column
@@ -2225,6 +2246,14 @@ private:
     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
     // --------------------------------
 
@@ -2273,8 +2302,10 @@ private:
     // common implementations of methods defined for both rows and columns
     void DeselectLine(int line, const wxGridOperations& oper);
     void DoEndDragResizeLine(const wxGridOperations& oper);
-    int  PosToLine(int pos, bool clipToMinMax,
-                   const wxGridOperations& oper) const;
+    int PosToLinePos(int pos, bool clipToMinMax,
+                     const wxGridOperations& oper) const;
+    int PosToLine(int pos, bool clipToMinMax,
+                  const wxGridOperations& oper) const;
     int PosToEdgeOfLine(int pos, const wxGridOperations& oper) const;
 
     bool DoMoveCursor(bool expandSelection,
index a3f5cb24c75276d9fd22a9fc8ebc3d12eb88e67e..3ec21337c0539c7b3da9ac68df076e1d49954328 100644 (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
         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 );
 
         // find the cells within these bounds
-        //
-        int row, col;
-        for ( row = internalYToRow(top); row < m_numRows; row++ )
+        wxArrayInt cols;
+        for ( int row = internalYToRow(top); row < m_numRows; row++ )
         {
             if ( GetRowBottom(row) <= top )
                 continue;
@@ -5612,19 +5611,23 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg ) const
             if ( GetRowTop(row) > bottom )
                 break;
 
-            int colPos;
-            for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ )
+            // add all dirty cells in this row: notice that the columns which
+            // 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 )
-                    continue;
-
-                if ( GetColLeft(col) > right )
+                // if there are no dirty columns at all, nothing to do
+                if ( cols.empty() )
                     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;
@@ -8737,15 +8740,14 @@ wxGridCellCoords wxGrid::XYToCell(int x, int y) const
 // m_defaultRowHeight/m_defaultColWidth or binary search on array of
 // m_rowBottoms/m_colRights to do it quickly (linear search shouldn't be used
 // for large grids)
-int
-wxGrid::PosToLine(int coord,
-                  bool clipToMinMax,
-                  const wxGridOperations& oper) const
+int wxGrid::PosToLinePos(int coord,
+                         bool clipToMinMax,
+                         const wxGridOperations& oper) const
 {
     const int numLines = oper.GetNumberOfLines(this);
 
     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);
     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
     const int lineAtMaxPos = oper.GetLineAt(this, maxPos);
     if ( coord >= lineEnds[lineAtMaxPos] )
-        return clipToMinMax ? lineAtMaxPos : -1;
+        return clipToMinMax ? maxPos : -1;
 
     // or before the first one
     const int lineAt0 = oper.GetLineAt(this, 0);
     if ( coord < lineEnds[lineAt0] )
-        return lineAt0;
+        return 0;
 
 
     // finally do perform the binary search
@@ -8803,10 +8805,10 @@ wxGrid::PosToLine(int coord,
         wxCHECK_MSG( lineEnds[oper.GetLineAt(this, minPos)] <= coord &&
                         coord < lineEnds[oper.GetLineAt(this, maxPos)],
                      -1,
-                     "wxGrid: internal error in PosToLine()" );
+                     "wxGrid: internal error in PosToLinePos()" );
 
         if ( coord >= lineEnds[oper.GetLineAt(this, maxPos - 1)] )
-            return oper.GetLineAt(this, maxPos);
+            return maxPos;
         else
             maxPos--;
 
@@ -8817,7 +8819,17 @@ wxGrid::PosToLine(int coord,
             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
@@ -8830,6 +8842,11 @@ int wxGrid::XToCol(int x, bool clipToMinMax) const
     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
 // not near an edge.
 //