[Mono-winforms-list] RadioButton fixes

John BouAntoun jba-mono@optusnet.com.au
Thu, 30 Sep 2004 23:22:19 +1000


--=-xZ8vVhL9UCsK1sK6eBtT
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hey guys,

I have completed a series of RadioButton rendering and other issue
fixes.

Below is a listing of all the fixes:

1) Render background for radio button knob with Window color.
2) Render outer circle as 1 pixel wide (not 2)
3) Render FlatStyle.Flat correctly
4) Render FlatStyle.Popup correctly (including hover effect)
5) Fix Appearance property setter not setting property properly.
5) Render Text string with same horizontal offset (distance from edge of
rectangle) as on windows.

If someone could look over and apply it, or comment about any bad
changes I'd appreciate it. If this gets checked in I'm going to move
onto regular button FlatStyle rendering.

JBA

--=-xZ8vVhL9UCsK1sK6eBtT
Content-Disposition: attachment; filename=RadioButtonFixes.patch
Content-Type: text/x-patch; name=RadioButtonFixes.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

? RadioButtonFixes.patch
Index: System.Windows.Forms/RadioButton.cs
===================================================================
RCS file: /cvs/public/mcs/class/Managed.Windows.Forms/System.Windows.Forms/RadioButton.cs,v
retrieving revision 1.4
diff -u -r1.4 RadioButton.cs
--- System.Windows.Forms/RadioButton.cs	28 Sep 2004 18:44:25 -0000	1.4
+++ System.Windows.Forms/RadioButton.cs	30 Sep 2004 10:59:29 -0000
@@ -136,7 +136,7 @@
 
 			set {
 				if (value != appearance) {
-					value = appearance;
+					appearance = value;
 					if (AppearanceChanged != null) {
 						AppearanceChanged(this, EventArgs.Empty);
 					}
Index: System.Windows.Forms/ThemeWin32Classic.cs
===================================================================
RCS file: /cvs/public/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs,v
retrieving revision 1.38
diff -u -r1.38 ThemeWin32Classic.cs
--- System.Windows.Forms/ThemeWin32Classic.cs	28 Sep 2004 18:44:25 -0000	1.38
+++ System.Windows.Forms/ThemeWin32Classic.cs	30 Sep 2004 10:59:30 -0000
@@ -921,16 +921,25 @@
 			sb=new SolidBrush(radio_button.BackColor);
 			dc.FillRectangle(sb, radio_button.ClientRectangle);
 			sb.Dispose();
-
-			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);
+				// render as per normal
+				if (radio_button.appearance!=Appearance.Button) {
+					ControlPaint.DrawRadioButton(dc, radiobutton_rectangle, state);
+				} else {
+					ControlPaint.DrawButton(dc, text_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); 
 
 			/* 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, text_rectangle, text_format);
+			dc.DrawString(radio_button.Text, radio_button.Font, sb, inner_text_rectangle, text_format);
 			sb.Dispose();
 
 			if (radio_button.Focused) {
@@ -943,10 +952,49 @@
 				return new Size(104,24);
 			}
 		}
+		
+		// renders a radio button with the Flat and Popup FlatStyle
+		private void DrawFlatStyleRadioButton(Graphics graphics, Rectangle rectangle, RadioButton radio_button)
+		{
+			int	lineWidth;
+			
+			// win32 compat fill in the background of the knob
+			graphics.FillPie(ResPool.GetSolidBrush(SystemColors.Window), rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
+			
+			// draw the outer flatstyle arcs
+			if (radio_button.FlatStyle == FlatStyle.Flat) {
+				graphics.DrawArc(ResPool.GetPen(SystemColors.ControlText), rectangle, 0, 359);
+			} else {
+				// must be a popup radio button
+				if (radio_button.is_entered) {
+					// draw the popup 3d button knob
+					graphics.DrawArc(SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
+
+					graphics.DrawArc(SystemPens.ControlDark, rectangle, 135, 180);
+					graphics.DrawArc(SystemPens.ControlLightLight, rectangle, 315, 180);
+				} else {
+					// just draw lighter flatstyle outer circle
+					graphics.DrawArc(SystemPens.ControlDark, rectangle, 0, 359);
+				}
+			}
+
+			// draw the check
+			lineWidth=Math.Max(1, Math.Min(rectangle.Width, rectangle.Height)/3);
+			if (radio_button.Checked) {
+				SolidBrush	buttonBrush;
+
+				if (!radio_button.Enabled) {
+					buttonBrush=(SolidBrush)SystemBrushes.ControlDark;
+				} else {
+					buttonBrush=(SolidBrush)SystemBrushes.ControlText;
+				}
+				graphics.FillPie(buttonBrush, rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2, 0, 359);
+			}			
+		}
 		#endregion	// RadioButton
 
 		#region ScrollBar
-		public override void DrawScrollBar(Graphics dc, Rectangle clip_rectangle, ScrollBar bar) {
+		public override void DrawScrollBar(Graphics dc, Rectangle clip_rectangle, ScrollBar bar) {
 			int		scrollbutton_width = bar.scrollbutton_width;
 			int		scrollbutton_height = bar.scrollbutton_height;
 			Rectangle	first_arrow_area;
@@ -2958,10 +3006,15 @@
 						CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom);
 					}
 				} else if ((State & DrawFrameControlStates.ButtonRadio)!=0) {
-					Pen			penFatDark	= new Pen(ColorButtonShadow, 2);
-					Pen			penFatLight	= new Pen(SystemColors.ControlLight, 2);
+					// win32 compat, the brushes aren't actually fat, i think they are 1 pixel wide
+					Pen			penFatDark	= new Pen(ColorButtonShadow, 1);
+					Pen			penFatLight	= new Pen(SystemColors.ControlLight, 1);
 					int			lineWidth;
 
+					// win32 compat fill in the background of the knob
+					graphics.FillPie(ResPool.GetSolidBrush(SystemColors.Window), rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
+					
+					// draw the rest of the radiobutton knob
 					graphics.DrawArc(penFatDark, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 135, 180);
 					graphics.DrawArc(penFatLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 315, 180);
 

--=-xZ8vVhL9UCsK1sK6eBtT--