The datagrid patch is pretty simple - call XplatUI.ScrollWindow once,
and don't call invalidate when scrolling, as the generated exposes will
cause us to redraw the areas that need it.  Turns out removing the
rectangle code made clear the methods could be substantially simplified,
so I went ahead and did that too.  This was all that was necessary to
get vertical scrolling to be fast.

The theme change keeps us from redrawing the entire row whenever a
portion of it is exposed (which makes horizontal scrolling as fast as
vertical.)

Chris
Index: System.Windows.Forms/DataGrid.cs
===================================================================
--- System.Windows.Forms/DataGrid.cs	(revision 60633)
+++ System.Windows.Forms/DataGrid.cs	(working copy)
@@ -1005,7 +1005,7 @@
 		}
 
 		protected virtual void CancelEditing ()
-		{			
+		{
 			if (current_cell.ColumnNumber < CurrentTableStyle.GridColumnStyles.Count) {
 				CurrentTableStyle.GridColumnStyles[current_cell.ColumnNumber].Abort (current_cell.RowNumber);
 			}
@@ -1969,7 +1969,7 @@
 			if (source != null && source as IListSource != null && source as IList != null) {
 				throw new Exception ("Wrong complex data binding source");
 			}
-			
+
 			current_cell = new DataGridCell ();
 			datasource = source;
 			DisconnectListManagerEvents ();
@@ -1985,7 +1985,7 @@
 		}
 
 		private void SetNewDataSource ()
-		{		
+		{			
 			if (ListManager != null && TableStyles[ListManager.ListName] == null) {
 				current_style.GridColumnStyles.Clear ();			
 				current_style.CreateColumnsForTable (false);
@@ -2132,103 +2132,47 @@
 
 		private void ScrollToColumnInPixels (int pixel)
 		{
-			Rectangle invalidate = new Rectangle ();
-			Rectangle invalidate_column = new Rectangle ();
+			int pixels;
 
 			if (pixel > horz_pixeloffset) { // ScrollRight
-				int pixels = pixel - horz_pixeloffset;
-				
-				horz_pixeloffset = horiz_scrollbar.Value = pixel;
-				grid_drawing.UpdateVisibleColumn ();
+				pixels = -1 * (pixel - horz_pixeloffset);
+			}
+			else {
+				pixels = horz_pixeloffset - pixel;
+			}
 
-				// Columns header
-				invalidate_column.X = grid_drawing.ColumnsHeadersArea.X + grid_drawing.ColumnsHeadersArea.Width - pixels;
-				invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
-				invalidate_column.Width = pixels;
-				invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
-				XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, -pixels, 0, false);
-
-				// Cells
-				invalidate.X = grid_drawing.CellsArea.X + grid_drawing.CellsArea.Width - pixels;
-				invalidate.Y = grid_drawing.CellsArea.Y;
-				invalidate.Width = pixels;
-				invalidate.Height = grid_drawing.CellsArea.Height;
+			Rectangle area = grid_drawing.CellsArea;
 				
-				
-				if (columnheaders_visible == true) {
-					invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
-					invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
-				}
-				
-				XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, -pixels, 0, false);
-				Invalidate (invalidate_column);
-				Invalidate (invalidate);
+			horz_pixeloffset = pixel;
+			grid_drawing.UpdateVisibleColumn ();
 
+			if (columnheaders_visible == true) {
+				area.Y -= grid_drawing.ColumnsHeadersArea.Height;
+				area.Height += grid_drawing.ColumnsHeadersArea.Height;
+			}
 
-			} else {
-				int pixels = horz_pixeloffset - pixel;
-				Rectangle area = grid_drawing.CellsArea;
-				
-				horz_pixeloffset = horiz_scrollbar.Value = pixel;
-				grid_drawing.UpdateVisibleColumn ();
-
-				// Columns header
-				invalidate_column.X = grid_drawing.ColumnsHeadersArea.X;
-				invalidate_column.Y = grid_drawing.ColumnsHeadersArea.Y;
-				invalidate_column.Width = pixels;
-				invalidate_column.Height = grid_drawing.ColumnsHeadersArea.Height;
-				//XplatUI.ScrollWindow (Handle, grid_drawing.ColumnsHeadersArea, pixels, 0, false);
-
-				// Cells
-				invalidate.X =  grid_drawing.CellsArea.X;
-				invalidate.Y =  grid_drawing.CellsArea.Y;
-				invalidate.Width = pixels;
-				invalidate.Height = grid_drawing.CellsArea.Height;
-				
-				if (columnheaders_visible == true) {
-					invalidate.Y -= grid_drawing.ColumnsHeadersArea.Height;
-					invalidate.Height += grid_drawing.ColumnsHeadersArea.Height;
-					area.Y -= grid_drawing.ColumnsHeadersArea.Height;
-					area.Height += grid_drawing.ColumnsHeadersArea.Height;
-				}
-				
-				XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
-				Invalidate (invalidate);
-			}		
-			
+			XplatUI.ScrollWindow (Handle, area, pixels, 0, false);
 		}
 
 		private void ScrollToRow (int old_row, int new_row)
 		{
-			Rectangle invalidate = new Rectangle ();			
-			
+			int pixels;
+
 			if (new_row > old_row) { // Scrolldown
-				int scrolled_rows = new_row - old_row;
-				int pixels = scrolled_rows * RowHeight;
-				Rectangle rows_area = grid_drawing.CellsArea; // Cells area - partial rows space
-				rows_area.Height = grid_drawing.CellsArea.Height - grid_drawing.CellsArea.Height % RowHeight;
-				
-				invalidate.X =  grid_drawing.CellsArea.X;
-				invalidate.Y =  grid_drawing.CellsArea.Y + rows_area.Height - pixels;
-				invalidate.Width = grid_drawing.CellsArea.Width;
-				invalidate.Height = pixels;
+				pixels = -1 * (new_row - old_row) * RowHeight;
+			}
+			else {
+				pixels = (old_row - new_row) * RowHeight;
+			}
 
-				XplatUI.ScrollWindow (Handle, rows_area, 0, -pixels, false);
-
-			} else { // ScrollUp
-				int scrolled_rows = old_row - new_row;				
-				int pixels = scrolled_rows * RowHeight;
-
-				invalidate.X =  grid_drawing.CellsArea.X;
-				invalidate.Y =  grid_drawing.CellsArea.Y;
-				invalidate.Width = grid_drawing.CellsArea.Width;
-				invalidate.Height = pixels;
-				XplatUI.ScrollWindow (Handle, grid_drawing.CellsArea, 0, pixels, false);				
+			Rectangle rows_area = grid_drawing.CellsArea; // Cells area - partial rows space
+			if (rowheaders_visible) {
+				rows_area.X -= RowHeaderWidth;
+				rows_area.Width += RowHeaderWidth;
 			}
+			rows_area.Height = grid_drawing.CellsArea.Height - grid_drawing.CellsArea.Height % RowHeight;
 
-			// Right now we use ScrollWindow Invalidate, let's leave remarked it here for X11 if need it
-			//Invalidate (invalidate);
-			Invalidate (grid_drawing.RowsHeadersArea);
+			XplatUI.ScrollWindow (Handle, rows_area, 0, pixels, false);
 		}
 
 		#endregion Private Instance Methods
Index: System.Windows.Forms/Theme.cs
===================================================================
--- System.Windows.Forms/Theme.cs	(revision 60633)
+++ System.Windows.Forms/Theme.cs	(working copy)
@@ -697,7 +697,7 @@
 		public abstract void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid);
 		public abstract void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid);
 		public abstract void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid);
-		public abstract void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, DataGrid grid);
+		public abstract void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, Rectangle clip, DataGrid grid);
 		
 		
 		#endregion // Datagrid
Index: System.Windows.Forms/ThemeWin32Classic.cs
===================================================================
--- System.Windows.Forms/ThemeWin32Classic.cs	(revision 60633)
+++ System.Windows.Forms/ThemeWin32Classic.cs	(working copy)
@@ -1048,14 +1048,14 @@
 			for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {								
 				rect_row.Y = cells.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
 				if (clip.IntersectsWith (rect_row)) {
-					DataGridPaintRow (g, row, rect_row, false, grid);
+					DataGridPaintRow (g, row, rect_row, false, clip, grid);
 				}
 			}
 			
 			if (grid.ShowEditRow && grid.RowsCount > 0 && grid.FirstVisibleRow + grid.VisibleRowCount == grid.RowsCount + 1) {
 				rect_row.Y = cells.Y + ((rowcnt - grid.FirstVisibleRow) * grid.RowHeight);
 				if (clip.IntersectsWith (rect_row)) {
-					DataGridPaintRow (g, rowcnt, rect_row, true, grid);
+					DataGridPaintRow (g, rowcnt, rect_row, true, clip, grid);
 				}
 			}			
 
@@ -1067,7 +1067,8 @@
 			g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
 		}
 		
-		public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, DataGrid grid)
+		public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+						       Rectangle clip, DataGrid grid)
 		{			
 			Rectangle rect_cell = new Rectangle ();
 			int col_pixel;
@@ -1088,37 +1089,41 @@
 				rect_cell.X = row_rect.X + col_pixel - grid.horz_pixeloffset;
 				rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
 
-				current_clip = new Region (row_rect);
-				g.Clip = current_clip;
+				if (clip.IntersectsWith (rect_cell)) {
+					current_clip = new Region (row_rect);
+					current_clip.Intersect (rect_cell);
+					g.Clip = current_clip;
 
-				if (grid.IsSelected (row)) {
-					backcolor =  grid.SelectionBackColor;
-					forecolor =  grid.SelectionForeColor;
-				} else {
-					if (row % 2 == 0) {
-						backcolor =  grid.BackColor;
+					if (grid.IsSelected (row)) {
+						backcolor =  grid.SelectionBackColor;
+						forecolor =  grid.SelectionForeColor;
 					} else {
-						backcolor =  grid.AlternatingBackColor;
-					}
+						if (row % 2 == 0) {
+							backcolor =  grid.BackColor;
+						} else {
+							backcolor =  grid.AlternatingBackColor;
+						}
 					
-					forecolor =  grid.ForeColor;
-				}			
+						forecolor =  grid.ForeColor;
+					}			
 
-				if (is_newrow) {
-					grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
-						ResPool.GetSolidBrush (backcolor),
-						ResPool.GetSolidBrush (forecolor));						
+					if (is_newrow) {
+						grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
+						     ResPool.GetSolidBrush (backcolor),
+						     ResPool.GetSolidBrush (forecolor));						
 					
-				} else {
-					grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
-						ResPool.GetSolidBrush (backcolor),
-						ResPool.GetSolidBrush (forecolor),
-						grid.RightToLeft == RightToLeft.Yes);
+					} else {
+						grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
+						       ResPool.GetSolidBrush (backcolor),
+						       ResPool.GetSolidBrush (forecolor),
+						       grid.RightToLeft == RightToLeft.Yes);
+					}
+
+					current_clip.Dispose ();
 				}
+			}
 
-				g.Clip = prev_clip;
-				current_clip.Dispose ();
-			}
+			g.Clip = prev_clip;
 			
 			if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
 
_______________________________________________
Mono-winforms-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list

Reply via email to