* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeWin32Classic.cs
index fdb091b5006dcd71ed79b2969b475693f5dd289c..b2d26b3100b4a55b0fb50c5017abb231f03136ee 100644 (file)
 //     Alexander Olk, alex.olk@googlemail.com
 //
 
-
+using System.ComponentModel;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.Drawing.Text;
+using System.Text;
 
 namespace System.Windows.Forms
 {
@@ -63,7 +64,7 @@ namespace System.Windows.Forms
                {                       
                        defaultWindowBackColor = this.ColorWindow;
                        defaultWindowForeColor = this.ColorControlText;
-                       default_font =  new Font (FontFamily.GenericSansSerif, 8.25f);
+                       default_font =  new Font (FontFamily.GenericSansSerif, 8f);
                        
                        /* Menu string formats */
                        string_format_menu_text = new StringFormat ();
@@ -83,7 +84,8 @@ namespace System.Windows.Forms
                }
 
                public override void ResetDefaults() {
-                       throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
+                       Console.WriteLine("NOT IMPLEMENTED: ResetDefault()");
+                       //throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
                }
 
                public override bool DoubleBufferingSupported {
@@ -106,13 +108,13 @@ namespace System.Windows.Forms
 
                #region Internal Methods
                protected Brush GetControlBackBrush (Color c) {
-                       if (c == DefaultControlBackColor)
+                       if (c.ToArgb () == DefaultControlBackColor.ToArgb ())
                                return SystemBrushes.Control;
                        return ResPool.GetSolidBrush (c);
                }
 
                protected Brush GetControlForeBrush (Color c) {
-                       if (c == DefaultControlForeColor)
+                       if (c.ToArgb () == DefaultControlForeColor.ToArgb ())
                                return SystemBrushes.ControlText;
                        return ResPool.GetSolidBrush (c);
                }
@@ -140,7 +142,7 @@ namespace System.Windows.Forms
                public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) {
                        
                        // Fill the button with the correct color
-                       bool is_ColorControl = button.BackColor == ColorControl ? true : false;
+                       bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
                        dc.FillRectangle (is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (button.BackColor), button.ClientRectangle);
                        
                        // First, draw the image
@@ -151,7 +153,7 @@ namespace System.Windows.Forms
                        ButtonBase_DrawButton(button, dc);
                        
                        // Draw the focus rectangle
-                       if ((button.has_focus || button.paint_as_acceptbutton) && button.is_enabled)
+                       if ((button.Focused || button.paint_as_acceptbutton) && button.Enabled)
                                ButtonBase_DrawFocus(button, dc);
                        
                        // Now the text
@@ -165,7 +167,7 @@ namespace System.Windows.Forms
                        bool check_or_radio = false;
                        bool check_or_radio_checked = false;
                        
-                       bool is_ColorControl = button.BackColor == ColorControl ? true : false;
+                       bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
                        
                        CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor);
                        
@@ -177,7 +179,7 @@ namespace System.Windows.Forms
                                check_or_radio_checked = ((RadioButton)button).Checked;
                        }
                        
-                       if ((button.has_focus || button.paint_as_acceptbutton) && button.is_enabled && !check_or_radio) {
+                       if ((button.Focused || button.paint_as_acceptbutton) && button.Enabled && !check_or_radio) {
                                // shrink the rectangle for the normal button drawing inside the focus rectangle
                                borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1);
                        } else {
@@ -210,7 +212,7 @@ namespace System.Windows.Forms
                                
                                Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor);
                        } else {
-                               if ((!button.is_pressed || !button.is_enabled) && !check_or_radio_checked)
+                               if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked)
                                        Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor);
                                else
                                        Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
@@ -342,7 +344,7 @@ namespace System.Windows.Forms
                                }
                        }
                        
-                       if (button.is_enabled) {
+                       if (button.Enabled) {
                                dc.DrawImage(i, image_x, image_y); 
                        }
                        else {
@@ -354,15 +356,20 @@ namespace System.Windows.Forms
                {
                        Color focus_color = button.ForeColor;
                        
-                       if (button.FlatStyle == FlatStyle.Popup)
-                               if (!button.is_pressed)
-                                       focus_color = ControlPaint.Dark(button.BackColor);
+                       int inflate_value = -3;
                        
-                       dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, 
-                                         button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
+                       if (!(button is CheckBox) && !(button is RadioButton)) {
+                               inflate_value = -4;
+                               
+                               if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed)
+                                       focus_color = ControlPaint.Dark(button.BackColor);
+                               
+                               dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, 
+                                                 button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
+                       }
                        
-                       if (button.has_focus) {
-                               Rectangle rect = Rectangle.Inflate (button.ClientRectangle, -4, -4);
+                       if (button.Focused) {
+                               Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value);
                                ControlPaint.DrawFocusRectangle (dc, rect);
                        }
                }
@@ -377,7 +384,7 @@ namespace System.Windows.Forms
                                text_rect.Y++;
                        }
                        
-                       if (button.is_enabled) {                                        
+                       if (button.Enabled) {                                   
                                dc.DrawString(button.text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
                        } else {
                                if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
@@ -581,11 +588,14 @@ namespace System.Windows.Forms
 
                protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )
                {
-                       Brush brush = checkbox.BackColor == ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor);
+                       Brush brush = checkbox.BackColor.ToArgb () == ColorControl.ToArgb () ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor);
                        dc.FillRectangle (brush, checkbox.ClientRectangle);                     
                        // render as per normal button
                        if (checkbox.appearance==Appearance.Button) {
                                ButtonBase_DrawButton (checkbox, dc);
+                               
+                               if ((checkbox.Focused) && checkbox.Enabled)
+                                       ButtonBase_DrawFocus(checkbox, dc);
                        } else {
                                // establish if we are rendering a flat style of some sort
                                if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
@@ -604,7 +614,8 @@ namespace System.Windows.Forms
                
                protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
                {
-                       // do nothing here. maybe an other theme needs it
+                       if ( checkbox.Focused && checkbox.appearance != Appearance.Button && checkbox.Enabled )
+                               DrawInnerFocusRectangle( dc, text_rectangle, checkbox.BackColor );
                }
                
                // renders a checkBox with the Flat and Popup FlatStyle
@@ -792,7 +803,10 @@ namespace System.Windows.Forms
                        else {
                                back_color = e.BackColor;
                                fore_color = e.ForeColor;
-                       }                       
+                       }
+                       
+                       if (!ctrl.Enabled)
+                               fore_color = ColorInactiveCaptionText;
                                                        
                        e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
 
@@ -831,57 +845,63 @@ namespace System.Windows.Forms
                
                public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
                {
-                       // Draw parent rows
-                       if (pe.ClipRectangle.IntersectsWith (grid.grid_drawing.parent_rows)) {
-                               pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), grid.grid_drawing.parent_rows);
-                       }
-
                        DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
-                       DataGridPaintColumnsHdrs (pe.Graphics, pe.ClipRectangle, grid);
-                       DataGridPaintRowsHeaders (pe.Graphics, pe.ClipRectangle, grid);
-                       DataGridPaintRows (pe.Graphics, grid.grid_drawing.cells_area, pe.ClipRectangle, grid);
+                       DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid);
+                       DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid);
+                       DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid);
 
                        // Paint scrollBar corner
-                       if (grid.vert_scrollbar.Visible && grid.horiz_scrollbar.Visible) {
+                       if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) {
 
-                               Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.horiz_scrollbar.Height,
-                                        grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.horiz_scrollbar.Height,
-                                        grid.horiz_scrollbar.Height, grid.horiz_scrollbar.Height);
+                               Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.HScrollBar.Width,
+                                                                 grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.VScrollBar.Height,
+                                                                 grid.VScrollBar.Width, grid.HScrollBar.Height);
 
                                if (pe.ClipRectangle.IntersectsWith (corner)) {
                                        pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
-                                               corner);
+                                                                  corner);
                                }
                        }
                }
-               
+
                public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
                {
                        Rectangle modified_area = clip;
-                       modified_area.Intersect (grid.grid_drawing.caption_area);
+                       modified_area.Intersect (grid.caption_area);
 
                        g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor),
-                               modified_area);
+                                        modified_area);
 
                        g.DrawString (grid.CaptionText, grid.CaptionFont,
-                               ResPool.GetSolidBrush (grid.CaptionForeColor),
-                               grid.grid_drawing.caption_area);                
+                                     ResPool.GetSolidBrush (grid.CaptionForeColor),
+                                     grid.caption_area);
+
+                       if (modified_area.IntersectsWith (grid.back_button_rect)) {
+                               g.DrawImage (grid.back_button_image, grid.back_button_rect);
+                               if (grid.back_button_mouseover) {
+                                       CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
+                               }
+                       }
+                       if (modified_area.IntersectsWith (grid.parent_rows_button_rect)) {
+                               g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
+                               if (grid.parent_rows_button_mouseover) {
+                                       CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
+                               }
+                       }
                }
 
-               public override void DataGridPaintColumnsHdrs (Graphics g, Rectangle clip, DataGrid grid)
+               public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
                {
-                       Rectangle columns_area = grid.grid_drawing.columnshdrs_area;
+                       Rectangle columns_area = grid.columnhdrs_area;
 
                        if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { // Paint corner shared between row and column header
-                               Rectangle rect_bloc = grid.grid_drawing.columnshdrs_area;
+                               Rectangle rect_bloc = grid.columnhdrs_area;
                                rect_bloc.Width = grid.RowHeaderWidth;
-                               rect_bloc.Height = grid.grid_drawing.columnshdrs_area.Height;
                                if (clip.IntersectsWith (rect_bloc)) {
-                                       if (grid.visiblecolumn_count > 0) {
+                                       if (grid.VisibleColumnCount > 0)
                                                g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
-                                       }else {
+                                       else
                                                g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), rect_bloc);
-                                       }
                                }
 
                                columns_area.X += grid.RowHeaderWidth;
@@ -889,11 +909,11 @@ namespace System.Windows.Forms
                        }
 
                        // Set unused area
-                       Rectangle columnshdrs_area_complete = columns_area;
-                       columnshdrs_area_complete.Width = grid.grid_drawing.columnshdrs_maxwidth;
+                       Rectangle columnhdrs_area_complete = columns_area;
+                       columnhdrs_area_complete.Width = grid.columnhdrs_maxwidth;
                        
                        if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
-                               columnshdrs_area_complete.Width -= grid.RowHeaderWidth;
+                               columnhdrs_area_complete.Width -= grid.RowHeaderWidth;
                        }               
 
                        // Set column painting
@@ -903,64 +923,129 @@ namespace System.Windows.Forms
                        rect_columnhdr.Y = columns_area.Y;
                        rect_columnhdr.Height = columns_area.Height;
                        
-                       current_clip = new Region (columns_area);
-                       g.Clip = current_clip;
-                       int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
-                       for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
+                       int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                       for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
                                
-                               col_pixel = grid.grid_drawing.GetColumnStartingPixel (column);
-                               rect_columnhdr.X = columns_area.X + col_pixel - grid.horz_pixeloffset;
+                               col_pixel = grid.GetColumnStartingPixel (column);
+                               rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
                                rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
 
                                if (clip.IntersectsWith (rect_columnhdr) == false)
                                        continue;
 
+                               current_clip = new Region (rect_columnhdr);
+                               current_clip.Intersect (columns_area);
+                               current_clip.Intersect (clip);
+                               g.Clip = current_clip;
+
                                grid.CurrentTableStyle.GridColumnStyles[column].PaintHeader (g, rect_columnhdr, column);
 
-                               
+                               current_clip.Dispose ();
                        }
 
-                       current_clip.Dispose ();
                        g.ResetClip ();
                                
-                       Rectangle not_usedarea = columnshdrs_area_complete;                             
+                       Rectangle not_usedarea = columnhdrs_area_complete;                              
                        not_usedarea.X = rect_columnhdr.X + rect_columnhdr.Width;
                        not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - rect_columnhdr.X - rect_columnhdr.Height;            
                        g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
                        
                }
 
-               public override void DataGridPaintRowsHeaders (Graphics g, Rectangle clip, DataGrid grid)
+               public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
                {
-                       Rectangle rowshdrs_area_complete = grid.grid_drawing.rowshdrs_area;
-                       rowshdrs_area_complete.Height = grid.grid_drawing.rowshdrs_maxheight;
                        Rectangle rect_row = new Rectangle ();
-                       rect_row.X = grid.grid_drawing.rowshdrs_area.X;                 
-                       int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
-                       Rectangle not_usedarea = rowshdrs_area_complete;                        
 
-                       if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
-                               rowcnt++;
-                       }
+                       rect_row.X = grid.ParentRowsArea.X;
+                       rect_row.Width = grid.ParentRowsArea.Width;
+                       rect_row.Height = (grid.CaptionFont.Height + 3);
+
+                       g.SetClip (grid.ParentRowsArea);
 
-                       g.SetClip (grid.grid_drawing.rowshdrs_area);
-                       for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {
+                       object[] parentRows = grid.dataSourceStack.ToArray();
+                       
+                       Region current_clip;
+                       for (int row = 0; row < parentRows.Length; row++) {
+                               rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
 
-                               rect_row.Width = grid.grid_drawing.rowshdrs_area.Width;
-                               rect_row.Height = grid.RowHeight;
-                               rect_row.Y = grid.grid_drawing.rowshdrs_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
+                               if (clip.IntersectsWith (rect_row) == false)
+                                       continue;
 
-                               if (clip.IntersectsWith (rect_row)) {
-                                       DataGridPaintRowHeader (g, rect_row, row, grid);                                        
-                               }
+                               current_clip = new Region (rect_row);
+                               current_clip.Intersect (clip);
+                               g.Clip = current_clip;
+
+                               DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
+
+                               current_clip.Dispose ();
                        }
                        
                        g.ResetClip ();
-                       not_usedarea.Height = grid.grid_drawing.rowshdrs_maxheight - grid.grid_drawing.rowshdrs_area.Height;
-                       not_usedarea.Y = grid.grid_drawing.rowshdrs_area.Y + grid.grid_drawing.rowshdrs_area.Height;
-                       g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
                }
-               
+
+               public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
+               {
+                       //Console.WriteLine ("drawing parent row {0}", row);
+
+                       // Background
+                       g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
+                                        bounds);
+
+                       Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
+                       // set up some standard string formating variables
+                       StringFormat text_format = new StringFormat();
+                       text_format.LineAlignment = StringAlignment.Center;
+                       text_format.Alignment = StringAlignment.Near;
+
+                       string table_name = ((ITypedList)row.view.DataView).GetListName (null) + ": ";
+
+                       Rectangle       text_rect;
+                       Size            text_size;
+
+                       text_size = g.MeasureString (table_name, bold_font).ToSize();
+                       text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
+
+                       //Console.WriteLine ("drawing text at {0}", text_rect);
+
+                       g.DrawString (table_name,
+                                     bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
+
+                       foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
+                               if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
+                                       continue;
+
+                               text_rect.X += text_rect.Size.Width + 5;
+
+                               string text = String.Format ("{0}: {1}",
+                                                            pd.Name,
+                                                            pd.GetValue (row.view));
+
+                               text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
+                               text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
+
+                               //Console.WriteLine ("drawing text at {0}", text_rect);
+
+                               g.DrawString (text,
+                                             grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
+                       }
+
+                       if (grid.FlatMode == false) {
+                               
+                               // Paint Borders
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                       bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlLight),
+                                       bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                       bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
+       
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                       bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
+                       }
+               }
+
                public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) 
                {               
                        Point[] arrow = new Point[3];
@@ -989,46 +1074,42 @@ namespace System.Windows.Forms
 
                public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
                {
+                       bool is_add_row = grid.ShowEditRow && row == grid.Rows.Length - 1;
+                       bool is_current_row = row == grid.CurrentCell.RowNumber;
+
                        // Background
                        g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor),
                                bounds);
-                               
-                       if (grid.FlatMode == false) {
-                               
+
+                       // Draw arrow
+                       if (is_current_row) {
+                               if (grid.IsChanging) {
+                                       g.DrawString ("...", grid.Font,
+                                                     ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
+                                                     bounds);
+                               } else {
+                                       Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
+                                       DataGridPaintRowHeaderArrow (g, rect, grid);
+                               }
+                       }
+                       else if (is_add_row) {
+                               g.DrawString ("*", grid.Font, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
+                                             bounds);
+                       }
+
+                       if (grid.FlatMode == false && !is_add_row) {
                                // Paint Borders
                                g.DrawLine (ResPool.GetPen (ColorControlLight),
-                                       bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
-       
+                                           bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
+
                                g.DrawLine (ResPool.GetPen (ColorControlLight),
-                                       bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
-       
-                               g.DrawLine (ResPool.GetPen (ColorControlDark),
-                                       bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
-       
+                                           bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
+
                                g.DrawLine (ResPool.GetPen (ColorControlDark),
-                                       bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
-                       }
+                                           bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
 
-                       if (grid.ShowEditRow && grid.RowsCount > 0 && row == grid.RowsCount  && !(row == grid.CurrentCell.RowNumber && grid.is_changing == true)) {
-                               
-                               g.DrawString ("*", grid.grid_drawing.font_newrow, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                       bounds);
-                               
-                       } else {
-                               // Draw arrow
-                               if (row == grid.CurrentCell.RowNumber) {
-       
-                                       if (grid.is_changing == true) {
-                                               g.DrawString ("...", grid.Font,
-                                                       ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
-                                                       bounds);
-       
-                                       } else {
-                                               
-                                               Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);                                                                                        
-                                               DataGridPaintRowHeaderArrow (g, rect, grid);
-                                       }
-                               }
+                               g.DrawLine (ResPool.GetPen (ColorControlDark),
+                                           bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
                        }
                }
                
@@ -1036,46 +1117,160 @@ namespace System.Windows.Forms
                {
                        Rectangle rect_row = new Rectangle ();
                        Rectangle not_usedarea = new Rectangle ();
-                       rect_row.X = cells.X;
 
-                       int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
+                       int rowcnt = grid.VisibleRowCount;
                        
-                       if (grid.ShowEditRow && grid.RowsCount > 0) {
-                               rowcnt--;
-                       }                       
+                       bool showing_add_row = false;
 
-                       if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
-                               rowcnt++;
-                       }                       
-                       
-                       rect_row.Height = grid.RowHeight;
-                       rect_row.Width = cells.Width;
-                       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, clip, grid);
+                       if (grid.ListManager.Count < grid.Rows.Length) {
+                               /* the table has an add row */
+
+                               if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.Rows.Length) {
+                                       showing_add_row = true;
                                }
                        }
-                       
-                       if (grid.ShowEditRow && grid.RowsCount > 0 && grid.FirstVisibleRow + grid.VisibleRowCount == grid.RowsCount + 1) {
-                               rect_row.Y = cells.Y + ((rowcnt - grid.FirstVisibleRow) * grid.RowHeight);
+
+                       rect_row.Width = cells.Width;
+                       for (int r = 0; r < rowcnt; r++) {
+                               int row = grid.FirstVisibleRow + r;
+                               if (row == grid.Rows.Length - 1)
+                                       rect_row.Height = grid.Rows[row].Height;
+                               else
+                                       rect_row.Height = grid.Rows[row + 1].VerticalOffset - grid.Rows[row].VerticalOffset;
+                               rect_row.Y = cells.Y + grid.Rows[row].VerticalOffset - grid.Rows[grid.FirstVisibleRow].VerticalOffset;
                                if (clip.IntersectsWith (rect_row)) {
-                                       DataGridPaintRow (g, rowcnt, rect_row, true, clip, grid);
+                                       if (grid.CurrentTableStyle.HasRelations
+                                           && !(showing_add_row && row == grid.Rows.Length - 1))
+                                               DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
+                                       else
+                                               DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.Rows.Length - 1, clip, grid);
                                }
                        }
 
-
+                       // XXX this should be moved elsewhere and turned into 1 g.FillRectangle call, not grid.Rows.Length separate calls
                        not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
                        not_usedarea.Y = rect_row.Y + rect_row.Height;
-                       not_usedarea.Width = rect_row.Width = cells.Width;
-                       not_usedarea.X = cells.X;
+                       not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
+                       not_usedarea.X = 0;
 
                        g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
                }
-               
-               public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
-                                                      Rectangle clip, DataGrid grid)
-               {                       
+
+               public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                              Rectangle clip, DataGrid grid)
+               {
+                       Rectangle rect_header;
+                       Rectangle icon_bounds = new Rectangle ();
+                       Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
+
+                       /* paint the header if it's visible and intersects the clip */
+                       if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
+                               rect_header = row_rect;
+                               rect_header.Width = grid.RowHeaderWidth;
+                               row_rect.X += grid.RowHeaderWidth;
+                               if (clip.IntersectsWith (rect_header)) {
+                                       DataGridPaintRowHeader (g, rect_header, row, grid);
+                               }
+
+                               icon_bounds = rect_header;
+                               icon_bounds.X += icon_bounds.Width / 2;
+                               icon_bounds.Y += 3;
+                               icon_bounds.Width = 8;
+                               icon_bounds.Height = 8;
+
+                               g.DrawRectangle (pen, icon_bounds);
+
+                               /* the - part of the icon */
+                               g.DrawLine (pen,
+                                           icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
+                                           icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
+                                           
+                               if (!grid.IsExpanded (row)) {
+                                       /* the | part of the icon */
+                                       g.DrawLine (pen,
+                                                   icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
+                                                   icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
+                               }
+                       }
+
+                       Rectangle nested_rect = row_rect;
+
+                       if (grid.Rows[row].IsExpanded)
+                               nested_rect.Height -= grid.Rows[row].RelationHeight;
+
+                       DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
+
+                       if (grid.Rows[row].IsExpanded) {
+                               // XXX we should create this in the
+                               // datagrid and cache it for use by
+                               // the theme instead of doing it each
+                               // time through here
+                               string[] relations = grid.CurrentTableStyle.Relations;
+                               StringBuilder relation_builder = new StringBuilder ("");
+
+                               for (int i = 0; i < relations.Length; i ++) {
+                                       if (i > 0)
+                                               relation_builder.Append ("\n");
+
+                                       relation_builder.Append (relations[i]);
+                               }
+                               string relation_text = relation_builder.ToString ();
+
+                               StringFormat string_format = new StringFormat ();
+                               string_format.FormatFlags |= StringFormatFlags.NoWrap;
+
+
+                               //Region prev_clip = g.Clip;
+                               //Region current_clip;
+                               Rectangle rect_cell = row_rect;
+
+                               rect_cell.X = row_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
+                               rect_cell.Y += nested_rect.Height;
+                               rect_cell.Height = grid.Rows[row].RelationHeight;
+                               rect_cell.Width = 0;
+
+                               int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                               for (int column = grid.FirstVisibleColumn; column < column_cnt; column++)
+                                       rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
+
+                               g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
+                                                rect_cell);
+
+
+                               /* draw the line leading from the +/- to the relation area */
+                               Rectangle outline = grid.Rows[row].relation_area;
+                               outline.Y = rect_cell.Y;
+                               outline.Height --;
+
+                               g.DrawLine (pen,
+                                           icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
+                                           icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
+
+                               g.DrawLine (pen,
+                                           icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
+                                           outline.X, outline.Y + outline.Height / 2);
+
+                               g.DrawRectangle (pen, outline);
+
+                               g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
+                                             outline, string_format);
+
+                               if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
+                                       Rectangle not_usedarea = new Rectangle ();
+                                       not_usedarea.X = rect_cell.X + rect_cell.Width;
+                                       not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
+                                       not_usedarea.Y = row_rect.Y;
+                                       not_usedarea.Height = row_rect.Height;
+                                       if (clip.IntersectsWith (not_usedarea))
+                                               g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
+                                                                not_usedarea);
+                               }
+                       }
+               }
+
+               public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                              Rectangle clip, DataGrid grid)
+               {
                        Rectangle rect_cell = new Rectangle ();
                        int col_pixel;
                        Color backcolor, forecolor;
@@ -1105,17 +1300,18 @@ namespace System.Windows.Forms
                        foreBrush = ResPool.GetSolidBrush (forecolor);
 
                        // PaintCells at row, column
-                       int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
-                       for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
+                       int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
+                       for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
 
-                               col_pixel = grid.grid_drawing.GetColumnStartingPixel (column);
+                               col_pixel = grid.GetColumnStartingPixel (column);
 
-                               rect_cell.X = row_rect.X + col_pixel - grid.horz_pixeloffset;
+                               rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
                                rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
 
                                if (clip.IntersectsWith (rect_cell)) {
-                                       current_clip = new Region (row_rect);
-                                       current_clip.Intersect (rect_cell);
+                                       current_clip = new Region (rect_cell);
+                                       current_clip.Intersect (row_rect);
+                                       current_clip.Intersect (clip);
                                        g.Clip = current_clip;
 
                                        if (is_newrow) {
@@ -1145,6 +1341,22 @@ namespace System.Windows.Forms
                                                         not_usedarea);
                        }
                }
+
+               public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
+                                                      Rectangle clip, DataGrid grid)
+               {                       
+                       /* paint the header if it's visible and intersects the clip */
+                       if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
+                               Rectangle rect_header = row_rect;
+                               rect_header.Width = grid.RowHeaderWidth;
+                               row_rect.X += grid.RowHeaderWidth;
+                               if (clip.IntersectsWith (rect_header)) {
+                                       DataGridPaintRowHeader (g, rect_header, row, grid);
+                               }
+                       }
+
+                       DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
+               }
                
                #endregion // Datagrid
                
@@ -1269,30 +1481,29 @@ namespace System.Windows.Forms
                #region LinkLabel
                public  override void DrawLinkLabel (Graphics dc, Rectangle clip_rectangle, LinkLabel label)
                {
-                       Color color;
-
                        dc.FillRectangle (GetControlBackBrush (label.BackColor), clip_rectangle);
 
-                       for (int i = 0; i < label.num_pieces; i++) {
-                               
-                               if (clip_rectangle.IntersectsWith (label.pieces[i].rect) == false) {
+                       if (label.pieces == null)
+                               return;
+
+                       for (int i = 0; i < label.pieces.Length; i ++) {
+                               RectangleF clipf = new RectangleF (clip_rectangle.X, clip_rectangle.Y,
+                                                                  clip_rectangle.Width, clip_rectangle.Height);
+                               RectangleF rectf = label.pieces[i].region.GetBounds (dc);
+
+                               if (!clipf.IntersectsWith (rectf))
                                        continue;
-                               }                               
-                               
-                               color = label.GetLinkColor (label.pieces[i], i);
 
-                               if (label.pieces[i].link == null)
-                                       dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (label.ForeColor),
-                                               label.pieces[i].rect.X, label.pieces[i].rect.Y);
-                               else
-                                       dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (color),
-                                               label.pieces[i].rect.X, label.pieces[i].rect.Y);
+                               dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (label.GetPieceColor (label.pieces[i], i)),
+                                              rectf, label.string_format);
 
-                               if (label.pieces[i].focused) {                                  
-                                       CPDrawFocusRectangle (dc, label.pieces[i].rect, label.ForeColor, label.BackColor);
+                               LinkLabel.Link link = label.pieces[i].link;
+                               if (link != null && link.Focused) {
+                                       Rectangle rect = new Rectangle ((int)rectf.X, (int)rectf.Y,
+                                                                       (int)rectf.Width, (int)rectf.Height);
+                                       CPDrawFocusRectangle (dc, rect, label.ForeColor, label.BackColor);
                                }
-                       }                       
-                       
+                       }
                }
                #endregion      // LinkLabel
                #region ListBox
@@ -1501,9 +1712,8 @@ namespace System.Windows.Forms
                        }
 
                        if (control.View == View.LargeIcon) {
-                               if (control.LargeImageList == null) {
-                                       dc.DrawLine (ResPool.GetSizedPen (this.ColorWindowText, 2), icon_rect.Left, icon_rect.Y, icon_rect.Left + 11, icon_rect.Y);
-                               } else if (item.ImageIndex > -1 && item.ImageIndex < control.LargeImageList.Images.Count)
+                               if (item.ImageIndex > -1 && control.LargeImageList != null &&
+                                   item.ImageIndex < control.LargeImageList.Images.Count)
                                        control.LargeImageList.Draw (dc, icon_rect.Location, item.ImageIndex);
                        } else {
                                if (item.ImageIndex > -1 && control.SmallImageList != null &&
@@ -1526,36 +1736,27 @@ namespace System.Windows.Forms
                        if (!control.LabelWrap)
                                format.FormatFlags = StringFormatFlags.NoWrap;
                        
-                       if (item.Selected && control.item_control.Focused) {
-                               if (control.View == View.Details) {
-                                       if (control.FullRowSelect) {
-                                               dc.FillRectangle (SystemBrushes.Highlight, text_rect);
-                                       }
-                                       else {
-                                               Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
-                                                                                               item.Font));
-                                               text_rect.Width = text_size.Width;
-                                               dc.FillRectangle (SystemBrushes.Highlight, text_rect);
-                                       }
-                               }
-                               else {
-                                       /*Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
-                                         item.Font));
-                                         Point loc = text_rect.Location;
-                                         loc.X += (text_rect.Width - text_size.Width) / 2;
-                                         text_rect.Width = text_size.Width;*/
-                                       dc.FillRectangle (SystemBrushes.Highlight, text_rect);
-                               }
+                       Rectangle highlight_rect = text_rect;
+                       if (control.View == View.Details && !control.FullRowSelect) {
+                               Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
+                               highlight_rect.Width = text_size.Width + 4;
                        }
+
+                       if (item.Selected && control.Focused)
+                               dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
                        else
                                dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
+                       
+                       Brush textBrush =
+                               !control.Enabled ? SystemBrushes.ControlLight :
+                               (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
+                               this.ResPool.GetSolidBrush (item.ForeColor);
 
                        if (item.Text != null && item.Text.Length > 0) {
-                               if (item.Selected && control.item_control.Focused)
-                                       dc.DrawString (item.Text, item.Font, SystemBrushes.HighlightText, text_rect, format);
+                               if (item.Selected && control.Focused)
+                                       dc.DrawString (item.Text, item.Font, textBrush, highlight_rect, format);
                                else
-                                       dc.DrawString (item.Text, item.Font, this.ResPool.GetSolidBrush
-                                                      (item.ForeColor), text_rect, format);
+                                       dc.DrawString (item.Text, item.Font, textBrush, text_rect, format);
                        }
 
                        if (control.View == View.Details && control.Columns.Count > 0) {
@@ -1614,8 +1815,8 @@ namespace System.Windows.Forms
                                }
                        }
                        
-                       if (item.Focused && control.item_control.Focused) {                             
-                               Rectangle focus_rect = text_rect;
+                       if (item.Focused && control.Focused) {                          
+                               Rectangle focus_rect = highlight_rect;
                                if (control.FullRowSelect && control.View == View.Details) {
                                        int width = 0;
                                        foreach (ColumnHeader col in control.Columns)
@@ -2749,6 +2950,9 @@ namespace System.Windows.Forms
                        
                        if (radio_button.appearance==Appearance.Button) {
                                ButtonBase_DrawButton (radio_button, dc);
+                               
+                               if ((radio_button.Focused) && radio_button.Enabled)
+                                       ButtonBase_DrawFocus(radio_button, dc);
                        } else {
                                // establish if we are rendering a flat style of some sort
                                if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
@@ -2767,7 +2971,8 @@ namespace System.Windows.Forms
                
                protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
                {
-                       // do nothing here. maybe an other theme needs it
+                       if ( radio_button.Focused && radio_button.appearance != Appearance.Button && radio_button.Enabled )
+                               DrawInnerFocusRectangle( dc, text_rectangle, radio_button.BackColor );
                }
                
                // renders a radio button with the Flat and Popup FlatStyle
@@ -3047,7 +3252,7 @@ namespace System.Windows.Forms
                        int horz_border = 2;
                        int vert_border = 2;
                        
-                       bool is_color_control = sb.BackColor == ColorControl;
+                       bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
 
                        Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
                        dc.FillRectangle (brush, clip);
@@ -3200,8 +3405,7 @@ namespace System.Windows.Forms
 
                public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
                {
-                       // Do we need to fill the back color? It can't be changed...
-                       Brush brush = tab.BackColor == DefaultControlBackColor ? SystemBrushes.Control : ResPool.GetSolidBrush (tab.BackColor);
+                       Brush brush = SystemBrushes.Control;
                        dc.FillRectangle (brush, area);
                        Rectangle panel_rect = GetTabPanelRectExt (tab);
 
@@ -3506,7 +3710,7 @@ namespace System.Windows.Forms
                public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
                {
                        StringFormat format = new StringFormat ();
-                       format.Trimming = StringTrimming.EllipsisWord;
+                       format.Trimming = StringTrimming.EllipsisCharacter;
                        format.LineAlignment = StringAlignment.Center;
                        if (control.TextAlign == ToolBarTextAlign.Underneath)
                                format.Alignment = StringAlignment.Center;
@@ -3531,30 +3735,25 @@ namespace System.Windows.Forms
                                if (clip_rectangle.Right == control.Right) {
                                        dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
                                }
-                       } else if (control.Divider) {
+                       } else {
 
-                               if (control.Appearance == ToolBarAppearance.Flat &&
-                                               control.Parent != null && control.Parent.BackgroundImage != null) {
-                                       using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile)) {
-                                               dc.FillRectangle (b, clip_rectangle);
+                               if (control.Appearance == ToolBarAppearance.Flat && control.Parent != null) {
+                                       if (control.Parent.BackgroundImage != null) {
+                                               using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile))
+                                                       dc.FillRectangle (b, clip_rectangle);
+                                       } else {
+                                               dc.FillRectangle (ResPool.GetSolidBrush (control.Parent.BackColor), clip_rectangle);
                                        }
                                } else {
                                        dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
                                }
 
-                               if (clip_rectangle.Y < 2) {
+                               if (control.Divider && clip_rectangle.Y < 2) {
                                        if (clip_rectangle.Y < 1) {
                                                dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
                                        }
                                        dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
                                }
-                       } else {
-                               if (control.Appearance == ToolBarAppearance.Flat &&
-                                               control.Parent != null && control.Parent.BackgroundImage != null) {
-                                       using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile)) {
-                                               dc.FillRectangle (b, clip_rectangle);
-                                       }
-                               }
                        }
 
                        foreach (ToolBarButton button in control.Buttons)
@@ -3683,10 +3882,14 @@ namespace System.Windows.Forms
                                        CPDrawImageDisabled (dc, button.Image, x, y, ColorControl);
                        }
 
+                       Rectangle text_rect = button.TextRectangle;
+                       if (text_rect.Width <= 0 || text_rect.Height <= 0)
+                               return;
+
                        if (button.Enabled)
-                               dc.DrawString (button.Text, control.Font, SystemBrushes.ControlText, button.TextRectangle, format);
+                               dc.DrawString (button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
                        else
-                               CPDrawStringDisabled (dc, button.Text, control.Font, control.BackColor, button.TextRectangle, format);
+                               CPDrawStringDisabled (dc, button.Text, control.Font, control.BackColor, text_rect, format);
                }
 
                // Grip width for the ToolBar
@@ -4158,7 +4361,9 @@ namespace System.Windows.Forms
 
                        area = tb.ClientRectangle;
 
-                       if (tb.thumb_pressed == true) {
+                       if (!tb.Enabled) {
+                               br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
+                       } else if (tb.thumb_pressed == true) {
                                br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
                        } else {
                                br_thumb = SystemBrushes.Control;
@@ -4166,7 +4371,7 @@ namespace System.Windows.Forms
 
                        
                        /* Control Background */
-                       if (tb.BackColor == DefaultControlBackColor) {
+                       if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
                                dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
                        } else {
                                dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
@@ -4221,7 +4426,7 @@ namespace System.Windows.Forms
 
                public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
                {
-                       if (wm.IsToolWindow)
+                       if (wm.IsToolWindow && !wm.IsMinimized)
                                return SystemInformation.ToolWindowCaptionHeight;
                        if (wm.Form.FormBorderStyle == FormBorderStyle.None)
                                return 0;
@@ -4245,7 +4450,7 @@ namespace System.Windows.Forms
                        int btw = btsize.Width;
                        int bth = btsize.Height;
 
-                       if (!wm.IsToolWindow && wm.HasBorders) {
+                       if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
                                if (!wm.IsMaximized) {
                                        wm.close_button.Rectangle = new Rectangle (wm.Form.Width - bw - btw - 2,
                                                        bw + 2, btw, bth);
@@ -4318,7 +4523,7 @@ namespace System.Windows.Forms
                                }
 
                                if (!wm.IsMaximized) {
-                                       if (!wm.IsToolWindow) {
+                                       if (!wm.IsToolWindow || wm.IsMinimized) {
                                                DrawTitleButton (dc, wm.minimize_button, clip);
                                                DrawTitleButton (dc, wm.maximize_button, clip);
                                        }
@@ -4329,6 +4534,22 @@ namespace System.Windows.Forms
                        }
                }
 
+               public override Size ManagedWindowButtonSize (InternalWindowManager wm)
+               {
+                       int height = ManagedWindowTitleBarHeight (wm);
+                       if (!wm.IsMaximized && !wm.IsMinimized) {
+                               if (wm.IsToolWindow)
+                                       return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
+                                                       height - 5);
+                               if (wm.Form.FormBorderStyle == FormBorderStyle.None)
+                                       return Size.Empty;
+                       } else
+                               height = SystemInformation.CaptionHeight;
+
+                       return new Size (SystemInformation.CaptionButtonSize.Width - 2,
+                                       height - 5);
+               }
+
                private void DrawTitleButton (Graphics dc, InternalWindowManager.TitleButton button, Rectangle clip)
                {
                        if (!button.Rectangle.IntersectsWith (clip))
@@ -4340,18 +4561,6 @@ namespace System.Windows.Forms
                                        button.Caption, ButtonState.Normal);
                }
 
-               private Size ManagedWindowButtonSize (InternalWindowManager wm)
-               {
-                       int height = wm.TitleBarHeight;
-                       if (wm.IsToolWindow)
-                               return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
-                                               height - 5);
-                       if (wm.Form.FormBorderStyle == FormBorderStyle.None)
-                               return Size.Empty;
-                       return new Size (SystemInformation.CaptionButtonSize.Width - 2,
-                                       height - 5);
-               }
-
                #region ControlPaint
                public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
                        ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
@@ -4374,7 +4583,7 @@ namespace System.Windows.Forms
                        Pen             penBottomRight;
                        Pen             penBottomRightInner;
                        Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
-                       bool is_ColorControl = control_color == ColorControl ? true : false;
+                       bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
                        
                        if ((style & Border3DStyle.Adjust) != 0) {
                                rect.Y -= 2;
@@ -4762,7 +4971,7 @@ namespace System.Windows.Forms
                        Color outerColor = foreColor;
                        // adjust focus color according to the flatstyle
                        if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
-                               outerColor = (backColor == ColorControl) ? ControlPaint.Dark(ColorControl) : ColorControlText;                          
+                               outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
                        }
                        
                        // draw the outer rectangle
@@ -4863,26 +5072,14 @@ namespace System.Windows.Forms
                                foreColor=Color.White;
                        }
 
-                       /* Slow method */
-
-                       Bitmap bitmap = new Bitmap(area.Width, area.Height, graphics);
+                       // still not perfect. it seems that ms calculates the position of the first dot or line
 
-                       for (int x=0; x<area.Width; x+=pixelsBetweenDots.Width) {
-                               for (int y=0; y<area.Height; y+=pixelsBetweenDots.Height) {
-                                       bitmap.SetPixel(x, y, foreColor);
-                               }
-                       }
-                       graphics.DrawImage(bitmap, area.X, area.Y, area.Width, area.Height);
-                       bitmap.Dispose();
-                       
-#if correct_but_needs_libgdiplus_fix_bug_nr_78059
                        using (Pen pen = new Pen (foreColor)) {
                                pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
                                
-                               for (int y = area.Y; y < area.Bottom; y += pixelsBetweenDots.Height - 1)
+                               for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
                                        graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
                        }
-#endif
                }
 
                public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
@@ -4964,7 +5161,7 @@ namespace System.Windows.Forms
                                rect.X-=shiftX;
                                centerX-=shiftX;
 
-                               P1=new Point(centerX, rect.Top-1);
+                               P1=new Point(centerX, rect.Top);
                                P2=new Point(centerX, rect.Bottom);
                                P3=new Point(rect.Right, centerY);
 
@@ -5093,99 +5290,195 @@ namespace System.Windows.Forms
 
 
                /* Scroll button: regular button + direction arrow */
-               public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state) {
+               public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
+               {
                        DrawScrollButtonPrimitive (dc, area, state);
-
-                       int arrow_y_pos_diff = 3;
                        
-                       switch (type) {
-                       case ScrollButton.Up:
-                               arrow_y_pos_diff = 2;
-                               break;
-                       case ScrollButton.Down:
-                               arrow_y_pos_diff = 4;
-                               break;
-                       default:
-                               break;
-                       }
+                       bool fill_rect = true;
+                       int offset = 0;
+                       
+                       if ((state & ButtonState.Pushed) != 0)
+                               offset = 1;
+                       
+                       // skip the border
+                       Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
                        
-                       // A lot of the following is adapted from the rewind project
-                       Rectangle rect = new Rectangle (area.X - 3, area.Y - arrow_y_pos_diff,
-                                       area.Width + 6, area.Height + 6);
-                       int small_diam = rect.Width > rect.Height ? rect.Height : rect.Width;
-                       if (rect.Width < rect.Height) {
-                               rect.Y += (rect.Height - rect.Width) / 2;
-                               rect.Height = small_diam;
-                       } else if (rect.Width > rect.Height) {
-                               rect.X += (rect.Width - rect.Height) / 2;
-                               rect.Width = small_diam;
-                       }
-
-                       small_diam -= 2;
-
-                       int tri = 290 * small_diam / 1000 - 1;
-                       if (tri == 0)
-                               tri = 1;
-
                        Point [] arrow = new Point [3];
                        for (int i = 0; i < 3; i++)
                                arrow [i] = new Point ();
-
-                       switch(type) {
-                       default:
-                       case ScrollButton.Down:
-                               arrow [2].X = rect.Left + 470 * small_diam / 1000 + 2;
-                               arrow [2].Y = rect.Top + 687 * small_diam / 1000 + 1;
-                               arrow [0].X = arrow [2].X - tri;
-                               arrow [1].X = arrow [2].X + tri;
-                               arrow [0].Y = arrow [1].Y = arrow [2].Y - tri;
-                               break;
-
-                       case ScrollButton.Up:
-                               arrow [2].X = rect.Left + 470 * small_diam / 1000 + 2;
-                               arrow [2].Y = rect.Bottom - (687 * small_diam / 1000 + 1);
-                               arrow [0].X = arrow [2].X - tri;
-                               arrow [1].X = arrow [2].X + tri;
-                               arrow [0].Y = arrow [1].Y = arrow [2].Y + tri;
-                               break;
-
-                       case ScrollButton.Left:
-                               arrow [2].X = rect.Right - (687 * small_diam / 1000 + 1);
-                               arrow [2].Y = rect.Top + 470 * small_diam / 1000 + 2;
-                               arrow [0].Y = arrow [2].Y - tri;
-                               arrow [1].Y = arrow [2].Y + tri;
-                               arrow [0].X = arrow [1].X = arrow [2].X + tri;
-                               break;
-                               // Left and Right are not drawn correctly because of libgdiplus problems
-                               // once that is solved change it to the code below to match ms
-//                     case ScrollButton.Left:
-//                             arrow [2].X = rect.Right - (687 * small_diam / 1000 + 1);
-//                             arrow [2].Y = (rect.Top + 470 * small_diam / 1000 + 2) - 1;
-//                             arrow [1].Y = arrow [2].Y + tri;
-//                             arrow [0].Y = arrow [2].Y - tri + 1;
-//                             arrow [0].X = arrow [1].X = arrow [2].X + tri;
-//                             break;
-                       case ScrollButton.Right:
-                               arrow [2].X = rect.Left + 687 * small_diam / 1000 + 1;
-                               arrow [2].Y = rect.Top + 470 * small_diam / 1000 + 2;
-                               arrow [0].Y = arrow [2].Y - tri;
-                               arrow [1].Y = arrow [2].Y + tri;
-                               arrow [0].X = arrow [1].X = arrow [2].X - tri;
-                               break;
+                       
+                       Pen pen = SystemPens.ControlText;
+                       
+                       if ((state & ButtonState.Inactive) != 0) {
+                               pen = SystemPens.ControlDark;
                        }
-
-                       /* Draw the arrow */
-                       if ((state & ButtonState.Inactive)!=0) {
-                               dc.FillPolygon (SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
-
-                               for (int i = 0; i < 3; i++) {
-                                       arrow [i].X--;
-                                       arrow [i].Y--;
-                               }
-                               
-                               dc.FillPolygon (SystemBrushes.ControlDark, arrow, FillMode.Winding);
-                       } else {
-                               dc.FillPolygon (SystemBrushes.ControlText, arrow, FillMode.Winding);
+                       
+                       switch (type) {
+                               default:
+                               case ScrollButton.Down:
+                                       int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
+                                       int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
+                                       if (x_middle == 1)
+                                               x_middle = 2;
+                                       
+                                       int triangle_height;
+                                       
+                                       if (rect.Height < 8) {
+                                               triangle_height = 2;
+                                               fill_rect = false;
+                                       } else if (rect.Height == 11) {
+                                               triangle_height = 3;
+                                       } else {
+                                               triangle_height = (int)Math.Round (rect.Height / 3.0f);
+                                       }
+                                       
+                                       arrow [0].X = rect.X + x_middle;
+                                       arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
+                                       
+                                       arrow [1].X = arrow [0].X + triangle_height - 1;
+                                       arrow [1].Y = arrow [0].Y - triangle_height + 1;
+                                       arrow [2].X = arrow [0].X - triangle_height + 1;
+                                       arrow [2].Y = arrow [1].Y;
+                                       
+                                       dc.DrawPolygon (pen, arrow);
+                                       
+                                       if ((state & ButtonState.Inactive) != 0) {
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
+                                       }
+                                       
+                                       if (fill_rect) {
+                                               for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
+                                                       dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
+                                                       arrow [1].X -= 1;
+                                                       arrow [2].X += 1;
+                                               }
+                                       }
+                                       break;
+                                       
+                               case ScrollButton.Up:
+                                       x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
+                                       y_middle = (int)Math.Round (rect.Height / 2.0f);
+                                       if (x_middle == 1)
+                                               x_middle = 2;
+                                       
+                                       if (y_middle == 1)
+                                               y_middle = 2;
+                                       
+                                       if (rect.Height < 8) {
+                                               triangle_height = 2;
+                                               fill_rect = false;
+                                       } else if (rect.Height == 11) {
+                                               triangle_height = 3;
+                                       } else {
+                                               triangle_height = (int)Math.Round (rect.Height / 3.0f);
+                                       }
+                                       
+                                       arrow [0].X = rect.X + x_middle;
+                                       arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
+                                       
+                                       arrow [1].X = arrow [0].X + triangle_height - 1;
+                                       arrow [1].Y = arrow [0].Y + triangle_height - 1;
+                                       arrow [2].X = arrow [0].X - triangle_height + 1;
+                                       arrow [2].Y = arrow [1].Y;
+                                       
+                                       dc.DrawPolygon (pen, arrow);
+                                       
+                                       if ((state & ButtonState.Inactive) != 0) {
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
+                                       }
+                                       
+                                       if (fill_rect) {
+                                               for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
+                                                       dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
+                                                       arrow [1].X -= 1;
+                                                       arrow [2].X += 1;
+                                               }
+                                       }
+                                       break;
+                                       
+                               case ScrollButton.Left:
+                                       y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
+                                       if (y_middle == 1)
+                                               y_middle = 2;
+                                       
+                                       int triangle_width;
+                                       
+                                       if (rect.Width < 8) {
+                                               triangle_width = 2;
+                                               fill_rect = false;
+                                       } else if (rect.Width == 11) {
+                                               triangle_width = 3;
+                                       } else {
+                                               triangle_width = (int)Math.Round (rect.Width / 3.0f);
+                                       }
+                                       
+                                       arrow [0].X = rect.Left + triangle_width - 1;
+                                       arrow [0].Y = rect.Y + y_middle;
+                                       
+                                       if (arrow [0].X - 1 == rect.X)
+                                               arrow [0].X += 1;
+                                       
+                                       arrow [1].X = arrow [0].X + triangle_width - 1;
+                                       arrow [1].Y = arrow [0].Y - triangle_width + 1;
+                                       arrow [2].X = arrow [1].X;
+                                       arrow [2].Y = arrow [0].Y + triangle_width - 1;
+                                       
+                                       dc.DrawPolygon (pen, arrow);
+                                       
+                                       if ((state & ButtonState.Inactive) != 0) {
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
+                                       }
+                                       
+                                       if (fill_rect) {
+                                               for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
+                                                       dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
+                                                       arrow [1].Y += 1;
+                                                       arrow [2].Y -= 1;
+                                               }
+                                       }
+                                       break;
+                                       
+                               case ScrollButton.Right:
+                                       y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
+                                       if (y_middle == 1)
+                                               y_middle = 2;
+                                       
+                                       if (rect.Width < 8) {
+                                               triangle_width = 2;
+                                               fill_rect = false;
+                                       } else if (rect.Width == 11) {
+                                               triangle_width = 3;
+                                       } else {
+                                               triangle_width = (int)Math.Round (rect.Width / 3.0f);
+                                       }
+                                       
+                                       arrow [0].X = rect.Right - triangle_width - 1;
+                                       arrow [0].Y = rect.Y + y_middle;
+                                       
+                                       if (arrow [0].X - 1 == rect.X)
+                                               arrow [0].X += 1;
+                                       
+                                       arrow [1].X = arrow [0].X - triangle_width + 1;
+                                       arrow [1].Y = arrow [0].Y - triangle_width + 1;
+                                       arrow [2].X = arrow [1].X;
+                                       arrow [2].Y = arrow [0].Y + triangle_width - 1;
+                                       
+                                       dc.DrawPolygon (pen, arrow);
+                                       
+                                       if ((state & ButtonState.Inactive) != 0) {
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
+                                               dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
+                                       }
+                                       
+                                       if (fill_rect) {
+                                               for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
+                                                       dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
+                                                       arrow [1].Y += 1;
+                                                       arrow [2].Y -= 1;
+                                               }
+                                       }
+                                       break;
                        }
                }