[Mono-winforms-list] Patch: Normal Button Rendering fixes

John BouAntoun jba-mono@optusnet.com.au
Wed, 27 Oct 2004 22:12:55 +1000


--=-8KNIoQmHHFp0yUX8+HZZ
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi guys,

This is the first part of my button rendering re-work (which it turns
out isn't going to be so extensive).

Anyhow fixes in this patch:

1) Correct outer rectangle color when drawing focus rectangle
2) Adjust button bounds to be 1 px smaller when focused
3) Make button not draw sunken 3d border when pushed (windows compat)
4) Fix CPDrawBorder3D to not make bottom right hand corner rounded
(extend border right to corner)
5) Offset the text in RadioButton and Checkbox when being rendered as a
button.

Still to come...
- Proper rendering of buttons in flatstyle
- rework of RadioButton and CheckBox Appearance.Button property to use
generic code (common to both).

Issues with this patch...
I'm not quite sure what the DrawFocusRectangle call that used to be used
is doing, because it doesn't seem to be drawing it properly. Once I get
to nut out what it's meant to do with someone more knowledgeable I'll
put it back in.

JBA

--=-8KNIoQmHHFp0yUX8+HZZ
Content-Disposition: attachment; filename=NormalButtonRenderingFixes.patch
Content-Type: text/x-patch; name=NormalButtonRenderingFixes.patch; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

? Makefile.SWF
? Makefile.solution.SWF
? NormalButtonRenderingFixes.patch
? SWF.cmbx
? SWF.mdsx
? SWF.pidb
? SWF.prjx
? make.sh
Index: System.Windows.Forms/ThemeWin32Classic.cs
===================================================================
RCS file: /cvs/public/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs,v
retrieving revision 1.51
diff -u -r1.51 ThemeWin32Classic.cs
--- System.Windows.Forms/ThemeWin32Classic.cs	26 Oct 2004 09:55:48 -0000	1.51
+++ System.Windows.Forms/ThemeWin32Classic.cs	27 Oct 2004 10:40:01 -0000
@@ -317,6 +317,7 @@
 		public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) {
 			int		width;
 			int		height;
+			Rectangle buttonRectangle;
 
 			width = button.ClientSize.Width;
 			height = button.ClientSize.Height;
@@ -324,13 +325,28 @@
 			SolidBrush	sb = new SolidBrush(button.BackColor);
 			dc.FillRectangle(sb, button.ClientRectangle);
 			sb.Dispose();
-
-			CPDrawButton(dc, button.ClientRectangle, button.ButtonState);
-
-			if (button.has_focus) {
-				CPDrawFocusRectangle(dc, button.ClientRectangle, ColorButtonText, ColorButtonFace);
+			
+			// set up the button rectangle
+			buttonRectangle = button.ClientRectangle;
+			if (button.has_focus || button.Capture) {
+				Color focusRectColor = button.ForeColor;
+				// adjust focus color according to the flatstyle
+				if (button.FlatStyle == FlatStyle.Popup && !button.Capture) {
+					focusRectColor = (button.BackColor == ColorButtonFace) ? ControlPaint.Dark(ColorButtonFace) : ColorButtonText;
+				} 
+				 
+				// draw the outer focus rectangle
+				dc.DrawRectangle(ResPool.GetPen(focusRectColor), buttonRectangle);
+				
+				// TODO: draw the inner focus rectangle
+				
+				// shrink the rectangle for the normal button drawing inside the focus rectangle
+				buttonRectangle = new Rectangle (buttonRectangle.X + 1, buttonRectangle.Y + 1, Math.Max(buttonRectangle.Width-2, 0), Math.Max(buttonRectangle.Height-2, 0));
 			}
 
+			
+			CPDrawButton(dc, buttonRectangle, button.ButtonState);
+			
 			// First, draw the image
 			if ((button.image != null) || (button.image_list != null)) {
 				// Need to draw a picture
@@ -626,15 +642,15 @@
 			dc.FillRectangle(sb, checkbox.ClientRectangle);
 			sb.Dispose();
 
-			// establish if we are rendering a flat style of some sort
-			if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
-				DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
-			} else {
-				// render as per normal
-				if (checkbox.appearance!=Appearance.Button) {
-					ControlPaint.DrawCheckBox(dc, checkbox_rectangle, state);
+			// render as per normal button
+			if (checkbox.appearance==Appearance.Button) {
+				ControlPaint.DrawButton(dc, text_rectangle, state);
+			} else {
+				// establish if we are rendering a flat style of some sort
+				if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
+					DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
 				} else {
-					ControlPaint.DrawButton(dc, text_rectangle, state);
+					ControlPaint.DrawCheckBox(dc, checkbox_rectangle, state);
 				}
 			}
 			
@@ -1206,25 +1222,46 @@
 			dc.FillRectangle(sb, radio_button.ClientRectangle);
 			sb.Dispose();
 			
-			// establish if we are rendering a flat style of some sort
-			if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
-				DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
+		
+			
+			if (radio_button.appearance==Appearance.Button) {
+				CPDrawButton (dc, text_rectangle, state);
 			} else {
-				// render as per normal
-				if (radio_button.appearance!=Appearance.Button) {
-					ControlPaint.DrawRadioButton (dc, radiobutton_rectangle, state);
+				// establish if we are rendering a flat style of some sort
+				if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
+					DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
 				} else {
-					ControlPaint.DrawButton (dc, text_rectangle, state);
+					ControlPaint.DrawRadioButton (dc, radiobutton_rectangle, state);
 				}
 			}
 			
 			// wind32 compat - win32 seems to give the text a slight (3px) offset when rendering
-			Rectangle inner_text_rectangle = new Rectangle (text_rectangle.X + 3, text_rectangle.Y, Math.Max (text_rectangle.Width - 3, 0), text_rectangle.Height); 
+			Rectangle inner_text_rectangle = new Rectangle (text_rectangle.X + 3, text_rectangle.Y, Math.Max (text_rectangle.Width - 3, 0), text_rectangle.Height);
+			// offset the text if it's pressed and a button
+			if (radio_button.Appearance == Appearance.Button) {
+				int buttonXOffset = 2;
+				int buttonYOffset = 0;
+				int pressedOffset = 0;
+				
+				if (radio_button.Checked || (radio_button.Capture && radio_button.FlatStyle != FlatStyle.Flat)) {
+					pressedOffset += 2;
+				}
+				
+				inner_text_rectangle = new Rectangle (inner_text_rectangle.X + buttonXOffset + pressedOffset, inner_text_rectangle.Y + buttonYOffset + pressedOffset, inner_text_rectangle.Width - 2*buttonXOffset, inner_text_rectangle.Height - 2*buttonYOffset); 
+			} 
 
 			/* Place the text; to be compatible with Windows place it after the radiobutton has been drawn */
 			sb=new SolidBrush(radio_button.ForeColor);
 			dc.DrawString (radio_button.Text, radio_button.Font, sb, inner_text_rectangle, text_format);
 			sb.Dispose();
+			if (radio_button.Enabled) {
+				sb = ResPool.GetSolidBrush(radio_button.ForeColor);
+				dc.DrawString(radio_button.Text, radio_button.Font, sb, inner_text_rectangle, text_format);				
+			} else if (radio_button.FlatStyle == FlatStyle.Flat) {
+				dc.DrawString(radio_button.Text, radio_button.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorButtonFace)), inner_text_rectangle, text_format);
+			} else {
+				CPDrawStringDisabled(dc, radio_button.Text, radio_button.Font, this.ColorButtonText, inner_text_rectangle, text_format);
+			}
 
 			if (radio_button.Focused) {
 				ControlPaint.DrawFocusRectangle(dc, text_rectangle);
@@ -2375,21 +2430,21 @@
 
 				if (doInner) {
 					if ((sides & Border3DSide.Left)!=0) {
-						graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Top+1, rect.Right-1, rect.Top+1);
+						graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Top+1, rect.Right-2, rect.Top+1);
 					} else {
-						graphics.DrawLine(penTopLeftInner, rect.Left, rect.Top+1, rect.Right-1, rect.Top+1);
+						graphics.DrawLine(penTopLeftInner, rect.Left, rect.Top+1, rect.Right-2, rect.Top+1);
 					}
 				}
 			}
 
 			if ((sides & Border3DSide.Right)!=0) {
-				graphics.DrawLine(penBottomRight, rect.Right-1, rect.Top, rect.Right-1, rect.Bottom-1);
+				graphics.DrawLine(penBottomRight, rect.Right, rect.Top, rect.Right, rect.Bottom);
 
 				if (doInner) {
 					if ((sides & Border3DSide.Top)!=0) {
-						graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top+1, rect.Right-2, rect.Bottom-1);
+						graphics.DrawLine(penBottomRightInner, rect.Right-1, rect.Top+1, rect.Right-1, rect.Bottom-1);
 					} else {
-						graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top, rect.Right-2, rect.Bottom-1);
+						graphics.DrawLine(penBottomRightInner, rect.Right-1, rect.Top, rect.Right-1, rect.Bottom-1);
 					}
 				}
 			}
@@ -2401,13 +2456,13 @@
 					left+=1;
 				}
 
-				graphics.DrawLine(penBottomRight, rect.Left, rect.Bottom-1, rect.Right-1, rect.Bottom-1);
+				graphics.DrawLine(penBottomRight, rect.Left, rect.Bottom, rect.Right, rect.Bottom);
 
 				if (doInner) {
 					if ((sides & Border3DSide.Right)!=0) {
-						graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-2, rect.Bottom-2);
+						graphics.DrawLine(penBottomRightInner, left, rect.Bottom-1, rect.Right-1, rect.Bottom-1);
 					} else {
-						graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-1, rect.Bottom-2);
+						graphics.DrawLine(penBottomRightInner, left, rect.Bottom-1, rect.Right, rect.Bottom-1);
 					}
 				}
 			}
@@ -3295,7 +3350,8 @@
 					}
 
 					if ((State & DrawFrameControlStates.Pushed)!=0) {
-						CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
+						//CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
+						graphics.DrawRectangle (ResPool.GetPen (ControlPaint.Dark (ColorButtonFace)), rectangle);
 					} else if ((State & DrawFrameControlStates.Flat)!=0) {
 						ControlPaint.DrawBorder(graphics, rectangle, ColorButtonShadow, ButtonBorderStyle.Solid);
 					} else if ((State & DrawFrameControlStates.Inactive)!=0) {

--=-8KNIoQmHHFp0yUX8+HZZ--