2006-05-31 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridDrawingLogic.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Jordi Mas i Hernandez <jordi@ximian.com>
24 //
25 // Datagrid drawing logic
26 //
27
28 // NOT COMPLETE
29
30 using System.Drawing;
31 using System.Drawing.Drawing2D;
32
33 namespace System.Windows.Forms
34 {
35         internal class DataGridDrawing
36         {
37                 #region Local Variables
38
39                 private DataGrid grid;
40
41                 // Areas
42                 internal Rectangle caption_area;
43                 internal Rectangle parent_rows;
44                 internal Rectangle columnshdrs_area;    // Used columns header area
45                 internal int columnshdrs_maxwidth;      // Total width (max width) for columns headrs
46                 internal Rectangle rowshdrs_area;       // Used Headers rows area
47                 internal int rowshdrs_maxheight;        // Total height for rows (max height)
48                 internal Rectangle cells_area;
49                 internal Font font_newrow = new Font (FontFamily.GenericSansSerif, 16);
50                 #endregion // Local Variables
51
52
53                 public DataGridDrawing (DataGrid datagrid)
54                 {
55                          grid = datagrid;                        
56                 }
57
58                 #region Public Instance Methods
59
60                 // Calc the max with of all columns
61                 internal int CalcAllColumnsWidth ()
62                 {
63                         int width = 0;
64                         int cnt = grid.CurrentTableStyle.GridColumnStyles.Count;
65
66                         for (int col = 0; col < cnt; col++) {
67                                 width += grid.CurrentTableStyle.GridColumnStyles[col].Width;
68                         }
69
70                         return width;
71                 }
72
73                 // Gets a column from a pixel
74                 private int FromPixelToColumn (int pixel, out int column_x)
75                 {
76                         int width = 0;
77                         int cnt = grid.CurrentTableStyle.GridColumnStyles.Count;
78                         column_x = 0;
79
80                         if (cnt == 0)
81                                 return 0;
82                                 
83                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
84                                 width += rowshdrs_area.X + rowshdrs_area.Width;
85                                 column_x += rowshdrs_area.X + rowshdrs_area.Width;
86                         }
87
88                         for (int col = 0; col < cnt; col++) {
89                                 width += grid.CurrentTableStyle.GridColumnStyles[col].Width;
90
91                                 if (pixel < width)
92                                         return col;
93
94                                 column_x += grid.CurrentTableStyle.GridColumnStyles[col].Width;
95                         }
96
97                         return cnt - 1;
98                 }
99
100                 //
101                 public int GetColumnStartingPixel (int my_col)
102                 {
103                         int width = 0;
104                         int cnt = grid.CurrentTableStyle.GridColumnStyles.Count;
105
106                         for (int col = 0; col < cnt; col++) {
107
108                                 if (my_col == col)
109                                         return width;
110
111                                 width += grid.CurrentTableStyle.GridColumnStyles[col].Width;
112                         }
113
114                         return 0;
115                 }
116                 
117                 // Which column has to be the first visible column to ensure a column visibility
118                 public int GetFirstColumnForColumnVisilibility (int current_first_visiblecolumn, int column)
119                 {
120                         int new_col = column;
121                         int width = 0;
122                         
123                         if (column > current_first_visiblecolumn) { // Going forward                                                            
124                                 for (new_col = column; new_col >= 0; new_col--){
125                                         width += grid.CurrentTableStyle.GridColumnStyles[new_col].Width;
126                                         
127                                         if (width >= cells_area.Width)
128                                                 return new_col + 1;
129                                                 //return new_col < grid.CurrentTableStyle.GridColumnStyles.Count ? new_col + 1 : grid.CurrentTableStyle.GridColumnStyles.Count;
130                                 }
131                                 return 0;
132                         } else {                                
133                                 return  column;
134                         }                       
135                 }
136
137                 bool in_calc_grid_areas;
138                 public void CalcGridAreas ()
139                 {
140                         if (grid.IsHandleCreated == false) // Delay calculations until the handle is created
141                                 return;
142
143                         /* make sure we don't happen to end up in this method again */
144                         if (in_calc_grid_areas)
145                                 return;
146
147                         in_calc_grid_areas = true;
148
149                         /* Order is important. E.g. row headers max. height depends on caption */
150                         grid.horz_pixeloffset = 0;                      
151                         CalcCaption ();
152                         CalcParentRows ();
153                         CalcRowsHeaders (grid.visiblerow_count);
154                         CalcColumnsHeader ();
155                         CalcCellsArea ();
156
157                         bool needHoriz = false;
158                         bool needVert = false;
159
160                         /* figure out which scrollbars we need, and what the visible areas are */
161                         int visible_cells_width = cells_area.Width;
162                         int visible_cells_height = cells_area.Height;
163                         int width_of_all_columns = CalcAllColumnsWidth ();
164                         int allrows = grid.RowsCount;
165                         if (grid.ShowEditRow && grid.RowsCount > 0)
166                                 allrows++;
167
168                         /* use a loop to iteratively calculate whether
169                          * we need horiz/vert scrollbars. */
170                         for (int i = 0; i < 3; i ++) {
171                                 if (needVert)
172                                         visible_cells_width = cells_area.Width - grid.vert_scrollbar.Width;
173                                 if (needHoriz)
174                                         visible_cells_height = cells_area.Height - grid.horiz_scrollbar.Height;
175
176                                 UpdateVisibleRowCount ();
177
178                                 needHoriz = (width_of_all_columns > visible_cells_width);
179                                 needVert = (grid.visiblerow_count != allrows);
180                         }
181
182                         int horiz_scrollbar_width = grid.ClientRectangle.Width;
183                         int horiz_scrollbar_maximum = 0;
184                         int vert_scrollbar_height = 0;
185                         int vert_scrollbar_maximum = 0;
186
187                         if (needVert)
188                                 SetUpVerticalScrollBar (out vert_scrollbar_height, out vert_scrollbar_maximum);
189
190                         if (needHoriz)
191                                 SetUpHorizontalScrollBar (out horiz_scrollbar_maximum);
192
193                         cells_area.Width = visible_cells_width;
194                         cells_area.Height = visible_cells_height;
195
196                         if (needVert && needHoriz) {
197                                 if (grid.ShowParentRowsVisible) {
198                                         parent_rows.Width -= grid.vert_scrollbar.Width;
199                                 }
200
201                                 if (!ShowingColumnHeaders) {
202                                         if (columnshdrs_area.X + columnshdrs_area.Width > grid.vert_scrollbar.Location.X) {
203                                                 columnshdrs_area.Width -= grid.vert_scrollbar.Width;
204                                         }
205                                 }
206
207                                 horiz_scrollbar_width -= grid.vert_scrollbar.Width;
208                                 vert_scrollbar_height -= grid.horiz_scrollbar.Height;
209                         }
210
211                         if (needVert) {
212                                 if (rowshdrs_area.Y + rowshdrs_area.Height > grid.ClientRectangle.Y + grid.ClientRectangle.Height) {
213                                         rowshdrs_area.Height -= grid.horiz_scrollbar.Height;
214                                         rowshdrs_maxheight -= grid.horiz_scrollbar.Height;
215                                 }
216
217                                 grid.vert_scrollbar.Height = vert_scrollbar_height;
218                                 grid.vert_scrollbar.Maximum = vert_scrollbar_maximum;
219                                 grid.Controls.Add (grid.vert_scrollbar);
220                                 grid.vert_scrollbar.Visible = true;
221                         }
222                         else {
223                                 grid.Controls.Remove (grid.vert_scrollbar);
224                                 grid.vert_scrollbar.Visible = false;
225                         }
226
227                         if (needHoriz) {
228                                 grid.horiz_scrollbar.Width = horiz_scrollbar_width;
229                                 grid.horiz_scrollbar.Maximum = horiz_scrollbar_maximum;
230                                 grid.Controls.Add (grid.horiz_scrollbar);
231                                 grid.horiz_scrollbar.Visible = true;
232                         }
233                         else {
234                                 grid.Controls.Remove (grid.horiz_scrollbar);
235                                 grid.horiz_scrollbar.Visible = false;
236                         }
237
238                         UpdateVisibleColumn ();
239                         UpdateVisibleRowCount ();
240
241                         //Console.WriteLine ("DataGridDrawing.CalcGridAreas caption_area:{0}", caption_area);
242                         //Console.WriteLine ("DataGridDrawing.CalcGridAreas parent_rows:{0}", parent_rows);
243                         //Console.WriteLine ("DataGridDrawing.CalcGridAreas rowshdrs_area:{0}", rowshdrs_area);
244                         //Console.WriteLine ("DataGridDrawing.CalcGridAreas columnshdrs_area:{0}", columnshdrs_area);
245                         //Console.WriteLine ("DataGridDrawing.CalcGridAreas cells:{0}", cells_area);
246
247                         in_calc_grid_areas = false;
248                 }
249
250                 private void CalcCaption ()
251                 {
252                         if (grid.caption_visible == false) {
253                                 caption_area = Rectangle.Empty;
254                                 return;
255                         }
256
257                         caption_area.X = grid.ClientRectangle.X;
258                         caption_area.Y = grid.ClientRectangle.Y;
259                         caption_area.Width = grid.ClientRectangle.Width;
260                         caption_area.Height = grid.CaptionFont.Height + 6;
261
262                         //Console.WriteLine ("DataGridDrawing.CalcCaption {0}", caption_area);
263                 }
264
265                 private void CalcCellsArea ()
266                 {
267                         if (grid.caption_visible) {
268                                 cells_area.Y = caption_area.Y + caption_area.Height;
269                         } else {
270                                 cells_area.Y = grid.ClientRectangle.Y;
271                         }
272
273                         if (grid.ShowParentRowsVisible) {
274                                 cells_area.Y += parent_rows.Height;
275                         }
276
277                         if (ShowingColumnHeaders) {
278                                 cells_area.Y += columnshdrs_area.Height;
279                         }
280
281                         cells_area.X = grid.ClientRectangle.X + rowshdrs_area.Width;
282                         cells_area.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - cells_area.X;
283                         cells_area.Height = grid.ClientRectangle.Y + grid.ClientRectangle.Height - cells_area.Y;
284
285                         //Console.WriteLine ("DataGridDrawing.CalcCellsArea {0}", cells_area);
286                 }
287
288                 private void CalcColumnsHeader ()
289                 {
290                         int width_all_cols, max_width_cols;
291                         
292                         if (!ShowingColumnHeaders) {
293                                 columnshdrs_area = Rectangle.Empty;                             
294                                 return;
295                         }
296
297                         if (grid.caption_visible) {
298                                 columnshdrs_area.Y = caption_area.Y + caption_area.Height;
299                         } else {
300                                 columnshdrs_area.Y = grid.ClientRectangle.Y;
301                         }
302
303                         if (grid.ShowParentRowsVisible) {
304                                 columnshdrs_area.Y += parent_rows.Height;
305                         }
306
307                         columnshdrs_area.X = grid.ClientRectangle.X;
308                         columnshdrs_area.Height = ColumnsHeaderHeight;
309                         width_all_cols = CalcAllColumnsWidth ();
310
311                         // TODO: take into account Scrollbars
312                         columnshdrs_maxwidth = grid.ClientRectangle.X + grid.ClientRectangle.Width - columnshdrs_area.X;
313                         max_width_cols = columnshdrs_maxwidth;
314
315                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
316                                 max_width_cols -= grid.RowHeaderWidth;
317                         }
318
319                         if (width_all_cols > max_width_cols) {
320                                 columnshdrs_area.Width = columnshdrs_maxwidth;
321                         } else {
322                                 columnshdrs_area.Width = width_all_cols;
323
324                                 if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
325                                         columnshdrs_area.Width += grid.RowHeaderWidth;
326                                 }
327                         }
328
329                         //Console.WriteLine ("DataGridDrawing.CalcColumnsHeader {0}", columnshdrs_area);
330                 }
331
332                 private void CalcParentRows ()
333                 {
334                         if (grid.ShowParentRowsVisible == false) {
335                                 parent_rows = Rectangle.Empty;
336                                 return;
337                         }
338
339                         if (grid.caption_visible) {
340                                 parent_rows.Y = caption_area.Y + caption_area.Height;
341
342                         } else {
343                                 parent_rows.Y = grid.ClientRectangle.Y;
344                         }
345
346                         parent_rows.X = grid.ClientRectangle.X;
347                         parent_rows.Width = grid.ClientRectangle.Width;
348                         parent_rows.Height = grid.CaptionFont.Height + 3;
349
350                         //Console.WriteLine ("DataGridDrawing.CalcParentRows {0}", parent_rows);
351                 }
352
353                 private void CalcRowsHeaders (int visiblerow_count)
354                 {
355                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible == false) {
356                                 rowshdrs_area = Rectangle.Empty;
357                                 return;
358                         }
359
360                         if (grid.caption_visible) {
361                                 rowshdrs_area.Y = caption_area.Y + caption_area.Height;
362                         } else {
363                                 rowshdrs_area.Y = grid.ClientRectangle.Y;
364                         }
365
366                         if (grid.ShowParentRowsVisible) {
367                                 rowshdrs_area.Y += parent_rows.Height;
368                         }
369
370                         if (ShowingColumnHeaders) { // first block is painted by ColumnHeader
371                                 rowshdrs_area.Y += ColumnsHeaderHeight;
372                         }
373
374                         rowshdrs_area.X = grid.ClientRectangle.X;
375                         rowshdrs_area.Width = grid.RowHeaderWidth;
376                         rowshdrs_area.Height = visiblerow_count * grid.RowHeight;
377                         rowshdrs_maxheight = grid.ClientRectangle.Height + grid.ClientRectangle.Y - rowshdrs_area.Y;
378
379                         //Console.WriteLine ("DataGridDrawing.CalcRowsHeaders {0} {1}", rowshdrs_area,
380                         //      rowshdrs_maxheight);
381                 }
382
383                 private int GetVisibleRowCount (int visibleHeight)
384                 {
385                         int rv;
386                         int total_rows = grid.RowsCount;
387                         
388                         if (grid.ShowEditRow && grid.RowsCount > 0) {
389                                 total_rows++;
390                         }
391
392                         int rows_height = (total_rows - grid.first_visiblerow) * grid.RowHeight;
393                         int max_rows = visibleHeight / grid.RowHeight;
394                                                 
395                         if (max_rows > total_rows) {
396                                 max_rows = total_rows;
397                         }
398
399                         if (rows_height > cells_area.Height) {
400                                 rv = max_rows;
401                         } else {
402                                 rv = total_rows;
403                         }       
404
405                         if (rv + grid.first_visiblerow > total_rows)
406                                 rv = total_rows - grid.first_visiblerow;
407                         return rv;
408                 }
409
410                 public void UpdateVisibleColumn ()
411                 {
412                         if (grid.CurrentTableStyle.GridColumnStyles.Count == 0) {
413                                 grid.visiblecolumn_count = 0;
414                                 return; 
415                         }
416                         
417                         int col;
418                         int max_pixel = grid.horz_pixeloffset + cells_area.Width;
419                         int unused;
420
421                         grid.first_visiblecolumn = FromPixelToColumn (grid.horz_pixeloffset, out unused);
422
423                         col = FromPixelToColumn (max_pixel, out unused);
424                         
425                         grid.visiblecolumn_count = 1 + col - grid.first_visiblecolumn;
426                         
427                         if (grid.first_visiblecolumn + grid.visiblecolumn_count < grid.CurrentTableStyle.GridColumnStyles.Count) { 
428                                 grid.visiblecolumn_count++; // Partially visible column
429                         }
430                 }
431
432                 public void UpdateVisibleRowCount ()
433                 {
434                         int max_height = cells_area.Height;
435                         int max_rows = max_height / grid.RowHeight;
436
437                         int total_rows = grid.RowsCount;
438                         
439                         if (grid.ShowEditRow && grid.RowsCount > 0) {
440                                 total_rows++;
441                         }
442
443                         if (max_rows > total_rows) {
444                                 max_rows = total_rows;
445                         }
446
447                         grid.visiblerow_count = GetVisibleRowCount (max_height);
448
449                         CalcRowsHeaders (grid.visiblerow_count); // Height depends on num of visible rows               
450
451                         if (grid.visiblerow_count < max_rows) {
452                                 grid.visiblerow_count = max_rows;
453                                 grid.first_visiblerow = total_rows - max_rows;
454                                 grid.Invalidate ();
455                         }
456                         
457                 }
458
459                 const int RESIZE_AREA_SIZE = 5;
460
461                 // From Point to Cell
462                 public DataGrid.HitTestInfo HitTest (int x, int y)
463                 {
464                         DataGrid.HitTestInfo hit = new DataGrid.HitTestInfo ();
465
466                         if (columnshdrs_area.Contains (x, y)) {
467                                 int offset_x = x + grid.horz_pixeloffset;
468                                 int column_x;
469                                 int column_under_mouse = FromPixelToColumn (offset_x, out column_x);
470                                 
471                                 if ((column_x + grid.CurrentTableStyle.GridColumnStyles[column_under_mouse].Width - offset_x < RESIZE_AREA_SIZE)
472                                     && column_under_mouse < grid.CurrentTableStyle.GridColumnStyles.Count) {
473                                         hit.type = DataGrid.HitTestType.ColumnResize;
474                                         hit.column = column_under_mouse;
475                                 }
476                                 else {
477                                         hit.type = DataGrid.HitTestType.ColumnHeader;
478                                         hit.column = column_under_mouse;
479                                 }
480                                 return hit;
481                         }
482
483                         // TODO: Add missing RowResize checks
484                         if (rowshdrs_area.Contains (x, y)) {
485                                 hit.type = DataGrid.HitTestType.RowHeader;
486                                 int posy;
487                                 int rcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
488                                 for (int r = grid.FirstVisibleRow; r < rcnt; r++) {
489                                         posy = cells_area.Y + ((r - grid.FirstVisibleRow) * grid.RowHeight);
490                                         if (y <= posy + grid.RowHeight) { // Found row
491                                                 hit.row = r;
492                                                 break;
493                                         }
494                                 }
495                                 return hit;
496                         }
497
498                         if (caption_area.Contains (x, y)) {
499                                 hit.type = DataGrid.HitTestType.Caption;
500                                 return hit;
501                         }
502
503                         if (parent_rows.Contains (x, y)) {
504                                 hit.type = DataGrid.HitTestType.ParentRows;
505                                 return hit;
506                         }
507
508                         int pos_y, pos_x, width;
509                         int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
510                         for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {
511                                 pos_y = cells_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
512
513                                 if (y <= pos_y + grid.RowHeight) { // Found row
514                                         hit.row = row;
515                                         hit.type = DataGrid.HitTestType.Cell;                                   
516                                         int col_pixel;
517                                         int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
518                                         for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
519
520                                                 col_pixel = GetColumnStartingPixel (column);
521                                                 pos_x = cells_area.X + col_pixel - grid.horz_pixeloffset;
522                                                 width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
523
524                                                 if (x <= pos_x + width) { // Column found
525                                                         hit.column = column;
526                                                         break;
527                                                 }
528                                         }
529
530                                         break;
531                                 }
532                         }
533
534                         return hit;
535                 }
536
537                 public Rectangle GetCellBounds (int row, int col)
538                 {
539                         Rectangle bounds = new Rectangle ();
540                         int col_pixel;
541
542                         bounds.Width = grid.CurrentTableStyle.GridColumnStyles[col].Width;
543                         bounds.Height = grid.RowHeight;
544                         bounds.Y = cells_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
545                         col_pixel = GetColumnStartingPixel (col);
546                         bounds.X = cells_area.X + col_pixel - grid.horz_pixeloffset;
547                         return bounds;
548                 }
549
550                 public void InvalidateCaption ()
551                 {
552                         if (caption_area.IsEmpty)
553                                 return;
554
555                         grid.Invalidate (caption_area);
556                 }
557
558                 public void InvalidateCells ()
559                 {
560                         if (cells_area.IsEmpty)
561                                 return;
562
563                         grid.Invalidate (cells_area);
564                 }
565                 
566                 public void InvalidateRow (int row)
567                 {
568                         if (row < grid.FirstVisibleRow || row > grid.FirstVisibleRow + grid.VisibleRowCount) {
569                                 return;
570                         }
571
572                         Rectangle rect_row = new Rectangle ();
573
574                         int row_width = CalcAllColumnsWidth ();
575                         if (row_width > cells_area.Width)
576                                 row_width = cells_area.Width;
577                         rect_row.X = cells_area.X;
578                         rect_row.Width = row_width;
579                         rect_row.Height = grid.RowHeight;
580                         rect_row.Y = cells_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
581                         grid.Invalidate (rect_row);
582                 }
583
584                 public void InvalidateRowHeader (int row)
585                 {
586                         Rectangle rect_rowhdr = new Rectangle ();
587                         rect_rowhdr.X = rowshdrs_area.X;
588                         rect_rowhdr.Width = rowshdrs_area.Width;
589                         rect_rowhdr.Height = grid.RowHeight;
590                         rect_rowhdr.Y = rowshdrs_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
591                         grid.Invalidate (rect_rowhdr);
592                 }       
593
594                 public void InvalidateColumn (DataGridColumnStyle column)
595                 {
596                         Rectangle rect_col = new Rectangle ();
597                         int col_pixel;
598                         int col = -1;
599
600                         col = grid.CurrentTableStyle.GridColumnStyles.IndexOf (column);
601
602                         if (col == -1) {
603                                 return;
604                         }
605
606                         rect_col.Width = column.Width;
607                         col_pixel = GetColumnStartingPixel (col);
608                         rect_col.X = cells_area.X + col_pixel - grid.horz_pixeloffset;
609                         rect_col.Y = cells_area.Y;
610                         rect_col.Height = cells_area.Height;
611                         grid.Invalidate (rect_col);
612                 }
613
614                 public void DrawResizeLine (int x)
615                 {
616                         XplatUI.DrawReversibleRectangle (grid.Handle,
617                                                          new Rectangle (x, CellsArea.Y, 1, CellsArea.Height),
618                                                          3);
619                 }
620
621                 void SetUpHorizontalScrollBar (out int maximum)
622                 {
623                         maximum = CalcAllColumnsWidth ();
624
625                         grid.horiz_scrollbar.Location = new Point (grid.ClientRectangle.X, grid.ClientRectangle.Y +
626                                 grid.ClientRectangle.Height - grid.horiz_scrollbar.Height);
627
628                         grid.horiz_scrollbar.Size = new Size (grid.ClientRectangle.Width,
629                                 grid.horiz_scrollbar.Height);
630
631                         grid.horiz_scrollbar.LargeChange = cells_area.Width;
632                 }
633
634
635                 void SetUpVerticalScrollBar (out int height, out int maximum)
636                 {
637                         int y;
638                         
639                         if (grid.caption_visible) {
640                                 y = grid.ClientRectangle.Y + caption_area.Height;
641                                 height = grid.ClientRectangle.Height - caption_area.Height;
642                         } else {
643                                 y = grid.ClientRectangle.Y;
644                                 height = grid.ClientRectangle.Height;
645                         }
646
647                         grid.vert_scrollbar.Location = new Point (grid.ClientRectangle.X +
648                                 grid.ClientRectangle.Width - grid.vert_scrollbar.Width, y);
649
650                         grid.vert_scrollbar.Size = new Size (grid.vert_scrollbar.Width,
651                                 height);
652
653                         maximum = grid.RowsCount;
654                         
655                         if (grid.ShowEditRow && grid.RowsCount > 0) {
656                                 maximum++;      
657                         }
658                         
659                         grid.vert_scrollbar.LargeChange = VLargeChange;
660                 }
661
662                 #endregion // Public Instance Methods
663
664                 #region Instance Properties
665                 public Rectangle CellsArea {
666                         get {
667                                 return cells_area;
668                         }
669                 }
670
671                 // Returns the ColumnsHeader area excluding the rectangle shared with RowsHeader
672                 public Rectangle ColumnsHeadersArea {
673                         get {
674                                 Rectangle columns_area = columnshdrs_area;
675
676                                 if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
677                                         columns_area.X += grid.RowHeaderWidth;
678                                         columns_area.Width -= grid.RowHeaderWidth;
679                                 }
680                                 return columns_area;
681                         }
682                 }
683
684                 bool ShowingColumnHeaders {
685                         get { return grid.columnheaders_visible != false && grid.CurrentTableStyle.GridColumnStyles.Count > 0; }
686                 }
687
688                 int ColumnsHeaderHeight {
689                         get {
690                                 return grid.CurrentTableStyle.HeaderFont.Height + 6;
691                         }
692                 }
693
694                 public Rectangle RowsHeadersArea {
695                         get {
696                                 return rowshdrs_area;
697                         }
698                 }
699
700                 public int VLargeChange {
701                         get {
702                                 return cells_area.Height / grid.RowHeight;
703                         }
704                 }
705
706                 #endregion Instance Properties
707         }
708 }