2007-08-22 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeWin32Classic.cs
index 74f24ab342672bf2df877aa5e3609dfdd535db78..12b2f384ab6e7d3534a8689459d30c6410877f89 100644 (file)
@@ -60,7 +60,7 @@ namespace System.Windows.Forms
                const int SEPARATOR_MIN_WIDTH = 20;
                const int SM_CXBORDER = 1;
                const int SM_CYBORDER = 1;              
-               const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tab
+               const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tabd
                const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
 
                #region Principal Theme Methods
@@ -227,8 +227,12 @@ namespace System.Windows.Forms
                {
                        if (button.Pressed)
                                ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance);
-                       else if (button.InternalSelected)
-                               ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
+                       else if (button.InternalSelected) {
+                               if (button.Entered) 
+                                       ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
+                               else
+                                       ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
+                       }
                        else if (button.Entered)
                                ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
                        else if (!button.Enabled)
@@ -240,7 +244,7 @@ namespace System.Windows.Forms
                public virtual void DrawFlatButtonFocus (Graphics g, Button button)
                {
                        if (!button.Pressed) {
-                               Color focus_color = ControlPaint.Light(button.BackColor);
+                               Color focus_color = ControlPaint.Dark (button.BackColor);
                                g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9));
                        }
                }
@@ -253,7 +257,7 @@ namespace System.Windows.Forms
 
                public virtual void DrawFlatButtonText (Graphics g, Button button, Rectangle textBounds)
                {
-                       // No changes from Standard for image for this theme
+                       // No changes from Standard for text for this theme
                        DrawButtonText (g, button, textBounds);
                }
                #endregion
@@ -311,7 +315,45 @@ namespace System.Windows.Forms
                #endregion
 
                #region Button Layout Calculations
-               public override void CalculateButtonTextAndImageLayout (Button button, out Rectangle textRectangle, out Rectangle imageRectangle)
+#if NET_2_0
+               public override Size CalculateButtonAutoSize (Button button)
+               {
+                       Size ret_size = Size.Empty;
+                       Size text_size = TextRenderer.MeasureTextInternal (button.Text, button.Font, button.UseCompatibleTextRendering);
+                       Size image_size = button.Image == null ? Size.Empty : button.Image.Size;
+                       
+                       // Pad the text size
+                       if (button.Text.Length != 0) {
+                               text_size.Height += 4;
+                               text_size.Width += 4;
+                       }
+                       
+                       switch (button.TextImageRelation) {
+                               case TextImageRelation.Overlay:
+                                       ret_size.Height = Math.Max (button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
+                                       ret_size.Width = Math.Max (text_size.Width, image_size.Width);
+                                       break;
+                               case TextImageRelation.ImageAboveText:
+                               case TextImageRelation.TextAboveImage:
+                                       ret_size.Height = text_size.Height + image_size.Height;
+                                       ret_size.Width = Math.Max (text_size.Width, image_size.Width);
+                                       break;
+                               case TextImageRelation.ImageBeforeText:
+                               case TextImageRelation.TextBeforeImage:
+                                       ret_size.Height = Math.Max (text_size.Height, image_size.Height);
+                                       ret_size.Width = text_size.Width + image_size.Width;
+                                       break;
+                       }
+
+                       // Pad the result
+                       ret_size.Height += (button.Padding.Vertical + 6);
+                       ret_size.Width += (button.Padding.Horizontal + 6);
+                       
+                       return ret_size;
+               }
+#endif
+
+               public override void CalculateButtonTextAndImageLayout (ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle)
                {
                        Image image = button.Image;
                        string text = button.Text;
@@ -832,6 +874,196 @@ namespace System.Windows.Forms
                #endregion      // ButtonBase
 
                #region CheckBox
+#if NET_2_0
+               public override void DrawCheckBox (Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
+               {
+                       // Draw Button Background
+                       DrawCheckBoxGlyph (g, cb, glyphArea);
+
+                       // If we have an image, draw it
+                       if (imageBounds.Size != Size.Empty)
+                               DrawCheckBoxImage (g, cb, imageBounds);
+
+                       if (cb.Focused && cb.Enabled && cb.ShowKeyboardCuesInternal && textBounds != Rectangle.Empty)
+                               DrawCheckBoxFocus (g, cb, textBounds);
+
+                       // If we have text, draw it
+                       if (textBounds != Rectangle.Empty)
+                               DrawCheckBoxText (g, cb, textBounds);
+               }
+
+               public virtual void DrawCheckBoxGlyph (Graphics g, CheckBox cb, Rectangle glyphArea)
+               {
+                       if (cb.Pressed)
+                               ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState);
+                       else if (cb.InternalSelected)
+                               ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
+                       else if (cb.Entered)
+                               ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState);
+                       else if (!cb.Enabled)
+                               ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState);
+                       else
+                               ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
+               }
+
+               public virtual void DrawCheckBoxFocus (Graphics g, CheckBox cb, Rectangle focusArea)
+               {
+                       ControlPaint.DrawFocusRectangle (g, focusArea);
+               }
+
+               public virtual void DrawCheckBoxImage (Graphics g, CheckBox cb, Rectangle imageBounds)
+               {
+                       if (cb.Enabled)
+                               g.DrawImage (cb.Image, imageBounds);
+                       else
+                               CPDrawImageDisabled (g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
+               }
+
+               public virtual void DrawCheckBoxText (Graphics g, CheckBox cb, Rectangle textBounds)
+               {
+                       if (cb.Enabled)
+                               TextRenderer.DrawTextInternal (g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
+                       else
+                               DrawStringDisabled20 (g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
+               }
+
+               public override void CalculateCheckBoxTextAndImageLayout (ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
+               {
+                       int check_size = 13;
+                       glyphArea = new Rectangle (0, (button.Height - check_size) / 2, check_size, check_size);
+                       
+                       Image image = button.Image;
+                       string text = button.Text;
+                       Rectangle content_rect = button.ClientRectangle;
+                       content_rect.Width -= check_size;
+                       content_rect.Offset (check_size, 0);
+                       
+                       Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering);
+                       Size image_size = image == null ? Size.Empty : image.Size;
+
+                       textRectangle = Rectangle.Empty;
+                       imageRectangle = Rectangle.Empty;
+
+                       switch (button.TextImageRelation) {
+                               case TextImageRelation.Overlay:
+                                       // Overlay is easy, text always goes here
+                                       textRectangle = Rectangle.Inflate (content_rect, -4, -4);
+                                       textRectangle.Offset (0, -2);
+
+                                       // Image is dependent on ImageAlign
+                                       if (image == null)
+                                               return;
+
+                                       int image_x = 0;
+                                       int image_y = 0;
+                                       int image_height = image.Height;
+                                       int image_width = image.Width;
+
+                                       switch (button.ImageAlign) {
+                                               case System.Drawing.ContentAlignment.TopLeft:
+                                                       image_x = 5;
+                                                       image_y = 5;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.TopCenter:
+                                                       image_x = (content_rect.Width - image_width) / 2;
+                                                       image_y = 5;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.TopRight:
+                                                       image_x = content_rect.Width - image_width - 5;
+                                                       image_y = 5;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.MiddleLeft:
+                                                       image_x = 5;
+                                                       image_y = (content_rect.Height - image_height) / 2;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.MiddleCenter:
+                                                       image_x = (content_rect.Width - image_width) / 2;
+                                                       image_y = (content_rect.Height - image_height) / 2;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.MiddleRight:
+                                                       image_x = content_rect.Width - image_width - 4;
+                                                       image_y = (content_rect.Height - image_height) / 2;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.BottomLeft:
+                                                       image_x = 5;
+                                                       image_y = content_rect.Height - image_height - 4;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.BottomCenter:
+                                                       image_x = (content_rect.Width - image_width) / 2;
+                                                       image_y = content_rect.Height - image_height - 4;
+                                                       break;
+                                               case System.Drawing.ContentAlignment.BottomRight:
+                                                       image_x = content_rect.Width - image_width - 4;
+                                                       image_y = content_rect.Height - image_height - 4;
+                                                       break;
+                                               default:
+                                                       image_x = 5;
+                                                       image_y = 5;
+                                                       break;
+                                       }
+
+                                       imageRectangle = new Rectangle (image_x + check_size, image_y, image_width, image_height);
+                                       break;
+                               case TextImageRelation.ImageAboveText:
+                                       content_rect.Inflate (-4, -4);
+                                       LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
+                                       break;
+                               case TextImageRelation.TextAboveImage:
+                                       content_rect.Inflate (-4, -4);
+                                       LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
+                                       break;
+                               case TextImageRelation.ImageBeforeText:
+                                       content_rect.Inflate (-4, -4);
+                                       LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
+                                       break;
+                               case TextImageRelation.TextBeforeImage:
+                                       content_rect.Inflate (-4, -4);
+                                       LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
+                                       break;
+                       }
+               }
+
+               public override Size CalculateCheckBoxAutoSize (CheckBox checkBox)
+               {
+                       Size ret_size = Size.Empty;
+                       Size text_size = TextRenderer.MeasureTextInternal (checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering);
+                       Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size;
+
+                       // Pad the text size
+                       if (checkBox.Text.Length != 0) {
+                               text_size.Height += 4;
+                               text_size.Width += 4;
+                       }
+
+                       switch (checkBox.TextImageRelation) {
+                               case TextImageRelation.Overlay:
+                                       ret_size.Height = Math.Max (checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
+                                       ret_size.Width = Math.Max (text_size.Width, image_size.Width);
+                                       break;
+                               case TextImageRelation.ImageAboveText:
+                               case TextImageRelation.TextAboveImage:
+                                       ret_size.Height = text_size.Height + image_size.Height;
+                                       ret_size.Width = Math.Max (text_size.Width, image_size.Width);
+                                       break;
+                               case TextImageRelation.ImageBeforeText:
+                               case TextImageRelation.TextBeforeImage:
+                                       ret_size.Height = Math.Max (text_size.Height, image_size.Height);
+                                       ret_size.Width = text_size.Width + image_size.Width;
+                                       break;
+                       }
+
+                       // Pad the result
+                       ret_size.Height += (checkBox.Padding.Vertical);
+                       ret_size.Width += (checkBox.Padding.Horizontal) + 15;
+
+                       // There seems to be a minimum height
+                       if (ret_size.Height == checkBox.Padding.Vertical)
+                               ret_size.Height += 14;
+                               
+                       return ret_size;
+               }
+#endif
+
                public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
                        StringFormat            text_format;
                        Rectangle               client_rectangle;
@@ -845,9 +1077,12 @@ namespace System.Windows.Forms
                        checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
 
                        text_format = new StringFormat();
-                       text_format.Alignment=StringAlignment.Near;
-                       text_format.LineAlignment=StringAlignment.Center;
-                       text_format.HotkeyPrefix = HotkeyPrefix.Show;
+                       text_format.Alignment = StringAlignment.Near;
+                       text_format.LineAlignment = StringAlignment.Center;
+                       if (checkbox.ShowKeyboardCuesInternal)
+                               text_format.HotkeyPrefix = HotkeyPrefix.Show;
+                       else
+                               text_format.HotkeyPrefix = HotkeyPrefix.Hide;
 
                        /* Calculate the position of text and checkbox rectangle */
                        if (checkbox.appearance!=Appearance.Button) {
@@ -1183,14 +1418,14 @@ namespace System.Windows.Forms
                        if (ctrl.ThreeDCheckBoxes == false)
                                state |= ButtonState.Flat;
 
-                       Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, 11, 11);
+                       Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, 13, 13);
                        ControlPaint.DrawCheckBox (e.Graphics,
                                item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
                                checkbox_rect.Width, checkbox_rect.Height,
                                state);
 
-                       item_rect.X += checkbox_rect.Width + checkbox_rect.X * 2;
-                       item_rect.Width -= checkbox_rect.Width + checkbox_rect.X * 2;
+                       item_rect.X += checkbox_rect.Right;
+                       item_rect.Width -= checkbox_rect.Right;
                        
                        /* Draw text*/
                        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
@@ -1207,7 +1442,7 @@ namespace System.Windows.Forms
 
                        e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
                                ResPool.GetSolidBrush (fore_color),
-                               item_rect, ctrl.StringFormat);
+                               item_rect.X, item_rect.Y, ctrl.StringFormat);
                                        
                        if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
                                CPDrawFocusRectangle (e.Graphics, item_rect,
@@ -2217,9 +2452,27 @@ namespace System.Windows.Forms
                        int first = control.FirstVisibleIndex;  
 
                        for (int i = first; i <= control.LastVisibleIndex; i ++) {                                      
-                               if (clip.IntersectsWith (control.Items[i].GetBounds (ItemBoundsPortion.Entire)))
-                                       DrawListViewItem (dc, control, control.Items [i]);
+                               if (clip.IntersectsWith (control.Items[i].GetBounds (ItemBoundsPortion.Entire))) {
+#if NET_2_0
+                                       bool owner_draw = false;
+                                       if (control.OwnerDraw)
+                                               owner_draw = DrawListViewItemOwnerDraw (dc, control.Items [i], i);
+                                       if (!owner_draw)
+#endif
+                                               DrawListViewItem (dc, control, control.Items [i]);
+                               }
                        }       
+
+#if NET_2_0
+                       // draw group headers
+                       if (control.ShowGroups && control.View != View.List) {
+                               for (int i = 0; i < control.Groups.Count; i++) {
+                                       ListViewGroup group = control.Groups [i];
+                                       if (group.Items.Count > 0 && clip.IntersectsWith (group.HeaderBounds))
+                                               DrawListViewGroupHeader (dc, control, group);
+                               }
+                       }
+#endif
                        
                        // draw the gridlines
                        if (details && control.GridLines) {
@@ -2265,7 +2518,7 @@ namespace System.Windows.Forms
                                dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect);
 
                }
-               
+
                public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
                {       
                        bool details = (control.View == View.Details);
@@ -2278,12 +2531,21 @@ namespace System.Windows.Forms
                                        foreach (ColumnHeader col in control.Columns) {
                                                Rectangle rect = col.Rect;
                                                rect.X -= control.h_marker;
+
+#if NET_2_0
+                                               bool owner_draw = false;
+                                               if (control.OwnerDraw)
+                                                       owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect);
+                                               if (owner_draw)
+                                                       continue;
+#endif
+
                                                ButtonState state;
                                                if (control.HeaderStyle == ColumnHeaderStyle.Clickable)
                                                        state = col.Pressed ? ButtonState.Pushed : ButtonState.Normal;
                                                else
                                                        state = ButtonState.Flat;
-                                               this.CPDrawButton (dc, rect, state);
+                                               CPDrawButton (dc, rect, state);
                                                rect.X += 8;
                                                rect.Width -= 13;
                                                if (rect.Width <= 0)
@@ -2324,6 +2586,49 @@ namespace System.Windows.Forms
                        dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
                }
 
+#if NET_2_0
+               protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
+               {
+                       ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
+                       if (column.Pressed)
+                               state |= ListViewItemStates.Selected;
+
+                       DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
+                                       bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
+                       control.OnDrawColumnHeader (args);
+
+                       return !args.DrawDefault;
+               }
+
+               protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
+               {
+                       ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
+                       if (item.Selected)
+                               item_state |= ListViewItemStates.Selected;
+                       if (item.Focused)
+                               item_state |= ListViewItemStates.Focused;
+                                               
+                       DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
+                                       item, item.Bounds, index, item_state);
+                       item.ListView.OnDrawItem (args);
+
+                       if (args.DrawDefault)
+                               return false;
+
+                       if (item.ListView.View == View.Details)
+                               for (int i = 0; i < item.SubItems.Count; i++) {
+                                       int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
+                                       
+                                       // Do system drawing for subitems if no owner draw is done
+                                       for (int j = 0; j < count; j++)
+                                               if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j))
+                                                       DrawListViewSubItem (dc, item.ListView, item, j);
+                               }
+
+                       return true;
+               }
+#endif
+
                protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
                {                               
                        Rectangle rect_checkrect = item.CheckRectReal;
@@ -2359,24 +2664,34 @@ namespace System.Windows.Forms
                                                // adjustments to get the check-mark at the right place
                                                rect.X ++; rect.Y ++;
                                                // following logic is taken from DrawFrameControl method
+                                               int x_offset = rect.Width / 5;
+                                               int y_offset = rect.Height / 3;
                                                for (int i = 0; i < check_wd; i++) {
-                                                       dc.DrawLine (check_pen, rect.Left + check_wd / 2,
-                                                                    rect.Top + check_wd + i,
-                                                                    rect.Left + check_wd / 2 + 2 * scale,
-                                                                    rect.Top + check_wd + 2 * scale + i);
+                                                       dc.DrawLine (check_pen, rect.Left + x_offset,
+                                                                    rect.Top + y_offset + i,
+                                                                    rect.Left + x_offset + 2 * scale,
+                                                                    rect.Top + y_offset + 2 * scale + i);
                                                        dc.DrawLine (check_pen,
-                                                                    rect.Left + check_wd / 2 + 2 * scale,
-                                                                    rect.Top + check_wd + 2 * scale + i,
-                                                                    rect.Left + check_wd / 2 + 6 * scale,
-                                                                    rect.Top + check_wd - 2 * scale + i);
+                                                                    rect.Left + x_offset + 2 * scale,
+                                                                    rect.Top + y_offset + 2 * scale + i,
+                                                                    rect.Left + x_offset + 6 * scale,
+                                                                    rect.Top + y_offset - 2 * scale + i);
                                                }
                                        }
                                }
                                else {
-                                       if (item.Checked && control.StateImageList.Images.Count > 1)
-                                               control.StateImageList.Draw (dc, rect_checkrect.Location, 1);
-                                       else if (control.StateImageList.Images.Count > 0)
-                                               control.StateImageList.Draw (dc, rect_checkrect.Location, 0);
+                                       int simage_idx;
+                                       if (item.Checked)
+#if NET_2_0
+                                               simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
+#else
+                                               simage_idx = control.StateImageList.Images.Count > 1 ? 1 : 0;
+#endif
+                                       else
+                                               simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
+
+                                       if (simage_idx > -1)
+                                               control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
                                }
                        }
 
@@ -2416,15 +2731,20 @@ namespace System.Windows.Forms
                        else
                                format.FormatFlags = StringFormatFlags.NoWrap;
 
+                       if ((control.View == View.LargeIcon && !item.Focused)
+                                       || control.View == View.Details 
+#if NET_2_0
+                                       || control.View == View.Tile
+#endif
+                          )
+                               format.Trimming = StringTrimming.EllipsisCharacter;
+
                        Rectangle highlight_rect = text_rect;
                        if (control.View == View.Details) { // Adjustments for Details view
                                Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
 
                                if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
                                        highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
-
-                               if (text_size.Width > text_rect.Width)
-                                       format.Trimming = StringTrimming.EllipsisCharacter;
                        }
 
                        if (item.Selected && control.Focused)
@@ -2459,10 +2779,16 @@ namespace System.Windows.Forms
 #endif
                        
                        if (item.Text != null && item.Text.Length > 0) {
+                               Font font = item.Font;
+#if NET_2_0
+                               if (control.HotTracking && item.Hot)
+                                       font = item.HotFont;
+#endif
+
                                if (item.Selected && control.Focused)
-                                       dc.DrawString (item.Text, item.Font, textBrush, highlight_rect, format);
+                                       dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
                                else
-                                       dc.DrawString (item.Text, item.Font, textBrush, text_rect, format);
+                                       dc.DrawString (item.Text, font, textBrush, text_rect, format);
                        }
 
                        if (control.View == View.Details && control.Columns.Count > 0) {
@@ -2472,71 +2798,15 @@ namespace System.Windows.Forms
                                             control.Columns.Count : subItems.Count);
 
                                if (count > 0) {
-                                       ColumnHeader col;
-                                       ListViewItem.ListViewSubItem subItem;
-                                       Rectangle sub_item_rect = text_rect; 
-
-                                       // set the format for subitems
-                                       format.FormatFlags = StringFormatFlags.NoWrap;
-
                                        // 0th subitem is the item already drawn
-                                       for (int index = 1; index < count; index++) {
-                                               subItem = subItems [index];
-                                               col = control.Columns [index];
-                                               format.Alignment = col.Format.Alignment;
-                                               sub_item_rect.X = col.Rect.X - control.h_marker;
-                                               sub_item_rect.Width = col.Wd;
-                                               Rectangle sub_item_text_rect = sub_item_rect;
-                                               sub_item_text_rect.X += 3;
-                                               sub_item_text_rect.Width -= 6;
-
-                                               SolidBrush sub_item_back_br = null;
-                                               SolidBrush sub_item_fore_br = null;
-                                               Font sub_item_font = null;
-
-                                               if (item.UseItemStyleForSubItems) {
-                                                       sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
-                                                       sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
-                                                       sub_item_font = item.Font;
-                                               } else {
-                                                       sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
-                                                       sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
-                                                       sub_item_font = subItem.Font;
-                                               }
-
-                                               int sub_item_text_width = (int) Math.Ceiling (control.DeviceContext.MeasureString (subItem.Text,
-                                                               sub_item_font).Width);
-
-                                               format.Trimming = sub_item_text_width > sub_item_text_rect.Width ? StringTrimming.EllipsisCharacter :
-                                                       StringTrimming.None;
-
-                                               if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
-                                                       Brush bg, text;
-                                                       if (control.Focused) {
-                                                               bg = SystemBrushes.Highlight;
-                                                               text = SystemBrushes.HighlightText;
-                                                       } else {
-                                                               bg = SystemBrushes.Control;
-                                                               text = sub_item_fore_br;
-                                                       }
-                                       
-                                                       dc.FillRectangle (bg, sub_item_rect);
-                                                       if (subItem.Text != null && subItem.Text.Length > 0)
-                                                               dc.DrawString (subItem.Text, sub_item_font,
-                                                                              text, sub_item_text_rect, format);
-                                               } else {
-                                                       dc.FillRectangle (sub_item_back_br, sub_item_rect);
-                                                       if (subItem.Text != null && subItem.Text.Length > 0)
-                                                               dc.DrawString (subItem.Text, sub_item_font,
-                                                                              sub_item_fore_br,
-                                                                              sub_item_text_rect, format);
-                                               }
-                                       }
+                                       for (int index = 1; index < count; index++)
+                                               DrawListViewSubItem (dc, control, item, index);
 
                                        // Fill in selection for remaining columns if Column.Count > SubItems.Count
+                                       ColumnHeader col;
+                                       Rectangle sub_item_rect = text_rect;
                                        if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
-                                               for (int index = count; index < control.Columns.Count; index++)
-                                               {
+                                               for (int index = count; index < control.Columns.Count; index++) {
                                                        col = control.Columns [index];
                                                        sub_item_rect.X = col.Rect.X - control.h_marker;
                                                        sub_item_rect.Width = col.Wd;
@@ -2566,6 +2836,117 @@ namespace System.Windows.Forms
                        format.Dispose ();
                }
 
+               protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
+               {
+                       ListViewItem.ListViewSubItem subItem = item.SubItems [index];
+                       ColumnHeader col = control.Columns [index];
+                       StringFormat format = new StringFormat ();
+                       format.Alignment = col.Format.Alignment;
+                       format.FormatFlags = StringFormatFlags.NoWrap;
+                       format.Trimming = StringTrimming.EllipsisCharacter;
+
+                       Rectangle sub_item_rect = subItem.Bounds;
+                       Rectangle sub_item_text_rect = sub_item_rect;
+                       sub_item_text_rect.X += 3;
+                       sub_item_text_rect.Width -= 6;
+                                               
+                       SolidBrush sub_item_back_br = null;
+                       SolidBrush sub_item_fore_br = null;
+                       Font sub_item_font = null;
+                                               
+                       if (item.UseItemStyleForSubItems) {
+                               sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
+                               sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
+#if NET_2_0
+                               // Hot tracking for subitems only applies when UseStyle is true
+                               if (control.HotTracking && item.Hot)
+                                       sub_item_font = item.HotFont;
+                               else
+#endif
+                                       sub_item_font = item.Font;
+                       } else {
+                               sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
+                               sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
+                               sub_item_font = subItem.Font;
+                       }
+                                               
+                       if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
+                               Brush bg, text;
+                               if (control.Focused) {
+                                       bg = SystemBrushes.Highlight;
+                                       text = SystemBrushes.HighlightText;
+                               } else {
+                                       bg = SystemBrushes.Control;
+                                       text = sub_item_fore_br;
+                                                       
+                               }
+                                                       
+                               dc.FillRectangle (bg, sub_item_rect);
+                               if (subItem.Text != null && subItem.Text.Length > 0)
+                                       dc.DrawString (subItem.Text, sub_item_font,
+                                                       text, sub_item_text_rect, format);
+                       } else {
+                               dc.FillRectangle (sub_item_back_br, sub_item_rect);
+                               if (subItem.Text != null && subItem.Text.Length > 0)
+                                       dc.DrawString (subItem.Text, sub_item_font,
+                                                       sub_item_fore_br,
+                                                       sub_item_text_rect, format);
+                       }
+
+                       format.Dispose ();
+               }
+
+#if NET_2_0
+               protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
+               {
+                       ListView control = item.ListView;
+                       ListViewItem.ListViewSubItem subitem = item.SubItems [index];
+
+                       DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, 
+                                       subitem, item.Index, index, control.Columns [index], state);
+                       control.OnDrawSubItem (args);
+                       
+                       return !args.DrawDefault;
+               }
+
+               protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
+               {
+                       Rectangle text_bounds = group.HeaderBounds;
+                       Rectangle header_bounds = group.HeaderBounds;
+                       text_bounds.Offset (8, 0);
+                       text_bounds.Inflate (-8, 0);
+                       Size text_size = control.text_size;
+
+                       Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
+                       Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), 
+                                       SystemColors.Desktop, Color.White);
+                       Pen pen = new Pen (brush);
+
+                       StringFormat sformat = new StringFormat ();
+                       switch (group.HeaderAlignment) {
+                               case HorizontalAlignment.Left:
+                                       sformat.Alignment = StringAlignment.Near;
+                                       break;
+                               case HorizontalAlignment.Center:
+                                       sformat.Alignment = StringAlignment.Center;
+                                       break;
+                               case HorizontalAlignment.Right:
+                                       sformat.Alignment = StringAlignment.Far;
+                                       break;
+                       }
+
+                       sformat.LineAlignment = StringAlignment.Near;
+                       dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
+                       dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_size.Height, header_bounds.Left + ListViewGroupLineWidth, 
+                                       header_bounds.Top + text_size.Height);
+
+                       sformat.Dispose ();
+                       font.Dispose ();
+                       pen.Dispose ();
+                       brush.Dispose ();
+               }
+#endif
+
                // Sizing
                public override Size ListViewCheckBoxSize {
                        get { return new Size (16, 16); }
@@ -2588,7 +2969,7 @@ namespace System.Windows.Forms
                }
 
                public override int ListViewHorizontalSpacing {
-                       get { return 10; }
+                       get { return 4; }
                }
 
                public override Size ListViewDefaultSize {
@@ -2599,6 +2980,10 @@ namespace System.Windows.Forms
                        get { return 20; }
                }
 
+               public int ListViewGroupLineWidth {
+                       get { return 200; }
+               }
+
                public override int ListViewTileWidthFactor {
                        get { return 22; }
                }
@@ -2766,7 +3151,7 @@ namespace System.Windows.Forms
                        Graphics gr = Graphics.FromImage (bmp);
                        Rectangle rect = new Rectangle (Point.Empty, size);
                        gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
-                       CPDrawMenuGlyph (gr, rect, glyph, color);
+                       CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
                        bmp.MakeTransparent (bg_color);
                        gr.Dispose ();
                        
@@ -3572,7 +3957,7 @@ namespace System.Windows.Forms
 #if NET_2_0
                        case 1: { // Continuous
                                int pixels_to_draw;
-                               pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(ctrl.Maximum - ctrl.Minimum)));
+                               pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
                                dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
                                break;
                        }
@@ -3596,7 +3981,7 @@ namespace System.Windows.Forms
                                int block_count = 0;
                                
                                block_width = (client_area.Height * 2) / 3;
-                               barpos_pixels = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum);
+                               barpos_pixels = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max(ctrl.Maximum - ctrl.Minimum, 1));
                                increment = block_width + space_betweenblocks;
                                
                                block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
@@ -4368,12 +4753,16 @@ namespace System.Windows.Forms
                        StringFormat format = new StringFormat ();
                        format.Trimming = StringTrimming.EllipsisCharacter;
                        format.LineAlignment = StringAlignment.Center;
-                       format.HotkeyPrefix = MenuAccessKeysUnderlined ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
+                       if (control.ShowKeyboardCuesInternal)
+                               format.HotkeyPrefix = HotkeyPrefix.Show;
+                       else
+                               format.HotkeyPrefix = HotkeyPrefix.Hide;
+
                        if (control.TextAlign == ToolBarTextAlign.Underneath)
                                format.Alignment = StringAlignment.Center;
                        else
                                format.Alignment = StringAlignment.Near;
-
+#if !NET_2_0
                        if (control is PropertyGrid.PropertyToolBar) {
                                dc.FillRectangle (ResPool.GetSolidBrush(control.BackColor), clip_rectangle);
                                
@@ -4393,7 +4782,7 @@ namespace System.Windows.Forms
                                        dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
                                }
                        } else {
-
+#endif
                                if (control.Appearance == ToolBarAppearance.Flat && control.Parent != null) {
                                        if (control.Parent.BackgroundImage != null) {
                                                using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile))
@@ -4411,7 +4800,9 @@ namespace System.Windows.Forms
                                        }
                                        dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
                                }
+#if !NET_2_0
                        }
+#endif
 
                        foreach (ToolBarItem item in control.items)
                                if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
@@ -4619,17 +5010,33 @@ namespace System.Windows.Forms
                #endregion      // ToolBar
 
                #region ToolTip
-               public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) {
-                       dc.FillRectangle(SystemBrushes.Info, control.ClientRectangle);
-                       dc.DrawRectangle(SystemPens.WindowFrame, 0, 0, control.Width-1, control.Height-1);
-                       dc.DrawString(control.Text, control.Font, ResPool.GetSolidBrush(this.ColorInfoText), control.ClientRectangle, control.string_format);
+               public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
+               {
+                       Rectangle text_rect = Rectangle.Inflate (control.ClientRectangle, -2, -1);
+
+#if NET_2_0
+                       Brush back_brush = ResPool.GetSolidBrush (control.BackColor);;
+                       Color foreground = control.ForeColor;
+#else
+                       Brush back_brush = SystemBrushes.Info;
+                       Color foreground = this.ColorInfoText;
+#endif
+
+                       dc.FillRectangle (back_brush, control.ClientRectangle);
+                       dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
+
+                       TextFormatFlags flags = TextFormatFlags.HidePrefix | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
+                       TextRenderer.DrawTextInternal (dc, control.Text, control.Font, text_rect, foreground, flags, false);
                }
 
-               public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) {
-                       SizeF   sizef;
+               public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
+               {
+                       Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
 
-                       sizef = tt.DeviceContext.MeasureString(text, tt.Font, SizeF.Empty, tt.string_format);
-                       return new Size((int)sizef.Width+8, (int)sizef.Height+3);       // Need space for the border
+                       size.Width += 8;
+                       size.Height += 3;
+                       
+                       return size;
                }
                #endregion      // ToolTip
 
@@ -4722,8 +5129,8 @@ namespace System.Windows.Forms
                        Rectangle deskrect = Screen.GetWorkingArea (control);
                        SizeF maxsize = new SizeF (250, 200);
 
-                       SizeF titlesize = control.DeviceContext.MeasureString (control.Title, control.Font, maxsize, control.Format);
-                       SizeF textsize = control.DeviceContext.MeasureString (control.Text, control.Font, maxsize, control.Format);
+                       SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
+                       SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
                        
                        if (titlesize.Height < balloon_iconsize)
                                titlesize.Height = balloon_iconsize;
@@ -5264,7 +5671,10 @@ namespace System.Windows.Forms
 
                public override int ManagedWindowBorderWidth (InternalWindowManager wm)
                {
-                       return 4;
+                       if (wm is ToolWindowManager && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow)
+                               return 3;
+                       else
+                               return 4;
                }
 
                public override int ManagedWindowIconWidth (InternalWindowManager wm)
@@ -5480,6 +5890,16 @@ namespace System.Windows.Forms
                        DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
                }
 
+               public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
+                       ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
+                       Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
+                       int bottomWidth, ButtonBorderStyle bottomStyle) {
+                       DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
+                       DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
+                       DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
+                       DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
+               }
+
                public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
                        CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
                }
@@ -5717,7 +6137,10 @@ namespace System.Windows.Forms
                                cb_rect.Width -= 2;
                                cb_rect.Height -= 2;
                                
-                               dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
+                               if ((state & ButtonState.Inactive) == ButtonState.Inactive)
+                                       dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
+                               else
+                                       dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
                                dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
                        } else {
                                cb_rect.Width -= 1;
@@ -5769,7 +6192,7 @@ namespace System.Windows.Forms
                                        int lineWidth = Math.Max (3, check_size / 3);
                                        int Scale = Math.Max (1, check_size / 9);
                                        
-                                       Rectangle rect = new Rectangle (cb_rect.X + (cb_rect.Width / 2) - (check_size / 2) - 1, cb_rect.Y + (cb_rect.Height / 2) - (check_size / 2) - 1, 
+                                       Rectangle rect = new Rectangle (cb_rect.X + (cb_rect.Width / 2) - (int)Math.Ceiling ((float)check_size / 2) - 1, cb_rect.Y + (cb_rect.Height / 2) - (check_size / 2) - 1, 
                                                                        check_size, check_size);
                                        
                                        for (int i = 0; i < lineWidth; i++) {
@@ -6065,10 +6488,13 @@ namespace System.Windows.Forms
                }
 
 
-               public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color) {
+               public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
                        Rectangle       rect;
                        int                     lineWidth;
 
+                       if (backColor != Color.Empty)
+                               graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
+                               
                        Brush brush = ResPool.GetSolidBrush (color);
 
                        switch(glyph) {
@@ -6439,7 +6865,32 @@ namespace System.Windows.Forms
                        dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
                }
 
-               private static void DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY,
+#if NET_2_0
+               public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
+               {
+                       CPColor cpcolor = ResPool.GetCPColor (color);
+
+                       layoutRectangle.Offset (1, 1);
+                       TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
+
+                       layoutRectangle.Offset (-1, -1);
+                       TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
+               }
+
+               public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
+               {
+                       graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
+               }
+#endif
+
+               private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
+                       int width, Color color, ButtonBorderStyle style, Border3DSide side) 
+               {
+                       DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, 
+                               width, color, style, side);
+               }
+
+               private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
                        int width, Color color, ButtonBorderStyle style, Border3DSide side) {
 
                        Pen pen = null;