TabControlPainter.cs: Horizontally center Text and Image when SizeMode = Fixed.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms.Theming / Default / TabControlPainter.cs
index a841863ddc801608ac59ba3c12bff698fbee715c..f3d4e9f181e792a7b2a5d9f8bedccbce0377f6ab 100644 (file)
@@ -24,7 +24,9 @@
 \r
 using System;\r
 using System.Drawing;\r
+using System.Drawing.Text;\r
 using System.Windows.Forms;\r
+using System.Windows.Forms.VisualStyles;\r
 \r
 namespace System.Windows.Forms.Theming.Default\r
 {\r
@@ -165,8 +167,8 @@ namespace System.Windows.Forms.Theming.Default
 \r
                public TabControlPainter ()\r
                {\r
-                       defaultItemSize = new Size (42, 21);\r
-                       defaultPadding = new Point (8, 3);\r
+                       defaultItemSize = new Size (42, 16);\r
+                       defaultPadding = new Point (6, 3);\r
                        selectedTabDelta = new Rectangle (2, 2, 4, 3);\r
                        selectedSpacing = 0;\r
 \r
@@ -186,9 +188,11 @@ namespace System.Windows.Forms.Theming.Default
                        imagePadding = new Point (2, 3);\r
 \r
                        defaultFormatting = new StringFormat();\r
-                       defaultFormatting.Alignment = StringAlignment.Center;\r
-                       defaultFormatting.LineAlignment = StringAlignment.Near;\r
+                       // Horizontal Alignment is handled in the Draw method\r
+                       defaultFormatting.Alignment = StringAlignment.Near;\r
+                       defaultFormatting.LineAlignment = StringAlignment.Center;\r
                        defaultFormatting.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip;\r
+                       defaultFormatting.HotkeyPrefix = HotkeyPrefix.Show;\r
 \r
                        borderThickness = new Rectangle (1, 1, 2, 2);\r
                }\r
@@ -226,16 +230,13 @@ namespace System.Windows.Forms.Theming.Default
                public Rectangle GetTabPanelRect (System.Windows.Forms.TabControl tab)\r
                {       \r
                        // Offset the tab page (panel) from the top corner\r
-                       Rectangle res = new Rectangle (tab.ClientRectangle.X,\r
-                               tab.ClientRectangle.Y,\r
-                               tab.ClientRectangle.Width,\r
-                               tab.ClientRectangle.Height);\r
+                       Rectangle res = tab.ClientRectangle;\r
 \r
                        if (tab.TabCount == 0)\r
                                return res;\r
 \r
                        int spacing = RowSpacing (tab).Height;\r
-                       int tabOffset = (tab.ItemSize.Height + spacing - (selectedTabDelta.Height - selectedTabDelta.Y)) * tab.RowCount;\r
+                       int tabOffset = (tab.ItemSize.Height + spacing - selectedTabDelta.Height) * tab.RowCount + selectedTabDelta.Y;\r
                        switch (tab.Alignment) {\r
                                case TabAlignment.Top:\r
                                        res.Y += tabOffset;\r
@@ -258,14 +259,7 @@ namespace System.Windows.Forms.Theming.Default
 \r
                public virtual void Draw (Graphics dc, Rectangle area, TabControl tab)\r
                {\r
-                       Brush brush = SystemBrushes.Control;\r
-                       dc.FillRectangle (brush, area);\r
-                       Rectangle panel_rect = GetTabPanelRect (tab);\r
-\r
-                       if (tab.Appearance == TabAppearance.Normal) {\r
-                               ControlPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top);\r
-                               ControlPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom);\r
-                       }\r
+                       DrawBackground (dc, area, tab);\r
 \r
                        int start = 0;\r
                        int end = tab.TabPages.Count;\r
@@ -276,6 +270,12 @@ namespace System.Windows.Forms.Theming.Default
                                end = 0;\r
                                delta = -1;\r
                        }\r
+\r
+                       if (tab.SizeMode == TabSizeMode.Fixed)\r
+                               defaultFormatting.Alignment = StringAlignment.Center;\r
+                       else\r
+                               defaultFormatting.Alignment = StringAlignment.Near;\r
+\r
                        int counter = start;\r
                        for (; counter != end; counter += delta) {\r
                                for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {\r
@@ -299,8 +299,35 @@ namespace System.Windows.Forms.Theming.Default
                        if (tab.ShowSlider) {\r
                                Rectangle right = GetRightScrollRect (tab);\r
                                Rectangle left = GetLeftScrollRect (tab);\r
-                               ControlPaint.DrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);\r
-                               ControlPaint.DrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);\r
+                               DrawScrollButton (dc, right, area, ScrollButton.Right, tab.RightSliderState);\r
+                               DrawScrollButton (dc, left, area, ScrollButton.Left, tab.LeftSliderState);\r
+                       }\r
+               }\r
+\r
+               protected virtual void DrawScrollButton (Graphics dc, Rectangle bounds, Rectangle clippingArea, ScrollButton button, PushButtonState state)\r
+               {\r
+                       ControlPaint.DrawScrollButton (dc, bounds, button, GetButtonState (state));\r
+               }\r
+\r
+               static ButtonState GetButtonState (PushButtonState state)\r
+               {\r
+                       switch (state) {\r
+                       case PushButtonState.Pressed:\r
+                               return ButtonState.Pushed;\r
+                       default:\r
+                               return ButtonState.Normal;\r
+                       }\r
+               }\r
+\r
+               protected virtual void DrawBackground (Graphics dc, Rectangle area, TabControl tab)\r
+               {\r
+                       Brush brush = SystemBrushes.Control;\r
+                       dc.FillRectangle (brush, area);\r
+                       Rectangle panel_rect = GetTabPanelRect (tab);\r
+\r
+                       if (tab.Appearance == TabAppearance.Normal) {\r
+                               ControlPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top);\r
+                               ControlPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom);\r
                        }\r
                }\r
 \r
@@ -391,16 +418,17 @@ namespace System.Windows.Forms.Theming.Default
                                }\r
                        }\r
 \r
-                       interior = new Rectangle (bounds.Left + focusRectSpacing.X + borderThickness.Left, \r
-                               bounds.Top + focusRectSpacing.Y +  + borderThickness.Top,\r
-                               bounds.Width - (focusRectSpacing.X * 2) - borderThickness.Width, \r
-                               bounds.Height - (focusRectSpacing.Y * 2) - borderThickness.Height);\r
+                       Point padding = tab.Padding;\r
+                       interior = new Rectangle (bounds.Left + padding.X - 1, // substract a little offset\r
+                               bounds.Top + padding.Y,\r
+                               bounds.Width - (padding.X * 2), \r
+                               bounds.Height - (padding.Y * 2));\r
 \r
                        if (tab.DrawMode == TabDrawMode.Normal && page.Text != null) {\r
                                if (tab.Alignment == TabAlignment.Left) {\r
                                        dc.TranslateTransform (bounds.Left, bounds.Bottom);\r
                                        dc.RotateTransform (-90);\r
-                                       dc.DrawString (page.Text, page.Font,\r
+                                       dc.DrawString (page.Text, tab.Font,\r
                                                SystemBrushes.ControlText, \r
                                                tab.Padding.X - 2, // drawstring adds some extra unwanted leading spaces, so trimming\r
                                                tab.Padding.Y,\r
@@ -409,7 +437,7 @@ namespace System.Windows.Forms.Theming.Default
                                } else if (tab.Alignment == TabAlignment.Right) {\r
                                        dc.TranslateTransform (bounds.Right, bounds.Top);\r
                                        dc.RotateTransform (90);\r
-                                       dc.DrawString (page.Text, page.Font,\r
+                                       dc.DrawString (page.Text, tab.Font,\r
                                                SystemBrushes.ControlText, \r
                                                tab.Padding.X - 2, // drawstring adds some extra unwanted leading spaces, so trimming\r
                                                tab.Padding.Y,\r
@@ -418,13 +446,24 @@ namespace System.Windows.Forms.Theming.Default
                                } else {\r
                                        Rectangle str_rect = interior;\r
 \r
-                                       if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {
-                                               int image_y = interior.Y + (interior.Height - tab.ImageList.ImageSize.Height) / 2;\r
-                                               tab.ImageList.Draw (dc, new Point (interior.X, image_y), page.ImageIndex);\r
+                                       if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {\r
+                                               int image_x;\r
+                                               if (tab.SizeMode != TabSizeMode.Fixed) {\r
+                                                       image_x = str_rect.X;\r
+                                               }\r
+                                               else {\r
+                                                       image_x = str_rect.X + (str_rect.Width - tab.ImageList.ImageSize.Width) / 2;\r
+                                                       if (page.Text != null) {\r
+                                                               SizeF textSize = dc.MeasureString(page.Text, page.Font, str_rect.Size);\r
+                                                               image_x -= (int)(textSize.Width / 2);\r
+                                                       }\r
+                                               }\r
+                                               int image_y = str_rect.Y + (str_rect.Height - tab.ImageList.ImageSize.Height) / 2;\r
+                                               tab.ImageList.Draw (dc, new Point (image_x, image_y), page.ImageIndex);\r
                                                str_rect.X += tab.ImageList.ImageSize.Width + 2;\r
                                                str_rect.Width -= tab.ImageList.ImageSize.Width + 2;\r
                                        }\r
-                                       dc.DrawString (page.Text, page.Font,\r
+                                       dc.DrawString (page.Text, tab.Font,\r
                                                SystemBrushes.ControlText,\r
                                                str_rect, \r
                                                defaultFormatting);\r
@@ -441,11 +480,18 @@ namespace System.Windows.Forms.Theming.Default
                                return res;\r
                        }\r
 \r
+                       // TabControl ignores the value of ShowFocusCues\r
                        if (page.Parent.Focused && is_selected) {\r
-                               ThemeEngine.Current.CPDrawFocusRectangle (dc, interior, tab.ForeColor, tab.BackColor);\r
+                               Rectangle focus_rect = bounds;\r
+                               focus_rect.Inflate (-2, -2);\r
+                               ThemeEngine.Current.CPDrawFocusRectangle (dc, focus_rect, tab.BackColor, tab.ForeColor);\r
                        }\r
 \r
                        return res;\r
                }\r
+\r
+               public virtual bool HasHotElementStyles (TabControl tabControl) {\r
+                       return false;\r
+               }\r
        }\r
 }\r