1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //	Jordi Mas i Hernandez, jordi@ximian.com
24 //	Peter Bartok, pbartok@novell.com
25 //	John BouAntoun, jba-mono@optusnet.com.au
26 //	Marek Safar, marek.safar@seznam.cz
27 //	Alexander Olk, alex.olk@googlemail.com
28 //
29 
30 using System.ComponentModel;
31 using System.Data;
32 using System.Drawing;
33 using System.Drawing.Drawing2D;
34 using System.Drawing.Imaging;
35 using System.Drawing.Printing;
36 using System.Drawing.Text;
37 using System.Text;
38 using System.Windows.Forms.Theming;
39 
40 namespace System.Windows.Forms
41 {
42 
43 	internal class ThemeWin32Classic : Theme
44 	{
45 		public override Version Version {
46 			get {
47 				return new Version(0, 1, 0, 0);
48 			}
49 		}
50 
51 		/* Hardcoded colour values not exposed in the API constants in all configurations */
52 		protected static readonly Color arrow_color = Color.Black;
53 		protected static readonly Color pen_ticks_color = Color.Black;
54 		protected static StringFormat string_format_menu_text;
55 		protected static StringFormat string_format_menu_shortcut;
56 		protected static StringFormat string_format_menu_menubar_text;
57 		static ImageAttributes imagedisabled_attributes;
58 		Font window_border_font;
59 		const int SEPARATOR_HEIGHT = 6;
60 		const int SEPARATOR_MIN_WIDTH = 20;
61 		const int SM_CXBORDER = 1;
62 		const int SM_CYBORDER = 1;
63 		const int MENU_TAB_SPACE = 8;		// Pixels added to the width of an item because of a tabd
64 		const int MENU_BAR_ITEMS_SPACE = 8;	// Space between menu bar items
65 		const int CheckSize = 13;
66 
67 		#region	Principal Theme Methods
ThemeWin32Classic()68 		public ThemeWin32Classic ()
69 		{
70 			ResetDefaults ();
71 		}
72 
ResetDefaults()73 		public override void ResetDefaults() {
74 			defaultWindowBackColor = this.ColorWindow;
75 			defaultWindowForeColor = this.ColorControlText;
76 			window_border_font = null;
77 
78 			/* Menu string formats */
79 			string_format_menu_text = new StringFormat ();
80 			string_format_menu_text.LineAlignment = StringAlignment.Center;
81 			string_format_menu_text.Alignment = StringAlignment.Near;
82 			string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show;
83 			string_format_menu_text.SetTabStops (0f, new float [] { 50f });
84 			string_format_menu_text.FormatFlags |= StringFormatFlags.NoWrap;
85 
86 			string_format_menu_shortcut = new StringFormat ();
87 			string_format_menu_shortcut.LineAlignment = StringAlignment.Center;
88 			string_format_menu_shortcut.Alignment = StringAlignment.Far;
89 
90 			string_format_menu_menubar_text = new StringFormat ();
91 			string_format_menu_menubar_text.LineAlignment = StringAlignment.Center;
92 			string_format_menu_menubar_text.Alignment = StringAlignment.Center;
93 			string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show;
94 		}
95 
96 		public override bool DoubleBufferingSupported {
97 			get {return true; }
98 		}
99 
100 		public override int HorizontalScrollBarHeight {
101 			get {
102 				return XplatUI.HorizontalScrollBarHeight;
103 			}
104 		}
105 
106 		public override int VerticalScrollBarWidth {
107 			get {
108 				return XplatUI.VerticalScrollBarWidth;
109 			}
110 		}
111 
112 		public override Font WindowBorderFont {
113 			get {
114 				return window_border_font ?? (window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold));
115 			}
116 		}
117 
118 		#endregion	// Principal Theme Methods
119 
120 		#region	Internal Methods
GetControlBackBrush(Color c)121 		protected Brush GetControlBackBrush (Color c) {
122 			if (c.ToArgb () == DefaultControlBackColor.ToArgb ())
123 				return SystemBrushes.Control;
124 			return ResPool.GetSolidBrush (c);
125 		}
126 
GetControlForeBrush(Color c)127 		protected Brush GetControlForeBrush (Color c) {
128 			if (c.ToArgb () == DefaultControlForeColor.ToArgb ())
129 				return SystemBrushes.ControlText;
130 			return ResPool.GetSolidBrush (c);
131 		}
132 		#endregion	// Internal Methods
133 
134 		#region Control
GetLinkFont(Control control)135 		public override Font GetLinkFont (Control control)
136 		{
137 			return new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Underline, control.Font.Unit);
138 		}
139 		#endregion	// Control
140 
141 		#region OwnerDraw Support
DrawOwnerDrawBackground(DrawItemEventArgs e)142 		public  override void DrawOwnerDrawBackground (DrawItemEventArgs e)
143 		{
144 			if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
145 				e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds);
146 				return;
147 			}
148 
149 			e.Graphics.FillRectangle (ResPool.GetSolidBrush(e.BackColor), e.Bounds);
150 		}
151 
DrawOwnerDrawFocusRectangle(DrawItemEventArgs e)152 		public  override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e)
153 		{
154 			if (e.State == DrawItemState.Focus)
155 				CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor);
156 		}
157 		#endregion	// OwnerDraw Support
158 
159 		#region Button
160 		#region Standard Button Style
DrawButton(Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)161 		public override void DrawButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
162 		{
163 			// Draw Button Background
164 			DrawButtonBackground (g, b, clipRectangle);
165 
166 			// If we have an image, draw it
167 			if (imageBounds.Size != Size.Empty)
168 				DrawButtonImage (g, b, imageBounds);
169 
170 			// If we're focused, draw a focus rectangle
171 			if (b.Focused && b.Enabled && b.ShowFocusCues)
172 				DrawButtonFocus (g, b);
173 
174 			// If we have text, draw it
175 			if (textBounds != Rectangle.Empty)
176 				DrawButtonText (g, b, textBounds);
177 		}
178 
DrawButtonBackground(Graphics g, Button button, Rectangle clipArea)179 		public virtual void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea)
180 		{
181 			if (button.Pressed)
182 				ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
183 			else if (button.InternalSelected)
184 				ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
185 			else if (button.Entered)
186 				ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
187 			else if (!button.Enabled)
188 				ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
189 			else
190 				ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
191 		}
192 
DrawButtonFocus(Graphics g, Button button)193 		public virtual void DrawButtonFocus (Graphics g, Button button)
194 		{
195 			ControlPaint.DrawFocusRectangle (g, Rectangle.Inflate (button.ClientRectangle, -4, -4));
196 		}
197 
DrawButtonImage(Graphics g, ButtonBase button, Rectangle imageBounds)198 		public virtual void DrawButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
199 		{
200 			if (button.Enabled)
201 				g.DrawImage (button.Image, imageBounds);
202 			else
203 				CPDrawImageDisabled (g, button.Image, imageBounds.Left, imageBounds.Top, ColorControl);
204 		}
205 
DrawButtonText(Graphics g, ButtonBase button, Rectangle textBounds)206 		public virtual void DrawButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
207 		{
208 			// Ensure that at least one line is going to get displayed.
209 			// Line limit does not ensure that despite its description.
210 			if (button.Font != null && button.Font.Height > 0)
211 				textBounds.Height = Math.Max (textBounds.Height, button.Font.Height);
212 
213 			if (button.Enabled)
214 				TextRenderer.DrawTextInternal (g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
215 			else
216 				DrawStringDisabled20 (g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
217 		}
218 		#endregion
219 
220 		#region FlatStyle Button Style
DrawFlatButton(Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)221 		public override void DrawFlatButton (Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
222 		{
223 			// Draw Button Background
224 			if (b.BackgroundImage == null)
225 				DrawFlatButtonBackground (g, b, clipRectangle);
226 
227 			// If we have an image, draw it
228 			if (imageBounds.Size != Size.Empty)
229 				DrawFlatButtonImage (g, b, imageBounds);
230 
231 			// If we're focused, draw a focus rectangle
232 			if (b.Focused && b.Enabled && b.ShowFocusCues)
233 				DrawFlatButtonFocus (g, b);
234 
235 			// If we have text, draw it
236 			if (textBounds != Rectangle.Empty)
237 				DrawFlatButtonText (g, b, textBounds);
238 		}
239 
DrawFlatButtonBackground(Graphics g, ButtonBase button, Rectangle clipArea)240 		public virtual void DrawFlatButtonBackground (Graphics g, ButtonBase button, Rectangle clipArea)
241 		{
242 			if (button.Pressed)
243 				ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance);
244 			else if (button.InternalSelected) {
245 				if (button.Entered)
246 					ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
247 				else
248 					ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
249 			}
250 			else if (button.Entered)
251 				ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
252 			else if (!button.Enabled)
253 				ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance);
254 			else
255 				ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance);
256 		}
257 
DrawFlatButtonFocus(Graphics g, ButtonBase button)258 		public virtual void DrawFlatButtonFocus (Graphics g, ButtonBase button)
259 		{
260 			if (!button.Pressed) {
261 				Color focus_color = ControlPaint.Dark (button.BackColor);
262 				g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9));
263 			}
264 		}
265 
DrawFlatButtonImage(Graphics g, ButtonBase button, Rectangle imageBounds)266 		public virtual void DrawFlatButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
267 		{
268 			// No changes from Standard for image for this theme
269 			DrawButtonImage (g, button, imageBounds);
270 		}
271 
DrawFlatButtonText(Graphics g, ButtonBase button, Rectangle textBounds)272 		public virtual void DrawFlatButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
273 		{
274 			// No changes from Standard for text for this theme
275 			DrawButtonText (g, button, textBounds);
276 		}
277 		#endregion
278 
279 		#region Popup Button Style
DrawPopupButton(Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)280 		public override void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
281 		{
282 			// Draw Button Background
283 			DrawPopupButtonBackground (g, b, clipRectangle);
284 
285 			// If we have an image, draw it
286 			if (imageBounds.Size != Size.Empty)
287 				DrawPopupButtonImage (g, b, imageBounds);
288 
289 			// If we're focused, draw a focus rectangle
290 			if (b.Focused && b.Enabled && b.ShowFocusCues)
291 				DrawPopupButtonFocus (g, b);
292 
293 			// If we have text, draw it
294 			if (textBounds != Rectangle.Empty)
295 				DrawPopupButtonText (g, b, textBounds);
296 		}
297 
DrawPopupButtonBackground(Graphics g, Button button, Rectangle clipArea)298 		public virtual void DrawPopupButtonBackground (Graphics g, Button button, Rectangle clipArea)
299 		{
300 			if (button.Pressed)
301 				ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
302 			else if (button.Entered)
303 				ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
304 			else if (button.InternalSelected)
305 				ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
306 			else if (!button.Enabled)
307 				ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
308 			else
309 				ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
310 		}
311 
DrawPopupButtonFocus(Graphics g, Button button)312 		public virtual void DrawPopupButtonFocus (Graphics g, Button button)
313 		{
314 			// No changes from Standard for image for this theme
315 			DrawButtonFocus (g, button);
316 		}
317 
DrawPopupButtonImage(Graphics g, Button button, Rectangle imageBounds)318 		public virtual void DrawPopupButtonImage (Graphics g, Button button, Rectangle imageBounds)
319 		{
320 			// No changes from Standard for image for this theme
321 			DrawButtonImage (g, button, imageBounds);
322 		}
323 
DrawPopupButtonText(Graphics g, Button button, Rectangle textBounds)324 		public virtual void DrawPopupButtonText (Graphics g, Button button, Rectangle textBounds)
325 		{
326 			// No changes from Standard for image for this theme
327 			DrawButtonText (g, button, textBounds);
328 		}
329 		#endregion
330 
331 		#region Button Layout Calculations
CalculateButtonAutoSize(Button button)332 		public override Size CalculateButtonAutoSize (Button button)
333 		{
334 			Size ret_size = Size.Empty;
335 			Size text_size = TextRenderer.MeasureTextInternal (button.Text, button.Font, button.UseCompatibleTextRendering);
336 			Size image_size = button.Image == null ? Size.Empty : button.Image.Size;
337 
338 			// Pad the text size
339 			if (button.Text.Length != 0) {
340 				text_size.Height += 4;
341 				text_size.Width += 4;
342 			}
343 
344 			switch (button.TextImageRelation) {
345 				case TextImageRelation.Overlay:
346 					ret_size.Height = Math.Max (button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
347 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
348 					break;
349 				case TextImageRelation.ImageAboveText:
350 				case TextImageRelation.TextAboveImage:
351 					ret_size.Height = text_size.Height + image_size.Height;
352 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
353 					break;
354 				case TextImageRelation.ImageBeforeText:
355 				case TextImageRelation.TextBeforeImage:
356 					ret_size.Height = Math.Max (text_size.Height, image_size.Height);
357 					ret_size.Width = text_size.Width + image_size.Width;
358 					break;
359 			}
360 
361 			// Pad the result
362 			ret_size.Height += (button.Padding.Vertical + 6);
363 			ret_size.Width += (button.Padding.Horizontal + 6);
364 
365 			return ret_size;
366 		}
367 
CalculateButtonTextAndImageLayout(Graphics g, ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle)368 		public override void CalculateButtonTextAndImageLayout (Graphics g, ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle)
369 		{
370 			Image image = button.Image;
371 			string text = button.Text;
372 			Rectangle content_rect = button.PaddingClientRectangle;
373 			Size text_size = TextRenderer.MeasureTextInternal (g, text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering);
374 			Size image_size = image == null ? Size.Empty : image.Size;
375 
376 			textRectangle = Rectangle.Inflate (content_rect, -4, -4);
377 			imageRectangle = Rectangle.Empty;
378 
379 			bool displayEllipsis = (button.TextFormatFlags & (TextFormatFlags.EndEllipsis | TextFormatFlags.PathEllipsis | TextFormatFlags.WordEllipsis)) != 0;
380 
381 			switch (button.TextImageRelation) {
382 				case TextImageRelation.Overlay:
383 					// Overlay is easy, text always goes here
384 
385 					// Image is dependent on ImageAlign
386 					if (image == null) {
387 						if (button.Pressed)
388 							textRectangle.Offset (1, 1);
389 						return;
390 					}
391 
392 					int image_x = 0;
393 					int image_y = 0;
394 					int image_height = image.Height;
395 					int image_width = image.Width;
396 
397 					switch (button.ImageAlign) {
398 						case System.Drawing.ContentAlignment.TopLeft:
399 							image_x = 5;
400 							image_y = 5;
401 							break;
402 						case System.Drawing.ContentAlignment.TopCenter:
403 							image_x = (content_rect.Width - image_width) / 2;
404 							image_y = 5;
405 							break;
406 						case System.Drawing.ContentAlignment.TopRight:
407 							image_x = content_rect.Width - image_width - 5;
408 							image_y = 5;
409 							break;
410 						case System.Drawing.ContentAlignment.MiddleLeft:
411 							image_x = 5;
412 							image_y = (content_rect.Height - image_height) / 2;
413 							break;
414 						case System.Drawing.ContentAlignment.MiddleCenter:
415 							image_x = (content_rect.Width - image_width) / 2;
416 							image_y = (content_rect.Height - image_height) / 2;
417 							break;
418 						case System.Drawing.ContentAlignment.MiddleRight:
419 							image_x = content_rect.Width - image_width - 4;
420 							image_y = (content_rect.Height - image_height) / 2;
421 							break;
422 						case System.Drawing.ContentAlignment.BottomLeft:
423 							image_x = 5;
424 							image_y = content_rect.Height - image_height - 4;
425 							break;
426 						case System.Drawing.ContentAlignment.BottomCenter:
427 							image_x = (content_rect.Width - image_width) / 2;
428 							image_y = content_rect.Height - image_height - 4;
429 							break;
430 						case System.Drawing.ContentAlignment.BottomRight:
431 							image_x = content_rect.Width - image_width - 4;
432 							image_y = content_rect.Height - image_height - 4;
433 							break;
434 						default:
435 							image_x = 5;
436 							image_y = 5;
437 							break;
438 					}
439 
440 					imageRectangle = new Rectangle (image_x, image_y, image_width, image_height);
441 					break;
442 				case TextImageRelation.ImageAboveText:
443 					LayoutTextAboveOrBelowImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle);
444 					break;
445 				case TextImageRelation.TextAboveImage:
446 					LayoutTextAboveOrBelowImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle);
447 					break;
448 				case TextImageRelation.ImageBeforeText:
449 					LayoutTextBeforeOrAfterImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
450 					break;
451 				case TextImageRelation.TextBeforeImage:
452 					LayoutTextBeforeOrAfterImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
453 					break;
454 			}
455 			if (button.Pressed)
456 				textRectangle.Offset (1, 1);
457 		}
458 
LayoutTextBeforeOrAfterImage(Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)459 		private void LayoutTextBeforeOrAfterImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)
460 		{
461 			int element_spacing = 0;	// Spacing between the Text and the Image
462 			int total_width = textSize.Width + element_spacing + imageSize.Width;
463 
464 			if (!textFirst)
465 				element_spacing += 2;
466 
467 			// If the text is too big, chop it down to the size we have available to it
468 			if (total_width > totalArea.Width) {
469 				textSize.Width = totalArea.Width - element_spacing - imageSize.Width;
470 				total_width = totalArea.Width;
471 			}
472 
473 			int excess_width = totalArea.Width - total_width;
474 			int offset = 0;
475 
476 			Rectangle final_text_rect;
477 			Rectangle final_image_rect;
478 
479 			HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
480 			HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
481 
482 			if (h_image == HorizontalAlignment.Left)
483 				offset = 0;
484 			else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
485 				offset = excess_width;
486 			else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
487 				offset += (int)(excess_width / 3);
488 			else
489 				offset += (int)(2 * (excess_width / 3));
490 
491 			if (textFirst) {
492 				final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
493 				final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
494 			}
495 			else {
496 				final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
497 				final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
498 			}
499 
500 			textRect = final_text_rect;
501 			imageRect = final_image_rect;
502 		}
503 
LayoutTextAboveOrBelowImage(Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, bool displayEllipsis, out Rectangle textRect, out Rectangle imageRect)504 		private void LayoutTextAboveOrBelowImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, bool displayEllipsis, out Rectangle textRect, out Rectangle imageRect)
505 		{
506 			int element_spacing = 0;	// Spacing between the Text and the Image
507 			int total_height = textSize.Height + element_spacing + imageSize.Height;
508 
509 			if (textFirst)
510 				element_spacing += 2;
511 
512 			if (textSize.Width > totalArea.Width)
513 				textSize.Width = totalArea.Width;
514 
515 			// If the there isn't enough room and we're text first, cut out the image
516 			if (total_height > totalArea.Height && textFirst) {
517 				imageSize = Size.Empty;
518 				total_height = totalArea.Height;
519 			}
520 
521 			int excess_height = totalArea.Height - total_height;
522 			int offset = 0;
523 
524 			Rectangle final_text_rect;
525 			Rectangle final_image_rect;
526 
527 			VerticalAlignment v_text = GetVerticalAlignment (textAlign);
528 			VerticalAlignment v_image = GetVerticalAlignment (imageAlign);
529 
530 			if (v_image == VerticalAlignment.Top)
531 				offset = 0;
532 			else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom)
533 				offset = excess_height;
534 			else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center))
535 				offset += (int)(excess_height / 3);
536 			else
537 				offset += (int)(2 * (excess_height / 3));
538 
539 			if (textFirst) {
540 				var textHeight = excess_height >= 0 ? totalArea.Height - imageSize.Height - element_spacing: textSize.Height;
541 				final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textHeight);
542 				final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height);
543 			}
544 			else {
545 				final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height);
546 				var textHeight = excess_height >= 0 ? totalArea.Height - final_image_rect.Height : textSize.Height;
547 				final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textHeight);
548 
549 				if (final_text_rect.Bottom > totalArea.Bottom) {
550 					final_text_rect.Y -= (final_text_rect.Bottom - totalArea.Bottom);
551 					if (final_text_rect.Y < totalArea.Top)
552 						final_text_rect.Y = totalArea.Top;
553 				}
554 			}
555 
556 			if (displayEllipsis) {
557 				// Don't use more space than is available otherwise ellipsis won't show
558 				if (final_text_rect.Height > totalArea.Bottom)
559 					final_text_rect.Height = totalArea.Bottom - final_text_rect.Top;
560 			}
561 
562 			textRect = final_text_rect;
563 			imageRect = final_image_rect;
564 		}
565 
GetHorizontalAlignment(System.Drawing.ContentAlignment align)566 		private HorizontalAlignment GetHorizontalAlignment (System.Drawing.ContentAlignment align)
567 		{
568 			switch (align) {
569 				case System.Drawing.ContentAlignment.BottomLeft:
570 				case System.Drawing.ContentAlignment.MiddleLeft:
571 				case System.Drawing.ContentAlignment.TopLeft:
572 					return HorizontalAlignment.Left;
573 				case System.Drawing.ContentAlignment.BottomCenter:
574 				case System.Drawing.ContentAlignment.MiddleCenter:
575 				case System.Drawing.ContentAlignment.TopCenter:
576 					return HorizontalAlignment.Center;
577 				case System.Drawing.ContentAlignment.BottomRight:
578 				case System.Drawing.ContentAlignment.MiddleRight:
579 				case System.Drawing.ContentAlignment.TopRight:
580 					return HorizontalAlignment.Right;
581 			}
582 
583 			return HorizontalAlignment.Left;
584 		}
585 
586 		private enum VerticalAlignment
587 		{
588 			Top = 0,
589 			Center = 1,
590 			Bottom = 2
591 		}
592 
GetVerticalAlignment(System.Drawing.ContentAlignment align)593 		private VerticalAlignment GetVerticalAlignment (System.Drawing.ContentAlignment align)
594 		{
595 			switch (align) {
596 				case System.Drawing.ContentAlignment.TopLeft:
597 				case System.Drawing.ContentAlignment.TopCenter:
598 				case System.Drawing.ContentAlignment.TopRight:
599 					return VerticalAlignment.Top;
600 				case System.Drawing.ContentAlignment.MiddleLeft:
601 				case System.Drawing.ContentAlignment.MiddleCenter:
602 				case System.Drawing.ContentAlignment.MiddleRight:
603 					return VerticalAlignment.Center;
604 				case System.Drawing.ContentAlignment.BottomLeft:
605 				case System.Drawing.ContentAlignment.BottomCenter:
606 				case System.Drawing.ContentAlignment.BottomRight:
607 					return VerticalAlignment.Bottom;
608 			}
609 
610 			return VerticalAlignment.Top;
611 		}
612 
AlignInRectangle(Rectangle outer, Size inner, System.Drawing.ContentAlignment align)613 		internal Rectangle AlignInRectangle (Rectangle outer, Size inner, System.Drawing.ContentAlignment align)
614 		{
615 			int x = 0;
616 			int y = 0;
617 
618 			if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft)
619 				x = outer.X;
620 			else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter)
621 				x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
622 			else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight)
623 				x = outer.Right - inner.Width;
624 			if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight)
625 				y = outer.Y;
626 			else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight)
627 				y = outer.Y + (outer.Height - inner.Height) / 2;
628 			else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft)
629 				y = outer.Bottom - inner.Height;
630 
631 			return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
632 		}
633 		#endregion
634 		#endregion
635 
636 		#region ButtonBase
DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button)637 		public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button)
638 		{
639 			// Draw the button: Draw border, etc.
640 			ButtonBase_DrawButton(button, dc);
641 
642 			// Draw the image
643 			if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null)))
644 				ButtonBase_DrawImage(button, dc);
645 
646 			// Draw the focus rectangle
647 			if (ShouldPaintFocusRectagle (button))
648 				ButtonBase_DrawFocus(button, dc);
649 
650 			// Now the text
651 			if (button.Text != null && button.Text != String.Empty)
652 				ButtonBase_DrawText(button, dc);
653 		}
654 
ShouldPaintFocusRectagle(ButtonBase button)655 		protected static bool ShouldPaintFocusRectagle (ButtonBase button)
656 		{
657 			return (button.Focused || button.paint_as_acceptbutton) && button.Enabled && button.ShowFocusCues;
658 		}
659 
ButtonBase_DrawButton(ButtonBase button, Graphics dc)660 		protected virtual void ButtonBase_DrawButton (ButtonBase button, Graphics dc)
661 		{
662 			Rectangle borderRectangle;
663 			bool check_or_radio = false;
664 			bool check_or_radio_checked = false;
665 
666 			bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
667 
668 			CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor);
669 
670 			if (button is CheckBox) {
671 				check_or_radio = true;
672 				check_or_radio_checked = ((CheckBox)button).Checked;
673 			} else if (button is RadioButton) {
674 				check_or_radio = true;
675 				check_or_radio_checked = ((RadioButton)button).Checked;
676 			}
677 
678 			if (button.Focused && button.Enabled && !check_or_radio) {
679 				// shrink the rectangle for the normal button drawing inside the focus rectangle
680 				borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1);
681 			} else {
682 				borderRectangle = button.ClientRectangle;
683 			}
684 
685 			if (button.FlatStyle == FlatStyle.Popup) {
686 				if (!button.is_pressed && !button.is_entered && !check_or_radio_checked)
687 					Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
688 				else if (!button.is_pressed && button.is_entered &&!check_or_radio_checked)
689 					Internal_DrawButton (dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor);
690 				else if (button.is_pressed || check_or_radio_checked)
691 					Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
692 			} else if (button.FlatStyle == FlatStyle.Flat) {
693 				if (button.is_entered && !button.is_pressed && !check_or_radio_checked) {
694 					if ((button.image == null) && (button.image_list == null)) {
695 						Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush (cpcolor.Dark);
696 						dc.FillRectangle (brush, borderRectangle);
697 					}
698 				} else if (button.is_pressed || check_or_radio_checked) {
699 					if ((button.image == null) && (button.image_list == null)) {
700 						Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush (cpcolor.LightLight);
701 						dc.FillRectangle (brush, borderRectangle);
702 					}
703 
704 					Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
705 					dc.DrawRectangle (pen, borderRectangle.X + 4, borderRectangle.Y + 4,
706 							  borderRectangle.Width - 9, borderRectangle.Height - 9);
707 				}
708 
709 				Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor);
710 			} else {
711 				if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked)
712 					Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor);
713 				else
714 					Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
715 			}
716 		}
717 
Internal_DrawButton(Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor)718 		private void Internal_DrawButton (Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor)
719 		{
720 			switch (state) {
721 			case 0: // normal or normal disabled button
722 				Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
723 				dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
724 				dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
725 
726 				pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen (backcolor);
727 				dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
728 				dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
729 
730 				pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
731 				dc.DrawLine (pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
732 				dc.DrawLine (pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3);
733 
734 				pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
735 				dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
736 				dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
737 				break;
738 			case 1: // popup button normal (or pressed normal or popup button)
739 				pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
740 				dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
741 				break;
742 			case 2: // popup button poped up
743 				pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
744 				dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
745 				dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
746 
747 				pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
748 				dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
749 				dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
750 				break;
751 			case 3: // flat button not entered
752 				pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
753 				dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
754 				break;
755 			default:
756 				break;
757 			}
758 		}
759 
ButtonBase_DrawImage(ButtonBase button, Graphics dc)760 		protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc)
761 		{
762 			// Need to draw a picture
763 			Image	i;
764 			int	image_x;
765 			int	image_y;
766 			int	image_width;
767 			int	image_height;
768 
769 			int width = button.ClientSize.Width;
770 			int height = button.ClientSize.Height;
771 
772 			if (button.ImageIndex != -1) {	 // We use ImageIndex instead of image_index since it will return -1 if image_list is null
773 				i = button.image_list.Images[button.ImageIndex];
774 			} else {
775 				i = button.image;
776 			}
777 
778 			image_width = i.Width;
779 			image_height = i.Height;
780 
781 			switch (button.ImageAlign) {
782 				case ContentAlignment.TopLeft: {
783 					image_x = 5;
784 					image_y = 5;
785 					break;
786 				}
787 
788 				case ContentAlignment.TopCenter: {
789 					image_x = (width - image_width) / 2;
790 					image_y = 5;
791 					break;
792 				}
793 
794 				case ContentAlignment.TopRight: {
795 					image_x = width - image_width - 5;
796 					image_y = 5;
797 					break;
798 				}
799 
800 				case ContentAlignment.MiddleLeft: {
801 					image_x = 5;
802 					image_y = (height - image_height) / 2;
803 					break;
804 				}
805 
806 				case ContentAlignment.MiddleCenter: {
807 					image_x = (width - image_width) / 2;
808 					image_y = (height - image_height) / 2;
809 					break;
810 				}
811 
812 				case ContentAlignment.MiddleRight: {
813 					image_x = width - image_width - 4;
814 					image_y = (height - image_height) / 2;
815 					break;
816 				}
817 
818 				case ContentAlignment.BottomLeft: {
819 					image_x = 5;
820 					image_y = height - image_height - 4;
821 					break;
822 				}
823 
824 				case ContentAlignment.BottomCenter: {
825 					image_x = (width - image_width) / 2;
826 					image_y = height - image_height - 4;
827 					break;
828 				}
829 
830 				case ContentAlignment.BottomRight: {
831 					image_x = width - image_width - 4;
832 					image_y = height - image_height - 4;
833 					break;
834 				}
835 
836 				default: {
837 					image_x = 5;
838 					image_y = 5;
839 					break;
840 				}
841 			}
842 
843 			dc.SetClip (new Rectangle(3, 3, width - 5, height - 5));
844 
845 			if (button.Enabled)
846 				dc.DrawImage (i, image_x, image_y, image_width, image_height);
847 			else
848 				CPDrawImageDisabled (dc, i, image_x, image_y, ColorControl);
849 
850 			dc.ResetClip ();
851 		}
852 
ButtonBase_DrawFocus(ButtonBase button, Graphics dc)853 		protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc)
854 		{
855 			Color focus_color = button.ForeColor;
856 
857 			int inflate_value = -3;
858 
859 			if (!(button is CheckBox) && !(button is RadioButton)) {
860 				inflate_value = -4;
861 
862 				if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed)
863 					focus_color = ControlPaint.Dark(button.BackColor);
864 
865 				dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y,
866 						  button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
867 			}
868 
869 			if (button.Focused) {
870 				Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value);
871 				ControlPaint.DrawFocusRectangle (dc, rect);
872 			}
873 		}
874 
ButtonBase_DrawText(ButtonBase button, Graphics dc)875 		protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc)
876 		{
877 			Rectangle buttonRectangle = button.ClientRectangle;
878 			Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
879 
880 			if (button.is_pressed) {
881 				text_rect.X++;
882 				text_rect.Y++;
883 			}
884 
885 			// Ensure that at least one line is going to get displayed.
886 			// Line limit does not ensure that despite its description.
887 			text_rect.Height = Math.Max (button.Font.Height, text_rect.Height);
888 
889 			if (button.Enabled) {
890 				dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
891 			} else {
892 				if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
893 					dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (ColorGrayText), text_rect, button.text_format);
894 				} else {
895 					CPDrawStringDisabled (dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format);
896 				}
897 			}
898 		}
899 
900 		public override Size ButtonBaseDefaultSize {
901 			get {
902 				return new Size (75, 23);
903 			}
904 		}
905 		#endregion	// ButtonBase
906 
907 		#region CheckBox
DrawCheckBox(Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)908 		public override void DrawCheckBox (Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
909 		{
910 			// Draw Button Background
911 			if (cb.Appearance == Appearance.Button && cb.FlatStyle != FlatStyle.Flat)
912 				ButtonBase_DrawButton (cb, g);
913 			else if (cb.Appearance != Appearance.Button)
914 				DrawCheckBoxGlyph (g, cb, glyphArea);
915 
916 			// Draw the borders and such for a Flat CheckBox Button
917 			if (cb.Appearance == Appearance.Button && cb.FlatStyle == FlatStyle.Flat)
918 			DrawFlatButton (g, cb, textBounds, imageBounds, clipRectangle);
919 
920 			// If we have an image, draw it
921 			if (imageBounds.Size != Size.Empty)
922 				DrawCheckBoxImage (g, cb, imageBounds);
923 
924 			if (cb.Focused && cb.Enabled && cb.ShowFocusCues && textBounds != Rectangle.Empty)
925 				DrawCheckBoxFocus (g, cb, textBounds);
926 
927 			// If we have text, draw it
928 			if (textBounds != Rectangle.Empty)
929 				DrawCheckBoxText (g, cb, textBounds);
930 		}
931 
DrawCheckBoxGlyph(Graphics g, CheckBox cb, Rectangle glyphArea)932 		public virtual void DrawCheckBoxGlyph (Graphics g, CheckBox cb, Rectangle glyphArea)
933 		{
934 			if (cb.Pressed)
935 				ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState);
936 			else if (cb.InternalSelected)
937 				ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
938 			else if (cb.Entered)
939 				ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState);
940 			else if (!cb.Enabled)
941 				ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState);
942 			else
943 				ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
944 		}
945 
DrawCheckBoxFocus(Graphics g, CheckBox cb, Rectangle focusArea)946 		public virtual void DrawCheckBoxFocus (Graphics g, CheckBox cb, Rectangle focusArea)
947 		{
948 			ControlPaint.DrawFocusRectangle (g, focusArea);
949 		}
950 
DrawCheckBoxImage(Graphics g, CheckBox cb, Rectangle imageBounds)951 		public virtual void DrawCheckBoxImage (Graphics g, CheckBox cb, Rectangle imageBounds)
952 		{
953 			if (cb.Enabled)
954 				g.DrawImage (cb.Image, imageBounds);
955 			else
956 				CPDrawImageDisabled (g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
957 		}
958 
DrawCheckBoxText(Graphics g, CheckBox cb, Rectangle textBounds)959 		public virtual void DrawCheckBoxText (Graphics g, CheckBox cb, Rectangle textBounds)
960 		{
961 			if (cb.Enabled)
962 				TextRenderer.DrawTextInternal (g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
963 			else
964 				DrawStringDisabled20 (g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
965 		}
966 
CalculateCheckBoxTextAndImageLayout(ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)967 		public override void CalculateCheckBoxTextAndImageLayout (ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
968 		{
969 			int check_size = CheckSize;
970 
971 			if (button is CheckBox)
972 				check_size = (button as CheckBox).Appearance == Appearance.Normal ? check_size : 0;
973 
974 			glyphArea = new Rectangle (button.Padding.Left, button.Padding.Top, check_size, check_size);
975 
976 			Rectangle content_rect = button.PaddingClientRectangle;
977 			ContentAlignment align = ContentAlignment.TopLeft;
978 
979 			if (button is CheckBox)
980 				align = (button as CheckBox).CheckAlign;
981 			else if (button is RadioButton)
982 				align = (button as RadioButton).CheckAlign;
983 
984 			switch (align) {
985 				case ContentAlignment.BottomCenter:
986 					glyphArea.Y += content_rect.Height - check_size - 2;
987 					glyphArea.X += (content_rect.Width - check_size) / 2;
988 					break;
989 				case ContentAlignment.BottomLeft:
990 					glyphArea.Y += content_rect.Height - check_size - 2;
991 					content_rect.Width -= check_size;
992 					content_rect.Offset (check_size, 0);
993 					break;
994 				case ContentAlignment.BottomRight:
995 					glyphArea.Y += content_rect.Height - check_size - 2;
996 					glyphArea.X += content_rect.Width - check_size;
997 					content_rect.Width -= check_size;
998 					break;
999 				case ContentAlignment.MiddleCenter:
1000 					glyphArea.Y += (content_rect.Height - check_size) / 2;
1001 					glyphArea.X += (content_rect.Width - check_size) / 2;
1002 					break;
1003 				case ContentAlignment.MiddleLeft:
1004 					glyphArea.Y += (content_rect.Height - check_size) / 2;
1005 					content_rect.Width -= check_size;
1006 					content_rect.Offset (check_size, 0);
1007 					break;
1008 				case ContentAlignment.MiddleRight:
1009 					glyphArea.Y += (content_rect.Height - check_size) / 2;
1010 					glyphArea.X += content_rect.Width - check_size;
1011 					content_rect.Width -= check_size;
1012 					break;
1013 				case ContentAlignment.TopCenter:
1014 					glyphArea.X += (content_rect.Width - check_size) / 2;
1015 					break;
1016 				case ContentAlignment.TopLeft:
1017 					content_rect.Width -= check_size;
1018 					content_rect.Offset (check_size, 0);
1019 					break;
1020 				case ContentAlignment.TopRight:
1021 					glyphArea.X += content_rect.Width - check_size;
1022 					content_rect.Width -= check_size;
1023 					break;
1024 			}
1025 
1026 			Image image = button.Image;
1027 			string text = button.Text;
1028 
1029 			Size proposed = Size.Empty;
1030 
1031 			// Force wrapping if we aren't AutoSize and our text is too long
1032 			if (!button.AutoSize)
1033 				proposed.Width = button.PaddingClientRectangle.Width - glyphArea.Width - 2;
1034 
1035 			Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, proposed, button.TextFormatFlags, button.UseCompatibleTextRendering);
1036 
1037 			// Text can't be bigger than the content rectangle
1038 			text_size.Height = Math.Min (text_size.Height, content_rect.Height);
1039 			text_size.Width = Math.Min (text_size.Width, content_rect.Width);
1040 
1041 			Size image_size = image == null ? Size.Empty : image.Size;
1042 
1043 			textRectangle = Rectangle.Empty;
1044 			imageRectangle = Rectangle.Empty;
1045 
1046 			switch (button.TextImageRelation) {
1047 				case TextImageRelation.Overlay:
1048 					// Text is centered vertically, and 2 pixels to the right
1049 					textRectangle.X = content_rect.Left + 2;
1050 					textRectangle.Y = button.PaddingClientRectangle.Top + ((content_rect.Height - text_size.Height) / 2) - 1;
1051 					textRectangle.Size = text_size;
1052 
1053 					// Image is dependent on ImageAlign
1054 					if (image == null)
1055 						return;
1056 
1057 					int image_x = button.PaddingClientRectangle.Left;
1058 					int image_y = button.PaddingClientRectangle.Top;
1059 					int image_height = image.Height;
1060 					int image_width = image.Width;
1061 
1062 					switch (button.ImageAlign) {
1063 						case System.Drawing.ContentAlignment.TopLeft:
1064 							image_x += 5;
1065 							image_y += 5;
1066 							break;
1067 						case System.Drawing.ContentAlignment.TopCenter:
1068 							image_x += (content_rect.Width - image_width) / 2;
1069 							image_y += 5;
1070 							break;
1071 						case System.Drawing.ContentAlignment.TopRight:
1072 							image_x += content_rect.Width - image_width - 5;
1073 							image_y += 5;
1074 							break;
1075 						case System.Drawing.ContentAlignment.MiddleLeft:
1076 							image_x += 5;
1077 							image_y += (content_rect.Height - image_height) / 2;
1078 							break;
1079 						case System.Drawing.ContentAlignment.MiddleCenter:
1080 							image_x += (content_rect.Width - image_width) / 2;
1081 							image_y += (content_rect.Height - image_height) / 2;
1082 							break;
1083 						case System.Drawing.ContentAlignment.MiddleRight:
1084 							image_x += content_rect.Width - image_width - 4;
1085 							image_y += (content_rect.Height - image_height) / 2;
1086 							break;
1087 						case System.Drawing.ContentAlignment.BottomLeft:
1088 							image_x += 5;
1089 							image_y += content_rect.Height - image_height - 4;
1090 							break;
1091 						case System.Drawing.ContentAlignment.BottomCenter:
1092 							image_x += (content_rect.Width - image_width) / 2;
1093 							image_y += content_rect.Height - image_height - 4;
1094 							break;
1095 						case System.Drawing.ContentAlignment.BottomRight:
1096 							image_x += content_rect.Width - image_width - 4;
1097 							image_y += content_rect.Height - image_height - 4;
1098 							break;
1099 						default:
1100 							image_x += 5;
1101 							image_y += 5;
1102 							break;
1103 					}
1104 
1105 					imageRectangle = new Rectangle (image_x + check_size, image_y, image_width, image_height);
1106 					break;
1107 				case TextImageRelation.ImageAboveText:
1108 					content_rect.Inflate (-4, -4);
1109 					LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle);
1110 					break;
1111 				case TextImageRelation.TextAboveImage:
1112 					content_rect.Inflate (-4, -4);
1113 					LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle);
1114 					break;
1115 				case TextImageRelation.ImageBeforeText:
1116 					content_rect.Inflate (-4, -4);
1117 					LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1118 					break;
1119 				case TextImageRelation.TextBeforeImage:
1120 					content_rect.Inflate (-4, -4);
1121 					LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1122 					break;
1123 			}
1124 		}
1125 
CalculateCheckBoxAutoSize(CheckBox checkBox)1126 		public override Size CalculateCheckBoxAutoSize (CheckBox checkBox)
1127 		{
1128 			Size ret_size = Size.Empty;
1129 			Size text_size = TextRenderer.MeasureTextInternal (checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering);
1130 			Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size;
1131 
1132 			// Pad the text size
1133 			if (checkBox.Text.Length != 0) {
1134 				text_size.Height += 4;
1135 				text_size.Width += 4;
1136 			}
1137 
1138 			switch (checkBox.TextImageRelation) {
1139 				case TextImageRelation.Overlay:
1140 					ret_size.Height = Math.Max (checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
1141 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1142 					break;
1143 				case TextImageRelation.ImageAboveText:
1144 				case TextImageRelation.TextAboveImage:
1145 					ret_size.Height = text_size.Height + image_size.Height;
1146 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1147 					break;
1148 				case TextImageRelation.ImageBeforeText:
1149 				case TextImageRelation.TextBeforeImage:
1150 					ret_size.Height = Math.Max (text_size.Height, image_size.Height);
1151 					ret_size.Width = text_size.Width + image_size.Width;
1152 					break;
1153 			}
1154 
1155 			// Pad the result
1156 			ret_size.Height += (checkBox.Padding.Vertical);
1157 			ret_size.Width += (checkBox.Padding.Horizontal) + 15;
1158 
1159 			// There seems to be a minimum height
1160 			if (ret_size.Height == checkBox.Padding.Vertical)
1161 				ret_size.Height += 14;
1162 
1163 			return ret_size;
1164 		}
1165 
DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox)1166 		public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
1167 			StringFormat		text_format;
1168 			Rectangle		client_rectangle;
1169 			Rectangle		text_rectangle;
1170 			Rectangle		checkbox_rectangle;
1171 			int			checkmark_size = CheckSize;
1172 			int			checkmark_space = 4;
1173 
1174 			client_rectangle = checkbox.ClientRectangle;
1175 			text_rectangle = client_rectangle;
1176 			checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
1177 
1178 			text_format = new StringFormat();
1179 			text_format.Alignment = StringAlignment.Near;
1180 			text_format.LineAlignment = StringAlignment.Center;
1181 			if (checkbox.ShowKeyboardCuesInternal)
1182 				text_format.HotkeyPrefix = HotkeyPrefix.Show;
1183 			else
1184 				text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1185 
1186 			/* Calculate the position of text and checkbox rectangle */
1187 			if (checkbox.appearance!=Appearance.Button) {
1188 				switch(checkbox.check_alignment) {
1189 					case ContentAlignment.BottomCenter: {
1190 						checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1191 						checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1192 						text_rectangle.X=client_rectangle.X;
1193 						text_rectangle.Width=client_rectangle.Width;
1194 						text_rectangle.Height=client_rectangle.Height-checkbox_rectangle.Y-checkmark_space;
1195 						break;
1196 					}
1197 
1198 					case ContentAlignment.BottomLeft: {
1199 						checkbox_rectangle.X=client_rectangle.Left;
1200 						checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1201 						text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1202 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1203 						break;
1204 					}
1205 
1206 					case ContentAlignment.BottomRight: {
1207 						checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1208 						checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1209 						text_rectangle.X=client_rectangle.X;
1210 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1211 						break;
1212 					}
1213 
1214 					case ContentAlignment.MiddleCenter: {
1215 						checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1216 						checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1217 						text_rectangle.X=client_rectangle.X;
1218 						text_rectangle.Width=client_rectangle.Width;
1219 						break;
1220 					}
1221 
1222 					default:
1223 					case ContentAlignment.MiddleLeft: {
1224 						checkbox_rectangle.X=client_rectangle.Left;
1225 						checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1226 						text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1227 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1228 						break;
1229 					}
1230 
1231 					case ContentAlignment.MiddleRight: {
1232 						checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1233 						checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1234 						text_rectangle.X=client_rectangle.X;
1235 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1236 						break;
1237 					}
1238 
1239 					case ContentAlignment.TopCenter: {
1240 						checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1241 						checkbox_rectangle.Y=client_rectangle.Top;
1242 						text_rectangle.X=client_rectangle.X;
1243 						text_rectangle.Width=client_rectangle.Width;
1244 						text_rectangle.Y=checkmark_size+checkmark_space;
1245 						text_rectangle.Height=client_rectangle.Height-checkmark_size-checkmark_space;
1246 						break;
1247 					}
1248 
1249 					case ContentAlignment.TopLeft: {
1250 						checkbox_rectangle.X=client_rectangle.Left;
1251 						text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1252 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1253 						break;
1254 					}
1255 
1256 					case ContentAlignment.TopRight: {
1257 						checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1258 						text_rectangle.X=client_rectangle.X;
1259 						text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1260 						break;
1261 					}
1262 				}
1263 			} else {
1264 				text_rectangle.X=client_rectangle.X;
1265 				text_rectangle.Width=client_rectangle.Width;
1266 			}
1267 
1268 			/* Set the horizontal alignment of our text */
1269 			switch(checkbox.text_alignment) {
1270 				case ContentAlignment.BottomLeft:
1271 				case ContentAlignment.MiddleLeft:
1272 				case ContentAlignment.TopLeft: {
1273 					text_format.Alignment=StringAlignment.Near;
1274 					break;
1275 				}
1276 
1277 				case ContentAlignment.BottomCenter:
1278 				case ContentAlignment.MiddleCenter:
1279 				case ContentAlignment.TopCenter: {
1280 					text_format.Alignment=StringAlignment.Center;
1281 					break;
1282 				}
1283 
1284 				case ContentAlignment.BottomRight:
1285 				case ContentAlignment.MiddleRight:
1286 				case ContentAlignment.TopRight: {
1287 					text_format.Alignment=StringAlignment.Far;
1288 					break;
1289 				}
1290 			}
1291 
1292 			/* Set the vertical alignment of our text */
1293 			switch(checkbox.text_alignment) {
1294 				case ContentAlignment.TopLeft:
1295 				case ContentAlignment.TopCenter:
1296 				case ContentAlignment.TopRight: {
1297 					text_format.LineAlignment=StringAlignment.Near;
1298 					break;
1299 				}
1300 
1301 				case ContentAlignment.BottomLeft:
1302 				case ContentAlignment.BottomCenter:
1303 				case ContentAlignment.BottomRight: {
1304 					text_format.LineAlignment=StringAlignment.Far;
1305 					break;
1306 				}
1307 
1308 				case ContentAlignment.MiddleLeft:
1309 				case ContentAlignment.MiddleCenter:
1310 				case ContentAlignment.MiddleRight: {
1311 					text_format.LineAlignment=StringAlignment.Center;
1312 					break;
1313 				}
1314 			}
1315 
1316 			ButtonState state = ButtonState.Normal;
1317 			if (checkbox.FlatStyle == FlatStyle.Flat) {
1318 				state |= ButtonState.Flat;
1319 			}
1320 
1321 			if (checkbox.Checked) {
1322 				state |= ButtonState.Checked;
1323 			}
1324 
1325 			if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) {
1326 				state |= ButtonState.Checked;
1327 				state |= ButtonState.Pushed;
1328 			}
1329 
1330 			// finally make sure the pushed and inavtive states are rendered
1331 			if (!checkbox.Enabled) {
1332 				state |= ButtonState.Inactive;
1333 			}
1334 			else if (checkbox.is_pressed) {
1335 				state |= ButtonState.Pushed;
1336 			}
1337 
1338 			// Start drawing
1339 
1340 			CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
1341 
1342 			if ((checkbox.image != null) || (checkbox.image_list != null))
1343 				ButtonBase_DrawImage(checkbox, dc);
1344 
1345 			CheckBox_DrawText(checkbox, text_rectangle, dc, text_format);
1346 
1347 			if (checkbox.Focused && checkbox.Enabled && checkbox.appearance != Appearance.Button && checkbox.Text != String.Empty && checkbox.ShowFocusCues) {
1348 				SizeF text_size = dc.MeasureString (checkbox.Text, checkbox.Font);
1349 
1350 				Rectangle focus_rect = Rectangle.Empty;
1351 				focus_rect.X = text_rectangle.X;
1352 				focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
1353 				focus_rect.Size = text_size.ToSize ();
1354 				CheckBox_DrawFocus (checkbox, dc, focus_rect);
1355 			}
1356 
1357 			text_format.Dispose ();
1358 		}
1359 
CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )1360 		protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )
1361 		{
1362 			Brush brush = checkbox.BackColor.ToArgb () == ColorControl.ToArgb () ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor);
1363 			dc.FillRectangle (brush, checkbox.ClientRectangle);
1364 			// render as per normal button
1365 			if (checkbox.appearance==Appearance.Button) {
1366 				ButtonBase_DrawButton (checkbox, dc);
1367 
1368 				if ((checkbox.Focused) && checkbox.Enabled)
1369 					ButtonBase_DrawFocus(checkbox, dc);
1370 			} else {
1371 				// establish if we are rendering a flat style of some sort
1372 				if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
1373 					DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
1374 				} else {
1375 					CPDrawCheckBox (dc, checkbox_rectangle, state);
1376 				}
1377 			}
1378 		}
1379 
CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format )1380 		protected virtual void CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format )
1381 		{
1382 			DrawCheckBox_and_RadioButtonText (checkbox, text_rectangle, dc,
1383 							  text_format, checkbox.Appearance, checkbox.Checked);
1384 		}
1385 
CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )1386 		protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
1387 		{
1388 			DrawInnerFocusRectangle (dc, text_rectangle, checkbox.BackColor);
1389 		}
1390 
1391 		// renders a checkBox with the Flat and Popup FlatStyle
DrawFlatStyleCheckBox(Graphics graphics, Rectangle rectangle, CheckBox checkbox)1392 		protected virtual void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox)
1393 		{
1394 			Pen			pen;
1395 			Rectangle	rect;
1396 			Rectangle	checkbox_rectangle;
1397 			Rectangle	fill_rectangle;
1398 			int			lineWidth;
1399 			int			Scale;
1400 
1401 			// set up our rectangles first
1402 			if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) {
1403 				// clip one pixel from bottom right for non popup rendered checkboxes
1404 				checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0));
1405 				fill_rectangle = new Rectangle(checkbox_rectangle.X+1, checkbox_rectangle.Y+1, Math.Max(checkbox_rectangle.Width-3, 0), Math.Max(checkbox_rectangle.Height-3,0));
1406 			} else {
1407 				// clip two pixels from bottom right for non popup rendered checkboxes
1408 				checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0));
1409 				fill_rectangle = new Rectangle(checkbox_rectangle.X+1, checkbox_rectangle.Y+1, Math.Max(checkbox_rectangle.Width-2, 0), Math.Max(checkbox_rectangle.Height-2,0));
1410 			}
1411 
1412 
1413 			// if disabled render in disabled state
1414 			if (checkbox.Enabled) {
1415 				// process the state of the checkbox
1416 				if (checkbox.is_entered || checkbox.Capture) {
1417 					// decide on which background color to use
1418 					if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) {
1419 						graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1420 					} else if (checkbox.FlatStyle == FlatStyle.Flat) {
1421 						if (!checkbox.is_pressed) {
1422 							graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1423 						} else
1424 							graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1425 					} else {
1426 						// use regular window background color
1427 						graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1428 					}
1429 
1430 					// render the outer border
1431 					if (checkbox.FlatStyle == FlatStyle.Flat) {
1432 						ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1433 					} else {
1434 						// draw sunken effect
1435 						CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, checkbox.BackColor);
1436 					}
1437 				} else {
1438 					graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1439 
1440 					if (checkbox.FlatStyle == FlatStyle.Flat) {
1441 						ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1442 					} else {
1443 						// draw the outer border
1444 						ControlPaint.DrawBorder(graphics, checkbox_rectangle, ControlPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid);
1445 					}
1446 				}
1447 			} else {
1448 				if (checkbox.FlatStyle == FlatStyle.Popup) {
1449 					graphics.FillRectangle(SystemBrushes.Control, fill_rectangle);
1450 				}
1451 
1452 				// draw disabled state,
1453 				ControlPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid);
1454 			}
1455 
1456 			if (checkbox.Checked) {
1457 				/* Need to draw a check-mark */
1458 
1459 				/* Make sure we've got at least a line width of 1 */
1460 				lineWidth = Math.Max(3, fill_rectangle.Width/3);
1461 				Scale=Math.Max(1, fill_rectangle.Width/9);
1462 
1463 				// flat style check box is rendered inside a rectangle shifted down by one
1464 				rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height);
1465 				if (checkbox.Enabled) {
1466 					pen=ResPool.GetPen(checkbox.ForeColor);
1467 				} else {
1468 					pen=SystemPens.ControlDark;
1469 				}
1470 
1471 				for (int i=0; i<lineWidth; i++) {
1472 					graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
1473 					graphics.DrawLine(pen, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i, rect.Left+lineWidth/2+6*Scale, rect.Top+lineWidth-2*Scale+i);
1474 				}
1475 			}
1476 		}
1477 
DrawCheckBox_and_RadioButtonText(ButtonBase button_base, Rectangle text_rectangle, Graphics dc, StringFormat text_format, Appearance appearance, bool ischecked)1478 		private void DrawCheckBox_and_RadioButtonText (ButtonBase button_base, Rectangle text_rectangle, Graphics dc,
1479 							       StringFormat text_format, Appearance appearance, bool ischecked)
1480 		{
1481 			// offset the text if it's pressed and a button
1482 			if (appearance == Appearance.Button) {
1483 				if (ischecked || (button_base.Capture && button_base.FlatStyle != FlatStyle.Flat)) {
1484 					text_rectangle.X ++;
1485 					text_rectangle.Y ++;
1486 				}
1487 
1488 				text_rectangle.Inflate (-4, -4);
1489 			}
1490 
1491 			/* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
1492 
1493 			// Windows seems to not wrap text in certain situations, this matches as close as I could get it
1494 			if ((float)(button_base.Font.Height * 1.5f) > text_rectangle.Height) {
1495 				text_format.FormatFlags |= StringFormatFlags.NoWrap;
1496 			}
1497 			if (button_base.Enabled) {
1498 				dc.DrawString (button_base.Text, button_base.Font, ResPool.GetSolidBrush (button_base.ForeColor), text_rectangle, text_format);
1499 			} else if (button_base.FlatStyle == FlatStyle.Flat || button_base.FlatStyle == FlatStyle.Popup) {
1500 				dc.DrawString (button_base.Text, button_base.Font, SystemBrushes.ControlDarkDark, text_rectangle, text_format);
1501 			} else {
1502 				CPDrawStringDisabled (dc, button_base.Text, button_base.Font, button_base.BackColor, text_rectangle, text_format);
1503 			}
1504 		}
1505 		#endregion	// CheckBox
1506 
1507 		#region CheckedListBox
1508 
DrawCheckedListBoxItem(CheckedListBox ctrl, DrawItemEventArgs e)1509 		public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e)
1510 		{
1511 			Color back_color, fore_color;
1512 			Rectangle item_rect = e.Bounds;
1513 			ButtonState state;
1514 
1515 			/* Draw checkbox */
1516 
1517 			if ((e.State & DrawItemState.Checked) == DrawItemState.Checked) {
1518 				state = ButtonState.Checked;
1519 				if ((e.State & DrawItemState.Inactive) == DrawItemState.Inactive)
1520 					state |= ButtonState.Inactive;
1521 			} else
1522 				state = ButtonState.Normal;
1523 
1524 			if (ctrl.ThreeDCheckBoxes == false)
1525 				state |= ButtonState.Flat;
1526 
1527 			Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, CheckSize, CheckSize);
1528 			ControlPaint.DrawCheckBox (e.Graphics,
1529 				item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
1530 				checkbox_rect.Width, checkbox_rect.Height,
1531 				state);
1532 
1533 			item_rect.X += checkbox_rect.Right;
1534 			item_rect.Width -= checkbox_rect.Right;
1535 
1536 			/* Draw text*/
1537 			if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1538 				back_color = ColorHighlight;
1539 				fore_color = ColorHighlightText;
1540 			}
1541 			else {
1542 				back_color = e.BackColor;
1543 				fore_color = e.ForeColor;
1544 			}
1545 
1546 			e.Graphics.FillRectangle (ResPool.GetSolidBrush
1547 				(back_color), item_rect);
1548 
1549 			e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1550 				ResPool.GetSolidBrush (fore_color),
1551 				item_rect, ctrl.StringFormat);
1552 
1553 			if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1554 				CPDrawFocusRectangle (e.Graphics, item_rect,
1555 					fore_color, back_color);
1556 			}
1557 		}
1558 
1559 		#endregion // CheckedListBox
1560 
1561 		#region ComboBox
DrawComboBoxItem(ComboBox ctrl, DrawItemEventArgs e)1562 		public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e)
1563 		{
1564 			Color back_color, fore_color;
1565 			Rectangle text_draw = e.Bounds;
1566 			StringFormat string_format = new StringFormat ();
1567 			string_format.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
1568 
1569 			if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1570 				back_color = ColorHighlight;
1571 				fore_color = ColorHighlightText;
1572 			}
1573 			else {
1574 				back_color = e.BackColor;
1575 				fore_color = e.ForeColor;
1576 			}
1577 
1578 			if (!ctrl.Enabled)
1579 				fore_color = ColorInactiveCaptionText;
1580 
1581 			e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
1582 
1583 			if (e.Index != -1) {
1584 				e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1585 					ResPool.GetSolidBrush (fore_color),
1586 					text_draw, string_format);
1587 			}
1588 
1589 			if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1590 				CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
1591 			}
1592 
1593 			string_format.Dispose ();
1594 		}
1595 
DrawFlatStyleComboButton(Graphics graphics, Rectangle rectangle, ButtonState state)1596 		public override void DrawFlatStyleComboButton (Graphics graphics, Rectangle rectangle, ButtonState state)
1597 		{
1598 			Point[]			arrow = new Point[3];
1599 			Point				P1;
1600 			Point				P2;
1601 			Point				P3;
1602 			int				centerX;
1603 			int				centerY;
1604 			int				shiftX;
1605 			int				shiftY;
1606 			Rectangle		rect;
1607 
1608 			rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
1609 			centerX=rect.Left+rect.Width/2;
1610 			centerY=rect.Top+rect.Height/2;
1611 			shiftX=Math.Max(1, rect.Width/8);
1612 			shiftY=Math.Max(1, rect.Height/8);
1613 
1614 			if ((state & ButtonState.Pushed)!=0) {
1615 				shiftX++;
1616 				shiftY++;
1617 			}
1618 
1619 			rect.Y-=shiftY;
1620 			centerY-=shiftY;
1621 			P1=new Point(rect.Left + 1, centerY);
1622 			P2=new Point(rect.Right - 1, centerY);
1623 			P3=new Point(centerX, rect.Bottom - 1);
1624 
1625 			arrow[0]=P1;
1626 			arrow[1]=P2;
1627 			arrow[2]=P3;
1628 
1629 			/* Draw the arrow */
1630 			if ((state & ButtonState.Inactive)!=0) {
1631 				/* Move away from the shadow */
1632 				arrow[0].X += 1;	arrow[0].Y += 1;
1633 				arrow[1].X += 1;	arrow[1].Y += 1;
1634 				arrow[2].X += 1;	arrow[2].Y += 1;
1635 
1636 				graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
1637 
1638 				arrow[0]=P1;
1639 				arrow[1]=P2;
1640 				arrow[2]=P3;
1641 
1642 				graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
1643 			} else {
1644 				graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
1645 			}
1646 		}
ComboBoxDrawNormalDropDownButton(ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state)1647 		public override void ComboBoxDrawNormalDropDownButton (ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state)
1648 		{
1649 			CPDrawComboButton (g, area, state);
1650 		}
ComboBoxNormalDropDownButtonHasTransparentBackground(ComboBox comboBox, ButtonState state)1651 		public override bool ComboBoxNormalDropDownButtonHasTransparentBackground (ComboBox comboBox, ButtonState state)
1652 		{
1653 			return true;
1654 		}
ComboBoxDropDownButtonHasHotElementStyle(ComboBox comboBox)1655 		public override bool ComboBoxDropDownButtonHasHotElementStyle (ComboBox comboBox)
1656 		{
1657 			return false;
1658 		}
ComboBoxDrawBackground(ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style)1659 		public override void ComboBoxDrawBackground (ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style)
1660 		{
1661 			if (!comboBox.Enabled)
1662 				g.FillRectangle (ResPool.GetSolidBrush (ColorControl), comboBox.ClientRectangle);
1663 
1664 			if (comboBox.DropDownStyle == ComboBoxStyle.Simple)
1665 				g.FillRectangle (ResPool.GetSolidBrush (comboBox.Parent.BackColor), comboBox.ClientRectangle);
1666 
1667 			if (style == FlatStyle.Popup && (comboBox.Entered || comboBox.Focused)) {
1668 				Rectangle area = comboBox.TextArea;
1669 				area.Height -= 1;
1670 				area.Width -= 1;
1671 				g.DrawRectangle (ResPool.GetPen (SystemColors.ControlDark), area);
1672 				g.DrawLine (ResPool.GetPen (SystemColors.ControlDark), comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Top, comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Bottom);
1673 			}
1674 			bool is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup;
1675 			if (!is_flat && clippingArea.IntersectsWith (comboBox.TextArea))
1676 				ControlPaint.DrawBorder3D (g, comboBox.TextArea, Border3DStyle.Sunken);
1677 		}
CombBoxBackgroundHasHotElementStyle(ComboBox comboBox)1678 		public override bool CombBoxBackgroundHasHotElementStyle (ComboBox comboBox)
1679 		{
1680 			return false;
1681 		}
1682 		#endregion ComboBox
1683 
1684 		#region Datagrid
1685 		public override int DataGridPreferredColumnWidth { get { return 75;} }
1686 		public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} }
1687 		public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} }
1688 		public override Color DataGridAlternatingBackColor { get { return ColorWindow;} }
1689 		public override Color DataGridBackColor { get  { return  ColorWindow;} }
1690 		public override Color DataGridBackgroundColor { get  { return  ColorAppWorkspace;} }
1691 		public override Color DataGridCaptionBackColor { get  { return ColorActiveCaption;} }
1692 		public override Color DataGridCaptionForeColor { get  { return ColorActiveCaptionText;} }
1693 		public override Color DataGridGridLineColor { get { return ColorControl;} }
1694 		public override Color DataGridHeaderBackColor { get  { return ColorControl;} }
1695 		public override Color DataGridHeaderForeColor { get  { return ColorControlText;} }
1696 		public override Color DataGridLinkColor { get  { return ColorHotTrack;} }
1697 		public override Color DataGridLinkHoverColor { get  { return ColorHotTrack;} }
1698 		public override Color DataGridParentRowsBackColor { get  { return ColorControl;} }
1699 		public override Color DataGridParentRowsForeColor { get  { return ColorWindowText;} }
1700 		public override Color DataGridSelectionBackColor { get  { return ColorActiveCaption;} }
1701 		public override Color DataGridSelectionForeColor { get  { return ColorActiveCaptionText;} }
1702 
DataGridPaint(PaintEventArgs pe, DataGrid grid)1703 		public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
1704 		{
1705 			DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
1706 			DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid);
1707 			DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid);
1708 			DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid);
1709 
1710 			// Paint scrollBar corner
1711 			if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) {
1712 
1713 				Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.VScrollBar.Width,
1714 								  grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.HScrollBar.Height,
1715 								  grid.VScrollBar.Width, grid.HScrollBar.Height);
1716 
1717 				if (pe.ClipRectangle.IntersectsWith (corner)) {
1718 					pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1719 								   corner);
1720 				}
1721 			}
1722 		}
1723 
DataGridPaintCaption(Graphics g, Rectangle clip, DataGrid grid)1724 		public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
1725 		{
1726 			Rectangle bounds = clip;
1727 			bounds.Intersect (grid.caption_area);
1728 
1729 			// Background
1730 			g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor), bounds);
1731 
1732 			// Bottom line
1733     		g.DrawLine (ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor),
1734 					bounds.X, bounds.Y + bounds.Height -1,
1735                     bounds.X + bounds.Width, bounds.Y + bounds.Height -1);
1736 
1737 			// Caption text
1738 			if (grid.CaptionText != String.Empty) {
1739 				Rectangle text_rect = grid.caption_area;
1740 				text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2;
1741 				text_rect.Height = grid.CaptionFont.Height;
1742 
1743 				g.DrawString (grid.CaptionText, grid.CaptionFont,
1744 					      ResPool.GetSolidBrush (grid.CaptionForeColor),
1745 					      text_rect);
1746 			}
1747 
1748 			// Back button
1749 			if (bounds.IntersectsWith (grid.back_button_rect)) {
1750 				g.DrawImage (grid.back_button_image, grid.back_button_rect);
1751 				if (grid.back_button_mouseover) {
1752 					CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1753 				}
1754 			}
1755 
1756 			// Rows button
1757 			if (bounds.IntersectsWith (grid.parent_rows_button_rect)) {
1758 				g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
1759 				if (grid.parent_rows_button_mouseover) {
1760 					CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1761 				}
1762 			}
1763 		}
1764 
DataGridPaintColumnHeaders(Graphics g, Rectangle clip, DataGrid grid)1765 		public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
1766 		{
1767 			if (!grid.CurrentTableStyle.ColumnHeadersVisible)
1768 				return;
1769 
1770 			Rectangle columns_area = grid.column_headers_area;
1771 
1772 			// Paint corner shared between row and column header
1773 			if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1774 				Rectangle rect_bloc = grid.column_headers_area;
1775 				rect_bloc.Width = grid.RowHeaderWidth;
1776 				if (clip.IntersectsWith (rect_bloc)) {
1777 					if (grid.FlatMode)
1778 						g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
1779 					else
1780 						CPDrawBorder3D (g, rect_bloc, Border3DStyle.RaisedInner,
1781 							Border3DSide.Left | Border3DSide.Right |
1782 							Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Middle,
1783 							grid.CurrentTableStyle.CurrentHeaderBackColor);
1784 				}
1785 
1786 				columns_area.X += grid.RowHeaderWidth;
1787 				columns_area.Width -= grid.RowHeaderWidth;
1788 			}
1789 
1790 			// Set column painting
1791 			Rectangle rect_columnhdr = new Rectangle ();
1792 			int col_pixel;
1793 			Region current_clip;
1794 			Region prev_clip = g.Clip;
1795 			rect_columnhdr.Y = columns_area.Y;
1796 			rect_columnhdr.Height = columns_area.Height;
1797 
1798 			int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
1799 			for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
1800 				if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
1801 					continue;
1802 
1803 				col_pixel = grid.GetColumnStartingPixel (column);
1804 				rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
1805 				rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
1806 
1807 				if (clip.IntersectsWith (rect_columnhdr) == false)
1808 					continue;
1809 
1810 				current_clip = new Region (rect_columnhdr);
1811 				current_clip.Intersect (columns_area);
1812 				current_clip.Intersect (prev_clip);
1813 				g.Clip = current_clip;
1814 
1815 				DataGridPaintColumnHeader (g, rect_columnhdr, grid, column);
1816 
1817 				current_clip.Dispose ();
1818 			}
1819 
1820 			g.Clip = prev_clip;
1821 
1822 			Rectangle not_usedarea = grid.column_headers_area;
1823 			not_usedarea.X = (column_cnt == 0) ? grid.RowHeaderWidth : rect_columnhdr.X + rect_columnhdr.Width;
1824 			not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - not_usedarea.X;
1825 			g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
1826 		}
1827 
DataGridPaintColumnHeader(Graphics g, Rectangle bounds, DataGrid grid, int col)1828 		public override void DataGridPaintColumnHeader (Graphics g, Rectangle bounds, DataGrid grid, int col)
1829 		{
1830 			// Background
1831 			g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.HeaderBackColor), bounds);
1832 
1833 			// Paint Borders
1834 			if (!grid.FlatMode) {
1835 				g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1836 					bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1837 
1838 				if (col == 0) {
1839 					g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1840 						bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height);
1841 				} else {
1842 					g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1843 						bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 3);
1844 				}
1845 
1846 				if (col == (grid.VisibleColumnCount -1)) {
1847 					g.DrawLine (ResPool.GetPen (ColorControlDark),
1848 						bounds.X + bounds.Width - 1, bounds.Y,
1849 						bounds.X + bounds.Width - 1, bounds.Y + bounds.Height);
1850 				} else {
1851 					g.DrawLine (ResPool.GetPen (ColorControlDark),
1852 						bounds.X + bounds.Width - 1, bounds.Y + 2,
1853 						bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 3);
1854 				}
1855 
1856 				g.DrawLine (ResPool.GetPen (ColorControlDark),
1857 					bounds.X, bounds.Y + bounds.Height - 1,
1858 					bounds.X + bounds.Width, bounds.Y + bounds.Height - 1);
1859 			}
1860 
1861 			bounds.X += 2;
1862 			bounds.Width -= 2;
1863 
1864 			DataGridColumnStyle style = grid.CurrentTableStyle.GridColumnStyles[col];
1865 
1866 			if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No)
1867 				bounds.Width -= 16;
1868 
1869 			// Caption
1870 			StringFormat format = new StringFormat ();
1871 			format.FormatFlags |= StringFormatFlags.NoWrap;
1872 			format.LineAlignment = StringAlignment.Center;
1873 			format.Trimming = StringTrimming.Character;
1874 
1875 			g.DrawString (style.HeaderText, grid.CurrentTableStyle.HeaderFont,
1876 				ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1877 				bounds, format);
1878 
1879 			// Arrow (6 x 6)
1880 			if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) {
1881 				Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2));
1882 
1883 				if (style.ArrowDrawingMode == DataGridColumnStyle.ArrowDrawing.Ascending) {
1884 					g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y);
1885 					g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6);
1886 					g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y);
1887 				} else {
1888 					g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6);
1889 					g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y);
1890 					g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6);
1891 				}
1892 			}
1893 		}
1894 
DataGridPaintParentRows(Graphics g, Rectangle clip, DataGrid grid)1895 		public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
1896 		{
1897 			Rectangle rect_row = new Rectangle ();
1898 
1899 			rect_row.X = grid.ParentRowsArea.X;
1900 			rect_row.Width = grid.ParentRowsArea.Width;
1901 			rect_row.Height = (grid.CaptionFont.Height + 3);
1902 
1903 			object[] parentRows = grid.data_source_stack.ToArray();
1904 
1905 			Region current_clip;
1906 			Region prev_clip = g.Clip;
1907 			for (int row = 0; row < parentRows.Length; row++) {
1908 				rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
1909 
1910 				if (clip.IntersectsWith (rect_row) == false)
1911 					continue;
1912 
1913 				current_clip = new Region (rect_row);
1914 				current_clip.Intersect (prev_clip);
1915 				g.Clip = current_clip;
1916 
1917 				DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
1918 
1919 				current_clip.Dispose ();
1920 			}
1921 
1922 			g.Clip = prev_clip;
1923 		}
1924 
DataGridPaintParentRow(Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)1925 		public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
1926 		{
1927 			// Background
1928 			g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1929 					 bounds);
1930 
1931 			Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
1932 			// set up some standard string formating variables
1933 			StringFormat text_format = new StringFormat();
1934 			text_format.LineAlignment = StringAlignment.Center;
1935 			text_format.Alignment = StringAlignment.Near;
1936 
1937 			string table_name = "";
1938 			if (row.view is DataRowView)
1939 				table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": ";
1940 			// XXX else?
1941 
1942 			Rectangle	text_rect;
1943 			Size		text_size;
1944 
1945 			text_size = g.MeasureString (table_name, bold_font).ToSize();
1946 			text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
1947 
1948 			g.DrawString (table_name,
1949 				      bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1950 
1951 			foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
1952 				if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
1953 					continue;
1954 
1955 				text_rect.X += text_rect.Size.Width + 5;
1956 
1957 				string text = String.Format ("{0}: {1}",
1958 							     pd.Name,
1959 							     pd.GetValue (row.view));
1960 
1961 				text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
1962 				text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
1963 
1964 				g.DrawString (text,
1965 					      grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1966 			}
1967 
1968             // Paint Borders
1969 			if (!grid.FlatMode) {
1970                 CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner,
1971                     Border3DSide.Left | Border3DSide.Right |
1972                     Border3DSide.Top | Border3DSide.Bottom);
1973 			}
1974 		}
1975 
DataGridPaintRowHeaderArrow(Graphics g, Rectangle bounds, DataGrid grid)1976 		public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid)
1977 		{
1978 			Point[] arrow = new Point[3];
1979 			Point P1, P2, P3;
1980 			int centerX, centerY, shiftX;
1981 			Rectangle rect;
1982 
1983 			rect = new Rectangle (bounds.X + bounds.Width /4,
1984 				bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2);
1985 
1986 			centerX = rect.Left + rect.Width / 2;
1987 			centerY = rect.Top + rect.Height / 2;
1988 			shiftX = Math.Max (1, rect.Width / 8);
1989 			rect.X -= shiftX;
1990 			centerX -= shiftX;
1991 			P1 = new Point (centerX, rect.Top - 1);
1992 			P2 = new Point (centerX, rect.Bottom);
1993 			P3 = new Point (rect.Right, centerY);
1994 			arrow[0] = P1;
1995 			arrow[1] = P2;
1996 			arrow[2] = P3;
1997 
1998 			g.FillPolygon (ResPool.GetSolidBrush
1999 				(grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding);
2000 		}
2001 
DataGridPaintRowHeaderStar(Graphics g, Rectangle bounds, DataGrid grid)2002 		public override void DataGridPaintRowHeaderStar (Graphics g, Rectangle bounds, DataGrid grid)
2003 		{
2004 			int x = bounds.X + 4;
2005 			int y = bounds.Y + 3;
2006 			Pen pen = ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor);
2007 
2008 			g.DrawLine (pen, x + 4, y, x + 4, y + 8);
2009 			g.DrawLine (pen, x, y + 4, x + 8, y + 4);
2010 			g.DrawLine (pen, x + 1, y + 1, x + 7, y + 7);
2011 			g.DrawLine (pen, x + 7, y + 1, x + 1, y + 7);
2012 		}
2013 
DataGridPaintRowHeader(Graphics g, Rectangle bounds, int row, DataGrid grid)2014 		public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
2015 		{
2016 			bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1;
2017 			bool is_current_row = row == grid.CurrentCell.RowNumber;
2018 
2019 			// Background
2020 			g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), bounds);
2021 
2022 			// Draw arrow
2023 			if (is_current_row) {
2024 				if (grid.IsChanging) {
2025 					g.DrawString ("...", grid.Font,
2026 						      ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
2027 						      bounds);
2028 				} else {
2029 					Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
2030 					DataGridPaintRowHeaderArrow (g, rect, grid);
2031 				}
2032 			}
2033 			else if (is_add_row) {
2034 				DataGridPaintRowHeaderStar (g, bounds, grid);
2035 			}
2036 
2037 			if (!grid.FlatMode && !is_add_row) {
2038 				CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner,
2039 					Border3DSide.Left | Border3DSide.Right |
2040 					Border3DSide.Top | Border3DSide.Bottom);
2041 			}
2042 		}
2043 
DataGridPaintRows(Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)2044 		public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)
2045 		{
2046 			Rectangle rect_row = new Rectangle ();
2047 			Rectangle not_usedarea = new Rectangle ();
2048 
2049 			int rowcnt = grid.VisibleRowCount;
2050 
2051 			bool showing_add_row = false;
2052 
2053 			if (grid.RowsCount < grid.DataGridRows.Length) {
2054 				/* the table has an add row */
2055 
2056 				if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) {
2057 					showing_add_row = true;
2058 				}
2059 			}
2060 
2061 			rect_row.Width = cells.Width + grid.RowHeadersArea.Width;
2062 			for (int r = 0; r < rowcnt; r++) {
2063 				int row = grid.FirstVisibleRow + r;
2064 				if (row == grid.DataGridRows.Length - 1)
2065 					rect_row.Height = grid.DataGridRows[row].Height;
2066 				else
2067 					rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset;
2068 				rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset;
2069 				if (clip.IntersectsWith (rect_row)) {
2070 					if (grid.CurrentTableStyle.HasRelations
2071 					    && !(showing_add_row && row == grid.DataGridRows.Length - 1))
2072 						DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
2073 					else
2074 						DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid);
2075 				}
2076 			}
2077 
2078 			not_usedarea.X = 0;
2079 			// the rowcnt == 0 check is needed because
2080 			// otherwise we'd draw over the caption on
2081 			// empty datasources (since rect_row would be
2082 			// Empty)
2083 			if (rowcnt == 0)
2084 				not_usedarea.Y = cells.Y;
2085 			else
2086 				not_usedarea.Y = rect_row.Y + rect_row.Height;
2087 			not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
2088 			not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
2089 
2090 			g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
2091 		}
2092 
DataGridPaintRelationRow(Graphics g, int row, Rectangle row_rect, bool is_newrow, Rectangle clip, DataGrid grid)2093 		public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2094 							       Rectangle clip, DataGrid grid)
2095 		{
2096 			Rectangle rect_header;
2097 			Rectangle icon_bounds = new Rectangle ();
2098 			Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
2099 
2100 			/* paint the header if it's visible and intersects the clip */
2101 			if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2102 				rect_header = row_rect;
2103 				rect_header.Width = grid.RowHeaderWidth;
2104 				row_rect.X += grid.RowHeaderWidth;
2105 				if (clip.IntersectsWith (rect_header)) {
2106 					DataGridPaintRowHeader (g, rect_header, row, grid);
2107 				}
2108 
2109 				icon_bounds = rect_header;
2110 				icon_bounds.X += icon_bounds.Width / 2;
2111 				icon_bounds.Y += 3;
2112 				icon_bounds.Width = 8;
2113 				icon_bounds.Height = 8;
2114 
2115 				g.DrawRectangle (pen, icon_bounds);
2116 
2117 				/* the - part of the icon */
2118 				g.DrawLine (pen,
2119 					    icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
2120 					    icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
2121 
2122 				if (!grid.IsExpanded (row)) {
2123 					/* the | part of the icon */
2124 					g.DrawLine (pen,
2125 						    icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
2126 						    icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
2127 				}
2128 			}
2129 
2130 			Rectangle nested_rect = row_rect;
2131 
2132 			if (grid.DataGridRows[row].IsExpanded)
2133 				nested_rect.Height -= grid.DataGridRows[row].RelationHeight;
2134 
2135 			DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
2136 
2137 			if (grid.DataGridRows[row].IsExpanded) {
2138 				// XXX we should create this in the
2139 				// datagrid and cache it for use by
2140 				// the theme instead of doing it each
2141 				// time through here
2142 				string[] relations = grid.CurrentTableStyle.Relations;
2143 				StringBuilder relation_builder = new StringBuilder ("");
2144 
2145 				for (int i = 0; i < relations.Length; i ++) {
2146 					if (i > 0)
2147 						relation_builder.Append ("\n");
2148 
2149 					relation_builder.Append (relations[i]);
2150 				}
2151 				string relation_text = relation_builder.ToString ();
2152 
2153 				StringFormat string_format = new StringFormat ();
2154 				string_format.FormatFlags |= StringFormatFlags.NoWrap;
2155 
2156 
2157 				//Region prev_clip = g.Clip;
2158 				//Region current_clip;
2159 				Rectangle rect_cell = row_rect;
2160 
2161 				rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
2162 				rect_cell.Y += nested_rect.Height;
2163 				rect_cell.Height = grid.DataGridRows[row].RelationHeight;
2164 
2165 				rect_cell.Width = 0;
2166 				int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2167 				for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2168 					if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2169 						continue;
2170 					rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
2171 				}
2172 				rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width);
2173 
2174 				g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
2175 						 rect_cell);
2176 
2177 
2178 				/* draw the line leading from the +/- to the relation area */
2179 				Rectangle outline = grid.DataGridRows[row].relation_area;
2180 				outline.Y = rect_cell.Y;
2181 				outline.Height --;
2182 
2183 				g.DrawLine (pen,
2184 					    icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
2185 					    icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
2186 
2187 				g.DrawLine (pen,
2188 					    icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
2189 					    outline.X, outline.Y + outline.Height / 2);
2190 
2191 				g.DrawRectangle (pen, outline);
2192 
2193 				g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
2194 					      outline, string_format);
2195 
2196 				if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2197 					Rectangle not_usedarea = new Rectangle ();
2198 					not_usedarea.X = rect_cell.X + rect_cell.Width;
2199 					not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2200 					not_usedarea.Y = row_rect.Y;
2201 					not_usedarea.Height = row_rect.Height;
2202 					if (clip.IntersectsWith (not_usedarea))
2203 						g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2204 								 not_usedarea);
2205 				}
2206 			}
2207 		}
2208 
DataGridPaintRowContents(Graphics g, int row, Rectangle row_rect, bool is_newrow, Rectangle clip, DataGrid grid)2209 		public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2210 							       Rectangle clip, DataGrid grid)
2211 		{
2212 			Rectangle rect_cell = new Rectangle ();
2213 			int col_pixel;
2214 			Color backcolor, forecolor;
2215 			Brush backBrush, foreBrush;
2216 			Rectangle not_usedarea = Rectangle.Empty;
2217 
2218 			rect_cell.Y = row_rect.Y;
2219 			rect_cell.Height = row_rect.Height;
2220 
2221 			if (grid.IsSelected (row)) {
2222 				backcolor =  grid.SelectionBackColor;
2223 				forecolor =  grid.SelectionForeColor;
2224 			} else {
2225 				if (row % 2 == 0) {
2226 					backcolor =  grid.BackColor;
2227 				} else {
2228 					backcolor =  grid.AlternatingBackColor;
2229 				}
2230 
2231 				forecolor =  grid.ForeColor;
2232 			}
2233 
2234 
2235 			backBrush = ResPool.GetSolidBrush (backcolor);
2236 			foreBrush = ResPool.GetSolidBrush (forecolor);
2237 
2238 			// PaintCells at row, column
2239 			int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2240 			DataGridCell current_cell = grid.CurrentCell;
2241 
2242 			if (column_cnt > 0) {
2243 				Region prev_clip = g.Clip;
2244 				Region current_clip;
2245 
2246 				for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2247 					if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2248 						continue;
2249 
2250 					col_pixel = grid.GetColumnStartingPixel (column);
2251 
2252 					rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
2253 					rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
2254 
2255 					if (clip.IntersectsWith (rect_cell)) {
2256 						current_clip = new Region (rect_cell);
2257 						current_clip.Intersect (row_rect);
2258 						current_clip.Intersect (prev_clip);
2259 						g.Clip = current_clip;
2260 
2261 						Brush colBackBrush = backBrush;
2262 						Brush colForeBrush = foreBrush;
2263 
2264 						// If we are in the precise cell we are editing, then use the normal colors
2265 						// even if we are selected.
2266 						if (grid.is_editing && column == current_cell.ColumnNumber && row == current_cell.RowNumber) {
2267 							colBackBrush = ResPool.GetSolidBrush (grid.BackColor);
2268 							colForeBrush = ResPool.GetSolidBrush (grid.ForeColor);
2269 						}
2270 
2271 						if (is_newrow) {
2272 							grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell,
2273 														     colBackBrush,
2274 														     colForeBrush);
2275 						} else {
2276 							grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
2277 													       colBackBrush,
2278 													       colForeBrush,
2279 													       grid.RightToLeft == RightToLeft.Yes);
2280 						}
2281 
2282 						current_clip.Dispose ();
2283 					}
2284 				}
2285 
2286 				g.Clip = prev_clip;
2287 
2288 				if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2289 					not_usedarea.X = rect_cell.X + rect_cell.Width;
2290 					not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2291 					not_usedarea.Y = row_rect.Y;
2292 					not_usedarea.Height = row_rect.Height;
2293 				}
2294 			}
2295 			else {
2296 				not_usedarea = row_rect;
2297 			}
2298 
2299 			if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea))
2300 				g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2301 						 not_usedarea);
2302 		}
2303 
DataGridPaintRow(Graphics g, int row, Rectangle row_rect, bool is_newrow, Rectangle clip, DataGrid grid)2304 		public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2305 						       Rectangle clip, DataGrid grid)
2306 		{
2307 			/* paint the header if it's visible and intersects the clip */
2308 			if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2309 				Rectangle rect_header = row_rect;
2310 				rect_header.Width = grid.RowHeaderWidth;
2311 				row_rect.X += grid.RowHeaderWidth;
2312 				if (clip.IntersectsWith (rect_header)) {
2313 					DataGridPaintRowHeader (g, rect_header, row, grid);
2314 				}
2315 			}
2316 
2317 			DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
2318 		}
2319 
2320 		#endregion // Datagrid
2321 
2322 		#region DataGridView
2323 		#region DataGridViewHeaderCell
2324 		#region DataGridViewRowHeaderCell
DataGridViewRowHeaderCellDrawBackground(DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)2325 		public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2326 		{
2327 			return false;
2328 		}
2329 
DataGridViewRowHeaderCellDrawSelectionBackground(DataGridViewRowHeaderCell cell)2330 		public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell)
2331 		{
2332 			return false;
2333 		}
2334 
DataGridViewRowHeaderCellDrawBorder(DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)2335 		public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2336 		{
2337 			return false;
2338 		}
2339 		#endregion
2340 
2341 		#region DataGridViewColumnHeaderCell
DataGridViewColumnHeaderCellDrawBackground(DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)2342 		public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2343 		{
2344 			return false;
2345 		}
2346 
DataGridViewColumnHeaderCellDrawBorder(DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)2347 		public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2348 		{
2349 			return false;
2350 		}
2351 		#endregion
2352 
DataGridViewHeaderCellHasPressedStyle(DataGridView dataGridView)2353 		public override bool DataGridViewHeaderCellHasPressedStyle  (DataGridView dataGridView)
2354 		{
2355 			return false;
2356 		}
2357 
DataGridViewHeaderCellHasHotStyle(DataGridView dataGridView)2358 		public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView)
2359 		{
2360 			return false;
2361 		}
2362 		#endregion
2363 		#endregion
2364 
2365 		#region DateTimePicker
DateTimePickerDrawBorder(DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)2366 		protected virtual void DateTimePickerDrawBorder (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2367 		{
2368 			this.CPDrawBorder3D (g, dateTimePicker.ClientRectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dateTimePicker.BackColor);
2369 		}
2370 
DateTimePickerDrawDropDownButton(DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)2371 		protected virtual void DateTimePickerDrawDropDownButton (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2372 		{
2373 			ButtonState state = dateTimePicker.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
2374 			g.FillRectangle (ResPool.GetSolidBrush (ColorControl), dateTimePicker.drop_down_arrow_rect);
2375 			this.CPDrawComboButton (
2376 			  g,
2377 			  dateTimePicker.drop_down_arrow_rect,
2378 			  state);
2379 		}
2380 
DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp)2381 		public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp)
2382 		{
2383 
2384 			if (!clip_rectangle.IntersectsWith (dtp.ClientRectangle))
2385 				return;
2386 
2387 			// draw the outer border
2388 			Rectangle button_bounds = dtp.ClientRectangle;
2389 			DateTimePickerDrawBorder (dtp, dc, clip_rectangle);
2390 
2391 			// deflate by the border width
2392 			if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
2393 				button_bounds.Inflate (-2,-2);
2394 				if (!dtp.ShowUpDown) {
2395 					DateTimePickerDrawDropDownButton (dtp, dc, clip_rectangle);
2396 				} else {
2397 					ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal;
2398 					ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal;
2399 					Rectangle up_bounds = dtp.drop_down_arrow_rect;
2400 					Rectangle down_bounds = dtp.drop_down_arrow_rect;
2401 
2402 					up_bounds.Height = up_bounds.Height / 2;
2403 					down_bounds.Y = up_bounds.Height;
2404 					down_bounds.Height = dtp.Height - up_bounds.Height;
2405 					if (down_bounds.Height > up_bounds.Height)
2406 					{
2407 						down_bounds.Y += 1;
2408 						down_bounds.Height -= 1;
2409 					}
2410 
2411 					up_bounds.Inflate (-1, -1);
2412 					down_bounds.Inflate (-1, -1);
2413 
2414 					ControlPaint.DrawScrollButton (dc, up_bounds, ScrollButton.Up, up_state);
2415 					ControlPaint.DrawScrollButton (dc, down_bounds, ScrollButton.Down, down_state);
2416 				}
2417 			}
2418 
2419 			// render the date part
2420 			if (!clip_rectangle.IntersectsWith (dtp.date_area_rect))
2421 				return;
2422 
2423 			// fill the background
2424 			dc.FillRectangle (SystemBrushes.Window, dtp.date_area_rect);
2425 
2426 			// Update date_area_rect if we are drawing the checkbox
2427 			Rectangle date_area_rect = dtp.date_area_rect;
2428 			if (dtp.ShowCheckBox) {
2429 				Rectangle check_box_rect = dtp.CheckBoxRect;
2430 				date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2;
2431 				date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2;
2432 
2433 				ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal;
2434 				CPDrawCheckBox(dc, check_box_rect, bs);
2435 
2436 				if (dtp.is_checkbox_selected)
2437 					CPDrawFocusRectangle (dc, check_box_rect, dtp.foreground_color, dtp.background_color);
2438 			}
2439 
2440 			// render each text part
2441 			using (StringFormat text_format = StringFormat.GenericTypographic)
2442 			{
2443 				text_format.LineAlignment = StringAlignment.Near;
2444 				text_format.Alignment = StringAlignment.Near;
2445 				text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
2446 				text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2447 
2448 				// Calculate the rectangles for each part
2449 				if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty)
2450 				{
2451 					Graphics gr = dc;
2452 					for (int i = 0; i < dtp.part_data.Length; i++)
2453 					{
2454 						DateTimePicker.PartData fd = dtp.part_data[i];
2455 						RectangleF text_rect = new RectangleF();
2456 						string text = fd.GetText(dtp.Value);
2457 						text_rect.Size = gr.MeasureString (text, dtp.Font, 250, text_format);
2458 						if (!fd.is_literal)
2459 							text_rect.Width = Math.Max (dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width);
2460 
2461 						if (i > 0) {
2462 							text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right;
2463 						} else {
2464 							text_rect.X = date_area_rect.X;
2465 						}
2466 						text_rect.Y = 2;
2467 						text_rect.Inflate (1, 0);
2468 						fd.drawing_rectangle = text_rect;
2469 					}
2470 				}
2471 
2472 				// draw the text part
2473 				Brush text_brush = ResPool.GetSolidBrush (dtp.ShowCheckBox && dtp.Checked == false ?
2474 						SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false
2475 				RectangleF clip_rectangleF = clip_rectangle;
2476 
2477 				for (int i = 0; i < dtp.part_data.Length; i++)
2478 				{
2479 					DateTimePicker.PartData fd = dtp.part_data [i];
2480 					string text;
2481 
2482 					if (!clip_rectangleF.IntersectsWith (fd.drawing_rectangle))
2483 						continue;
2484 
2485 					text = dtp.editing_part_index == i ? dtp.editing_text : fd.GetText (dtp.Value);
2486 
2487 					PointF text_position = new PointF ();
2488 					SizeF text_size;
2489 					RectangleF text_rect;
2490 
2491 					text_size = dc.MeasureString (text, dtp.Font, 250, text_format);
2492 					text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2;
2493 					text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2;
2494 					text_rect = new RectangleF (text_position, text_size);
2495 					text_rect = RectangleF.Intersect (text_rect, date_area_rect);
2496 
2497 					if (text_rect.IsEmpty)
2498 						break;
2499 
2500 					if (text_rect.Right >= date_area_rect.Right)
2501 						text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2502 					else
2503 						text_format.FormatFlags |= StringFormatFlags.NoClip;
2504 
2505 					if (fd.Selected) {
2506 						dc.FillRectangle (SystemBrushes.Highlight, text_rect);
2507 						dc.DrawString (text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format);
2508 
2509 					} else {
2510 						dc.DrawString (text, dtp.Font, text_brush, text_rect, text_format);
2511 					}
2512 
2513 					if (fd.drawing_rectangle.Right > date_area_rect.Right)
2514 						break; // the next part would be not be visible, so don't draw anything more.
2515 				}
2516 			}
2517 		}
2518 
2519 		public override bool DateTimePickerBorderHasHotElementStyle {
2520 			get {
2521 				return false;
2522 			}
2523 		}
2524 
DateTimePickerGetDropDownButtonArea(DateTimePicker dateTimePicker)2525 		public override Rectangle DateTimePickerGetDropDownButtonArea (DateTimePicker dateTimePicker)
2526 		{
2527 			Rectangle rect = dateTimePicker.ClientRectangle;
2528 			rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2;
2529 			if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) {
2530 				rect.Width = SystemInformation.VerticalScrollBarWidth;
2531 			} else {
2532 				rect.Width = Math.Max (rect.Width - 2, 0);
2533 			}
2534 
2535 			rect.Inflate (0, -2);
2536 			return rect;
2537 		}
2538 
DateTimePickerGetDateArea(DateTimePicker dateTimePicker)2539 		public override Rectangle DateTimePickerGetDateArea (DateTimePicker dateTimePicker)
2540 		{
2541 			Rectangle rect = dateTimePicker.ClientRectangle;
2542 			if (dateTimePicker.ShowUpDown) {
2543 				// set the space to the left of the up/down button
2544 				if (rect.Width > (DateTimePicker.up_down_width + 4)) {
2545 					rect.Width -= (DateTimePicker.up_down_width + 4);
2546 				} else {
2547 					rect.Width = 0;
2548 				}
2549 			} else {
2550 				// set the space to the left of the up/down button
2551 				// TODO make this use up down button
2552 				if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) {
2553 					rect.Width -= SystemInformation.VerticalScrollBarWidth;
2554 				} else {
2555 					rect.Width = 0;
2556 				}
2557 			}
2558 
2559 			rect.Inflate (-2, -2);
2560 			return rect;
2561 		}
2562 		public override bool DateTimePickerDropDownButtonHasHotElementStyle {
2563 			get {
2564 				return false;
2565 			}
2566 		}
2567 		#endregion // DateTimePicker
2568 
2569 		#region GroupBox
DrawGroupBox(Graphics dc, Rectangle area, GroupBox box)2570 		public override void DrawGroupBox (Graphics dc,  Rectangle area, GroupBox box) {
2571 			StringFormat	text_format;
2572 			SizeF		size;
2573 			int		width;
2574 			int		y;
2575 
2576 			dc.FillRectangle (GetControlBackBrush (box.BackColor), box.ClientRectangle);
2577 
2578 			text_format = new StringFormat();
2579 			text_format.HotkeyPrefix = HotkeyPrefix.Show;
2580 
2581 			size = dc.MeasureString (box.Text, box.Font);
2582 			width = 0;
2583 
2584 			if (size.Width > 0) {
2585 				width = ((int) size.Width) + 7;
2586 
2587 				if (width > box.Width - 16)
2588 					width = box.Width - 16;
2589 			}
2590 
2591 			y = box.Font.Height / 2;
2592 
2593 			// Clip the are that the text will be in
2594 			Region prev_clip = dc.Clip;
2595 			dc.SetClip (new Rectangle (10, 0, width, box.Font.Height), CombineMode.Exclude);
2596 			/* Draw group box*/
2597 			CPDrawBorder3D (dc, new Rectangle (0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor);
2598 			dc.Clip = prev_clip;
2599 
2600 			/* Text */
2601 			if (box.Text.Length != 0) {
2602 				if (box.Enabled) {
2603 					dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format);
2604 				} else {
2605 					CPDrawStringDisabled (dc, box.Text, box.Font, box.BackColor,
2606 							      new RectangleF (10, 0, width,  box.Font.Height), text_format);
2607 				}
2608 			}
2609 
2610 			text_format.Dispose ();
2611 		}
2612 
2613 		public override Size GroupBoxDefaultSize {
2614 			get {
2615 				return new Size (200,100);
2616 			}
2617 		}
2618 		#endregion
2619 
2620 		#region HScrollBar
2621 		public override Size HScrollBarDefaultSize {
2622 			get {
2623 				return new Size (80, this.ScrollBarButtonSize);
2624 			}
2625 		}
2626 
2627 		#endregion	// HScrollBar
2628 
2629 		#region ListBox
2630 
DrawListBoxItem(ListBox ctrl, DrawItemEventArgs e)2631 		public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
2632 		{
2633 			Color back_color, fore_color;
2634 
2635 			if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
2636 				back_color = ColorHighlight;
2637 				fore_color = ColorHighlightText;
2638 			} else {
2639 				back_color = e.BackColor;
2640 				fore_color = e.ForeColor;
2641 			}
2642 
2643 			e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
2644 
2645 			e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
2646 					       ResPool.GetSolidBrush (fore_color),
2647 					       e.Bounds, ctrl.StringFormat);
2648 
2649 			if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
2650 				CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
2651 		}
2652 
2653 		#endregion ListBox
2654 
2655 		#region ListView
2656 		// Drawing
DrawListViewItems(Graphics dc, Rectangle clip, ListView control)2657 		public override void DrawListViewItems (Graphics dc, Rectangle clip, ListView control)
2658 		{
2659 			bool details = control.View == View.Details;
2660 			int first = control.FirstVisibleIndex;
2661 			int lastvisibleindex = control.LastVisibleIndex;
2662 
2663 			if (control.VirtualMode)
2664 				control.OnCacheVirtualItems (new CacheVirtualItemsEventArgs (first, lastvisibleindex));
2665 
2666 			for (int i = first; i <= lastvisibleindex; i++) {
2667 				ListViewItem item = control.GetItemAtDisplayIndex (i);
2668 				if (clip.IntersectsWith (item.Bounds)) {
2669 					bool owner_draw = false;
2670 					if (control.OwnerDraw)
2671 						owner_draw = DrawListViewItemOwnerDraw (dc, item, i);
2672 					if (!owner_draw)
2673 					{
2674 						DrawListViewItem (dc, control, item);
2675 						if (control.View == View.Details)
2676 							DrawListViewSubItems (dc, control, item);
2677 					}
2678 				}
2679 			}
2680 
2681 			if (control.UsingGroups) {
2682 				// Use InternalCount instead of Count to take into account Default Group as needed
2683 				for (int i = 0; i < control.Groups.InternalCount; i++) {
2684 					ListViewGroup group = control.Groups.GetInternalGroup (i);
2685 					if (group.ItemCount > 0 && clip.IntersectsWith (group.HeaderBounds))
2686 						DrawListViewGroupHeader (dc, control, group);
2687 				}
2688 			}
2689 
2690 			ListViewInsertionMark insertion_mark = control.InsertionMark;
2691 			int insertion_mark_index = insertion_mark.Index;
2692 			if (Application.VisualStylesEnabled && insertion_mark.Bounds != Rectangle.Empty &&
2693 					(control.View != View.Details && control.View != View.List) &&
2694 					insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) {
2695 
2696 				Brush brush = ResPool.GetSolidBrush (insertion_mark.Color);
2697 				dc.FillRectangle (brush, insertion_mark.Line);
2698 				dc.FillPolygon (brush, insertion_mark.TopTriangle);
2699 				dc.FillPolygon (brush, insertion_mark.BottomTriangle);
2700 			}
2701 
2702 			// draw the gridlines
2703 			if (details && control.GridLines && !control.UsingGroups) {
2704 				Size control_size = control.ClientSize;
2705 				int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
2706 					0 : control.header_control.Height;
2707 
2708 				// draw vertical gridlines
2709 				foreach (ColumnHeader col in control.Columns) {
2710 					int column_right = col.Rect.Right - control.h_marker;
2711 					dc.DrawLine (SystemPens.Control,
2712 						     column_right, top,
2713 						     column_right, control_size.Height);
2714 				}
2715 
2716 				// draw horizontal gridlines
2717 				int item_height = control.ItemSize.Height;
2718 				if (item_height == 0)
2719 					item_height =  control.Font.Height + 2;
2720 
2721 				int y = top + item_height - (control.v_marker % item_height); // scroll bar offset
2722 				while (y < control_size.Height) {
2723 					dc.DrawLine (SystemPens.Control, 0, y, control_size.Width, y);
2724 					y += item_height;
2725 				}
2726 			}
2727 
2728 			// Draw corner between the two scrollbars
2729 			if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) {
2730 				Rectangle rect = new Rectangle ();
2731 				rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
2732 				rect.Width = control.v_scroll.Width;
2733 				rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height;
2734 				rect.Height = control.h_scroll.Height;
2735 				dc.FillRectangle (SystemBrushes.Control, rect);
2736 			}
2737 
2738 			Rectangle box_select_rect = control.item_control.BoxSelectRectangle;
2739 			if (!box_select_rect.Size.IsEmpty)
2740 				dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect);
2741 
2742 		}
2743 
DrawListViewHeader(Graphics dc, Rectangle clip, ListView control)2744 		public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
2745 		{
2746 			bool details = (control.View == View.Details);
2747 
2748 			// border is drawn directly in the Paint method
2749 			if (details && control.HeaderStyle != ColumnHeaderStyle.None) {
2750 				dc.FillRectangle (SystemBrushes.Control,
2751 						  0, 0, control.TotalWidth, control.Font.Height + 5);
2752 				if (control.Columns.Count > 0) {
2753 					foreach (ColumnHeader col in control.Columns) {
2754 						Rectangle rect = col.Rect;
2755 						rect.X -= control.h_marker;
2756 
2757 						bool owner_draw = false;
2758 						if (control.OwnerDraw)
2759 							owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect);
2760 						if (owner_draw)
2761 							continue;
2762 
2763 						ListViewDrawColumnHeaderBackground (control, col, dc, rect, clip);
2764 						rect.X += 5;
2765 						rect.Width -= 10;
2766 						if (rect.Width <= 0)
2767 							continue;
2768 
2769 						int image_index;
2770 						if (control.SmallImageList == null)
2771 							image_index = -1;
2772 						else
2773 							image_index = col.ImageKey == String.Empty ? col.ImageIndex : control.SmallImageList.Images.IndexOfKey (col.ImageKey);
2774 
2775 						if (image_index > -1 && image_index < control.SmallImageList.Images.Count) {
2776 							int image_width = control.SmallImageList.ImageSize.Width + 5;
2777 							int text_width = (int)dc.MeasureString (col.Text, control.Font).Width;
2778 							int x_origin = rect.X;
2779 							int y_origin = rect.Y + ((rect.Height - control.SmallImageList.ImageSize.Height) / 2);
2780 
2781 							switch (col.TextAlign) {
2782 								case HorizontalAlignment.Left:
2783 									break;
2784 								case HorizontalAlignment.Right:
2785 									x_origin = rect.Right - (text_width + image_width);
2786 									break;
2787 								case HorizontalAlignment.Center:
2788 									x_origin = (rect.Width - (text_width + image_width)) / 2 + rect.X;
2789 									break;
2790 							}
2791 
2792 							if (x_origin < rect.X)
2793 								x_origin = rect.X;
2794 
2795 							control.SmallImageList.Draw (dc, new Point (x_origin, y_origin), image_index);
2796 							rect.X += image_width;
2797 							rect.Width -= image_width;
2798 						}
2799 
2800 						dc.DrawString (col.Text, control.Font, SystemBrushes.ControlText, rect, col.Format);
2801 					}
2802 					int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker;
2803 					if (right < control.Right) {
2804 						Rectangle rect = control.Columns [0].Rect;
2805 						rect.X = right;
2806 						rect.Width = control.Right - right;
2807 						ListViewDrawUnusedHeaderBackground (control, dc, rect, clip);
2808 					}
2809 				}
2810 			}
2811 		}
2812 
ListViewDrawColumnHeaderBackground(ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)2813 		protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)
2814 		{
2815 			ButtonState state;
2816 			if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2817 				state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal;
2818 			else
2819 				state = ButtonState.Flat;
2820 			CPDrawButton (g, area, state);
2821 		}
2822 
ListViewDrawUnusedHeaderBackground(ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)2823 		protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)
2824 		{
2825 			ButtonState state;
2826 			if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2827 				state = ButtonState.Normal;
2828 			else
2829 				state = ButtonState.Flat;
2830 			CPDrawButton (g, area, state);
2831 		}
2832 
DrawListViewHeaderDragDetails(Graphics dc, ListView view, ColumnHeader col, int target_x)2833 		public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x)
2834 		{
2835 			Rectangle rect = col.Rect;
2836 			rect.X -= view.h_marker;
2837 			Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B);
2838 			dc.FillRectangle (ResPool.GetSolidBrush (color), rect);
2839 			rect.X += 3;
2840 			rect.Width -= 8;
2841 			if (rect.Width <= 0)
2842 				return;
2843 			color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B);
2844 			dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format);
2845 			dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
2846 		}
2847 
DrawListViewColumnHeaderOwnerDraw(Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)2848 		protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
2849 		{
2850 			ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
2851 			if (column.Pressed)
2852 				state |= ListViewItemStates.Selected;
2853 
2854 			DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
2855 					bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
2856 			control.OnDrawColumnHeader (args);
2857 
2858 			return !args.DrawDefault;
2859 		}
2860 
DrawListViewItemOwnerDraw(Graphics dc, ListViewItem item, int index)2861 		protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
2862 		{
2863 			ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
2864 			if (item.Selected)
2865 				item_state |= ListViewItemStates.Selected;
2866 			if (item.Focused)
2867 				item_state |= ListViewItemStates.Focused;
2868 
2869 			DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
2870 					item, item.Bounds, index, item_state);
2871 			item.ListView.OnDrawItem (args);
2872 
2873 			if (args.DrawDefault)
2874 				return false;
2875 
2876 			if (item.ListView.View == View.Details) {
2877 				int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
2878 
2879 				// Do system drawing for subitems if no owner draw is done
2880 				for (int j = 0; j < count; j++) {
2881 					if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j)) {
2882 						if (j == 0) // The first sub item contains the main item semantics
2883 							DrawListViewItem (dc, item.ListView, item);
2884 						else
2885 							DrawListViewSubItem (dc, item.ListView, item, j);
2886 					}
2887 				}
2888 			}
2889 
2890 			return true;
2891 		}
2892 
DrawListViewItem(Graphics dc, ListView control, ListViewItem item)2893 		protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
2894 		{
2895 			Rectangle rect_checkrect = item.CheckRectReal;
2896 			Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2897 			Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2898 			Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);
2899 
2900 			// Tile view doesn't support CheckBoxes
2901 			if (control.CheckBoxes && control.View != View.Tile) {
2902 				if (control.StateImageList == null) {
2903 					// Make sure we've got at least a line width of 1
2904 					int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2905 					int scale = Math.Max (1, rect_checkrect.Width / 12);
2906 
2907 					// set the checkbox background
2908 					dc.FillRectangle (SystemBrushes.Window,
2909 							  rect_checkrect);
2910 					// define a rectangle inside the border area
2911 					Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2912 									rect_checkrect.Y + 2,
2913 									rect_checkrect.Width - 4,
2914 									rect_checkrect.Height - 4);
2915 					Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2916 					dc.DrawRectangle (pen, rect);
2917 
2918 					// Need to draw a check-mark
2919 					if (item.Checked) {
2920 						Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2921 						// adjustments to get the check-mark at the right place
2922 						rect.X ++; rect.Y ++;
2923 						// following logic is taken from DrawFrameControl method
2924 						int x_offset = rect.Width / 5;
2925 						int y_offset = rect.Height / 3;
2926 						for (int i = 0; i < check_wd; i++) {
2927 							dc.DrawLine (check_pen, rect.Left + x_offset,
2928 								     rect.Top + y_offset + i,
2929 								     rect.Left + x_offset + 2 * scale,
2930 								     rect.Top + y_offset + 2 * scale + i);
2931 							dc.DrawLine (check_pen,
2932 								     rect.Left + x_offset + 2 * scale,
2933 								     rect.Top + y_offset + 2 * scale + i,
2934 								     rect.Left + x_offset + 6 * scale,
2935 								     rect.Top + y_offset - 2 * scale + i);
2936 						}
2937 					}
2938 				}
2939 				else {
2940 					int simage_idx;
2941 					if (item.Checked)
2942 						simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
2943 					else
2944 						simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
2945 
2946 					if (simage_idx > -1)
2947 						control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
2948 				}
2949 			}
2950 
2951 			ImageList image_list = control.View == View.LargeIcon || control.View == View.Tile ? control.LargeImageList : control.SmallImageList;
2952 			if (image_list != null) {
2953 				int idx;
2954 
2955 				if (item.ImageKey != String.Empty)
2956 					idx = image_list.Images.IndexOfKey (item.ImageKey);
2957 				else
2958 					idx = item.ImageIndex;
2959 
2960 				if (idx > -1 && idx < image_list.Images.Count) {
2961 					// Draw a thumbnail image if it exists for a FileViewListViewItem, otherwise draw
2962 					// the standard icon.  See https://bugzilla.xamarin.com/show_bug.cgi?id=28025.
2963 					var fi = item as System.Windows.Forms.FileViewListViewItem;
2964 					if (fi != null && fi.FSEntry != null && fi.FSEntry.Image != null)
2965 						dc.DrawImage(fi.FSEntry.Image, icon_rect);
2966 					else
2967 						image_list.Draw(dc, icon_rect.Location, idx);
2968 				}
2969 			}
2970 
2971 			// draw the item text
2972 			// format for the item text
2973 			StringFormat format = new StringFormat ();
2974 			if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2975 				format.LineAlignment = StringAlignment.Near;
2976 			else
2977 				format.LineAlignment = StringAlignment.Center;
2978 			if (control.View == View.LargeIcon)
2979 				format.Alignment = StringAlignment.Center;
2980 			else
2981 				format.Alignment = StringAlignment.Near;
2982 
2983 			if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2984 				format.FormatFlags = StringFormatFlags.LineLimit;
2985 			else
2986 				format.FormatFlags = StringFormatFlags.NoWrap;
2987 
2988 			if ((control.View == View.LargeIcon && !item.Focused) || control.View == View.Details || control.View == View.Tile)
2989 				format.Trimming = StringTrimming.EllipsisCharacter;
2990 
2991 			Rectangle highlight_rect = text_rect;
2992 			if (control.View == View.Details) { // Adjustments for Details view
2993 				Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2994 
2995 				if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2996 					highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2997 			}
2998 
2999 			if (item.Selected && control.Focused)
3000 				dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
3001 			else if (item.Selected && !control.HideSelection)
3002 				dc.FillRectangle (SystemBrushes.Control, highlight_rect);
3003 			else
3004 				dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
3005 
3006 			Brush textBrush =
3007 				!control.Enabled ? SystemBrushes.ControlLight :
3008 				(item.Selected && control.Focused) ? SystemBrushes.HighlightText :
3009 				this.ResPool.GetSolidBrush (item.ForeColor);
3010 
3011 			// Tile view renders its Text in a different fashion
3012 			if (control.View == View.Tile && Application.VisualStylesEnabled) {
3013 				// Item.Text is drawn using its first subitem's bounds
3014 				dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
3015 
3016 				int count = Math.Min (control.Columns.Count, item.SubItems.Count);
3017 				for (int i = 1; i < count; i++) {
3018 					ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
3019 					if (sub_item.Text == null || sub_item.Text.Length == 0)
3020 						continue;
3021 
3022 					Brush itemBrush = item.Selected && control.Focused ?
3023 						SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
3024 					dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
3025 				}
3026 			} else
3027 
3028 			if (item.Text != null && item.Text.Length > 0) {
3029 				Font font = item.Font;
3030 
3031 				if (control.HotTracking && item.Hot)
3032 					font = item.HotFont;
3033 
3034 				if (item.Selected && control.Focused)
3035 					dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
3036 				else
3037 					dc.DrawString (item.Text, font, textBrush, text_rect, format);
3038 			}
3039 
3040 			if (item.Focused && control.Focused) {
3041 				Rectangle focus_rect = highlight_rect;
3042 				if (control.FullRowSelect && control.View == View.Details) {
3043 					int width = 0;
3044 					foreach (ColumnHeader col in control.Columns)
3045 						width += col.Width;
3046 					focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
3047 				}
3048 				if (control.ShowFocusCues) {
3049 					if (item.Selected)
3050 						CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
3051 					else
3052 						CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
3053 				}
3054 			}
3055 
3056 			format.Dispose ();
3057 		}
3058 
DrawListViewSubItems(Graphics dc, ListView control, ListViewItem item)3059 		protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item)
3060 		{
3061 			int columns_count = control.Columns.Count;
3062 			int count = Math.Min (item.SubItems.Count, columns_count);
3063 			// 0th item already done (in this case)
3064 			for (int i = 1; i < count; i++)
3065 				DrawListViewSubItem (dc, control, item, i);
3066 
3067 			// Fill in selection for remaining columns if Column.Count > SubItems.Count
3068 			Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label);
3069 			if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3070 				for (int index = count; index < columns_count; index++) {
3071 					ColumnHeader col = control.Columns [index];
3072 					sub_item_rect.X = col.Rect.X - control.h_marker;
3073 					sub_item_rect.Width = col.Wd;
3074 					dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control,
3075 							sub_item_rect);
3076 				}
3077 			}
3078 		}
3079 
DrawListViewSubItem(Graphics dc, ListView control, ListViewItem item, int index)3080 		protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
3081 		{
3082 			ListViewItem.ListViewSubItem subItem = item.SubItems [index];
3083 			ColumnHeader col = control.Columns [index];
3084 			StringFormat format = new StringFormat ();
3085 			format.Alignment = col.Format.Alignment;
3086 			format.LineAlignment = StringAlignment.Center;
3087 			format.FormatFlags = StringFormatFlags.NoWrap;
3088 			format.Trimming = StringTrimming.EllipsisCharacter;
3089 
3090 			Rectangle sub_item_rect = subItem.Bounds;
3091 			Rectangle sub_item_text_rect = sub_item_rect;
3092 			sub_item_text_rect.X += 3;
3093 			sub_item_text_rect.Width -= ListViewItemPaddingWidth;
3094 
3095 			SolidBrush sub_item_back_br = null;
3096 			SolidBrush sub_item_fore_br = null;
3097 			Font sub_item_font = null;
3098 
3099 			if (item.UseItemStyleForSubItems) {
3100 				sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
3101 				sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
3102 
3103 				// Hot tracking for subitems only applies when UseStyle is true
3104 				if (control.HotTracking && item.Hot)
3105 					sub_item_font = item.HotFont;
3106 				else
3107 					sub_item_font = item.Font;
3108 			} else {
3109 				sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
3110 				sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
3111 				sub_item_font = subItem.Font;
3112 			}
3113 
3114 			if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3115 				Brush bg, text;
3116 				if (control.Focused) {
3117 					bg = SystemBrushes.Highlight;
3118 					text = SystemBrushes.HighlightText;
3119 				} else {
3120 					bg = SystemBrushes.Control;
3121 					text = sub_item_fore_br;
3122 
3123 				}
3124 
3125 				dc.FillRectangle (bg, sub_item_rect);
3126 				if (subItem.Text != null && subItem.Text.Length > 0)
3127 					dc.DrawString (subItem.Text, sub_item_font,
3128 							text, sub_item_text_rect, format);
3129 			} else {
3130 				dc.FillRectangle (sub_item_back_br, sub_item_rect);
3131 				if (subItem.Text != null && subItem.Text.Length > 0)
3132 					dc.DrawString (subItem.Text, sub_item_font,
3133 							sub_item_fore_br,
3134 							sub_item_text_rect, format);
3135 			}
3136 
3137 			format.Dispose ();
3138 		}
3139 
DrawListViewSubItemOwnerDraw(Graphics dc, ListViewItem item, ListViewItemStates state, int index)3140 		protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
3141 		{
3142 			ListView control = item.ListView;
3143 			ListViewItem.ListViewSubItem subitem = item.SubItems [index];
3144 
3145 			DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item,
3146 					subitem, item.Index, index, control.Columns [index], state);
3147 			control.OnDrawSubItem (args);
3148 
3149 			return !args.DrawDefault;
3150 		}
3151 
DrawListViewGroupHeader(Graphics dc, ListView control, ListViewGroup group)3152 		protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
3153 		{
3154 			Rectangle text_bounds = group.HeaderBounds;
3155 			Rectangle header_bounds = group.HeaderBounds;
3156 			text_bounds.Offset (8, 0);
3157 			text_bounds.Inflate (-8, 0);
3158 			int text_height = control.Font.Height + 2; // add a tiny padding between the text and the group line
3159 
3160 			Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
3161 			Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0),
3162 					SystemColors.Desktop, Color.White);
3163 			Pen pen = new Pen (brush);
3164 
3165 			StringFormat sformat = new StringFormat ();
3166 			switch (group.HeaderAlignment) {
3167 				case HorizontalAlignment.Left:
3168 					sformat.Alignment = StringAlignment.Near;
3169 					break;
3170 				case HorizontalAlignment.Center:
3171 					sformat.Alignment = StringAlignment.Center;
3172 					break;
3173 				case HorizontalAlignment.Right:
3174 					sformat.Alignment = StringAlignment.Far;
3175 					break;
3176 			}
3177 
3178 			sformat.LineAlignment = StringAlignment.Near;
3179 			dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
3180 			dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_height, header_bounds.Left + ListViewGroupLineWidth,
3181 					header_bounds.Top + text_height);
3182 
3183 			sformat.Dispose ();
3184 			font.Dispose ();
3185 			pen.Dispose ();
3186 			brush.Dispose ();
3187 		}
3188 
3189 		public override bool ListViewHasHotHeaderStyle {
3190 			get {
3191 				return false;
3192 			}
3193 		}
3194 
3195 		// Sizing
ListViewGetHeaderHeight(ListView listView, Font font)3196 		public override int ListViewGetHeaderHeight (ListView listView, Font font)
3197 		{
3198 			return ListViewGetHeaderHeight (font);
3199 		}
3200 
ListViewGetHeaderHeight(Font font)3201 		static int ListViewGetHeaderHeight (Font font)
3202 		{
3203 			return font.Height + 5;
3204 		}
3205 
ListViewGetHeaderHeight()3206 		public static int ListViewGetHeaderHeight ()
3207 		{
3208 			return ListViewGetHeaderHeight (ThemeEngine.Current.DefaultFont);
3209 		}
3210 
3211 		public override Size ListViewCheckBoxSize {
3212 			get { return new Size (16, 16); }
3213 		}
3214 
3215 		public override int ListViewColumnHeaderHeight {
3216 			get { return 16; }
3217 		}
3218 
3219 		public override int ListViewDefaultColumnWidth {
3220 			get { return 60; }
3221 		}
3222 
3223 		public override int ListViewVerticalSpacing {
3224 			get { return 22; }
3225 		}
3226 
3227 		public override int ListViewEmptyColumnWidth {
3228 			get { return 10; }
3229 		}
3230 
3231 		public override int ListViewHorizontalSpacing {
3232 			get { return 4; }
3233 		}
3234 
3235 		public override int ListViewItemPaddingWidth {
3236 			get { return 6; }
3237 		}
3238 
3239 		public override Size ListViewDefaultSize {
3240 			get { return new Size (121, 97); }
3241 		}
3242 
3243 		public override int ListViewGroupHeight {
3244 			get { return 20; }
3245 		}
3246 
3247 		public int ListViewGroupLineWidth {
3248 			get { return 200; }
3249 		}
3250 
3251 		public override int ListViewTileWidthFactor {
3252 			get { return 22; }
3253 		}
3254 
3255 		public override int ListViewTileHeightFactor {
3256 			get { return 3; }
3257 		}
3258 		#endregion	// ListView
3259 
3260 		#region Menus
3261 
CalcItemSize(Graphics dc, MenuItem item, int y, int x, bool menuBar)3262 		public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3263 		{
3264 			item.X = x;
3265 			item.Y = y;
3266 
3267 			if (item.Visible == false) {
3268 				item.Width = 0;
3269 				item.Height = 0;
3270 				return;
3271 			}
3272 
3273 			if (item.Separator == true) {
3274 				item.Height = SEPARATOR_HEIGHT;
3275 				item.Width = SEPARATOR_MIN_WIDTH;
3276 				return;
3277 			}
3278 
3279 			if (item.MeasureEventDefined) {
3280 				MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3281 				item.PerformMeasureItem (mi);
3282 				item.Height = mi.ItemHeight;
3283 				item.Width = mi.ItemWidth;
3284 				return;
3285 			} else {
3286 				SizeF size;
3287 				size =  dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3288 				item.Width = (int) size.Width;
3289 				item.Height = (int) size.Height;
3290 
3291 				if (!menuBar) {
3292 					if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3293 						item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3294 						size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3295 						item.Width += MENU_TAB_SPACE + (int) size.Width;
3296 					}
3297 
3298 					item.Width += 4 + (MenuCheckSize.Width * 2);
3299 				} else {
3300 					item.Width += MENU_BAR_ITEMS_SPACE;
3301 					x += item.Width;
3302 				}
3303 
3304 				if (item.Height < MenuHeight)
3305 					item.Height = MenuHeight;
3306 			}
3307 		}
3308 
3309 		// Updates the menu rect and returns the height
CalcMenuBarSize(Graphics dc, Menu menu, int width)3310 		public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3311 		{
3312 			int x = 0;
3313 			int y = 0;
3314 			menu.Height = 0;
3315 
3316 			foreach (MenuItem item in menu.MenuItems) {
3317 
3318 				CalcItemSize (dc, item, y, x, true);
3319 
3320 				if (x + item.Width > width) {
3321 					item.X = 0;
3322 					y += item.Height;
3323 					item.Y = y;
3324 					x = 0;
3325 				}
3326 
3327 				x += item.Width;
3328 				item.MenuBar = true;
3329 
3330 				if (y + item.Height > menu.Height)
3331 					menu.Height = item.Height + y;
3332 			}
3333 
3334 			menu.Width = width;
3335 			return menu.Height;
3336 		}
3337 
CalcPopupMenuSize(Graphics dc, Menu menu)3338 		public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3339 		{
3340 			int x = 3;
3341 			int start = 0;
3342 			int i, n, y, max;
3343 
3344 			menu.Height = 0;
3345 
3346 			while (start < menu.MenuItems.Count) {
3347 				y = 3;
3348 				max = 0;
3349 				for (i = start; i < menu.MenuItems.Count; i++) {
3350 					MenuItem item = menu.MenuItems [i];
3351 
3352 					if ((i != start) && (item.Break || item.BarBreak))
3353 						break;
3354 
3355 					CalcItemSize (dc, item, y, x, false);
3356 					y += item.Height;
3357 
3358 					if (item.Width > max)
3359 						max = item.Width;
3360 				}
3361 
3362 				// Replace the -1 by the menu width (separators)
3363 				for (n = start; n < i; n++, start++)
3364 					menu.MenuItems [n].Width = max;
3365 
3366 				if (y > menu.Height)
3367 					menu.Height = y;
3368 
3369 				x+= max;
3370 			}
3371 
3372 			menu.Width = x;
3373 
3374 			//space for border
3375 			menu.Width += 2;
3376 			menu.Height += 2;
3377 
3378 			menu.Width += SM_CXBORDER;
3379     		menu.Height += SM_CYBORDER;
3380 		}
3381 
3382 		// Draws a menu bar in a window
DrawMenuBar(Graphics dc, Menu menu, Rectangle rect)3383 		public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3384 		{
3385 			if (menu.Height == 0)
3386 				CalcMenuBarSize (dc, menu, rect.Width);
3387 
3388 			bool keynav = (menu as MainMenu).tracker.hotkey_active;
3389 			HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3390 			string_format_menu_menubar_text.HotkeyPrefix = hp;
3391 			string_format_menu_text.HotkeyPrefix = hp;
3392 
3393 			rect.Height = menu.Height;
3394 			dc.FillRectangle (SystemBrushes.Menu, rect);
3395 
3396 			for (int i = 0; i < menu.MenuItems.Count; i++) {
3397 				MenuItem item = menu.MenuItems [i];
3398 				Rectangle item_rect = item.bounds;
3399 				item_rect.X += rect.X;
3400 				item_rect.Y += rect.Y;
3401 				item.MenuHeight = menu.Height;
3402 				item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status));
3403 			}
3404 		}
3405 
CreateGlyphBitmap(Size size, MenuGlyph glyph, Color color)3406 		protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3407 		{
3408 			Color bg_color;
3409 			if (color.R == 0 && color.G == 0 && color.B == 0)
3410 				bg_color = Color.White;
3411 			else
3412 				bg_color = Color.Black;
3413 
3414 			Bitmap	bmp = new Bitmap (size.Width, size.Height);
3415 			Graphics gr = Graphics.FromImage (bmp);
3416 			Rectangle rect = new Rectangle (Point.Empty, size);
3417 			gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3418 			CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3419 			bmp.MakeTransparent (bg_color);
3420 			gr.Dispose ();
3421 
3422 			return bmp;
3423 		}
3424 
DrawMenuItem(MenuItem item, DrawItemEventArgs e)3425 		public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3426 		{
3427 			StringFormat string_format;
3428 			Rectangle rect_text = e.Bounds;
3429 
3430 			if (item.Visible == false)
3431 				return;
3432 
3433 			if (item.MenuBar)
3434 				string_format = string_format_menu_menubar_text;
3435 			else
3436 				string_format = string_format_menu_text;
3437 
3438 			if (item.Separator == true) {
3439 				int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3440 
3441 				e.Graphics.DrawLine (SystemPens.ControlDark,
3442 					e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3443 
3444 				e.Graphics.DrawLine (SystemPens.ControlLight,
3445 					e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3446 
3447 				return;
3448 			}
3449 
3450 			if (!item.MenuBar)
3451 				rect_text.X += MenuCheckSize.Width;
3452 
3453 			if (item.BarBreak) { /* Draw vertical break bar*/
3454 				Rectangle rect = e.Bounds;
3455 				rect.Y++;
3456 				rect.Width = 3;
3457 				rect.Height = item.MenuHeight - 6;
3458 
3459 				e.Graphics.DrawLine (SystemPens.ControlDark,
3460 					rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3461 
3462 				e.Graphics.DrawLine (SystemPens.ControlLight,
3463 					rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3464 			}
3465 
3466 			Color color_text;
3467 			Color color_back;
3468 			Brush brush_text = null;
3469 			Brush brush_back = null;
3470 
3471 			if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3472 				color_text = ColorHighlightText;
3473 				color_back = ColorHighlight;
3474 				brush_text = SystemBrushes.HighlightText;
3475 				brush_back = SystemBrushes.Highlight;
3476 			} else {
3477 				color_text = ColorMenuText;
3478 				color_back = ColorMenu;
3479 				brush_text = ResPool.GetSolidBrush (ColorMenuText);
3480 				brush_back = SystemBrushes.Menu;
3481 			}
3482 
3483 			/* Draw background */
3484 			if (!item.MenuBar)
3485 				e.Graphics.FillRectangle (brush_back, e.Bounds);
3486 
3487 			if (item.Enabled) {
3488 				e.Graphics.DrawString (item.Text, e.Font,
3489 					brush_text,
3490 					rect_text, string_format);
3491 
3492 				if (item.MenuBar) {
3493 					Border3DStyle border_style = Border3DStyle.Adjust;
3494 					if ((item.Status & DrawItemState.HotLight) != 0)
3495 						border_style = Border3DStyle.RaisedInner;
3496 					else if ((item.Status & DrawItemState.Selected) != 0)
3497 						border_style = Border3DStyle.SunkenOuter;
3498 
3499 					if (border_style != Border3DStyle.Adjust)
3500 						CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3501 				}
3502 			} else {
3503 				if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3504 					e.Graphics.DrawString (item.Text, e.Font, Brushes.White,
3505 							       new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3506 							       string_format);
3507 
3508 				}
3509 
3510 				e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3511 			}
3512 
3513 			if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3514 				string str = item.GetShortCutText ();
3515 				Rectangle rect = rect_text;
3516 				rect.X = item.XTab;
3517 				rect.Width -= item.XTab;
3518 
3519 				if (item.Enabled) {
3520 					e.Graphics.DrawString (str, e.Font, brush_text, rect, string_format_menu_shortcut);
3521 				} else {
3522 					if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3523 						e.Graphics.DrawString (str, e.Font, Brushes.White,
3524 								       new RectangleF(rect.X + 1, rect.Y + 1, rect.Width, rect_text.Height),
3525 								       string_format_menu_shortcut);
3526 
3527 					}
3528 					e.Graphics.DrawString (str, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect, string_format_menu_shortcut);
3529 				}
3530 			}
3531 
3532 			/* Draw arrow */
3533 			if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3534 
3535 				int cx = MenuCheckSize.Width;
3536 				int cy = MenuCheckSize.Height;
3537 				Bitmap	bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3538 
3539 				if (item.Enabled) {
3540 					e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3541 						e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3542 				} else {
3543 					ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3544 						e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
3545 				}
3546 
3547 				bmp.Dispose ();
3548 			}
3549 
3550 			/* Draw checked or radio */
3551 			if (item.MenuBar == false && item.Checked) {
3552 
3553 				Rectangle area = e.Bounds;
3554 				int cx = MenuCheckSize.Width;
3555 				int cy = MenuCheckSize.Height;
3556 				Bitmap	bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3557 
3558 				e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3559 
3560 				bmp.Dispose ();
3561 			}
3562 		}
3563 
DrawPopupMenu(Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)3564 		public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3565 		{
3566 			// Fill rectangle area
3567 			dc.FillRectangle (SystemBrushes.Menu, cliparea);
3568 
3569 			// Draw menu borders
3570 			CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3571 
3572 			// Draw menu items
3573 			for (int i = 0; i < menu.MenuItems.Count; i++) {
3574 				if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3575 					MenuItem item = menu.MenuItems [i];
3576 					item.MenuHeight = menu.Height;
3577 					item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3578 				}
3579 			}
3580 		}
3581 
3582 		#endregion // Menus
3583 
3584 		#region MonthCalendar
3585 
3586 		// draw the month calendar
DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc)3587 		public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc)
3588 		{
3589 			Rectangle client_rectangle = mc.ClientRectangle;
3590 			Size month_size = mc.SingleMonthSize;
3591 			// cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3592 			Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3593 			Size date_cell_size = (Size)((object)mc.date_cell_size);
3594 
3595 			// draw the singlecalendars
3596 			int x_offset = 1;
3597 			int y_offset = 1;
3598 			// adjust for the position of the specific month
3599 			for (int i=0; i < mc.CalendarDimensions.Height; i++)
3600 			{
3601 				if (i > 0)
3602 				{
3603 					y_offset += month_size.Height + calendar_spacing.Height;
3604 				}
3605 				// now adjust for x position
3606 				for (int j=0; j < mc.CalendarDimensions.Width; j++)
3607 				{
3608 					if (j > 0)
3609 					{
3610 						x_offset += month_size.Width + calendar_spacing.Width;
3611 					}
3612 					else
3613 					{
3614 						x_offset = 1;
3615 					}
3616 
3617 					Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3618 					if (month_rect.IntersectsWith (clip_rectangle)) {
3619 						DrawSingleMonth (
3620 							dc,
3621 							clip_rectangle,
3622 							month_rect,
3623 							mc,
3624 							i,
3625 							j);
3626 					}
3627 				}
3628 			}
3629 
3630 			Rectangle bottom_rect = new Rectangle (
3631 						client_rectangle.X,
3632 						Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3633 						client_rectangle.Width,
3634 						date_cell_size.Height + 2);
3635 			// draw the today date if it's set
3636 			if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle))
3637 			{
3638 				dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3639 				if (mc.ShowToday) {
3640 					int today_offset = 5;
3641 					if (mc.ShowTodayCircle)
3642 					{
3643 						Rectangle today_circle_rect = new Rectangle (
3644 							client_rectangle.X + 5,
3645 							Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3646 							date_cell_size.Width,
3647 							date_cell_size.Height);
3648 							DrawTodayCircle (dc, today_circle_rect);
3649 						today_offset += date_cell_size.Width + 5;
3650 					}
3651 					// draw today's date
3652 					StringFormat text_format = new StringFormat();
3653 					text_format.LineAlignment = StringAlignment.Center;
3654 					text_format.Alignment = StringAlignment.Near;
3655 					Rectangle today_rect = new Rectangle (
3656 							today_offset + client_rectangle.X,
3657 							Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3658 							Math.Max(client_rectangle.Width - today_offset, 0),
3659 							date_cell_size.Height);
3660 					dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3661 					text_format.Dispose ();
3662 				}
3663 			}
3664 
3665 			Brush border_brush;
3666 
3667 			if (mc.owner == null)
3668 				border_brush = GetControlBackBrush (mc.BackColor);
3669 			else
3670 				border_brush = SystemBrushes.ControlDarkDark;
3671 
3672 			// finally paint the borders of the calendars as required
3673 			for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3674 				if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3675 					dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3676 				} else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3677 					dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3678 				} else {
3679 					Rectangle rect = new Rectangle (
3680 						client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3681 						client_rectangle.Y,
3682 						calendar_spacing.Width,
3683 						client_rectangle.Height);
3684 					if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3685 						dc.FillRectangle (border_brush, rect);
3686 					}
3687 				}
3688 			}
3689 			for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3690 				if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3691 					dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3692 				} else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3693 					dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3694 				} else {
3695 					Rectangle rect = new Rectangle (
3696 						client_rectangle.X,
3697 						client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3698 						client_rectangle.Width,
3699 						calendar_spacing.Height);
3700 					if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3701 						dc.FillRectangle (border_brush, rect);
3702 					}
3703 				}
3704 			}
3705 
3706 			// draw the drop down border if need
3707 			if (mc.owner != null) {
3708 				Rectangle bounds = mc.ClientRectangle;
3709 				if (clip_rectangle.Contains (mc.Location)) {
3710 					// find out if top or left line to draw
3711 					if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3712 
3713 						dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3714 					}
3715 					if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3716 						dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3717 					}
3718 				}
3719 				if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3720 					// find out if bottom or right line to draw
3721 					if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3722 						dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3723 					}
3724 					if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3725 						dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3726 					}
3727 				}
3728 			}
3729 		}
3730 
3731 		// darws a single part of the month calendar (with one month)
DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col)3732 		private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col)
3733 		{
3734 			// cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3735 			Size title_size = (Size)((object)mc.title_size);
3736 			Size date_cell_size = (Size)((object)mc.date_cell_size);
3737 			DateTime current_month = (DateTime)((object)mc.current_month);
3738 			DateTime sunday = new DateTime(2006, 10, 1);
3739 
3740 			// draw the title back ground
3741 			DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3742 			Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3743 			if (title_rect.IntersectsWith (clip_rectangle)) {
3744 				dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3745 				// draw the title
3746 				string title_text = this_month.ToString ("MMMM yyyy");
3747 				dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3748 
3749 				if (mc.ShowYearUpDown) {
3750 					Rectangle year_rect;
3751 					Rectangle upRect, downRect;
3752 					ButtonState upState, downState;
3753 
3754 					mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3755 					dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3756 					dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3757 
3758 					upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3759 					downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3760 
3761 					ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3762 					ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3763 				}
3764 
3765 				// draw previous and next buttons if it's time
3766 				if (row == 0 && col == 0)
3767 				{
3768 					// draw previous button
3769 					DrawMonthCalendarButton (
3770 						dc,
3771 						rectangle,
3772 						mc,
3773 						title_size,
3774 						mc.button_x_offset,
3775 						(System.Drawing.Size)((object)mc.button_size),
3776 						true);
3777 				}
3778 				if (row == 0 && col == mc.CalendarDimensions.Width-1)
3779 				{
3780 					// draw next button
3781 					DrawMonthCalendarButton (
3782 						dc,
3783 						rectangle,
3784 						mc,
3785 						title_size,
3786 						mc.button_x_offset,
3787 						(System.Drawing.Size)((object)mc.button_size),
3788 						false);
3789 				}
3790 			}
3791 
3792 			// set the week offset and draw week nums if needed
3793 			int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3794 			Rectangle day_name_rect = new Rectangle(
3795 				rectangle.X,
3796 				rectangle.Y + title_size.Height,
3797 				(7 + col_offset) * date_cell_size.Width,
3798 				date_cell_size.Height);
3799 			if (day_name_rect.IntersectsWith (clip_rectangle)) {
3800 				dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3801 				// draw the day names
3802 				DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3803 				for (int i=0; i < 7; i++)
3804 				{
3805 					int position = i - (int) first_day_of_week;
3806 					if (position < 0)
3807 					{
3808 						position = 7 + position;
3809 					}
3810 					// draw it
3811 					Rectangle day_rect = new Rectangle(
3812 						day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3813 						day_name_rect.Y,
3814 						date_cell_size.Width,
3815 						date_cell_size.Height);
3816 					dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3817 				}
3818 
3819 				// draw the vertical divider
3820 				int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3821 				dc.DrawLine (
3822 					ResPool.GetPen (mc.ForeColor),
3823 					rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3824 					rectangle.Y + vert_divider_y,
3825 					rectangle.Right - mc.divider_line_offset,
3826 					rectangle.Y + vert_divider_y);
3827 			}
3828 
3829 
3830 			// draw the actual date items in the grid (including the week numbers)
3831 			Rectangle date_rect = new Rectangle (
3832 				rectangle.X,
3833 				rectangle.Y + title_size.Height + date_cell_size.Height,
3834 				date_cell_size.Width,
3835 				date_cell_size.Height);
3836 			int month_row_count = 0;
3837 			bool draw_week_num_divider = false;
3838 			DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3839 			for (int i=0; i < 6; i++)
3840 			{
3841 				// establish if this row is in our clip_area
3842 				Rectangle row_rect = new Rectangle (
3843 					rectangle.X,
3844 					rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3845 					date_cell_size.Width * 7,
3846 					date_cell_size.Height);
3847 				if (mc.ShowWeekNumbers) {
3848 					row_rect.Width += date_cell_size.Width;
3849 				}
3850 
3851 				bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3852 				if (draw_row) {
3853 					dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3854 				}
3855 				// establish if this is a valid week to draw
3856 				if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3857 					month_row_count = i;
3858 				}
3859 
3860 				// draw the week number if required
3861 				if (mc.ShowWeekNumbers && month_row_count == i) {
3862 					if (!draw_week_num_divider) {
3863 						draw_week_num_divider = draw_row;
3864 					}
3865 					// get the week for this row
3866 					int week = mc.GetWeekOfYear (current_date);
3867 
3868 					if (draw_row) {
3869 						dc.DrawString (
3870 							week.ToString(),
3871 							mc.Font,
3872 							ResPool.GetSolidBrush (mc.TitleBackColor),
3873 							date_rect,
3874 							mc.centered_format);
3875 					}
3876 					date_rect.Offset(date_cell_size.Width, 0);
3877 				}
3878 
3879 				// only draw the days if we have to
3880 				if(month_row_count == i) {
3881 					for (int j=0; j < 7; j++)
3882 					{
3883 						if (draw_row) {
3884 							DrawMonthCalendarDate (
3885 								dc,
3886 								date_rect,
3887 								mc,
3888 								current_date,
3889 								this_month,
3890 								row,
3891 								col);
3892 						}
3893 
3894 						// move the day on
3895 						current_date = current_date.AddDays(1);
3896 						date_rect.Offset(date_cell_size.Width, 0);
3897 					}
3898 
3899 					// shift the rectangle down one row
3900 					int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3901 					date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3902 				}
3903 			}
3904 
3905 			// month_row_count is zero based, so add one
3906 			month_row_count++;
3907 
3908 			// draw week numbers if required
3909 			if (draw_week_num_divider) {
3910 				col_offset = 1;
3911 				dc.DrawLine (
3912 					ResPool.GetPen (mc.ForeColor),
3913 					rectangle.X + date_cell_size.Width - 1,
3914 					rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3915 					rectangle.X + date_cell_size.Width - 1,
3916 					rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3917 			}
3918 		}
3919 
3920 		// draws the pervious or next button
DrawMonthCalendarButton(Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous)3921 		private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous)
3922 		{
3923 			const int arrow_width = 4;
3924 			const int arrow_height = 7;
3925 
3926 			bool is_clicked = false;
3927 			Rectangle button_rect;
3928 			PointF arrow_center;
3929 			PointF [] arrow_path = new PointF [3];
3930 
3931 			// prepare the button
3932 			if (is_previous)
3933 			{
3934 				is_clicked = mc.is_previous_clicked;
3935 
3936 				button_rect = new Rectangle (
3937 					rectangle.X + 1 + x_offset,
3938 					rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3939 					Math.Max(button_size.Width - 1, 0),
3940 					Math.Max(button_size.Height - 1, 0));
3941 
3942 				arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f),
3943 											rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3944 				if (is_clicked) {
3945 					arrow_center.X += 1;
3946 					arrow_center.Y += 1;
3947 				}
3948 
3949 				arrow_path [0].X = arrow_center.X;
3950 				arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3951 				arrow_path [1].X = arrow_center.X;
3952 				arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3953 				arrow_path [2].X = arrow_center.X - arrow_width;
3954 				arrow_path [2].Y = arrow_center.Y + 0.5f;
3955 			}
3956 			else
3957 			{
3958 				is_clicked = mc.is_next_clicked;
3959 
3960 				button_rect = new Rectangle (
3961 					rectangle.Right - 1 - x_offset - button_size.Width,
3962 					rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3963 					Math.Max(button_size.Width - 1, 0),
3964 					Math.Max(button_size.Height - 1, 0));
3965 
3966 				arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f),
3967 											rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3968 				if (is_clicked) {
3969 					arrow_center.X += 1;
3970 					arrow_center.Y += 1;
3971 				}
3972 
3973 				arrow_path [0].X = arrow_center.X - arrow_width;
3974 				arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3975 				arrow_path [1].X = arrow_center.X - arrow_width;
3976 				arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3977 				arrow_path [2].X = arrow_center.X;
3978 				arrow_path [2].Y = arrow_center.Y + 0.5f;
3979 			}
3980 
3981 			// fill the background
3982 			dc.FillRectangle (SystemBrushes.Control, button_rect);
3983 			// draw the border
3984 			if (is_clicked) {
3985 				dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3986 			}
3987 			else {
3988 				CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3989 			}
3990 			// draw the arrow
3991 			dc.FillPolygon (SystemBrushes.ControlText, arrow_path);
3992 			//dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3993 		}
3994 
3995 
3996 		// draws one day in the calendar grid
DrawMonthCalendarDate(Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col)3997 		private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc,	DateTime date, DateTime month, int row, int col) {
3998 			Color date_color = mc.ForeColor;
3999 			Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
4000 
4001 			// find out if we are the lead of the first calendar or the trail of the last calendar
4002 			if (date.Year != month.Year || date.Month != month.Month) {
4003 				DateTime check_date = month.AddMonths (-1);
4004 				// check if it's the month before
4005 				if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
4006 					date_color = mc.TrailingForeColor;
4007 				} else {
4008 					// check if it's the month after
4009 					check_date = month.AddMonths (1);
4010 					if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
4011 						date_color = mc.TrailingForeColor;
4012 					} else {
4013 						return;
4014 					}
4015 				}
4016 			} else {
4017 				date_color = mc.ForeColor;
4018 			}
4019 
4020 			const int inflate = -1;
4021 
4022 			if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
4023 				// see if the date is in the start of selection
4024 				date_color = mc.BackColor;
4025 				// draw the left hand of the back ground
4026 				Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4027 				dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
4028 			} else if (date == mc.SelectionStart.Date) {
4029 				// see if the date is in the start of selection
4030 				date_color = mc.BackColor;
4031 				// draw the left hand of the back ground
4032 				Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4033 				dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
4034 				// fill the other side as a straight rect
4035 				if (date < mc.SelectionEnd.Date)
4036 				{
4037 					// use rectangle instead of rectangle to go all the way to edge of rect
4038 					selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
4039 					selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
4040 					dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4041 				}
4042 			} else if (date == mc.SelectionEnd.Date) {
4043 				// see if it is the end of selection
4044 				date_color = mc.BackColor;
4045 				// draw the left hand of the back ground
4046 				Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4047 				dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
4048 				// fill the other side as a straight rect
4049 				if (date > mc.SelectionStart.Date) {
4050 					selection_rect.X = rectangle.X;
4051 					selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
4052 					dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4053 				}
4054 			} else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
4055 				// now see if it's in the middle
4056 				date_color = mc.BackColor;
4057 				// draw the left hand of the back ground
4058 				Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
4059 				dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4060 			}
4061 
4062 			// establish if it's a bolded font
4063 			Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
4064 
4065 			// just draw the date now
4066 			dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
4067 
4068 			// today circle if needed
4069 			if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
4070 				DrawTodayCircle (dc, interior);
4071 			}
4072 
4073 			// draw the selection grid
4074 			if (mc.is_date_clicked && mc.clicked_date == date) {
4075 				Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
4076 				dc.DrawRectangle (pen, interior);
4077 			}
4078 		}
4079 
DrawTodayCircle(Graphics dc, Rectangle rectangle)4080 		private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
4081 			Color circle_color = Color.FromArgb (248, 0, 0);
4082 			// draw the left hand of the circle
4083 			Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
4084 			Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
4085 			Point [] curve_points = new Point [3];
4086 			curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
4087 			curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
4088 			curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
4089 
4090 			Pen pen = ResPool.GetSizedPen(circle_color, 2);
4091 			dc.DrawArc (pen, lhs_circle_rect, 90, 180);
4092 			dc.DrawArc (pen, rhs_circle_rect, 270, 180);
4093 			dc.DrawCurve (pen, curve_points);
4094 			dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
4095 		}
4096 
4097 		#endregion 	// MonthCalendar
4098 
4099 		#region Panel
4100 		public override Size PanelDefaultSize {
4101 			get {
4102 				return new Size (200, 100);
4103 			}
4104 		}
4105 		#endregion	// Panel
4106 
4107 		#region PictureBox
DrawPictureBox(Graphics dc, Rectangle clip, PictureBox pb)4108 		public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
4109 			Rectangle client = pb.ClientRectangle;
4110 
4111 			client = new Rectangle (client.Left + pb.Padding.Left, client.Top + pb.Padding.Top, client.Width - pb.Padding.Horizontal, client.Height - pb.Padding.Vertical);
4112 
4113 			// FIXME - instead of drawing the whole picturebox every time
4114 			// intersect the clip rectangle with the drawn picture and only draw what's needed,
4115 			// Also, we only need a background fill where no image goes
4116 			if (pb.Image != null) {
4117 				switch (pb.SizeMode) {
4118 				case PictureBoxSizeMode.StretchImage:
4119 					dc.DrawImage (pb.Image, client.Left, client.Top, client.Width, client.Height);
4120 					break;
4121 
4122 				case PictureBoxSizeMode.CenterImage:
4123 					dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
4124 					break;
4125 
4126 				case PictureBoxSizeMode.Zoom:
4127 					Size image_size;
4128 
4129 					if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
4130 						image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
4131 					else
4132 						image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
4133 
4134 					dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
4135 					break;
4136 
4137 				default:
4138 					// Normal, AutoSize
4139 					dc.DrawImage (pb.Image, client.Left, client.Top, pb.Image.Width, pb.Image.Height);
4140 					break;
4141 				}
4142 
4143 				return;
4144 			}
4145 		}
4146 
4147 		public override Size PictureBoxDefaultSize {
4148 			get {
4149 				return new Size (100, 50);
4150 			}
4151 		}
4152 		#endregion	// PictureBox
4153 
4154 		#region PrintPreviewControl
4155 		public override int PrintPreviewControlPadding {
4156 			get { return 8; }
4157 		}
4158 
PrintPreviewControlGetPageSize(PrintPreviewControl preview)4159 		public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
4160 		{
4161 			int page_width, page_height;
4162 			int padding = PrintPreviewControlPadding;
4163 			PreviewPageInfo[] pis = preview.page_infos;
4164 
4165 			if (preview.AutoZoom) {
4166 				int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
4167 				int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
4168 
4169 				float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
4170 
4171 				/* try to lay things out using the width to determine the size */
4172 				page_width = width_available / preview.Columns;
4173 				page_height = (int)(page_width / image_ratio);
4174 
4175 				/* does the height fit? */
4176 				if (page_height * (preview.Rows + 1) > height_available) {
4177 					/* no, lay things out via the height */
4178 					page_height = height_available / (preview.Rows + 1);
4179 					page_width = (int)(page_height * image_ratio);
4180 				}
4181 			}
4182 			else {
4183 				page_width = (int)(pis[0].Image.Width * preview.Zoom);
4184 				page_height = (int)(pis[0].Image.Height * preview.Zoom);
4185 			}
4186 
4187 			return new Size (page_width, page_height);
4188 		}
4189 
PrintPreviewControlPaint(PaintEventArgs pe, PrintPreviewControl preview, Size page_size)4190 		public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
4191 		{
4192 			int padding = 8;
4193 			PreviewPageInfo[] pis = preview.page_infos;
4194 			if (pis == null)
4195 				return;
4196 
4197 			int page_x, page_y;
4198 
4199 			int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
4200 			int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
4201 
4202 			Rectangle viewport = preview.ViewPort;
4203 
4204 			pe.Graphics.Clip = new Region (viewport);
4205 
4206 			/* center things if we can */
4207 			int off_x = viewport.Width / 2 - width / 2;
4208 			if (off_x < 0) off_x = 0;
4209 			int off_y = viewport.Height / 2 - height / 2;
4210 			if (off_y < 0) off_y = 0;
4211 
4212 			page_y = off_y + padding - preview.vbar_value;
4213 
4214 			if (preview.StartPage > 0) {
4215 				int p = preview.StartPage - 1;
4216 				for (int py = 0; py < preview.Rows + 1; py ++) {
4217 					page_x = off_x + padding - preview.hbar_value;
4218 					for (int px = 0; px < preview.Columns; px ++) {
4219 						if (p >= pis.Length)
4220 							continue;
4221 						Image image = preview.image_cache[p];
4222 						if (image == null)
4223 							image = pis[p].Image;
4224 						Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4225 
4226 						pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4227 
4228 						page_x += padding + page_size.Width;
4229 						p++;
4230 					}
4231 					page_y += padding + page_size.Height;
4232 				}
4233 			}
4234 		}
4235 		#endregion      // PrintPreviewControl
4236 
4237 		#region ProgressBar
DrawProgressBar(Graphics dc, Rectangle clip_rect, ProgressBar ctrl)4238 		public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
4239 		{
4240 			Rectangle client_area = ctrl.client_area;
4241 
4242 			/* Draw border */
4243 			CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4244 
4245 			/* Draw Blocks */
4246 			int draw_mode = 0;
4247 			int max_blocks = int.MaxValue;
4248 			int start_pixel = client_area.X;
4249 			draw_mode = (int) ctrl.Style;
4250 
4251 			switch (draw_mode) {
4252 			case 1: { // Continuous
4253 				int pixels_to_draw;
4254 				pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4255 				dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4256 				break;
4257 			}
4258 			case 2: // Marquee
4259 				if (XplatUI.ThemesEnabled) {
4260 					int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4261 					double percent_done = (double) ms_diff / ProgressBarMarqueeSpeedScaling
4262 						% (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4263 					max_blocks = 5;
4264 					start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4265 				}
4266 
4267 				goto case 0;
4268 			case 0:
4269 			default:  // Blocks
4270 				Rectangle block_rect;
4271 				int space_betweenblocks = ProgressBarChunkSpacing;
4272 				int block_width;
4273 				int increment;
4274 				int barpos_pixels;
4275 				int block_count = 0;
4276 
4277 				block_width = ProgressBarGetChunkSize (client_area.Height);
4278 				block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0!
4279 				barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4280 				increment = block_width + space_betweenblocks;
4281 
4282 				block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4283 				while (true) {
4284 					if (max_blocks != int.MaxValue) {
4285 						if (block_count >= max_blocks)
4286 							break;
4287 						if (block_rect.X > client_area.Width)
4288 							block_rect.X -= client_area.Width;
4289 					} else {
4290 						if ((block_rect.X - client_area.X) >= barpos_pixels)
4291 							break;
4292 					}
4293 
4294 					if (clip_rect.IntersectsWith (block_rect) == true) {
4295 						dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), block_rect);
4296 					}
4297 
4298 					block_rect.X  += increment;
4299 					block_count++;
4300 				}
4301 				break;
4302 
4303 			}
4304 		}
4305 
4306 		public const int ProgressBarChunkSpacing = 2;
4307 
ProgressBarGetChunkSize()4308 		public static int ProgressBarGetChunkSize ()
4309 		{
4310 			return ProgressBarGetChunkSize (ProgressBarDefaultHeight);
4311 		}
4312 
ProgressBarGetChunkSize(int progressBarClientAreaHeight)4313 		static int ProgressBarGetChunkSize (int progressBarClientAreaHeight)
4314 		{
4315 			int size = (progressBarClientAreaHeight * 2) / 3;
4316 			return size;
4317 		}
4318 
4319 		const int ProgressBarDefaultHeight = 23;
4320 
4321 		public override Size ProgressBarDefaultSize {
4322 			get {
4323 				return new Size (100, ProgressBarDefaultHeight);
4324 			}
4325 		}
4326 
4327 		public const double ProgressBarMarqueeSpeedScaling = 15;
4328 
4329 		#endregion	// ProgressBar
4330 
4331 		#region RadioButton
DrawRadioButton(Graphics dc, Rectangle clip_rectangle, RadioButton radio_button)4332 		public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4333 			StringFormat	text_format;
4334 			Rectangle 	client_rectangle;
4335 			Rectangle	text_rectangle;
4336 			Rectangle 	radiobutton_rectangle;
4337 			int		radiobutton_size = 13;
4338 			int 	radiobutton_space = 4;
4339 
4340 			client_rectangle = radio_button.ClientRectangle;
4341 			text_rectangle = client_rectangle;
4342 			radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4343 
4344 			text_format = new StringFormat();
4345 			text_format.Alignment = StringAlignment.Near;
4346 			text_format.LineAlignment = StringAlignment.Center;
4347 			text_format.HotkeyPrefix = HotkeyPrefix.Show;
4348 
4349 			/* Calculate the position of text and checkbox rectangle */
4350 			if (radio_button.appearance!=Appearance.Button) {
4351 				switch(radio_button.radiobutton_alignment) {
4352 				case ContentAlignment.BottomCenter: {
4353 					radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4354 					radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4355 					text_rectangle.X=client_rectangle.X;
4356 					text_rectangle.Width=client_rectangle.Width;
4357 					text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4358 					break;
4359 				}
4360 
4361 				case ContentAlignment.BottomLeft: {
4362 					radiobutton_rectangle.X=client_rectangle.Left;
4363 					radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4364 					text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4365 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4366 					break;
4367 				}
4368 
4369 				case ContentAlignment.BottomRight: {
4370 					radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4371 					radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4372 					text_rectangle.X=client_rectangle.X;
4373 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4374 					break;
4375 				}
4376 
4377 				case ContentAlignment.MiddleCenter: {
4378 					radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4379 					radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4380 					text_rectangle.X=client_rectangle.X;
4381 					text_rectangle.Width=client_rectangle.Width;
4382 					break;
4383 				}
4384 
4385 				default:
4386 				case ContentAlignment.MiddleLeft: {
4387 					radiobutton_rectangle.X=client_rectangle.Left;
4388 					radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4389 					text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4390 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4391 					break;
4392 				}
4393 
4394 				case ContentAlignment.MiddleRight: {
4395 					radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4396 					radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4397 					text_rectangle.X=client_rectangle.X;
4398 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4399 					break;
4400 				}
4401 
4402 				case ContentAlignment.TopCenter: {
4403 					radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4404 					radiobutton_rectangle.Y=client_rectangle.Top;
4405 					text_rectangle.X=client_rectangle.X;
4406 					text_rectangle.Y=radiobutton_size+radiobutton_space;
4407 					text_rectangle.Width=client_rectangle.Width;
4408 					text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4409 					break;
4410 				}
4411 
4412 				case ContentAlignment.TopLeft: {
4413 					radiobutton_rectangle.X=client_rectangle.Left;
4414 					radiobutton_rectangle.Y=client_rectangle.Top;
4415 					text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4416 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4417 					break;
4418 				}
4419 
4420 				case ContentAlignment.TopRight: {
4421 					radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4422 					radiobutton_rectangle.Y=client_rectangle.Top;
4423 					text_rectangle.X=client_rectangle.X;
4424 					text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4425 					break;
4426 				}
4427 				}
4428 			} else {
4429 				text_rectangle.X=client_rectangle.X;
4430 				text_rectangle.Width=client_rectangle.Width;
4431 			}
4432 
4433 			/* Set the horizontal alignment of our text */
4434 			switch(radio_button.text_alignment) {
4435 				case ContentAlignment.BottomLeft:
4436 				case ContentAlignment.MiddleLeft:
4437 				case ContentAlignment.TopLeft: {
4438 					text_format.Alignment=StringAlignment.Near;
4439 					break;
4440 				}
4441 
4442 				case ContentAlignment.BottomCenter:
4443 				case ContentAlignment.MiddleCenter:
4444 				case ContentAlignment.TopCenter: {
4445 					text_format.Alignment=StringAlignment.Center;
4446 					break;
4447 				}
4448 
4449 				case ContentAlignment.BottomRight:
4450 				case ContentAlignment.MiddleRight:
4451 				case ContentAlignment.TopRight: {
4452 					text_format.Alignment=StringAlignment.Far;
4453 					break;
4454 				}
4455 			}
4456 
4457 			/* Set the vertical alignment of our text */
4458 			switch(radio_button.text_alignment) {
4459 				case ContentAlignment.TopLeft:
4460 				case ContentAlignment.TopCenter:
4461 				case ContentAlignment.TopRight: {
4462 					text_format.LineAlignment=StringAlignment.Near;
4463 					break;
4464 				}
4465 
4466 				case ContentAlignment.BottomLeft:
4467 				case ContentAlignment.BottomCenter:
4468 				case ContentAlignment.BottomRight: {
4469 					text_format.LineAlignment=StringAlignment.Far;
4470 					break;
4471 				}
4472 
4473 				case ContentAlignment.MiddleLeft:
4474 				case ContentAlignment.MiddleCenter:
4475 				case ContentAlignment.MiddleRight: {
4476 					text_format.LineAlignment=StringAlignment.Center;
4477 					break;
4478 				}
4479 			}
4480 
4481 			ButtonState state = ButtonState.Normal;
4482 			if (radio_button.FlatStyle == FlatStyle.Flat) {
4483 				state |= ButtonState.Flat;
4484 			}
4485 
4486 			if (radio_button.Checked) {
4487 				state |= ButtonState.Checked;
4488 			}
4489 
4490 			if (!radio_button.Enabled) {
4491 				state |= ButtonState.Inactive;
4492 			}
4493 
4494 			// Start drawing
4495 			RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4496 
4497 			if ((radio_button.image != null) || (radio_button.image_list != null))
4498 				ButtonBase_DrawImage(radio_button, dc);
4499 
4500 			RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4501 
4502 			if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4503 				SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4504 
4505 				Rectangle focus_rect = Rectangle.Empty;
4506 				focus_rect.X = text_rectangle.X;
4507 				focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4508 				focus_rect.Size = text_size.ToSize ();
4509 
4510 				RadioButton_DrawFocus (radio_button, dc, focus_rect);
4511 			}
4512 
4513 			text_format.Dispose ();
4514 		}
4515 
RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)4516 		protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4517 		{
4518 			dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4519 
4520 			if (radio_button.appearance==Appearance.Button) {
4521 				ButtonBase_DrawButton (radio_button, dc);
4522 
4523 				if ((radio_button.Focused) && radio_button.Enabled)
4524 					ButtonBase_DrawFocus(radio_button, dc);
4525 			} else {
4526 				// establish if we are rendering a flat style of some sort
4527 				if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4528 					DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4529 				} else {
4530 					CPDrawRadioButton(dc, radiobutton_rectangle, state);
4531 				}
4532 			}
4533 		}
4534 
RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)4535 		protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4536 		{
4537 			DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc,
4538 							  text_format, radio_button.Appearance, radio_button.Checked);
4539 		}
4540 
RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)4541 		protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4542 		{
4543 			DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4544 		}
4545 
4546 
4547 		// renders a radio button with the Flat and Popup FlatStyle
DrawFlatStyleRadioButton(Graphics graphics, Rectangle rectangle, RadioButton radio_button)4548 		protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4549 		{
4550 			int	lineWidth;
4551 
4552 			if (radio_button.Enabled) {
4553 
4554 				// draw the outer flatstyle arcs
4555 				if (radio_button.FlatStyle == FlatStyle.Flat) {
4556 					graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4557 
4558 					// fill in the area depending on whether or not the mouse is hovering
4559 					if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4560 						graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4561 					} else {
4562 						graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4563 					}
4564 				} else {
4565 					// must be a popup radio button
4566 					// fill the control
4567 					graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4568 
4569 					if (radio_button.is_entered || radio_button.Capture) {
4570 						// draw the popup 3d button knob
4571 						graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4572 
4573 						graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4574 						graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4575 
4576 					} else {
4577 						// just draw lighter flatstyle outer circle
4578 						graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4579 					}
4580 				}
4581 			} else {
4582 				// disabled
4583 				// fill control background color regardless of actual backcolor
4584 				graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4585 				// draw the ark as control dark
4586 				graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4587 			}
4588 
4589 			// draw the check
4590 			if (radio_button.Checked) {
4591 				lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4592 
4593 				Pen dot_pen = SystemPens.ControlDarkDark;
4594 				Brush dot_brush = SystemBrushes.ControlDarkDark;
4595 
4596 				if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4597 					dot_pen = SystemPens.ControlDark;
4598 					dot_brush = SystemBrushes.ControlDark;
4599 				}
4600 
4601 				if (rectangle.Height >  13) {
4602 					graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4603 				} else {
4604 					int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4605 					int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4606 
4607 					graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4608 					graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4609 
4610 					graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4611 					graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4612 				}
4613 			}
4614 		}
4615 
4616 		public override Size RadioButtonDefaultSize {
4617 			get {
4618 				return new Size (104,24);
4619 			}
4620 		}
4621 
DrawRadioButton(Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)4622 		public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4623 		{
4624 			// Draw Button Background
4625 			if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4626 				glyphArea.Height -= 2;
4627 				glyphArea.Width -= 2;
4628 			}
4629 
4630 			DrawRadioButtonGlyph (g, rb, glyphArea);
4631 
4632 			// If we have an image, draw it
4633 			if (imageBounds.Size != Size.Empty)
4634 				DrawRadioButtonImage (g, rb, imageBounds);
4635 
4636 			if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4637 				DrawRadioButtonFocus (g, rb, textBounds);
4638 
4639 			// If we have text, draw it
4640 			if (textBounds != Rectangle.Empty)
4641 				DrawRadioButtonText (g, rb, textBounds);
4642 		}
4643 
DrawRadioButtonGlyph(Graphics g, RadioButton rb, Rectangle glyphArea)4644 		public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4645 		{
4646 			if (rb.Pressed)
4647 				ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4648 			else if (rb.InternalSelected)
4649 				ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4650 			else if (rb.Entered)
4651 				ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4652 			else if (!rb.Enabled)
4653 				ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4654 			else
4655 				ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4656 		}
4657 
DrawRadioButtonFocus(Graphics g, RadioButton rb, Rectangle focusArea)4658 		public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4659 		{
4660 			ControlPaint.DrawFocusRectangle (g, focusArea);
4661 		}
4662 
DrawRadioButtonImage(Graphics g, RadioButton rb, Rectangle imageBounds)4663 		public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4664 		{
4665 			if (rb.Enabled)
4666 				g.DrawImage (rb.Image, imageBounds);
4667 			else
4668 				CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4669 		}
4670 
DrawRadioButtonText(Graphics g, RadioButton rb, Rectangle textBounds)4671 		public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4672 		{
4673 			if (rb.Enabled)
4674 				TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4675 			else
4676 				DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4677 		}
4678 
CalculateRadioButtonAutoSize(RadioButton rb)4679 		public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4680 		{
4681 			Size ret_size = Size.Empty;
4682 			Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4683 			Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4684 
4685 			// Pad the text size
4686 			if (rb.Text.Length != 0) {
4687 				text_size.Height += 4;
4688 				text_size.Width += 4;
4689 			}
4690 
4691 			switch (rb.TextImageRelation) {
4692 				case TextImageRelation.Overlay:
4693 					ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4694 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4695 					break;
4696 				case TextImageRelation.ImageAboveText:
4697 				case TextImageRelation.TextAboveImage:
4698 					ret_size.Height = text_size.Height + image_size.Height;
4699 					ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4700 					break;
4701 				case TextImageRelation.ImageBeforeText:
4702 				case TextImageRelation.TextBeforeImage:
4703 					ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4704 					ret_size.Width = text_size.Width + image_size.Width;
4705 					break;
4706 			}
4707 
4708 			// Pad the result
4709 			ret_size.Height += (rb.Padding.Vertical);
4710 			ret_size.Width += (rb.Padding.Horizontal) + 15;
4711 
4712 			// There seems to be a minimum height
4713 			if (ret_size.Height == rb.Padding.Vertical)
4714 				ret_size.Height += 14;
4715 
4716 			return ret_size;
4717 		}
4718 
CalculateRadioButtonTextAndImageLayout(ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)4719 		public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4720 		{
4721 			CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4722 		}
4723 		#endregion	// RadioButton
4724 
4725 		#region ScrollBar
DrawScrollBar(Graphics dc, Rectangle clip, ScrollBar bar)4726 		public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4727 		{
4728 			int		scrollbutton_width = bar.scrollbutton_width;
4729 			int		scrollbutton_height = bar.scrollbutton_height;
4730 			Rectangle	first_arrow_area;
4731 			Rectangle	second_arrow_area;
4732 			Rectangle	thumb_pos;
4733 
4734 			thumb_pos = bar.ThumbPos;
4735 
4736 			if (bar.vert) {
4737 				first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4738 				bar.FirstArrowArea = first_arrow_area;
4739 
4740 				second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4741 				bar.SecondArrowArea = second_arrow_area;
4742 
4743 				thumb_pos.Width = bar.Width;
4744 				bar.ThumbPos = thumb_pos;
4745 
4746 				Brush VerticalBrush;
4747 				/* Background, upper track */
4748 				if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4749 					VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4750 				else
4751 					VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4752 				Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4753 				if (clip.IntersectsWith (UpperTrack))
4754 					dc.FillRectangle (VerticalBrush, UpperTrack);
4755 
4756 				/* Background, lower track */
4757 				if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4758 					VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4759 				else
4760 					VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4761 				Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4762 				if (clip.IntersectsWith (LowerTrack))
4763 					dc.FillRectangle (VerticalBrush, LowerTrack);
4764 
4765 				/* Buttons */
4766 				if (clip.IntersectsWith (first_arrow_area))
4767 					CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4768 				if (clip.IntersectsWith (second_arrow_area))
4769 					CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4770 			} else {
4771 				first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4772 				bar.FirstArrowArea = first_arrow_area;
4773 
4774 				second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4775 				bar.SecondArrowArea = second_arrow_area;
4776 
4777 				thumb_pos.Height = bar.Height;
4778 				bar.ThumbPos = thumb_pos;
4779 
4780 				Brush HorizontalBrush;
4781 				//Background, left track
4782 				if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4783 					HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4784 				else
4785 					HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4786 				Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4787 				if (clip.IntersectsWith (LeftTrack))
4788 					dc.FillRectangle (HorizontalBrush, LeftTrack);
4789 
4790 				//Background, right track
4791 				if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4792 					HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4793 				else
4794 					HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4795 				Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4796 				if (clip.IntersectsWith (RightTrack))
4797 					dc.FillRectangle (HorizontalBrush, RightTrack);
4798 
4799 				/* Buttons */
4800 				if (clip.IntersectsWith (first_arrow_area))
4801 					CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4802 				if (clip.IntersectsWith (second_arrow_area))
4803 					CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4804 			}
4805 
4806 			/* Thumb */
4807 			ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);
4808 		}
4809 
ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)4810 		protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4811 		{
4812 			if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4813 				DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4814 		}
4815 
4816 		public override int ScrollBarButtonSize {
4817 			get { return 16; }
4818 		}
4819 
4820 		public override bool ScrollBarHasHotElementStyles {
4821 			get {
4822 				return false;
4823 			}
4824 		}
4825 
4826 		public override bool ScrollBarHasPressedThumbStyle {
4827 			get {
4828 				return false;
4829 			}
4830 		}
4831 
4832 		public override bool ScrollBarHasHoverArrowButtonStyle {
4833 			get {
4834 				return false;
4835 			}
4836 		}
4837 		#endregion	// ScrollBar
4838 
4839 		#region StatusBar
DrawStatusBar(Graphics real_dc, Rectangle clip, StatusBar sb)4840 		public	override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4841 			Rectangle area = sb.ClientRectangle;
4842 			int horz_border = 2;
4843 			int vert_border = 2;
4844 
4845 			Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4846 			Graphics dc = Graphics.FromImage (backbuffer);
4847 
4848 			DrawStatusBarBackground (dc, clip, sb);
4849 
4850 			if (!sb.ShowPanels && sb.Text != String.Empty) {
4851 				string text = sb.Text;
4852 				StringFormat string_format = new StringFormat ();
4853 				string_format.Trimming = StringTrimming.Character;
4854 				string_format.FormatFlags = StringFormatFlags.NoWrap;
4855 
4856 				if (text.Length > 127)
4857 					text = text.Substring (0, 127);
4858 
4859 				if (text [0] == '\t') {
4860 					string_format.Alignment = StringAlignment.Center;
4861 					text = text.Substring (1);
4862 					if (text [0] == '\t') {
4863 						string_format.Alignment = StringAlignment.Far;
4864 						text = text.Substring (1);
4865 					}
4866 				}
4867 
4868 				dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4869 						new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4870 				string_format.Dispose ();
4871 			} else if (sb.ShowPanels) {
4872 				Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4873 				int prev_x = area.X + horz_border;
4874 				int y = area.Y + vert_border;
4875 				for (int i = 0; i < sb.Panels.Count; i++) {
4876 					Rectangle pr = new Rectangle (prev_x, y,
4877 						sb.Panels [i].Width, area.Height);
4878 					prev_x += pr.Width + StatusBarHorzGapWidth;
4879 					if (pr.IntersectsWith (clip))
4880 						DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4881 				}
4882 			}
4883 
4884 			if (sb.SizingGrip)
4885 				DrawStatusBarSizingGrip (dc, clip, sb, area);
4886 
4887 			real_dc.DrawImage (backbuffer, 0, 0);
4888 			dc.Dispose ();
4889 			backbuffer.Dispose ();
4890 
4891 		}
4892 
DrawStatusBarBackground(Graphics dc, Rectangle clip, StatusBar sb)4893 		protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4894 		{
4895 			bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4896 
4897 			Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4898 			dc.FillRectangle (brush, clip);
4899 		}
4900 
DrawStatusBarSizingGrip(Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)4901 		protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4902 		{
4903 			area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4904 			CPDrawSizeGrip (dc, ColorControl, area);
4905 		}
4906 
DrawStatusBarPanel(Graphics dc, Rectangle area, int index, Brush br_forecolor, StatusBarPanel panel)4907 		protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4908 			Brush br_forecolor, StatusBarPanel panel) {
4909 			int border_size = 3; // this is actually const, even if the border style is none
4910 			int icon_width = 16;
4911 
4912 			area.Height -= border_size;
4913 
4914 			DrawStatusBarPanelBackground (dc, area, panel);
4915 
4916 			if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4917 				StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4918 					dc, panel.Parent.Font, area, index, DrawItemState.Default,
4919 					panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4920 				panel.Parent.OnDrawItemInternal (e);
4921 				return;
4922 			}
4923 
4924 			string text = panel.Text;
4925 			StringFormat string_format = new StringFormat ();
4926 			string_format.Trimming = StringTrimming.Character;
4927 			string_format.FormatFlags = StringFormatFlags.NoWrap;
4928 
4929 
4930 			if (text != null && text.Length > 0 && text [0] == '\t') {
4931 				string_format.Alignment = StringAlignment.Center;
4932 				text = text.Substring (1);
4933 				if (text [0] == '\t') {
4934 					string_format.Alignment = StringAlignment.Far;
4935 					text = text.Substring (1);
4936 				}
4937 			}
4938 
4939 			Rectangle string_rect = Rectangle.Empty;
4940 			int x;
4941 			int len;
4942 			int icon_x = 0;
4943 			int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4944 
4945 			switch (panel.Alignment) {
4946 			case HorizontalAlignment.Right:
4947 				len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4948 				x = area.Right - len - 4;
4949 				string_rect = new Rectangle (x, y,
4950 						area.Right - x - border_size,
4951 						area.Bottom - y - border_size);
4952 				if (panel.Icon != null) {
4953 					icon_x = x - icon_width - 2;
4954 				}
4955 				break;
4956 			case HorizontalAlignment.Center:
4957 				len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4958 				x = area.Left + ((panel.Width - len) / 2);
4959 
4960 				string_rect = new Rectangle (x, y,
4961 						area.Right - x - border_size,
4962 						area.Bottom - y - border_size);
4963 
4964 				if (panel.Icon != null) {
4965 					icon_x = x - icon_width - 2;
4966 				}
4967 				break;
4968 
4969 
4970 			default:
4971 				int left = area.Left + border_size;;
4972 				if (panel.Icon != null) {
4973 					icon_x = area.Left + 2;
4974 					left = icon_x + icon_width + 2;
4975 				}
4976 
4977 				x = left;
4978 				string_rect = new Rectangle (x, y,
4979 						area.Right - x - border_size,
4980 						area.Bottom - y - border_size);
4981 				break;
4982 			}
4983 
4984 			RectangleF clip_bounds = dc.ClipBounds;
4985 			dc.SetClip (area);
4986 			dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);
4987 			dc.SetClip (clip_bounds);
4988 
4989 			if (panel.Icon != null) {
4990 				dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4991 			}
4992 		}
4993 
DrawStatusBarPanelBackground(Graphics dc, Rectangle area, StatusBarPanel panel)4994 		protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4995 		{
4996 			if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4997 				Border3DStyle border_style = Border3DStyle.SunkenOuter;
4998 				if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4999 					border_style = Border3DStyle.RaisedInner;
5000 
5001 				CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
5002 			}
5003 		}
5004 
5005 		public override int StatusBarSizeGripWidth {
5006 			get { return 15; }
5007 		}
5008 
5009 		public override int StatusBarHorzGapWidth {
5010 			get { return 3; }
5011 		}
5012 
5013 		public override Size StatusBarDefaultSize {
5014 			get {
5015 				return new Size (100, 22);
5016 			}
5017 		}
5018 		#endregion	// StatusBar
5019 
5020 		#region TabControl
5021 
5022 		#region TabControl settings
5023 
5024 		public override Size TabControlDefaultItemSize {
5025 			get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
5026 		}
5027 
5028 		public override Point TabControlDefaultPadding {
5029 			get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
5030 		}
5031 
5032 		public override int TabControlMinimumTabWidth {
5033 			get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
5034 		}
5035 
5036 		public override Rectangle TabControlSelectedDelta {
5037 			get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
5038 		}
5039 
5040 		public override int TabControlSelectedSpacing {
5041 			get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
5042 		}
5043 
5044 		public override int TabPanelOffsetX {
5045 			get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
5046 		}
5047 
5048 		public override int TabPanelOffsetY {
5049 			get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
5050 		}
5051 
5052 		public override int TabControlColSpacing {
5053 			get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
5054 		}
5055 
5056 		public override Point TabControlImagePadding {
5057 			get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
5058 		}
5059 
5060 		public override int TabControlScrollerWidth {
5061 			get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
5062 		}
5063 
5064 
TabControlGetSpacing(TabControl tab)5065 		public override Size TabControlGetSpacing (TabControl tab)
5066 		{
5067 			try {
5068 				return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
5069 			} catch {
5070 				throw new Exception ("Invalid Appearance value: " + tab.Appearance);
5071 			}
5072 		}
5073 		#endregion
5074 
DrawTabControl(Graphics dc, Rectangle area, TabControl tab)5075 		public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
5076 		{
5077 			ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
5078 		}
5079 
TabControlGetDisplayRectangle(TabControl tab)5080 		public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
5081 		{
5082 			return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
5083 		}
5084 
TabControlGetPanelRect(TabControl tab)5085 		public override Rectangle TabControlGetPanelRect (TabControl tab)
5086 		{
5087 			return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
5088 		}
5089 
5090 		#endregion
5091 
5092 		#region TextBox
TextBoxBaseFillBackground(TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)5093 		public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
5094 		{
5095 			if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
5096 				g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
5097 			} else {
5098 				g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
5099 			}
5100 		}
5101 
TextBoxBaseHandleWmNcPaint(TextBoxBase textBoxBase, ref Message m)5102 		public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
5103 		{
5104 			return false;
5105 		}
5106 
TextBoxBaseShouldPaintBackground(TextBoxBase textBoxBase)5107 		public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
5108 		{
5109 			return true;
5110 		}
5111 		#endregion
5112 
5113 		#region ToolBar
DrawToolBar(Graphics dc, Rectangle clip_rectangle, ToolBar control)5114 		public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control)
5115 		{
5116 			StringFormat format = new StringFormat ();
5117 			format.Trimming = StringTrimming.EllipsisCharacter;
5118 			format.LineAlignment = StringAlignment.Center;
5119 			if (control.ShowKeyboardCuesInternal)
5120 				format.HotkeyPrefix = HotkeyPrefix.Show;
5121 			else
5122 				format.HotkeyPrefix = HotkeyPrefix.Hide;
5123 
5124 			if (control.TextAlign == ToolBarTextAlign.Underneath)
5125 				format.Alignment = StringAlignment.Center;
5126 			else
5127 				format.Alignment = StringAlignment.Near;
5128 
5129 			if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
5130 				dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5131 			}
5132 
5133 			if (control.Divider && clip_rectangle.Y < 2) {
5134 				if (clip_rectangle.Y < 1) {
5135 					dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
5136 				}
5137 				dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5138 			}
5139 
5140 			foreach (ToolBarItem item in control.items)
5141 				if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
5142 					DrawToolBarButton (dc, control, item, format);
5143 
5144 			format.Dispose ();
5145 		}
5146 
DrawToolBarButton(Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)5147 		protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5148 		{
5149 			bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
5150 
5151 			DrawToolBarButtonBorder (dc, item, is_flat);
5152 
5153 			switch (item.Button.Style) {
5154 			case ToolBarButtonStyle.DropDownButton:
5155 				if (control.DropDownArrows)
5156 					DrawToolBarDropDownArrow (dc, item, is_flat);
5157 				DrawToolBarButtonContents (dc, control, item, format);
5158 				break;
5159 
5160 			case ToolBarButtonStyle.Separator:
5161 				if (is_flat)
5162 					DrawToolBarSeparator (dc, item);
5163 				break;
5164 
5165 			case ToolBarButtonStyle.ToggleButton:
5166 				DrawToolBarToggleButtonBackground (dc, item);
5167 				DrawToolBarButtonContents (dc, control, item, format);
5168 				break;
5169 
5170 			default:
5171 				DrawToolBarButtonContents (dc, control, item, format);
5172 				break;
5173 			}
5174 		}
5175 
5176 		const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
5177 
DrawToolBarButtonBorder(Graphics dc, ToolBarItem item, bool is_flat)5178 		protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
5179 		{
5180 			if (item.Button.Style == ToolBarButtonStyle.Separator)
5181 				return;
5182 
5183 			Border3DStyle style;
5184 
5185 			if (is_flat) {
5186 				if (item.Button.Pushed || item.Pressed)
5187 					style = Border3DStyle.SunkenOuter;
5188 				else if (item.Hilight)
5189 					style = Border3DStyle.RaisedInner;
5190 				else
5191 					return;
5192 
5193 			} else {
5194 				if (item.Button.Pushed || item.Pressed)
5195 					style = Border3DStyle.Sunken;
5196 				else
5197 					style = Border3DStyle.Raised;
5198 			}
5199 
5200 			Rectangle rect = item.Rectangle;
5201 			if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5202 				rect.Width -= ToolBarDropDownWidth;
5203 
5204 			CPDrawBorder3D (dc, rect, style, all_sides);
5205 		}
5206 
DrawToolBarSeparator(Graphics dc, ToolBarItem item)5207 		protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5208 		{
5209 			Rectangle area = item.Rectangle;
5210 			int offset = (int) SystemPens.Control.Width + 1;
5211 			dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5212 			dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5213 		}
5214 
DrawToolBarToggleButtonBackground(Graphics dc, ToolBarItem item)5215 		protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5216 		{
5217 			Brush brush;
5218 			Rectangle area = item.Rectangle;
5219 			area.X += ToolBarImageGripWidth;
5220 			area.Y += ToolBarImageGripWidth;
5221 			area.Width -= 2 * ToolBarImageGripWidth;
5222 			area.Height -= 2 * ToolBarImageGripWidth;
5223 
5224 			if (item.Button.Pushed)
5225 				brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5226 			else if (item.Button.PartialPush)
5227 				brush = SystemBrushes.ControlLight;
5228 			else
5229 				brush = SystemBrushes.Control;
5230 
5231 			dc.FillRectangle (brush, area);
5232 		}
5233 
DrawToolBarDropDownArrow(Graphics dc, ToolBarItem item, bool is_flat)5234 		protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5235 		{
5236 			Rectangle rect = item.Rectangle;
5237 			rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5238 			rect.Width = ToolBarDropDownWidth;
5239 
5240 			if (is_flat) {
5241 				if (item.DDPressed)
5242 					CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5243 				else if (item.Button.Pushed || item.Pressed)
5244 					CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5245 				else if (item.Hilight)
5246 					CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5247 			} else {
5248 				if (item.DDPressed)
5249 					CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5250 				else if (item.Button.Pushed || item.Pressed)
5251 					CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5252 				else
5253 					CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5254 			}
5255 
5256 			PointF [] vertices = new PointF [3];
5257 			PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5258 
5259 			// Increase vertical and horizontal position by 1 when button is pressed
5260 			if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5261 			    ddCenter.X += 1;
5262 			    ddCenter.Y += 1;
5263 			}
5264 
5265 			vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5266 			vertices [0].Y = ddCenter.Y;
5267 			vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5268 			vertices [1].Y = ddCenter.Y;
5269 			vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5270 			vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5271 			dc.FillPolygon (SystemBrushes.ControlText, vertices);
5272 		}
5273 
DrawToolBarButtonContents(Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)5274 		protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5275 		{
5276 			if (item.Button.Image != null) {
5277 				int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5278 				int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5279 
5280 				// Increase vertical and horizontal position by 1 when button is pressed
5281 				if (item.Pressed || item.Button.Pushed) {
5282 				    x += 1;
5283 				    y += 1;
5284 				}
5285 
5286 				if (item.Button.Enabled)
5287 					dc.DrawImage (item.Button.Image, x, y);
5288 				else
5289 					CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5290 			}
5291 
5292 			Rectangle text_rect = item.TextRectangle;
5293 			if (text_rect.Width <= 0 || text_rect.Height <= 0)
5294 				return;
5295 
5296 			if (item.Pressed || item.Button.Pushed) {
5297 				text_rect.X += 1;
5298 				text_rect.Y += 1;
5299 			}
5300 
5301 			if (item.Button.Enabled)
5302 				dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5303 			else
5304 				CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5305 		}
5306 
5307 		// Grip width for the ToolBar
5308 		public override int ToolBarGripWidth {
5309 			get { return 2;}
5310 		}
5311 
5312 		// Grip width for the Image on the ToolBarButton
5313 		public override int ToolBarImageGripWidth {
5314 			get { return 2;}
5315 		}
5316 
5317 		// width of the separator
5318 		public override int ToolBarSeparatorWidth {
5319 			get { return 4; }
5320 		}
5321 
5322 		// width of the dropdown arrow rect
5323 		public override int ToolBarDropDownWidth {
5324 			get { return 13; }
5325 		}
5326 
5327 		// width for the dropdown arrow on the ToolBarButton
5328 		public override int ToolBarDropDownArrowWidth {
5329 			get { return 5;}
5330 		}
5331 
5332 		// height for the dropdown arrow on the ToolBarButton
5333 		public override int ToolBarDropDownArrowHeight {
5334 			get { return 3;}
5335 		}
5336 
5337 		public override Size ToolBarDefaultSize {
5338 			get {
5339 				return new Size (100, 42);
5340 			}
5341 		}
5342 
ToolBarHasHotElementStyles(ToolBar toolBar)5343 		public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5344 		{
5345 			return toolBar.Appearance == ToolBarAppearance.Flat;
5346 		}
5347 
5348 		public override bool ToolBarHasHotCheckedElementStyles {
5349 			get {
5350 				return false;
5351 			}
5352 		}
5353 		#endregion	// ToolBar
5354 
5355 		#region ToolTip
DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)5356 		public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5357 		{
5358 			ToolTipDrawBackground (dc, clip_rectangle, control);
5359 
5360 			TextFormatFlags flags = TextFormatFlags.HidePrefix;
5361 
5362 			Color foreground = control.ForeColor;
5363 			if (control.title.Length > 0) {
5364 				Font bold_font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
5365 				TextRenderer.DrawTextInternal (dc, control.title, bold_font, control.title_rect,
5366 						foreground, flags, false);
5367 				bold_font.Dispose ();
5368 			}
5369 
5370 			if (control.icon != null)
5371 				dc.DrawIcon (control.icon, control.icon_rect);
5372 
5373 			TextRenderer.DrawTextInternal (dc, control.Text, control.Font, control.text_rect, foreground, flags, false);
5374 		}
5375 
ToolTipDrawBackground(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)5376 		protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5377 		{
5378 			Brush back_brush = ResPool.GetSolidBrush (control.BackColor);
5379 			dc.FillRectangle (back_brush, control.ClientRectangle);
5380 			dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5381 		}
5382 
ToolTipSize(ToolTip.ToolTipWindow tt, string text)5383 		public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5384 		{
5385 			Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5386 			size.Width += 4;
5387 			size.Height += 3;
5388 			Rectangle text_rect = new Rectangle (Point.Empty, size);
5389 			text_rect.Inflate (-2, -1);
5390 			tt.text_rect = text_rect;
5391 			tt.icon_rect = tt.title_rect = Rectangle.Empty;
5392 
5393 			Size title_size = Size.Empty;
5394 			if (tt.title.Length > 0) {
5395 				Font bold_font = new Font (tt.Font, tt.Font.Style | FontStyle.Bold);
5396 				title_size = TextRenderer.MeasureTextInternal (tt.title, bold_font, false);
5397 				bold_font.Dispose ();
5398 			}
5399 
5400 			Size icon_size = Size.Empty;
5401 			if (tt.icon != null)
5402 				icon_size = new Size (size.Height, size.Height);
5403 
5404 			if (icon_size != Size.Empty || title_size != Size.Empty) {
5405 				int padding = 8;
5406 				int top_area_width = 0;
5407 				int top_area_height = icon_size.Height > title_size.Height ? icon_size.Height : title_size.Height;
5408 				Size text_size = size;
5409 				Point location = new Point (padding, padding);
5410 
5411 				if (icon_size != Size.Empty) {
5412 					tt.icon_rect = new Rectangle (location, icon_size);
5413 					top_area_width = icon_size.Width + padding;
5414 				}
5415 
5416 				if (title_size != Size.Empty) {
5417 					Rectangle title_rect = new Rectangle (location, new Size (title_size.Width, top_area_height));
5418 					if (icon_size != Size.Empty)
5419 						title_rect.X += icon_size.Width + padding;
5420 
5421 					tt.title_rect = title_rect;
5422 					top_area_width += title_size.Width;
5423 				}
5424 
5425 				tt.text_rect = new Rectangle (new Point (location.X, location.Y + top_area_height + padding),
5426 						text_size);
5427 
5428 				size.Height += padding + top_area_height;
5429 				if (top_area_width > size.Width)
5430 					size.Width = top_area_width;
5431 
5432 				// margins
5433 				size.Width += padding * 2;
5434 				size.Height += padding * 2;
5435 			}
5436 
5437 			return size;
5438 		}
5439 
5440 		public override bool ToolTipTransparentBackground {
5441 			get {
5442 				return false;
5443 			}
5444  		}
5445 		#endregion	// ToolTip
5446 
5447 		#region BalloonWindow
5448 		NotifyIcon.BalloonWindow balloon_window;
5449 
ShowBalloonWindow(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)5450 		public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5451 		{
5452 			Control control = Control.FromHandle(handle);
5453 
5454 			if (control == null)
5455 				return;
5456 
5457 			if (balloon_window != null) {
5458 				balloon_window.Close ();
5459 				balloon_window.Dispose ();
5460 			}
5461 
5462 			balloon_window = new NotifyIcon.BalloonWindow (handle);
5463 			balloon_window.Title = title;
5464 			balloon_window.Text = text;
5465 			balloon_window.Icon = icon;
5466 			balloon_window.Timeout = timeout;
5467 			balloon_window.Show ();
5468 		}
5469 
HideBalloonWindow(IntPtr handle)5470 		public override void HideBalloonWindow (IntPtr handle)
5471 		{
5472 			if (balloon_window == null || balloon_window.OwnerHandle != handle)
5473 				return;
5474 
5475 			balloon_window.Close ();
5476 			balloon_window.Dispose ();
5477 			balloon_window = null;
5478 		}
5479 
5480 		private const int balloon_iconsize = 16;
5481 		private const int balloon_bordersize = 8;
5482 
DrawBalloonWindow(Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control)5483 		public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control)
5484 		{
5485 			Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5486 			Rectangle rect = control.ClientRectangle;
5487 			int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5488 
5489 			// Rectangle borders and background.
5490 			dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5491 			dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5492 
5493 			// Icon
5494 			Image image;
5495 			switch (control.Icon) {
5496 				case ToolTipIcon.Info: {
5497 					image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5498 					break;
5499 				}
5500 
5501 				case ToolTipIcon.Warning: {
5502 					image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5503 					break;
5504 				}
5505 
5506 				case ToolTipIcon.Error: {
5507 					image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5508 					break;
5509 				}
5510 
5511 				default: {
5512 					image = null;
5513 					break;
5514 				}
5515 			}
5516 
5517 			if (control.Icon != ToolTipIcon.None)
5518 				dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5519 
5520 			// Title
5521 			Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0),
5522 												rect.Y + balloon_bordersize,
5523 												rect.Width - ((3 * balloon_bordersize) + iconsize),
5524 												rect.Height - (2 * balloon_bordersize));
5525 
5526 			Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5527 			dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5528 
5529 			// Text
5530 			Rectangle textrect = new Rectangle (rect.X + balloon_bordersize,
5531 												rect.Y + balloon_bordersize,
5532 												rect.Width - (2 * balloon_bordersize),
5533 												rect.Height - (2 * balloon_bordersize));
5534 
5535 			StringFormat textformat = control.Format;
5536 			textformat.LineAlignment = StringAlignment.Far;
5537 			dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5538 		}
5539 
BalloonWindowRect(NotifyIcon.BalloonWindow control)5540 		public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5541 		{
5542 			Rectangle deskrect = Screen.GetWorkingArea (control);
5543 			SizeF maxsize = new SizeF (250, 200);
5544 
5545 			SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5546 			SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5547 
5548 			if (titlesize.Height < balloon_iconsize)
5549 				titlesize.Height = balloon_iconsize;
5550 
5551 			Rectangle rect = new Rectangle ();
5552 			rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5553 			rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5554 			rect.X = deskrect.Width - rect.Width - 2;
5555 			rect.Y = deskrect.Height - rect.Height - 2;
5556 
5557 			return rect;
5558 		}
5559 		#endregion	// BalloonWindow
5560 
5561 		#region	TrackBar
TrackBarValueFromMousePosition(int x, int y, TrackBar tb)5562 		public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5563 		{
5564 			int result = tb.Value;
5565 			int value_pos = tb.Value;
5566 			float pixels_betweenticks;
5567 			Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5568 			Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5569 
5570 			GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5571 
5572 			/* Convert thumb position from mouse position to value*/
5573 			if (tb.Orientation == Orientation.Vertical) {
5574 				value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5575 
5576 				if (value_pos + tb.Minimum > tb.Maximum)
5577 					value_pos = tb.Maximum - tb.Minimum;
5578 				else if (value_pos + tb.Minimum < tb.Minimum)
5579 					value_pos = 0;
5580 
5581 				result = value_pos + tb.Minimum;
5582 			} else {
5583 				value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5584 
5585 				if (value_pos + tb.Minimum > tb.Maximum)
5586 					value_pos = tb.Maximum - tb.Minimum;
5587 				else if (value_pos + tb.Minimum < tb.Minimum)
5588 					value_pos = 0;
5589 
5590 				result = value_pos + tb.Minimum;
5591 			}
5592 
5593 			return result;
5594 		}
5595 
GetTrackBarDrawingInfo(TrackBar tb, out float pixels_betweenticks, out Rectangle thumb_area, out Rectangle thumb_pos, out Point channel_startpoint, out Point bottomtick_startpoint, out Point toptick_startpoint)5596 		private void GetTrackBarDrawingInfo (TrackBar tb, out float pixels_betweenticks, out Rectangle thumb_area, out Rectangle thumb_pos, out Point channel_startpoint, out Point bottomtick_startpoint, out Point toptick_startpoint)
5597 		{
5598 			thumb_area = Rectangle.Empty;
5599 			thumb_pos = Rectangle.Empty;
5600 
5601 			if (tb.Orientation == Orientation.Vertical) {
5602 				toptick_startpoint = new Point ();
5603 				bottomtick_startpoint = new Point ();
5604 				channel_startpoint = new Point ();
5605 				float pixel_len;
5606 				const int space_from_right = 8;
5607 				const int space_from_left = 8;
5608 				const int space_from_bottom = 11;
5609 				Rectangle area = tb.ClientRectangle;
5610 
5611 				switch (tb.TickStyle) {
5612 				case TickStyle.BottomRight:
5613 				case TickStyle.None:
5614 					channel_startpoint.Y = 8;
5615 					channel_startpoint.X = 9;
5616 					bottomtick_startpoint.Y = 13;
5617 					bottomtick_startpoint.X = 24;
5618 					break;
5619 				case TickStyle.TopLeft:
5620 					channel_startpoint.Y = 8;
5621 					channel_startpoint.X = 19;
5622 					toptick_startpoint.Y = 13;
5623 					toptick_startpoint.X = 8;
5624 					break;
5625 				case TickStyle.Both:
5626 					channel_startpoint.Y = 8;
5627 					channel_startpoint.X = 18;
5628 					bottomtick_startpoint.Y = 13;
5629 					bottomtick_startpoint.X = 32;
5630 					toptick_startpoint.Y = 13;
5631 					toptick_startpoint.X = 8;
5632 					break;
5633 				default:
5634 					break;
5635 				}
5636 
5637 				thumb_area.X = area.X + channel_startpoint.X;
5638 				thumb_area.Y = area.Y + channel_startpoint.Y;
5639 				thumb_area.Height = area.Height - space_from_right - space_from_left;
5640 				thumb_area.Width = TrackBarVerticalTrackWidth;
5641 
5642 				pixel_len = thumb_area.Height - 11;
5643 				if (tb.Maximum == tb.Minimum) {
5644 					pixels_betweenticks = 0;
5645 				} else {
5646 					pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5647 				}
5648 
5649 				thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5650 			} else {
5651 				toptick_startpoint = new Point ();
5652 				bottomtick_startpoint = new Point ();
5653 				channel_startpoint = new Point ();
5654 				float pixel_len;
5655 				const int space_from_right = 8;
5656 				const int space_from_left = 8;
5657 				Rectangle area = tb.ClientRectangle;
5658 
5659 				switch (tb.TickStyle) {
5660 				case TickStyle.BottomRight:
5661 				case TickStyle.None:
5662 					channel_startpoint.X = 8;
5663 					channel_startpoint.Y = 9;
5664 					bottomtick_startpoint.X = 13;
5665 					bottomtick_startpoint.Y = 24;
5666 					break;
5667 				case TickStyle.TopLeft:
5668 					channel_startpoint.X = 8;
5669 					channel_startpoint.Y = 19;
5670 					toptick_startpoint.X = 13;
5671 					toptick_startpoint.Y = 8;
5672 					break;
5673 				case TickStyle.Both:
5674 					channel_startpoint.X = 8;
5675 					channel_startpoint.Y = 18;
5676 					bottomtick_startpoint.X = 13;
5677 					bottomtick_startpoint.Y = 32;
5678 					toptick_startpoint.X = 13;
5679 					toptick_startpoint.Y = 8;
5680 					break;
5681 				default:
5682 					break;
5683 				}
5684 
5685 				thumb_area.X = area.X + channel_startpoint.X;
5686 				thumb_area.Y = area.Y + channel_startpoint.Y;
5687 				thumb_area.Width = area.Width - space_from_right - space_from_left;
5688 				thumb_area.Height = TrackBarHorizontalTrackHeight;
5689 
5690 				pixel_len = thumb_area.Width - 11;
5691 				if (tb.Maximum == tb.Minimum) {
5692 					pixels_betweenticks = 0;
5693 				} else {
5694 					pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5695 				}
5696 
5697 				thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5698 			}
5699 
5700 			thumb_pos.Size = TrackBarGetThumbSize (tb);
5701 		}
5702 
TrackBarGetThumbSize(TrackBar trackBar)5703 		protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5704 		{
5705 			return TrackBarGetThumbSize ();
5706 		}
5707 
TrackBarGetThumbSize()5708 		public static Size TrackBarGetThumbSize ()
5709 		{
5710 			/* Draw thumb fixed 10x22 size */
5711 			return new Size (10, 22);
5712 		}
5713 
5714 		public const int TrackBarVerticalTrackWidth = 4;
5715 
5716 		public const int TrackBarHorizontalTrackHeight = 4;
5717 
5718 		#region Ticks
5719 		protected interface ITrackBarTickPainter
5720 		{
Paint(float x1, float y1, float x2, float y2)5721 			void Paint (float x1, float y1, float x2, float y2);
5722 		}
5723 
5724 		class TrackBarTickPainter : ITrackBarTickPainter
5725 		{
5726 			readonly Graphics g;
5727 			readonly Pen pen;
TrackBarTickPainter(Graphics g, Pen pen)5728 			public TrackBarTickPainter (Graphics g, Pen pen)
5729 			{
5730 				this.g = g;
5731 				this.pen = pen;
5732 			}
Paint(float x1, float y1, float x2, float y2)5733 			public void Paint (float x1, float y1, float x2, float y2)
5734 			{
5735 				g.DrawLine (pen, x1, y1, x2, y2);
5736 			}
5737 		}
GetTrackBarTickPainter(Graphics g)5738 		protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5739 		{
5740 			return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5741 		}
5742 		#endregion
5743 
5744 		#region DrawTrackBar_Vertical
DrawTrackBar_Vertical(Graphics dc, Rectangle clip_rectangle, TrackBar tb, ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb, float ticks, int value_pos, bool mouse_value)5745 		private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5746 			ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5747 			float ticks, int value_pos, bool mouse_value) {
5748 
5749 			Point toptick_startpoint = new Point ();
5750 			Point bottomtick_startpoint = new Point ();
5751 			Point channel_startpoint = new Point ();
5752 			float pixel_len;
5753 			float pixels_betweenticks;
5754 			Rectangle area = tb.ClientRectangle;
5755 
5756 			GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5757 
5758 			#region Track
5759 			TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5760 			#endregion
5761 
5762 			#region Thumb
5763 			switch (tb.TickStyle) 	{
5764 			case TickStyle.BottomRight:
5765 			case TickStyle.None:
5766 				thumb_pos.X = channel_startpoint.X - 8;
5767 				TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5768 				break;
5769 			case TickStyle.TopLeft:
5770 				thumb_pos.X = channel_startpoint.X - 10;
5771 				TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5772 				break;
5773 			default:
5774 				thumb_pos.X = area.X + 10;
5775 				TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5776 				break;
5777 			}
5778 			#endregion
5779 
5780 			pixel_len = thumb_area.Height - 11;
5781 			pixels_betweenticks = pixel_len / ticks;
5782 
5783 			thumb_area.X = thumb_pos.X;
5784 			thumb_area.Y = channel_startpoint.Y;
5785 			thumb_area.Width = thumb_pos.Height;
5786 
5787 			#region Ticks
5788 			if (pixels_betweenticks <= 0)
5789 				return;
5790 			if (tb.TickStyle == TickStyle.None)
5791 				return;
5792 			Region outside = new Region (area);
5793 			outside.Exclude (thumb_area);
5794 
5795 			if (outside.IsVisible (clip_rectangle)) {
5796 				ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5797 
5798 				if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5799 					float x = area.X + bottomtick_startpoint.X;
5800 					for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) 	{
5801 						float y = area.Y + bottomtick_startpoint.Y + inc;
5802 						tick_painter.Paint (
5803 							x, y,
5804 							x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5805 					}
5806 				}
5807 
5808 				if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5809 					float x = area.X + toptick_startpoint.X;
5810 					for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {
5811 						float y = area.Y + toptick_startpoint.Y + inc;
5812 						tick_painter.Paint (
5813 							x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5814 							x, y);
5815 					}
5816 				}
5817 			}
5818 
5819 			outside.Dispose ();
5820 			#endregion
5821 		}
5822 
5823 		#region Track
TrackBarDrawVerticalTrack(Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)5824 		protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5825 		{
5826 			dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5827 				1, thumb_area.Height);
5828 
5829 			dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5830 				1, thumb_area.Height);
5831 
5832 			dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5833 				1, thumb_area.Height);
5834 		}
5835 		#endregion
5836 
5837 		#region Thumb
TrackBarDrawVerticalThumbRight(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)5838 		protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5839 		{
5840 			Pen pen = SystemPens.ControlLightLight;
5841 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5842 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5843 			dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5844 
5845 			pen = SystemPens.ControlDark;
5846 			dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5847 			dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5848 
5849 			pen = SystemPens.ControlDarkDark;
5850 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5851 			dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5852 
5853 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5854 			dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5855 			dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5856 			dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5857 		}
5858 
TrackBarDrawVerticalThumbLeft(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)5859 		protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5860 		{
5861 			Pen pen = SystemPens.ControlLightLight;
5862 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5863 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5864 
5865 			pen = SystemPens.ControlDark;
5866 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5867 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5868 			dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5869 
5870 			pen = SystemPens.ControlDarkDark;
5871 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5872 			dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5873 			dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5874 
5875 			dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5876 			dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5877 			dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5878 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5879 		}
5880 
TrackBarDrawVerticalThumb(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)5881 		protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5882 		{
5883 			Pen pen = SystemPens.ControlLightLight;
5884 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5885 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5886 
5887 			pen = SystemPens.ControlDark;
5888 			dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5889 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5890 
5891 			pen = SystemPens.ControlDarkDark;
5892 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5893 			dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5894 
5895 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5896 		}
5897 		#endregion
5898 
5899 		#region Ticks
TrackBarGetVerticalTickPainter(Graphics g)5900 		protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5901 		{
5902 			return GetTrackBarTickPainter (g);
5903 		}
5904 		#endregion
5905 		#endregion
5906 
5907 		#region DrawTrackBar_Horizontal
5908 		/*
5909 			Horizontal trackbar
5910 
5911 			Does not matter the size of the control, Win32 always draws:
5912 				- Ticks starting from pixel 13, 8
5913 				- Channel starting at pos 8, 19 and ends at Width - 8
5914 				- Autosize makes always the control 45 pixels high
5915 				- Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5916 
5917 		*/
DrawTrackBar_Horizontal(Graphics dc, Rectangle clip_rectangle, TrackBar tb, ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb, float ticks, int value_pos, bool mouse_value)5918 		private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5919 			ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5920 			float ticks, int value_pos, bool mouse_value) {
5921 			Point toptick_startpoint = new Point ();
5922 			Point bottomtick_startpoint = new Point ();
5923 			Point channel_startpoint = new Point ();
5924 			float pixel_len;
5925 			float pixels_betweenticks;
5926 			Rectangle area = tb.ClientRectangle;
5927 
5928 			GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5929 
5930 			#region Track
5931 			TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5932 			#endregion
5933 
5934 			#region Thumb
5935 			switch (tb.TickStyle) {
5936 			case TickStyle.BottomRight:
5937 			case TickStyle.None:
5938 				thumb_pos.Y = channel_startpoint.Y - 8;
5939 				TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5940 				break;
5941 			case TickStyle.TopLeft:
5942 				thumb_pos.Y = channel_startpoint.Y - 10;
5943 				TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5944 				break;
5945 			default:
5946 				thumb_pos.Y = area.Y + 10;
5947 				TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5948 				break;
5949 			}
5950 			#endregion
5951 
5952 			pixel_len = thumb_area.Width - 11;
5953 			pixels_betweenticks = pixel_len / ticks;
5954 
5955 			thumb_area.Y = thumb_pos.Y;
5956 			thumb_area.X = channel_startpoint.X;
5957 			thumb_area.Height = thumb_pos.Height;
5958 			#region Ticks
5959 			if (pixels_betweenticks <= 0)
5960 				return;
5961 			if (tb.TickStyle == TickStyle.None)
5962 				return;
5963 			Region outside = new Region (area);
5964 			outside.Exclude (thumb_area);
5965 
5966 			if (outside.IsVisible (clip_rectangle)) {
5967 				ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5968 
5969 				if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5970 					float y = area.Y + bottomtick_startpoint.Y;
5971 					for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {
5972 						float x = area.X + bottomtick_startpoint.X + inc;
5973 						tick_painter.Paint (
5974 							x, y,
5975 							x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5976 					}
5977 				}
5978 
5979 				if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5980 					float y = area.Y + toptick_startpoint.Y;
5981 					for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {
5982 						float x = area.X + toptick_startpoint.X + inc;
5983 						tick_painter.Paint (
5984 							x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2),
5985 							x, y);
5986 					}
5987 				}
5988 			}
5989 
5990 			outside.Dispose ();
5991 			#endregion
5992 		}
5993 
5994 		#region Track
TrackBarDrawHorizontalTrack(Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)5995 		protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5996 		{
5997 			dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5998 				thumb_area.Width, 1);
5999 
6000 			dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
6001 				thumb_area.Width, 1);
6002 
6003 			dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
6004 				thumb_area.Width, 1);
6005 		}
6006 		#endregion
6007 
6008 		#region Thumb
TrackBarDrawHorizontalThumbBottom(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)6009 		protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6010 		{
6011 			Pen pen = SystemPens.ControlLightLight;
6012 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
6013 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
6014 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
6015 
6016 			pen = SystemPens.ControlDark;
6017 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
6018 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
6019 
6020 			pen = SystemPens.ControlDarkDark;
6021 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
6022 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
6023 
6024 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
6025 			dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
6026 			dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
6027 			dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
6028 		}
6029 
TrackBarDrawHorizontalThumbTop(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)6030 		protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6031 		{
6032 			Pen pen = SystemPens.ControlLightLight;
6033 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
6034 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
6035 
6036 			pen = SystemPens.ControlDark;
6037 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
6038 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
6039 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
6040 
6041 			pen = SystemPens.ControlDarkDark;
6042 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
6043 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
6044 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
6045 
6046 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
6047 			dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
6048 			dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
6049 			dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
6050 		}
6051 
TrackBarDrawHorizontalThumb(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)6052 		protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6053 		{
6054 			Pen pen = SystemPens.ControlLightLight;
6055 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
6056 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
6057 
6058 			pen = SystemPens.ControlDark;
6059 			dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
6060 			dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
6061 
6062 			pen = SystemPens.ControlDarkDark;
6063 			dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
6064 			dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
6065 
6066 			dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
6067 		}
6068 		#endregion
6069 
6070 		#region Ticks
TrackBarGetHorizontalTickPainter(Graphics g)6071 		protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
6072 		{
6073 			return GetTrackBarTickPainter (g);
6074 		}
6075 		#endregion
6076 		#endregion
6077 
DrawTrackBar(Graphics dc, Rectangle clip_rectangle, TrackBar tb)6078 		public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb)
6079 		{
6080 			Brush		br_thumb;
6081 			int		value_pos;
6082 			bool		mouse_value;
6083 			float		ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
6084 			Rectangle	area;
6085 			Rectangle	thumb_pos = tb.ThumbPos;
6086 			Rectangle	thumb_area = tb.ThumbArea;
6087 
6088 			if (tb.thumb_pressed) {
6089 				value_pos = tb.thumb_mouseclick;
6090 				mouse_value = true;
6091 			} else {
6092 				value_pos = tb.Value - tb.Minimum;
6093 				mouse_value = false;
6094 			}
6095 
6096 			area = tb.ClientRectangle;
6097 
6098 			if (!tb.Enabled) {
6099 				br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
6100 			} else if (tb.thumb_pressed == true) {
6101 				br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
6102 			} else {
6103 				br_thumb = SystemBrushes.Control;
6104 			}
6105 
6106 
6107 			/* Control Background */
6108 			if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
6109 				dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
6110 			} else {
6111 				dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
6112 			}
6113 
6114 			if (tb.Focused) {
6115 				CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
6116 			}
6117 
6118 			if (tb.Orientation == Orientation.Vertical) {
6119 				DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6120 					br_thumb, ticks, value_pos, mouse_value);
6121 
6122 			} else {
6123 				DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6124 					br_thumb, ticks, value_pos, mouse_value);
6125 			}
6126 
6127 			tb.ThumbPos = thumb_pos;
6128 			tb.ThumbArea = thumb_area;
6129 		}
6130 
6131 		public override Size TrackBarDefaultSize {
6132 			get {
6133 				return new Size (104, 42);
6134 			}
6135 		}
6136 
6137 		public override bool TrackBarHasHotThumbStyle {
6138 			get {
6139 				return false;
6140 			}
6141 		}
6142 		#endregion	// TrackBar
6143 
6144 		#region UpDownBase
UpDownBaseDrawButton(Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)6145 		public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
6146 		{
6147 			ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
6148 		}
6149 
6150 		public override bool UpDownBaseHasHotButtonStyle {
6151 			get {
6152 				return false;
6153 			}
6154 		}
6155 		#endregion
6156 
6157 		#region	VScrollBar
6158 		public override Size VScrollBarDefaultSize {
6159 			get {
6160 				return new Size (this.ScrollBarButtonSize, 80);
6161 			}
6162 		}
6163 		#endregion	// VScrollBar
6164 
6165 		#region TreeView
6166 		public override Size TreeViewDefaultSize {
6167 			get {
6168 				return new Size (121, 97);
6169 			}
6170 		}
6171 
TreeViewDrawNodePlusMinus(TreeView treeView, TreeNode node, Graphics dc, int x, int middle)6172 		public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
6173 		{
6174 			int height = treeView.ActualItemHeight - 2;
6175 			dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
6176 
6177 			dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
6178 
6179 			if (node.IsExpanded) {
6180 				dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6181 			} else {
6182 				dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6183 				dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
6184 			}
6185 		}
6186 		#endregion
6187 
6188 		#region Managed window
ManagedWindowTitleBarHeight(InternalWindowManager wm)6189 		public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
6190 		{
6191 			if (wm.IsToolWindow && !wm.IsMinimized)
6192 				return SystemInformation.ToolWindowCaptionHeight;
6193 			if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6194 				return 0;
6195 			return SystemInformation.CaptionHeight;
6196 		}
6197 
ManagedWindowBorderWidth(InternalWindowManager wm)6198 		public override int ManagedWindowBorderWidth (InternalWindowManager wm)
6199 		{
6200 			if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) ||
6201 				wm.IsMinimized)
6202 				return 3;
6203 			else
6204 				return 4;
6205 		}
6206 
ManagedWindowIconWidth(InternalWindowManager wm)6207 		public override int ManagedWindowIconWidth (InternalWindowManager wm)
6208 		{
6209 			return ManagedWindowTitleBarHeight (wm) - 5;
6210 		}
6211 
ManagedWindowSetButtonLocations(InternalWindowManager wm)6212 		public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
6213 		{
6214 			TitleButtons buttons = wm.TitleButtons;
6215 			Form form = wm.form;
6216 
6217 			buttons.HelpButton.Visible = form.HelpButton;
6218 
6219 			foreach (TitleButton button in buttons) {
6220 				button.Visible = false;
6221 			}
6222 
6223 			switch (form.FormBorderStyle) {
6224 			case FormBorderStyle.None:
6225 				if (form.WindowState != FormWindowState.Normal)
6226 					goto case FormBorderStyle.Sizable;
6227 				break;
6228 			case FormBorderStyle.FixedToolWindow:
6229 			case FormBorderStyle.SizableToolWindow:
6230 				buttons.CloseButton.Visible = true;
6231 				if (form.WindowState != FormWindowState.Normal)
6232 					goto case FormBorderStyle.Sizable;
6233 				break;
6234 			case FormBorderStyle.FixedSingle:
6235 			case FormBorderStyle.Fixed3D:
6236 			case FormBorderStyle.FixedDialog:
6237 			case FormBorderStyle.Sizable:
6238 				switch (form.WindowState) {
6239 					case FormWindowState.Normal:
6240 						buttons.MinimizeButton.Visible = true;
6241 						buttons.MaximizeButton.Visible = true;
6242 						buttons.RestoreButton.Visible = false;
6243 						break;
6244 					case FormWindowState.Maximized:
6245 						buttons.MinimizeButton.Visible = true;
6246 						buttons.MaximizeButton.Visible = false;
6247 						buttons.RestoreButton.Visible = true;
6248 						break;
6249 					case FormWindowState.Minimized:
6250 						buttons.MinimizeButton.Visible = false;
6251 						buttons.MaximizeButton.Visible = true;
6252 						buttons.RestoreButton.Visible = true;
6253 						break;
6254 				}
6255 				buttons.CloseButton.Visible = true;
6256 				break;
6257 			}
6258 
6259 			// Respect MinimizeBox/MaximizeBox
6260 			if (form.MinimizeBox == false && form.MaximizeBox == false) {
6261 				buttons.MinimizeButton.Visible = false;
6262 				buttons.MaximizeButton.Visible = false;
6263 			} else if (form.MinimizeBox == false)
6264 				buttons.MinimizeButton.State = ButtonState.Inactive;
6265 			else if (form.MaximizeBox == false)
6266 				buttons.MaximizeButton.State = ButtonState.Inactive;
6267 
6268 			int bw = ManagedWindowBorderWidth (wm);
6269 			Size btsize = ManagedWindowButtonSize (wm);
6270 			int btw = btsize.Width;
6271 			int bth = btsize.Height;
6272 			int top = bw + 2;
6273 			int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton;
6274 
6275 			if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6276 				buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6277 				left -= 2 + btw;
6278 
6279 				if (buttons.MaximizeButton.Visible) {
6280 					buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6281 					left -= 2 + btw;
6282 				}
6283 				if (buttons.RestoreButton.Visible) {
6284 					buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6285 					left -= 2 + btw;
6286 				}
6287 
6288 				buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6289 				left -= 2 + btw;
6290 			} else if (wm.IsToolWindow) {
6291 				buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6292 				left -= 2 + btw;
6293 			}
6294 		}
6295 
ManagedWindowDrawTitleBarAndBorders(Graphics dc, Rectangle clip, InternalWindowManager wm)6296 		protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm)
6297 		{
6298 			Form form = wm.Form;
6299 			int tbheight = ManagedWindowTitleBarHeight (wm);
6300 			int bdwidth = ManagedWindowBorderWidth (wm);
6301 			Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6302 			Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6303 			Color color = ThemeEngine.Current.ColorControlDark;
6304 			Color color2 = Color.FromArgb (255, 192, 192, 192);
6305 
6306 			Pen pen = ResPool.GetPen (ColorControl);
6307 			Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6308 			ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6309 			// The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6310 			borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6311 			for (int i = 2; i < bdwidth; i++) {
6312 				dc.DrawRectangle (pen, borders);
6313 				borders.Inflate (-1, -1);
6314 			}
6315 
6316 
6317 			bool draw_titlebar_enabled = false;
6318 			if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6319 				draw_titlebar_enabled = false;
6320 			} else if (wm.IsActive && !wm.IsMaximized) {
6321 				draw_titlebar_enabled = true;
6322 			}
6323 			if (draw_titlebar_enabled) {
6324 				color = titlebar_color;
6325 				color2 = titlebar_color2;
6326 			}
6327 
6328 			Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6329 
6330 			// HACK: For now always draw the titlebar until we get updates better
6331 			if (tb.Width > 0 && tb.Height > 0) {
6332 				using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6333 				{
6334 					dc.FillRectangle (gradient, tb);
6335 				}
6336 			}
6337 
6338 			if (!wm.IsMinimized)
6339 				// Draw the line just beneath the title bar
6340 				dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6341 						tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6342 						tbheight + bdwidth - 1);
6343 			return tb;
6344 		}
6345 
DrawManagedWindowDecorations(Graphics dc, Rectangle clip, InternalWindowManager wm)6346 		public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6347 		{
6348 #if debug
6349 			Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6350 			dc.FillRectangle (Brushes.Black, clip);
6351 #endif
6352 			Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm);
6353 
6354 			Form form = wm.Form;
6355 			if (wm.ShowIcon) {
6356 				Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6357 				if (icon.IntersectsWith (clip))
6358 					dc.DrawIcon (form.Icon, icon);
6359 				const int SpacingBetweenIconAndCaption = 2;
6360 				tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ;
6361 				tb.X = icon.Right + SpacingBetweenIconAndCaption;
6362 			}
6363 
6364 			foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6365 				tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form));
6366 			}
6367 			const int SpacingBetweenCaptionAndLeftMostButton = 3;
6368 			tb.Width -= SpacingBetweenCaptionAndLeftMostButton;
6369 
6370 			string window_caption = form.Text;
6371 			window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6372 
6373 			if (window_caption != null && window_caption != string.Empty) {
6374 				StringFormat format = new StringFormat ();
6375 				format.FormatFlags = StringFormatFlags.NoWrap;
6376 				format.Trimming = StringTrimming.EllipsisCharacter;
6377 				format.LineAlignment = StringAlignment.Center;
6378 
6379 				if (tb.IntersectsWith (clip))
6380 					dc.DrawString (window_caption, WindowBorderFont,
6381 						ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6382 						tb, format);
6383 			}
6384 		}
6385 
ManagedWindowButtonSize(InternalWindowManager wm)6386 		public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6387 		{
6388 			int height = ManagedWindowTitleBarHeight (wm);
6389 			if (!wm.IsMaximized && !wm.IsMinimized) {
6390 				if (wm.IsToolWindow)
6391 					return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6392 							height - 5);
6393 				if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6394 					return Size.Empty;
6395 			} else
6396 				height = SystemInformation.CaptionHeight;
6397 
6398 			return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6399 					height - 5);
6400 		}
6401 
DrawTitleButton(Graphics dc, TitleButton button, Rectangle clip, Form form)6402 		private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6403 		{
6404 			if (!button.Visible) {
6405 				return int.MaxValue;
6406 			}
6407 
6408 			if (button.Rectangle.IntersectsWith (clip)) {
6409 				ManagedWindowDrawTitleButton (dc, button, clip, form);
6410 			}
6411 			return button.Rectangle.Left;
6412 		}
6413 
ManagedWindowDrawTitleButton(Graphics dc, TitleButton button, Rectangle clip, Form form)6414 		protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6415 		{
6416 			dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6417 
6418 			ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6419 					button.Caption, button.State);
6420 		}
6421 
ManagedWindowGetTitleBarIconArea(InternalWindowManager wm)6422 		public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6423 		{
6424 			int bw = ManagedWindowBorderWidth (wm);
6425 			return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6426 		}
6427 
ManagedWindowGetMenuButtonSize(InternalWindowManager wm)6428 		public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm)
6429 		{
6430 			Size result = SystemInformation.MenuButtonSize;
6431 			result.Width -= 2;
6432 			result.Height -= 4;
6433 			return result;
6434 		}
6435 
ManagedWindowTitleButtonHasHotElementStyle(TitleButton button, Form form)6436 		public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form)
6437 		{
6438 			return false;
6439 		}
6440 
ManagedWindowDrawMenuButton(Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)6441 		public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)
6442 		{
6443 			dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6444 			ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6445 					button.Caption, button.State);
6446 		}
6447 
ManagedWindowOnSizeInitializedOrChanged(Form form)6448 		public override void ManagedWindowOnSizeInitializedOrChanged (Form form)
6449 		{
6450 		}
6451 		#endregion
6452 
6453 		#region ControlPaint
CPDrawBorder(Graphics graphics, Rectangle 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)6454 		public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6455 			ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6456 			Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6457 			int bottomWidth, ButtonBorderStyle bottomStyle) {
6458 			DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6459 			DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6460 			DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6461 			DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6462 		}
6463 
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)6464 		public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6465 			ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6466 			Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6467 			int bottomWidth, ButtonBorderStyle bottomStyle) {
6468 			DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6469 			DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6470 			DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6471 			DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6472 		}
6473 
CPDrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides)6474 		public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6475 			CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6476 		}
6477 
CPDrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)6478 		public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6479 		{
6480 			Pen		penTopLeft;
6481 			Pen		penTopLeftInner;
6482 			Pen		penBottomRight;
6483 			Pen		penBottomRightInner;
6484 			Rectangle	rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6485 			bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6486 
6487 			if ((style & Border3DStyle.Adjust) != 0) {
6488 				rect.Y -= 2;
6489 				rect.X -= 2;
6490 				rect.Width += 4;
6491 				rect.Height += 4;
6492 			}
6493 
6494 			penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6495 
6496 			CPColor cpcolor = CPColor.Empty;
6497 
6498 			if (!is_ColorControl)
6499 				cpcolor = ResPool.GetCPColor (control_color);
6500 
6501 			switch (style) {
6502 			case Border3DStyle.Raised:
6503 				penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6504 				penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6505 				penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6506 				break;
6507 			case Border3DStyle.Sunken:
6508 				penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6509 				penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6510 				penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6511 				break;
6512 			case Border3DStyle.Etched:
6513 				penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6514 				penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6515 				break;
6516 			case Border3DStyle.RaisedOuter:
6517 				penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6518 				break;
6519 			case Border3DStyle.SunkenOuter:
6520 				penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6521 				penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6522 				break;
6523 			case Border3DStyle.RaisedInner:
6524 				penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6525 				penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6526 				break;
6527 			case Border3DStyle.SunkenInner:
6528 				penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6529 				break;
6530 			case Border3DStyle.Flat:
6531 				penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6532 				break;
6533 			case Border3DStyle.Bump:
6534 				penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6535 				break;
6536 			default:
6537 				break;
6538 			}
6539 
6540 			bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6541 
6542 			if ((sides & Border3DSide.Middle) != 0) {
6543 				Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6544 				graphics.FillRectangle (brush, rect);
6545 			}
6546 
6547 			if ((sides & Border3DSide.Left) != 0) {
6548 				graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6549 				if ((rect.Width > 2) && inner)
6550 					graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6551 			}
6552 
6553 			if ((sides & Border3DSide.Top) != 0) {
6554 				graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6555 				if ((rect.Height > 2) && inner)
6556 					graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6557 			}
6558 
6559 			if ((sides & Border3DSide.Right) != 0) {
6560 				graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6561 				if ((rect.Width > 3) && inner)
6562 					graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6563 			}
6564 
6565 			if ((sides & Border3DSide.Bottom) != 0) {
6566 				graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6567 				if ((rect.Height > 3) && inner)
6568 					graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6569 			}
6570 		}
6571 
CPDrawButton(Graphics dc, Rectangle rectangle, ButtonState state)6572 		public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6573 		{
6574 			CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6575 		}
6576 
CPDrawButtonInternal(Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)6577 		private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6578 		{
6579 			// sadly enough, the rectangle gets always filled with a hatchbrush
6580 			dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6581 								 Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6582 										 ColorControl.G, ColorControl.B),
6583 								 ColorControl),
6584 					  rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6585 
6586 			if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6587 				dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6588 
6589 				dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6590 			} else
6591 			if ((state & ButtonState.Flat) == ButtonState.Flat) {
6592 				dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6593 			} else
6594 			if ((state & ButtonState.Checked) == ButtonState.Checked) {
6595 				dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6596 
6597 				Pen pen = DarkPen;
6598 				dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6599 				dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6600 
6601 				pen = NormalPen;
6602 				dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6603 				dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6604 
6605 				pen = LightPen;
6606 				dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6607 				dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6608 			} else
6609 			if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6610 				Pen pen = DarkPen;
6611 				dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6612 				dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6613 
6614 				pen = NormalPen;
6615 				dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6616 				dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6617 
6618 				pen = LightPen;
6619 				dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6620 				dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6621 			} else
6622 			if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6623 				Pen pen = LightPen;
6624 				dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6625 				dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6626 
6627 				pen = NormalPen;
6628 				dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6629 				dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6630 
6631 				pen = DarkPen;
6632 				dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6633 				dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6634 			}
6635 		}
6636 
6637 
CPDrawCaptionButton(Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state)6638 		public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6639 			Rectangle	captionRect;
6640 			int			lineWidth;
6641 
6642 			CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6643 
6644 			if (rectangle.Width<rectangle.Height) {
6645 				captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6646 			} else {
6647 				captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6648 			}
6649 
6650 			if ((state & ButtonState.Pushed)!=0) {
6651 				captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6652 			}
6653 
6654 			/* Make sure we've got at least a line width of 1 */
6655 			lineWidth=Math.Max(1, captionRect.Width/7);
6656 
6657 			switch(button) {
6658 			case CaptionButton.Close: {
6659 				Pen	pen;
6660 
6661 				if ((state & ButtonState.Inactive)!=0) {
6662 					pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6663 					DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6664 
6665 					pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6666 					DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6667 					return;
6668 				} else {
6669 					pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6670 					DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6671 					return;
6672 				}
6673 			}
6674 
6675 			case CaptionButton.Help:
6676 			case CaptionButton.Maximize:
6677 			case CaptionButton.Minimize:
6678 			case CaptionButton.Restore: {
6679 				if ((state & ButtonState.Inactive)!=0) {
6680 					DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6681 
6682 					DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6683 					return;
6684 				} else {
6685 					DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6686 					return;
6687 				}
6688 			}
6689 			}
6690 		}
6691 
CPDrawCheckBox(Graphics dc, Rectangle rectangle, ButtonState state)6692 		public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6693 		{
6694 			CPDrawCheckBoxInternal (dc, rectangle, state, false /* mixed */);
6695 		}
6696 
CPDrawCheckBoxInternal(Graphics dc, Rectangle rectangle, ButtonState state, bool mixed)6697 		private void CPDrawCheckBoxInternal (Graphics dc, Rectangle rectangle, ButtonState state, bool mixed)
6698 		{
6699 			Pen check_pen = (mixed) ? Pens.Gray : Pens.Black;
6700 
6701 			Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6702 
6703 			if ((state & ButtonState.All) == ButtonState.All) {
6704 				cb_rect.Width -= 2;
6705 				cb_rect.Height -= 2;
6706 
6707 				dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6708 				dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6709 
6710 				check_pen = SystemPens.ControlDark;
6711 			} else
6712 			if ((state & ButtonState.Flat) == ButtonState.Flat) {
6713 				cb_rect.Width -= 2;
6714 				cb_rect.Height -= 2;
6715 
6716 				if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6717 					dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6718 				else
6719 					dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6720 				dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6721 			} else {
6722 				cb_rect.Width -= 1;
6723 				cb_rect.Height -= 1;
6724 
6725 				int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6726 
6727 				int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6728 				int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6729 
6730 				Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6731 
6732 				if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6733 					dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6734 										 Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6735 												 ColorControl.G, ColorControl.B),
6736 										 ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6737 				} else
6738 					dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6739 
6740 				Pen pen = SystemPens.ControlDark;
6741 				dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6742 				dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6743 
6744 				pen = SystemPens.ControlDarkDark;
6745 				dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6746 				dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6747 
6748 				pen = SystemPens.ControlLightLight;
6749 				dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6750 				dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6751 
6752 				// oh boy, matching ms is like fighting against windmills
6753 				using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6754 										   Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6755 												   ColorControl.G, ColorControl.B), ColorControl))) {
6756 					dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6757 					dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6758 				}
6759 
6760 				if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6761 					check_pen = SystemPens.ControlDark;
6762 			}
6763 
6764 			if ((state & ButtonState.Checked) == ButtonState.Checked) {
6765 				int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6766 
6767 				if (check_size < 7) {
6768 					int lineWidth = Math.Max (3, check_size / 3);
6769 					int Scale = Math.Max (1, check_size / 9);
6770 
6771 					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,
6772 									check_size, check_size);
6773 
6774 					for (int i = 0; i < lineWidth; i++) {
6775 						dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6776 						dc.DrawLine (check_pen, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i, rect.Left + lineWidth / 2 + 6 * Scale, rect.Top + lineWidth - 2 * Scale + i);
6777 					}
6778 				} else {
6779 					int lineWidth = Math.Max (3, check_size / 3) + 1;
6780 
6781 					int x_half = cb_rect.Width / 2;
6782 					int y_half = cb_rect.Height / 2;
6783 
6784 					Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2),
6785 									check_size, check_size);
6786 
6787 					int gradient_left = check_size / 3;
6788 					int gradient_right = check_size - gradient_left - 1;
6789 
6790 
6791 					for (int i = 0; i < lineWidth; i++) {
6792 						dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6793 						dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6794 					}
6795 				}
6796 			}
6797 		}
6798 
CPDrawComboButton(Graphics graphics, Rectangle rectangle, ButtonState state)6799 		public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6800 			Point[]			arrow = new Point[3];
6801 			Point				P1;
6802 			Point				P2;
6803 			Point				P3;
6804 			int				centerX;
6805 			int				centerY;
6806 			int				shiftX;
6807 			int				shiftY;
6808 			Rectangle		rect;
6809 
6810 			if ((state & ButtonState.Checked)!=0) {
6811 				graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);
6812 			}
6813 
6814 			if ((state & ButtonState.Flat)!=0) {
6815 				ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6816 			} else {
6817 				if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6818 					// this needs to render like a pushed button - jba
6819 					// CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6820 					Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6821 					graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6822 				} else {
6823 					CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6824 				}
6825 			}
6826 
6827 			rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6828 			centerX=rect.Left+rect.Width/2;
6829 			centerY=rect.Top+rect.Height/2;
6830 			shiftX=Math.Max(1, rect.Width/8);
6831 			shiftY=Math.Max(1, rect.Height/8);
6832 
6833 			if ((state & ButtonState.Pushed)!=0) {
6834 				shiftX++;
6835 				shiftY++;
6836 			}
6837 
6838 			rect.Y-=shiftY;
6839 			centerY-=shiftY;
6840 			P1=new Point(rect.Left, centerY);
6841 			P2=new Point(rect.Right, centerY);
6842 			P3=new Point(centerX, rect.Bottom);
6843 
6844 			arrow[0]=P1;
6845 			arrow[1]=P2;
6846 			arrow[2]=P3;
6847 
6848 			/* Draw the arrow */
6849 			if ((state & ButtonState.Inactive)!=0) {
6850 				/* Move away from the shadow */
6851 				arrow[0].X += 1;	arrow[0].Y += 1;
6852 				arrow[1].X += 1;	arrow[1].Y += 1;
6853 				arrow[2].X += 1;	arrow[2].Y += 1;
6854 
6855 				graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6856 
6857 				arrow[0]=P1;
6858 				arrow[1]=P2;
6859 				arrow[2]=P3;
6860 
6861 				graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6862 			} else {
6863 				graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6864 			}
6865 		}
6866 
6867 
CPDrawContainerGrabHandle(Graphics graphics, Rectangle bounds)6868 		public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6869 		{
6870 			Pen			pen	= Pens.Black;
6871 			Rectangle	rect	= new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);	// Dunno why, but MS does it that way, too
6872 			int			X;
6873 			int			Y;
6874 
6875 			graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6876 			graphics.DrawRectangle (pen, rect);
6877 
6878 			X = rect.X + rect.Width / 2;
6879 			Y = rect.Y + rect.Height / 2;
6880 
6881 			/* Draw the cross */
6882 			graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6883 			graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6884 
6885 			/* Draw 'arrows' for vertical lines */
6886 			graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6887 			graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6888 
6889 			/* Draw 'arrows' for horizontal lines */
6890 			graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6891 			graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6892 		}
6893 
DrawFlatStyleFocusRectangle(Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor)6894 		public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6895 			// make a rectange to trace around border of the button
6896 			Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6897 
6898 			Color outerColor = foreColor;
6899 			// adjust focus color according to the flatstyle
6900 			if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6901 				outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;
6902 			}
6903 
6904 			// draw the outer rectangle
6905 			graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);
6906 
6907 			// draw the inner rectangle
6908 			if (button.FlatStyle == FlatStyle.Popup) {
6909 				DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6910 			} else {
6911 				// draw a flat inner rectangle
6912 				Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6913 				graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));
6914 			}
6915 		}
6916 
DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)6917 		public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6918 		{
6919 			// make a rectange to trace around border of the button
6920 			Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6921 
6922 #if NotUntilCairoIsFixed
6923 			Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6924 			DashStyle oldStyle; // used for caching old penstyle
6925 			Pen pen = ResPool.GetPen (colorBackInverted);
6926 
6927 			oldStyle = pen.DashStyle;
6928 			pen.DashStyle = DashStyle.Dot;
6929 
6930 			graphics.DrawRectangle (pen, trace_rectangle);
6931 			pen.DashStyle = oldStyle;
6932 #else
6933 			CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6934 #endif
6935 		}
6936 
6937 
CPDrawFocusRectangle(Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor)6938 		public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor)
6939 		{
6940 			Rectangle rect = rectangle;
6941 			Pen pen;
6942 			HatchBrush brush;
6943 
6944 			if (backColor.GetBrightness () >= 0.5) {
6945 				foreColor = Color.Transparent;
6946 				backColor = Color.Black;
6947 
6948 			} else {
6949 				backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6950 				foreColor = Color.Black;
6951 			}
6952 
6953 			brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6954 			pen = new Pen (brush, 1);
6955 
6956 			rect.Width--;
6957 			rect.Height--;
6958 
6959 			graphics.DrawRectangle (pen, rect);
6960 			pen.Dispose ();
6961 		}
6962 
CPDrawGrabHandle(Graphics graphics, Rectangle rectangle, bool primary, bool enabled)6963 		public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6964 		{
6965 			Brush	sb;
6966 			Pen pen;
6967 
6968 			if (primary == true) {
6969 				pen = Pens.Black;
6970 				if (enabled == true) {
6971 					sb = Brushes.White;
6972 				} else {
6973 					sb = SystemBrushes.Control;
6974 				}
6975 			} else {
6976 				pen = Pens.White;
6977 				if (enabled == true) {
6978 					sb = Brushes.Black;
6979 				} else {
6980 					sb = SystemBrushes.Control;
6981 				}
6982 			}
6983 			graphics.FillRectangle (sb, rectangle);
6984 			graphics.DrawRectangle (pen, rectangle);
6985 		}
6986 
6987 
CPDrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor)6988 		public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6989 			Color	foreColor;
6990 			int	h;
6991 			int	b;
6992 			int	s;
6993 
6994 			ControlPaint.Color2HBS(backColor, out h, out b, out s);
6995 
6996 			if (b>127) {
6997 				foreColor=Color.Black;
6998 			} else {
6999 				foreColor=Color.White;
7000 			}
7001 
7002 			// still not perfect. it seems that ms calculates the position of the first dot or line
7003 
7004 			using (Pen pen = new Pen (foreColor)) {
7005 				pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
7006 
7007 				for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
7008 					graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
7009 			}
7010 		}
7011 
CPDrawImageDisabled(Graphics graphics, Image image, int x, int y, Color background)7012 		public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
7013 			/*
7014 				Microsoft seems to ignore the background and simply make
7015 				the image grayscale. At least when having > 256 colors on
7016 				the display.
7017 			*/
7018 
7019 			if (imagedisabled_attributes == null) {
7020 				imagedisabled_attributes = new ImageAttributes ();
7021 				ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
7022 					  // This table would create a perfect grayscale image, based on luminance
7023 					  //				new float[]{0.3f,0.3f,0.3f,0,0},
7024 					  //				new float[]{0.59f,0.59f,0.59f,0,0},
7025 					  //				new float[]{0.11f,0.11f,0.11f,0,0},
7026 					  //				new float[]{0,0,0,1,0,0},
7027 					  //				new float[]{0,0,0,0,1,0},
7028 					  //				new float[]{0,0,0,0,0,1}
7029 
7030 					  // This table generates a image that is grayscaled and then
7031 					  // brightened up. Seems to match MS close enough.
7032 					  new float[]{0.2f,0.2f,0.2f,0,0},
7033 					  new float[]{0.41f,0.41f,0.41f,0,0},
7034 					  new float[]{0.11f,0.11f,0.11f,0,0},
7035 					  new float[]{0.15f,0.15f,0.15f,1,0,0},
7036 					  new float[]{0.15f,0.15f,0.15f,0,1,0},
7037 					  new float[]{0.15f,0.15f,0.15f,0,0,1}
7038 				  });
7039 
7040 				 imagedisabled_attributes.SetColorMatrix (colorMatrix);
7041 			}
7042 
7043 			graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
7044 
7045 		}
7046 
7047 
CPDrawLockedFrame(Graphics graphics, Rectangle rectangle, bool primary)7048 		public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
7049 			Pen	penBorder;
7050 			Pen	penInside;
7051 
7052 			if (primary) {
7053 				penBorder = ResPool.GetSizedPen (Color.White, 2);
7054 				penInside = ResPool.GetPen (Color.Black);
7055 			} else {
7056 				penBorder = ResPool.GetSizedPen (Color.Black, 2);
7057 				penInside = ResPool.GetPen (Color.White);
7058 			}
7059 			penBorder.Alignment=PenAlignment.Inset;
7060 			penInside.Alignment=PenAlignment.Inset;
7061 
7062 			graphics.DrawRectangle(penBorder, rectangle);
7063 			graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
7064 		}
7065 
7066 
CPDrawMenuGlyph(Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor)7067 		public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
7068 			Rectangle	rect;
7069 			int			lineWidth;
7070 
7071 			if (backColor != Color.Empty)
7072 				graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
7073 
7074 			Brush brush = ResPool.GetSolidBrush (color);
7075 
7076 			switch(glyph) {
7077 			case MenuGlyph.Arrow: {
7078 				float height = rectangle.Height * 0.7f;
7079 				float width  = height / 2.0f;
7080 
7081 				PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
7082 
7083 				PointF [] vertices = new PointF [3];
7084 				vertices [0].X = ddCenter.X;
7085 				vertices [0].Y = ddCenter.Y - (height / 2.0f);
7086 				vertices [1].X = ddCenter.X;
7087 				vertices [1].Y = ddCenter.Y + (height / 2.0f);
7088 				vertices [2].X = ddCenter.X + width + 0.1f;
7089 				vertices [2].Y = ddCenter.Y;
7090 
7091 				graphics.FillPolygon (brush, vertices);
7092 
7093 				return;
7094 			}
7095 
7096 			case MenuGlyph.Bullet: {
7097 
7098 				lineWidth=Math.Max(2, rectangle.Width/3);
7099 				rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
7100 
7101 				graphics.FillEllipse(brush, rect);
7102 
7103 				return;
7104 			}
7105 
7106 			case MenuGlyph.Checkmark: {
7107 
7108 				Pen pen = ResPool.GetPen (color);
7109 				lineWidth = Math.Max (2, rectangle.Width / 6);
7110 				rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
7111 
7112 				int Scale = Math.Max (1, rectangle.Width / 12);
7113 				int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
7114 
7115 				for (int i=0; i<lineWidth; i++) {
7116 					graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
7117 					graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
7118 				}
7119 				return;
7120 			}
7121 			}
7122 
7123 		}
7124 
CPDrawMixedCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)7125 		public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
7126 		{
7127 			CPDrawCheckBoxInternal (graphics, rectangle, state, true /* mixed */);
7128 		}
7129 
CPDrawRadioButton(Graphics dc, Rectangle rectangle, ButtonState state)7130 		public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
7131 		{
7132 			CPColor cpcolor = ResPool.GetCPColor (ColorControl);
7133 
7134 			Color dot_color = Color.Black;
7135 
7136 			Color top_left_outer = Color.Black;
7137 			Color top_left_inner = Color.Black;
7138 			Color bottom_right_outer = Color.Black;
7139 			Color bottom_right_inner = Color.Black;
7140 
7141 			int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
7142 			int radius = ellipse_diameter / 2;
7143 
7144 			Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
7145 
7146 			Brush brush = null;
7147 
7148 			if ((state & ButtonState.All) == ButtonState.All) {
7149 				brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
7150 												     ColorControl.G, ColorControl.B), ColorControl);
7151 				dot_color = cpcolor.Dark;
7152 			} else
7153 			if ((state & ButtonState.Flat) == ButtonState.Flat) {
7154 				if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7155 					brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7156 				else
7157 					brush = SystemBrushes.ControlLightLight;
7158 			} else {
7159 				if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7160 					brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7161 				else
7162 					brush = SystemBrushes.ControlLightLight;
7163 
7164 				top_left_outer = cpcolor.Dark;
7165 				top_left_inner = cpcolor.DarkDark;
7166 				bottom_right_outer = cpcolor.Light;
7167 				bottom_right_inner = Color.Transparent;
7168 
7169 				if ((state & ButtonState.Inactive) == ButtonState.Inactive)
7170 					dot_color = cpcolor.Dark;
7171 			}
7172 
7173 			dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
7174 
7175 			int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
7176 
7177 			dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
7178 			dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
7179 			dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
7180 
7181 			if (bottom_right_inner != Color.Transparent)
7182 				dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7183 			else
7184 				using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl), line_width)) {
7185 					dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7186 				}
7187 
7188 			if ((state & ButtonState.Checked) == ButtonState.Checked) {
7189 				int inflate = line_width * 4;
7190 				Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
7191 				if (rectangle.Height >  13) {
7192 					tmp.X += 1;
7193 					tmp.Y += 1;
7194 					tmp.Height -= 1;
7195 					dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
7196 				} else {
7197 					Pen pen = ResPool.GetPen (dot_color);
7198 					dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
7199 					dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
7200 
7201 					dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
7202 					dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
7203 				}
7204 			}
7205 		}
7206 
CPDrawReversibleFrame(Rectangle rectangle, Color backColor, FrameStyle style)7207 		public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
7208 
7209 		}
7210 
7211 
CPDrawReversibleLine(Point start, Point end, Color backColor)7212 		public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
7213 
7214 		}
7215 
7216 
7217 		/* Scroll button: regular button + direction arrow */
CPDrawScrollButton(Graphics dc, Rectangle area, ScrollButton type, ButtonState state)7218 		public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
7219 		{
7220 			DrawScrollButtonPrimitive (dc, area, state);
7221 
7222 			bool fill_rect = true;
7223 			int offset = 0;
7224 
7225 			if ((state & ButtonState.Pushed) != 0)
7226 				offset = 1;
7227 
7228 			// skip the border
7229 			Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
7230 
7231 			Point [] arrow = new Point [3];
7232 			for (int i = 0; i < 3; i++)
7233 				arrow [i] = new Point ();
7234 
7235 			Pen pen = SystemPens.ControlText;
7236 
7237 			if ((state & ButtonState.Inactive) != 0) {
7238 				pen = SystemPens.ControlDark;
7239 			}
7240 
7241 			switch (type) {
7242 				default:
7243 				case ScrollButton.Down:
7244 					int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7245 					int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7246 					if (x_middle == 1)
7247 						x_middle = 2;
7248 
7249 					int triangle_height;
7250 
7251 					if (rect.Height < 8) {
7252 						triangle_height = 2;
7253 						fill_rect = false;
7254 					} else if (rect.Height == 11) {
7255 						triangle_height = 3;
7256 					} else {
7257 						triangle_height = (int)Math.Round (rect.Height / 3.0f);
7258 					}
7259 
7260 					arrow [0].X = rect.X + x_middle;
7261 					arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
7262 
7263 					arrow [1].X = arrow [0].X + triangle_height - 1;
7264 					arrow [1].Y = arrow [0].Y - triangle_height + 1;
7265 					arrow [2].X = arrow [0].X - triangle_height + 1;
7266 					arrow [2].Y = arrow [1].Y;
7267 
7268 					dc.DrawPolygon (pen, arrow);
7269 
7270 					if ((state & ButtonState.Inactive) != 0) {
7271 						dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
7272 						dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
7273 					}
7274 
7275 					if (fill_rect) {
7276 						for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
7277 							dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
7278 							arrow [1].X -= 1;
7279 							arrow [2].X += 1;
7280 						}
7281 					}
7282 					break;
7283 
7284 				case ScrollButton.Up:
7285 					x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7286 					y_middle = (int)Math.Round (rect.Height / 2.0f);
7287 					if (x_middle == 1)
7288 						x_middle = 2;
7289 
7290 					if (y_middle == 1)
7291 						y_middle = 2;
7292 
7293 					if (rect.Height < 8) {
7294 						triangle_height = 2;
7295 						fill_rect = false;
7296 					} else if (rect.Height == 11) {
7297 						triangle_height = 3;
7298 					} else {
7299 						triangle_height = (int)Math.Round (rect.Height / 3.0f);
7300 					}
7301 
7302 					arrow [0].X = rect.X + x_middle;
7303 					arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7304 
7305 					arrow [1].X = arrow [0].X + triangle_height - 1;
7306 					arrow [1].Y = arrow [0].Y + triangle_height - 1;
7307 					arrow [2].X = arrow [0].X - triangle_height + 1;
7308 					arrow [2].Y = arrow [1].Y;
7309 
7310 					dc.DrawPolygon (pen, arrow);
7311 
7312 					if ((state & ButtonState.Inactive) != 0) {
7313 						dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7314 					}
7315 
7316 					if (fill_rect) {
7317 						for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7318 							dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7319 							arrow [1].X -= 1;
7320 							arrow [2].X += 1;
7321 						}
7322 					}
7323 					break;
7324 
7325 				case ScrollButton.Left:
7326 					y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7327 					if (y_middle == 1)
7328 						y_middle = 2;
7329 
7330 					int triangle_width;
7331 
7332 					if (rect.Width < 8) {
7333 						triangle_width = 2;
7334 						fill_rect = false;
7335 					} else if (rect.Width == 11) {
7336 						triangle_width = 3;
7337 					} else {
7338 						triangle_width = (int)Math.Round (rect.Width / 3.0f);
7339 					}
7340 
7341 					arrow [0].X = rect.Left + triangle_width - 1;
7342 					arrow [0].Y = rect.Y + y_middle;
7343 
7344 					if (arrow [0].X - 1 == rect.X)
7345 						arrow [0].X += 1;
7346 
7347 					arrow [1].X = arrow [0].X + triangle_width - 1;
7348 					arrow [1].Y = arrow [0].Y - triangle_width + 1;
7349 					arrow [2].X = arrow [1].X;
7350 					arrow [2].Y = arrow [0].Y + triangle_width - 1;
7351 
7352 					dc.DrawPolygon (pen, arrow);
7353 
7354 					if ((state & ButtonState.Inactive) != 0) {
7355 						dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7356 					}
7357 
7358 					if (fill_rect) {
7359 						for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7360 							dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7361 							arrow [1].Y += 1;
7362 							arrow [2].Y -= 1;
7363 						}
7364 					}
7365 					break;
7366 
7367 				case ScrollButton.Right:
7368 					y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7369 					if (y_middle == 1)
7370 						y_middle = 2;
7371 
7372 					if (rect.Width < 8) {
7373 						triangle_width = 2;
7374 						fill_rect = false;
7375 					} else if (rect.Width == 11) {
7376 						triangle_width = 3;
7377 					} else {
7378 						triangle_width = (int)Math.Round (rect.Width / 3.0f);
7379 					}
7380 
7381 					arrow [0].X = rect.Right - triangle_width - 1;
7382 					arrow [0].Y = rect.Y + y_middle;
7383 
7384 					if (arrow [0].X - 1 == rect.X)
7385 						arrow [0].X += 1;
7386 
7387 					arrow [1].X = arrow [0].X - triangle_width + 1;
7388 					arrow [1].Y = arrow [0].Y - triangle_width + 1;
7389 					arrow [2].X = arrow [1].X;
7390 					arrow [2].Y = arrow [0].Y + triangle_width - 1;
7391 
7392 					dc.DrawPolygon (pen, arrow);
7393 
7394 					if ((state & ButtonState.Inactive) != 0) {
7395 						dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7396 						dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7397 					}
7398 
7399 					if (fill_rect) {
7400 						for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7401 							dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7402 							arrow [1].Y += 1;
7403 							arrow [2].Y -= 1;
7404 						}
7405 					}
7406 					break;
7407 			}
7408 		}
7409 
CPDrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, Color backColor)7410 		public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7411 			Color backColor) {
7412 
7413 		}
7414 
7415 
CPDrawSizeGrip(Graphics dc, Color backColor, Rectangle bounds)7416 		public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7417 		{
7418 			Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7419 			Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7420 
7421 			for (int i = 2; i < bounds.Width - 2; i += 4) {
7422 				dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7423 				dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7424 				dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7425 			}
7426 		}
7427 
DrawStringDisabled20(Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)7428 		private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7429 		{
7430 			CPColor cpcolor = ResPool.GetCPColor (color);
7431 
7432 			layoutRectangle.Offset (1, 1);
7433 			TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7434 
7435 			layoutRectangle.Offset (-1, -1);
7436 			TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7437 		}
7438 
CPDrawStringDisabled(Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)7439 		public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7440 		{
7441 			CPColor cpcolor = ResPool.GetCPColor (color);
7442 
7443 			dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight),
7444 				       new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7445 				       format);
7446 			dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7447 		}
7448 
CPDrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)7449 		public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7450 		{
7451 			CPColor cpcolor = ResPool.GetCPColor (color);
7452 
7453 			layoutRectangle.Offset (1, 1);
7454 			TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7455 
7456 			layoutRectangle.Offset (-1, -1);
7457 			TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7458 		}
7459 
CPDrawVisualStyleBorder(Graphics graphics, Rectangle bounds)7460 		public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7461 		{
7462 			graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7463 		}
7464 
DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY, int width, Color color, ButtonBorderStyle style, Border3DSide side)7465 		private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7466 			int width, Color color, ButtonBorderStyle style, Border3DSide side)
7467 		{
7468 			DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY,
7469 				width, color, style, side);
7470 		}
7471 
DrawBorderInternal(Graphics graphics, float startX, float startY, float endX, float endY, int width, Color color, ButtonBorderStyle style, Border3DSide side)7472 		private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7473 			int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7474 
7475 			Pen pen = null;
7476 
7477 			switch (style) {
7478 			case ButtonBorderStyle.Solid:
7479 			case ButtonBorderStyle.Inset:
7480 			case ButtonBorderStyle.Outset:
7481 					pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7482 					break;
7483 			case ButtonBorderStyle.Dashed:
7484 					pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7485 					break;
7486 			case ButtonBorderStyle.Dotted:
7487 					pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7488 					break;
7489 			default:
7490 			case ButtonBorderStyle.None:
7491 					return;
7492 			}
7493 
7494 			switch(style) {
7495 			case ButtonBorderStyle.Outset: {
7496 				Color		colorGrade;
7497 				int		hue, brightness, saturation;
7498 				int		brightnessSteps;
7499 				int		brightnessDownSteps;
7500 
7501 				ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7502 
7503 				brightnessDownSteps=brightness/width;
7504 				if (brightness>127) {
7505 					brightnessSteps=Math.Max(6, (160-brightness)/width);
7506 				} else {
7507 					brightnessSteps=(127-brightness)/width;
7508 				}
7509 
7510 				for (int i=0; i<width; i++) {
7511 					switch(side) {
7512 					case Border3DSide.Left:	{
7513 						colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7514 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7515 						graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7516 						break;
7517 					}
7518 
7519 					case Border3DSide.Right: {
7520 						colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7521 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7522 						graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7523 						break;
7524 					}
7525 
7526 					case Border3DSide.Top: {
7527 						colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7528 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7529 						graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7530 						break;
7531 					}
7532 
7533 					case Border3DSide.Bottom: {
7534 						colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7535 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7536 						graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7537 						break;
7538 					}
7539 					}
7540 				}
7541 				break;
7542 			}
7543 
7544 			case ButtonBorderStyle.Inset: {
7545 				Color		colorGrade;
7546 				int		hue, brightness, saturation;
7547 				int		brightnessSteps;
7548 				int		brightnessDownSteps;
7549 
7550 				ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7551 
7552 				brightnessDownSteps=brightness/width;
7553 				if (brightness>127) {
7554 					brightnessSteps=Math.Max(6, (160-brightness)/width);
7555 				} else {
7556 					brightnessSteps=(127-brightness)/width;
7557 				}
7558 
7559 				for (int i=0; i<width; i++) {
7560 					switch(side) {
7561 					case Border3DSide.Left:	{
7562 						colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7563 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7564 						graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7565 						break;
7566 					}
7567 
7568 					case Border3DSide.Right: {
7569 						colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7570 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7571 						graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7572 						break;
7573 					}
7574 
7575 					case Border3DSide.Top: {
7576 						colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7577 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7578 						graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7579 						break;
7580 					}
7581 
7582 					case Border3DSide.Bottom: {
7583 						colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7584 						pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7585 						graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7586 						break;
7587 					}
7588 					}
7589 				}
7590 				break;
7591 			}
7592 
7593 				/*
7594 					I decided to have the for-loop duplicated for speed reasons;
7595 					that way we only have to switch once (as opposed to have the
7596 					for-loop around the switch)
7597 				*/
7598 			default: {
7599 				switch(side) {
7600 				case Border3DSide.Left:	{
7601 					for (int i=0; i<width; i++) {
7602 						graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7603 					}
7604 					break;
7605 				}
7606 
7607 				case Border3DSide.Right: {
7608 					for (int i=0; i<width; i++) {
7609 						graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7610 					}
7611 					break;
7612 				}
7613 
7614 				case Border3DSide.Top: {
7615 					for (int i=0; i<width; i++) {
7616 						graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7617 					}
7618 					break;
7619 				}
7620 
7621 				case Border3DSide.Bottom: {
7622 					for (int i=0; i<width; i++) {
7623 						graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7624 					}
7625 					break;
7626 				}
7627 				}
7628 				break;
7629 			}
7630 			}
7631 		}
7632 
7633 		/*
7634 			This function actually draws the various caption elements.
7635 			This way we can scale them nicely, no matter what size, and they
7636 			still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7637 		*/
7638 
DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button)7639 		private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7640 			switch(button) {
7641 			case CaptionButton.Close: {
7642 				if (lineWidth<2) {
7643 					graphics.DrawLine(pen, captionRect.Left+2*lineWidth+1+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+1+shift, captionRect.Bottom-2*lineWidth+shift);
7644 					graphics.DrawLine(pen, captionRect.Right-2*lineWidth+1+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+1+shift, captionRect.Bottom-2*lineWidth+shift);
7645 				}
7646 
7647 				graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7648 				graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7649 				return;
7650 			}
7651 
7652 			case CaptionButton.Help: {
7653 				StringFormat	sf = new StringFormat();
7654 				Font				font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7655 
7656 				sf.Alignment=StringAlignment.Center;
7657 				sf.LineAlignment=StringAlignment.Center;
7658 
7659 
7660 				graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7661 
7662 				sf.Dispose();
7663 				font.Dispose();
7664 
7665 				return;
7666 			}
7667 
7668 			case CaptionButton.Maximize: {
7669 				/* Top 'caption bar' line */
7670 				for (int i=0; i<Math.Max(2, lineWidth); i++) {
7671 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Top+2*lineWidth+shift+i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+2*lineWidth+shift+i);
7672 				}
7673 
7674 				/* Left side line */
7675 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7676 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7677 				}
7678 
7679 				/* Right side line */
7680 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7681 					graphics.DrawLine(pen, captionRect.Right-lineWidth-lineWidth/2+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Right-lineWidth-lineWidth/2+shift+i, captionRect.Bottom-lineWidth+shift);
7682 				}
7683 
7684 				/* Bottom line */
7685 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7686 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7687 				}
7688 				return;
7689 			}
7690 
7691 			case CaptionButton.Minimize: {
7692 				/* Bottom line */
7693 				for (int i=0; i<Math.Max(2, lineWidth); i++) {
7694 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7695 				}
7696 				return;
7697 			}
7698 
7699 			case CaptionButton.Restore: {
7700 				/** First 'window' **/
7701 				/* Top 'caption bar' line */
7702 				for (int i=0; i<Math.Max(2, lineWidth); i++) {
7703 					graphics.DrawLine(pen, captionRect.Left+3*lineWidth+shift, captionRect.Top+2*lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+2*lineWidth+shift-i);
7704 				}
7705 
7706 				/* Left side line */
7707 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7708 					graphics.DrawLine(pen, captionRect.Left+3*lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+3*lineWidth+shift+i, captionRect.Top+4*lineWidth+shift);
7709 				}
7710 
7711 				/* Right side line */
7712 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7713 					graphics.DrawLine(pen, captionRect.Right-lineWidth-lineWidth/2+shift-i, captionRect.Top+2*lineWidth+shift, captionRect.Right-lineWidth-lineWidth/2+shift-i, captionRect.Top+5*lineWidth-lineWidth/2+shift);
7714 				}
7715 
7716 				/* Bottom line */
7717 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7718 					graphics.DrawLine(pen, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Top+5*lineWidth-lineWidth/2+shift+1+i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+5*lineWidth-lineWidth/2+shift+1+i);
7719 				}
7720 
7721 				/** Second 'window' **/
7722 				/* Top 'caption bar' line */
7723 				for (int i=0; i<Math.Max(2, lineWidth); i++) {
7724 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Top+4*lineWidth+shift+1-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Top+4*lineWidth+shift+1-i);
7725 				}
7726 
7727 				/* Left side line */
7728 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7729 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7730 				}
7731 
7732 				/* Right side line */
7733 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7734 					graphics.DrawLine(pen, captionRect.Right-3*lineWidth-lineWidth/2+shift-i, captionRect.Top+4*lineWidth+shift+1, captionRect.Right-3*lineWidth-lineWidth/2+shift-i, captionRect.Bottom-lineWidth+shift);
7735 				}
7736 
7737 				/* Bottom line */
7738 				for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7739 					graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7740 				}
7741 
7742 				return;
7743 			}
7744 
7745 			}
7746 		}
7747 
7748 		/* Generic scroll button */
DrawScrollButtonPrimitive(Graphics dc, Rectangle area, ButtonState state)7749 		public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7750 			if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7751 				dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7752 					area.Y + 1, area.Width - 2 , area.Height - 2);
7753 
7754 				dc.DrawRectangle (SystemPens.ControlDark, area.X,
7755 					area.Y, area.Width, area.Height);
7756 
7757 				return;
7758 			}
7759 
7760 			Brush sb_control = SystemBrushes.Control;
7761 			Brush sb_lightlight = SystemBrushes.ControlLightLight;
7762 			Brush sb_dark = SystemBrushes.ControlDark;
7763 			Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7764 
7765 			dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7766 			dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7767 
7768 			dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7769 			dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7770 				area.Height - 4);
7771 
7772 			dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7773 				area.Width - 2, 1);
7774 
7775 			dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7776 				area.Width , 1);
7777 
7778 			dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7779 				area.Y + 1, 1, area.Height -3);
7780 
7781 			dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7782 				area.Y, 1, area.Height - 1);
7783 
7784 			dc.FillRectangle (sb_control, area.X + 2,
7785 				area.Y + 2, area.Width - 4, area.Height - 4);
7786 
7787 		}
7788 
CPDrawBorderStyle(Graphics dc, Rectangle area, BorderStyle border_style)7789 		public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7790 			switch (border_style){
7791 			case BorderStyle.Fixed3D:
7792 				dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7793 				dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7794 				dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width ,
7795 					area.Y + area.Height - 1);
7796 				dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1,
7797 					area.Y + area.Height);
7798 
7799 				dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7800 				dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7801 				dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7802 				dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7803 				break;
7804 			case BorderStyle.FixedSingle:
7805 				dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7806 				break;
7807 			case BorderStyle.None:
7808 			default:
7809 				break;
7810 			}
7811 
7812 		}
7813 		#endregion	// ControlPaint
7814 
7815 
7816 	} //class
7817 }
7818