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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004-2006 Novell, Inc.
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
30 using System.ComponentModel;
33 using System.Drawing.Drawing2D;
34 using System.Drawing.Imaging;
35 using System.Drawing.Printing;
36 using System.Drawing.Text;
38 using System.Windows.Forms.Theming;
40 namespace System.Windows.Forms
43 internal class ThemeWin32Classic : Theme
45 public override Version Version {
47 return new Version(0, 1, 0, 0);
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;
67 #region Principal Theme Methods
68 public ThemeWin32Classic ()
73 public override void ResetDefaults() {
74 defaultWindowBackColor = this.ColorWindow;
75 defaultWindowForeColor = this.ColorControlText;
76 window_border_font = null;
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;
86 string_format_menu_shortcut = new StringFormat ();
87 string_format_menu_shortcut.LineAlignment = StringAlignment.Center;
88 string_format_menu_shortcut.Alignment = StringAlignment.Far;
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;
96 public override bool DoubleBufferingSupported {
100 public override int HorizontalScrollBarHeight {
102 return XplatUI.HorizontalScrollBarHeight;
106 public override int VerticalScrollBarWidth {
108 return XplatUI.VerticalScrollBarWidth;
112 public override Font WindowBorderFont {
114 return window_border_font ?? (window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold));
118 #endregion // Principal Theme Methods
120 #region Internal Methods
121 protected Brush GetControlBackBrush (Color c) {
122 if (c.ToArgb () == DefaultControlBackColor.ToArgb ())
123 return SystemBrushes.Control;
124 return ResPool.GetSolidBrush (c);
127 protected Brush GetControlForeBrush (Color c) {
128 if (c.ToArgb () == DefaultControlForeColor.ToArgb ())
129 return SystemBrushes.ControlText;
130 return ResPool.GetSolidBrush (c);
132 #endregion // Internal Methods
135 public override Font GetLinkFont (Control control)
137 return new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Underline, control.Font.Unit);
139 #endregion // Control
141 #region OwnerDraw Support
142 public override void DrawOwnerDrawBackground (DrawItemEventArgs e)
144 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
145 e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds);
149 e.Graphics.FillRectangle (ResPool.GetSolidBrush(e.BackColor), e.Bounds);
152 public override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e)
154 if (e.State == DrawItemState.Focus)
155 CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor);
157 #endregion // OwnerDraw Support
160 #region Standard Button Style
161 public override void DrawButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
163 // Draw Button Background
164 DrawButtonBackground (g, b, clipRectangle);
166 // If we have an image, draw it
167 if (imageBounds.Size != Size.Empty)
168 DrawButtonImage (g, b, imageBounds);
170 // If we're focused, draw a focus rectangle
171 if (b.Focused && b.Enabled && b.ShowFocusCues)
172 DrawButtonFocus (g, b);
174 // If we have text, draw it
175 if (textBounds != Rectangle.Empty)
176 DrawButtonText (g, b, textBounds);
179 public virtual void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea)
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);
190 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
193 public virtual void DrawButtonFocus (Graphics g, Button button)
195 ControlPaint.DrawFocusRectangle (g, Rectangle.Inflate (button.ClientRectangle, -4, -4));
198 public virtual void DrawButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
201 g.DrawImage (button.Image, imageBounds);
203 CPDrawImageDisabled (g, button.Image, imageBounds.Left, imageBounds.Top, ColorControl);
206 public virtual void DrawButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
208 // Ensure that at least one line is going to get displayed.
209 // Line limit does not ensure that despite its description.
210 textBounds.Height = Math.Max (textBounds.Height, button.Font.Height);
213 TextRenderer.DrawTextInternal (g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
215 DrawStringDisabled20 (g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
219 #region FlatStyle Button Style
220 public override void DrawFlatButton (Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
222 // Draw Button Background
223 if (b.BackgroundImage == null)
224 DrawFlatButtonBackground (g, b, clipRectangle);
226 // If we have an image, draw it
227 if (imageBounds.Size != Size.Empty)
228 DrawFlatButtonImage (g, b, imageBounds);
230 // If we're focused, draw a focus rectangle
231 if (b.Focused && b.Enabled && b.ShowFocusCues)
232 DrawFlatButtonFocus (g, b);
234 // If we have text, draw it
235 if (textBounds != Rectangle.Empty)
236 DrawFlatButtonText (g, b, textBounds);
239 public virtual void DrawFlatButtonBackground (Graphics g, ButtonBase button, Rectangle clipArea)
242 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance);
243 else if (button.InternalSelected) {
245 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
247 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
249 else if (button.Entered)
250 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
251 else if (!button.Enabled)
252 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance);
254 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance);
257 public virtual void DrawFlatButtonFocus (Graphics g, ButtonBase button)
259 if (!button.Pressed) {
260 Color focus_color = ControlPaint.Dark (button.BackColor);
261 g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9));
265 public virtual void DrawFlatButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
267 // No changes from Standard for image for this theme
268 DrawButtonImage (g, button, imageBounds);
271 public virtual void DrawFlatButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
273 // No changes from Standard for text for this theme
274 DrawButtonText (g, button, textBounds);
278 #region Popup Button Style
279 public override void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
281 // Draw Button Background
282 DrawPopupButtonBackground (g, b, clipRectangle);
284 // If we have an image, draw it
285 if (imageBounds.Size != Size.Empty)
286 DrawPopupButtonImage (g, b, imageBounds);
288 // If we're focused, draw a focus rectangle
289 if (b.Focused && b.Enabled && b.ShowFocusCues)
290 DrawPopupButtonFocus (g, b);
292 // If we have text, draw it
293 if (textBounds != Rectangle.Empty)
294 DrawPopupButtonText (g, b, textBounds);
297 public virtual void DrawPopupButtonBackground (Graphics g, Button button, Rectangle clipArea)
300 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
301 else if (button.Entered)
302 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
303 else if (button.InternalSelected)
304 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
305 else if (!button.Enabled)
306 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
308 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
311 public virtual void DrawPopupButtonFocus (Graphics g, Button button)
313 // No changes from Standard for image for this theme
314 DrawButtonFocus (g, button);
317 public virtual void DrawPopupButtonImage (Graphics g, Button button, Rectangle imageBounds)
319 // No changes from Standard for image for this theme
320 DrawButtonImage (g, button, imageBounds);
323 public virtual void DrawPopupButtonText (Graphics g, Button button, Rectangle textBounds)
325 // No changes from Standard for image for this theme
326 DrawButtonText (g, button, textBounds);
330 #region Button Layout Calculations
331 public override Size CalculateButtonAutoSize (Button button)
333 Size ret_size = Size.Empty;
334 Size text_size = TextRenderer.MeasureTextInternal (button.Text, button.Font, button.UseCompatibleTextRendering);
335 Size image_size = button.Image == null ? Size.Empty : button.Image.Size;
338 if (button.Text.Length != 0) {
339 text_size.Height += 4;
340 text_size.Width += 4;
343 switch (button.TextImageRelation) {
344 case TextImageRelation.Overlay:
345 ret_size.Height = Math.Max (button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
346 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
348 case TextImageRelation.ImageAboveText:
349 case TextImageRelation.TextAboveImage:
350 ret_size.Height = text_size.Height + image_size.Height;
351 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
353 case TextImageRelation.ImageBeforeText:
354 case TextImageRelation.TextBeforeImage:
355 ret_size.Height = Math.Max (text_size.Height, image_size.Height);
356 ret_size.Width = text_size.Width + image_size.Width;
361 ret_size.Height += (button.Padding.Vertical + 6);
362 ret_size.Width += (button.Padding.Horizontal + 6);
367 public override void CalculateButtonTextAndImageLayout (Graphics g, ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle)
369 Image image = button.Image;
370 string text = button.Text;
371 Rectangle content_rect = button.PaddingClientRectangle;
372 Size text_size = TextRenderer.MeasureTextInternal (g, text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering);
373 Size image_size = image == null ? Size.Empty : image.Size;
375 textRectangle = Rectangle.Inflate (content_rect, -4, -4);
376 imageRectangle = Rectangle.Empty;
378 bool displayEllipsis = (button.TextFormatFlags & (TextFormatFlags.EndEllipsis | TextFormatFlags.PathEllipsis | TextFormatFlags.WordEllipsis)) != 0;
380 switch (button.TextImageRelation) {
381 case TextImageRelation.Overlay:
382 // Overlay is easy, text always goes here
384 // Image is dependent on ImageAlign
387 textRectangle.Offset (1, 1);
393 int image_height = image.Height;
394 int image_width = image.Width;
396 switch (button.ImageAlign) {
397 case System.Drawing.ContentAlignment.TopLeft:
401 case System.Drawing.ContentAlignment.TopCenter:
402 image_x = (content_rect.Width - image_width) / 2;
405 case System.Drawing.ContentAlignment.TopRight:
406 image_x = content_rect.Width - image_width - 5;
409 case System.Drawing.ContentAlignment.MiddleLeft:
411 image_y = (content_rect.Height - image_height) / 2;
413 case System.Drawing.ContentAlignment.MiddleCenter:
414 image_x = (content_rect.Width - image_width) / 2;
415 image_y = (content_rect.Height - image_height) / 2;
417 case System.Drawing.ContentAlignment.MiddleRight:
418 image_x = content_rect.Width - image_width - 4;
419 image_y = (content_rect.Height - image_height) / 2;
421 case System.Drawing.ContentAlignment.BottomLeft:
423 image_y = content_rect.Height - image_height - 4;
425 case System.Drawing.ContentAlignment.BottomCenter:
426 image_x = (content_rect.Width - image_width) / 2;
427 image_y = content_rect.Height - image_height - 4;
429 case System.Drawing.ContentAlignment.BottomRight:
430 image_x = content_rect.Width - image_width - 4;
431 image_y = content_rect.Height - image_height - 4;
439 imageRectangle = new Rectangle (image_x, image_y, image_width, image_height);
441 case TextImageRelation.ImageAboveText:
442 LayoutTextAboveOrBelowImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle);
444 case TextImageRelation.TextAboveImage:
445 LayoutTextAboveOrBelowImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle);
447 case TextImageRelation.ImageBeforeText:
448 LayoutTextBeforeOrAfterImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
450 case TextImageRelation.TextBeforeImage:
451 LayoutTextBeforeOrAfterImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
455 textRectangle.Offset (1, 1);
458 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 int element_spacing = 0; // Spacing between the Text and the Image
461 int total_width = textSize.Width + element_spacing + imageSize.Width;
464 element_spacing += 2;
466 // If the text is too big, chop it down to the size we have available to it
467 if (total_width > totalArea.Width) {
468 textSize.Width = totalArea.Width - element_spacing - imageSize.Width;
469 total_width = totalArea.Width;
472 int excess_width = totalArea.Width - total_width;
475 Rectangle final_text_rect;
476 Rectangle final_image_rect;
478 HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
479 HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
481 if (h_image == HorizontalAlignment.Left)
483 else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
484 offset = excess_width;
485 else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
486 offset += (int)(excess_width / 3);
488 offset += (int)(2 * (excess_width / 3));
491 final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
492 final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
495 final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
496 final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
499 textRect = final_text_rect;
500 imageRect = final_image_rect;
503 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 int element_spacing = 0; // Spacing between the Text and the Image
506 int total_height = textSize.Height + element_spacing + imageSize.Height;
509 element_spacing += 2;
511 if (textSize.Width > totalArea.Width)
512 textSize.Width = totalArea.Width;
514 // If the there isn't enough room and we're text first, cut out the image
515 if (total_height > totalArea.Height && textFirst) {
516 imageSize = Size.Empty;
517 total_height = totalArea.Height;
520 int excess_height = totalArea.Height - total_height;
523 Rectangle final_text_rect;
524 Rectangle final_image_rect;
526 VerticalAlignment v_text = GetVerticalAlignment (textAlign);
527 VerticalAlignment v_image = GetVerticalAlignment (imageAlign);
529 if (v_image == VerticalAlignment.Top)
531 else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom)
532 offset = excess_height;
533 else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center))
534 offset += (int)(excess_height / 3);
536 offset += (int)(2 * (excess_height / 3));
539 var textHeight = excess_height >= 0 ? totalArea.Height - imageSize.Height - element_spacing: textSize.Height;
540 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textHeight);
541 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height);
544 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height);
545 var textHeight = excess_height >= 0 ? totalArea.Height - final_image_rect.Height : textSize.Height;
546 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textHeight);
548 if (final_text_rect.Bottom > totalArea.Bottom) {
549 final_text_rect.Y -= (final_text_rect.Bottom - totalArea.Bottom);
550 if (final_text_rect.Y < totalArea.Top)
551 final_text_rect.Y = totalArea.Top;
555 if (displayEllipsis) {
556 // Don't use more space than is available otherwise ellipsis won't show
557 if (final_text_rect.Height > totalArea.Bottom)
558 final_text_rect.Height = totalArea.Bottom - final_text_rect.Top;
561 textRect = final_text_rect;
562 imageRect = final_image_rect;
565 private HorizontalAlignment GetHorizontalAlignment (System.Drawing.ContentAlignment align)
568 case System.Drawing.ContentAlignment.BottomLeft:
569 case System.Drawing.ContentAlignment.MiddleLeft:
570 case System.Drawing.ContentAlignment.TopLeft:
571 return HorizontalAlignment.Left;
572 case System.Drawing.ContentAlignment.BottomCenter:
573 case System.Drawing.ContentAlignment.MiddleCenter:
574 case System.Drawing.ContentAlignment.TopCenter:
575 return HorizontalAlignment.Center;
576 case System.Drawing.ContentAlignment.BottomRight:
577 case System.Drawing.ContentAlignment.MiddleRight:
578 case System.Drawing.ContentAlignment.TopRight:
579 return HorizontalAlignment.Right;
582 return HorizontalAlignment.Left;
585 private enum VerticalAlignment
592 private VerticalAlignment GetVerticalAlignment (System.Drawing.ContentAlignment align)
595 case System.Drawing.ContentAlignment.TopLeft:
596 case System.Drawing.ContentAlignment.TopCenter:
597 case System.Drawing.ContentAlignment.TopRight:
598 return VerticalAlignment.Top;
599 case System.Drawing.ContentAlignment.MiddleLeft:
600 case System.Drawing.ContentAlignment.MiddleCenter:
601 case System.Drawing.ContentAlignment.MiddleRight:
602 return VerticalAlignment.Center;
603 case System.Drawing.ContentAlignment.BottomLeft:
604 case System.Drawing.ContentAlignment.BottomCenter:
605 case System.Drawing.ContentAlignment.BottomRight:
606 return VerticalAlignment.Bottom;
609 return VerticalAlignment.Top;
612 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, System.Drawing.ContentAlignment align)
617 if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft)
619 else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter)
620 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
621 else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight)
622 x = outer.Right - inner.Width;
623 if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight)
625 else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight)
626 y = outer.Y + (outer.Height - inner.Height) / 2;
627 else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft)
628 y = outer.Bottom - inner.Height;
630 return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
636 public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button)
638 // Draw the button: Draw border, etc.
639 ButtonBase_DrawButton(button, dc);
642 if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null)))
643 ButtonBase_DrawImage(button, dc);
645 // Draw the focus rectangle
646 if (ShouldPaintFocusRectagle (button))
647 ButtonBase_DrawFocus(button, dc);
650 if (button.Text != null && button.Text != String.Empty)
651 ButtonBase_DrawText(button, dc);
654 protected static bool ShouldPaintFocusRectagle (ButtonBase button)
656 return (button.Focused || button.paint_as_acceptbutton) && button.Enabled && button.ShowFocusCues;
659 protected virtual void ButtonBase_DrawButton (ButtonBase button, Graphics dc)
661 Rectangle borderRectangle;
662 bool check_or_radio = false;
663 bool check_or_radio_checked = false;
665 bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
667 CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor);
669 if (button is CheckBox) {
670 check_or_radio = true;
671 check_or_radio_checked = ((CheckBox)button).Checked;
672 } else if (button is RadioButton) {
673 check_or_radio = true;
674 check_or_radio_checked = ((RadioButton)button).Checked;
677 if (button.Focused && button.Enabled && !check_or_radio) {
678 // shrink the rectangle for the normal button drawing inside the focus rectangle
679 borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1);
681 borderRectangle = button.ClientRectangle;
684 if (button.FlatStyle == FlatStyle.Popup) {
685 if (!button.is_pressed && !button.is_entered && !check_or_radio_checked)
686 Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
687 else if (!button.is_pressed && button.is_entered &&!check_or_radio_checked)
688 Internal_DrawButton (dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor);
689 else if (button.is_pressed || check_or_radio_checked)
690 Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
691 } else if (button.FlatStyle == FlatStyle.Flat) {
692 if (button.is_entered && !button.is_pressed && !check_or_radio_checked) {
693 if ((button.image == null) && (button.image_list == null)) {
694 Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush (cpcolor.Dark);
695 dc.FillRectangle (brush, borderRectangle);
697 } else if (button.is_pressed || check_or_radio_checked) {
698 if ((button.image == null) && (button.image_list == null)) {
699 Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush (cpcolor.LightLight);
700 dc.FillRectangle (brush, borderRectangle);
703 Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
704 dc.DrawRectangle (pen, borderRectangle.X + 4, borderRectangle.Y + 4,
705 borderRectangle.Width - 9, borderRectangle.Height - 9);
708 Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor);
710 if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked)
711 Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor);
713 Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
717 private void Internal_DrawButton (Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor)
720 case 0: // normal or normal disabled button
721 Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
722 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
723 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
725 pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen (backcolor);
726 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
727 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
729 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
730 dc.DrawLine (pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
731 dc.DrawLine (pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3);
733 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
734 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
735 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
737 case 1: // popup button normal (or pressed normal or popup button)
738 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
739 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
741 case 2: // popup button poped up
742 pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
743 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
744 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
746 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
747 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
748 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
750 case 3: // flat button not entered
751 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
752 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
759 protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc)
761 // Need to draw a picture
768 int width = button.ClientSize.Width;
769 int height = button.ClientSize.Height;
771 if (button.ImageIndex != -1) { // We use ImageIndex instead of image_index since it will return -1 if image_list is null
772 i = button.image_list.Images[button.ImageIndex];
777 image_width = i.Width;
778 image_height = i.Height;
780 switch (button.ImageAlign) {
781 case ContentAlignment.TopLeft: {
787 case ContentAlignment.TopCenter: {
788 image_x = (width - image_width) / 2;
793 case ContentAlignment.TopRight: {
794 image_x = width - image_width - 5;
799 case ContentAlignment.MiddleLeft: {
801 image_y = (height - image_height) / 2;
805 case ContentAlignment.MiddleCenter: {
806 image_x = (width - image_width) / 2;
807 image_y = (height - image_height) / 2;
811 case ContentAlignment.MiddleRight: {
812 image_x = width - image_width - 4;
813 image_y = (height - image_height) / 2;
817 case ContentAlignment.BottomLeft: {
819 image_y = height - image_height - 4;
823 case ContentAlignment.BottomCenter: {
824 image_x = (width - image_width) / 2;
825 image_y = height - image_height - 4;
829 case ContentAlignment.BottomRight: {
830 image_x = width - image_width - 4;
831 image_y = height - image_height - 4;
842 dc.SetClip (new Rectangle(3, 3, width - 5, height - 5));
845 dc.DrawImage (i, image_x, image_y, image_width, image_height);
847 CPDrawImageDisabled (dc, i, image_x, image_y, ColorControl);
852 protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc)
854 Color focus_color = button.ForeColor;
856 int inflate_value = -3;
858 if (!(button is CheckBox) && !(button is RadioButton)) {
861 if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed)
862 focus_color = ControlPaint.Dark(button.BackColor);
864 dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y,
865 button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
868 if (button.Focused) {
869 Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value);
870 ControlPaint.DrawFocusRectangle (dc, rect);
874 protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc)
876 Rectangle buttonRectangle = button.ClientRectangle;
877 Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
879 if (button.is_pressed) {
884 // Ensure that at least one line is going to get displayed.
885 // Line limit does not ensure that despite its description.
886 text_rect.Height = Math.Max (button.Font.Height, text_rect.Height);
888 if (button.Enabled) {
889 dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
891 if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
892 dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (ColorGrayText), text_rect, button.text_format);
894 CPDrawStringDisabled (dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format);
899 public override Size ButtonBaseDefaultSize {
901 return new Size (75, 23);
904 #endregion // ButtonBase
907 public override void DrawCheckBox (Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
909 // Draw Button Background
910 if (cb.Appearance == Appearance.Button && cb.FlatStyle != FlatStyle.Flat)
911 ButtonBase_DrawButton (cb, g);
912 else if (cb.Appearance != Appearance.Button)
913 DrawCheckBoxGlyph (g, cb, glyphArea);
915 // Draw the borders and such for a Flat CheckBox Button
916 if (cb.Appearance == Appearance.Button && cb.FlatStyle == FlatStyle.Flat)
917 DrawFlatButton (g, cb, textBounds, imageBounds, clipRectangle);
919 // If we have an image, draw it
920 if (imageBounds.Size != Size.Empty)
921 DrawCheckBoxImage (g, cb, imageBounds);
923 if (cb.Focused && cb.Enabled && cb.ShowFocusCues && textBounds != Rectangle.Empty)
924 DrawCheckBoxFocus (g, cb, textBounds);
926 // If we have text, draw it
927 if (textBounds != Rectangle.Empty)
928 DrawCheckBoxText (g, cb, textBounds);
931 public virtual void DrawCheckBoxGlyph (Graphics g, CheckBox cb, Rectangle glyphArea)
934 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState);
935 else if (cb.InternalSelected)
936 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
938 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState);
939 else if (!cb.Enabled)
940 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState);
942 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
945 public virtual void DrawCheckBoxFocus (Graphics g, CheckBox cb, Rectangle focusArea)
947 ControlPaint.DrawFocusRectangle (g, focusArea);
950 public virtual void DrawCheckBoxImage (Graphics g, CheckBox cb, Rectangle imageBounds)
953 g.DrawImage (cb.Image, imageBounds);
955 CPDrawImageDisabled (g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
958 public virtual void DrawCheckBoxText (Graphics g, CheckBox cb, Rectangle textBounds)
961 TextRenderer.DrawTextInternal (g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
963 DrawStringDisabled20 (g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
966 public override void CalculateCheckBoxTextAndImageLayout (ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
968 int check_size = CheckSize;
970 if (button is CheckBox)
971 check_size = (button as CheckBox).Appearance == Appearance.Normal ? check_size : 0;
973 glyphArea = new Rectangle (button.Padding.Left, button.Padding.Top, check_size, check_size);
975 Rectangle content_rect = button.PaddingClientRectangle;
976 ContentAlignment align = ContentAlignment.TopLeft;
978 if (button is CheckBox)
979 align = (button as CheckBox).CheckAlign;
980 else if (button is RadioButton)
981 align = (button as RadioButton).CheckAlign;
984 case ContentAlignment.BottomCenter:
985 glyphArea.Y += content_rect.Height - check_size - 2;
986 glyphArea.X += (content_rect.Width - check_size) / 2;
988 case ContentAlignment.BottomLeft:
989 glyphArea.Y += content_rect.Height - check_size - 2;
990 content_rect.Width -= check_size;
991 content_rect.Offset (check_size, 0);
993 case ContentAlignment.BottomRight:
994 glyphArea.Y += content_rect.Height - check_size - 2;
995 glyphArea.X += content_rect.Width - check_size;
996 content_rect.Width -= check_size;
998 case ContentAlignment.MiddleCenter:
999 glyphArea.Y += (content_rect.Height - check_size) / 2;
1000 glyphArea.X += (content_rect.Width - check_size) / 2;
1002 case ContentAlignment.MiddleLeft:
1003 glyphArea.Y += (content_rect.Height - check_size) / 2;
1004 content_rect.Width -= check_size;
1005 content_rect.Offset (check_size, 0);
1007 case ContentAlignment.MiddleRight:
1008 glyphArea.Y += (content_rect.Height - check_size) / 2;
1009 glyphArea.X += content_rect.Width - check_size;
1010 content_rect.Width -= check_size;
1012 case ContentAlignment.TopCenter:
1013 glyphArea.X += (content_rect.Width - check_size) / 2;
1015 case ContentAlignment.TopLeft:
1016 content_rect.Width -= check_size;
1017 content_rect.Offset (check_size, 0);
1019 case ContentAlignment.TopRight:
1020 glyphArea.X += content_rect.Width - check_size;
1021 content_rect.Width -= check_size;
1025 Image image = button.Image;
1026 string text = button.Text;
1028 Size proposed = Size.Empty;
1030 // Force wrapping if we aren't AutoSize and our text is too long
1031 if (!button.AutoSize)
1032 proposed.Width = button.PaddingClientRectangle.Width - glyphArea.Width - 2;
1034 Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, proposed, button.TextFormatFlags, button.UseCompatibleTextRendering);
1036 // Text can't be bigger than the content rectangle
1037 text_size.Height = Math.Min (text_size.Height, content_rect.Height);
1038 text_size.Width = Math.Min (text_size.Width, content_rect.Width);
1040 Size image_size = image == null ? Size.Empty : image.Size;
1042 textRectangle = Rectangle.Empty;
1043 imageRectangle = Rectangle.Empty;
1045 switch (button.TextImageRelation) {
1046 case TextImageRelation.Overlay:
1047 // Text is centered vertically, and 2 pixels to the right
1048 textRectangle.X = content_rect.Left + 2;
1049 textRectangle.Y = button.PaddingClientRectangle.Top + ((content_rect.Height - text_size.Height) / 2) - 1;
1050 textRectangle.Size = text_size;
1052 // Image is dependent on ImageAlign
1056 int image_x = button.PaddingClientRectangle.Left;
1057 int image_y = button.PaddingClientRectangle.Top;
1058 int image_height = image.Height;
1059 int image_width = image.Width;
1061 switch (button.ImageAlign) {
1062 case System.Drawing.ContentAlignment.TopLeft:
1066 case System.Drawing.ContentAlignment.TopCenter:
1067 image_x += (content_rect.Width - image_width) / 2;
1070 case System.Drawing.ContentAlignment.TopRight:
1071 image_x += content_rect.Width - image_width - 5;
1074 case System.Drawing.ContentAlignment.MiddleLeft:
1076 image_y += (content_rect.Height - image_height) / 2;
1078 case System.Drawing.ContentAlignment.MiddleCenter:
1079 image_x += (content_rect.Width - image_width) / 2;
1080 image_y += (content_rect.Height - image_height) / 2;
1082 case System.Drawing.ContentAlignment.MiddleRight:
1083 image_x += content_rect.Width - image_width - 4;
1084 image_y += (content_rect.Height - image_height) / 2;
1086 case System.Drawing.ContentAlignment.BottomLeft:
1088 image_y += content_rect.Height - image_height - 4;
1090 case System.Drawing.ContentAlignment.BottomCenter:
1091 image_x += (content_rect.Width - image_width) / 2;
1092 image_y += content_rect.Height - image_height - 4;
1094 case System.Drawing.ContentAlignment.BottomRight:
1095 image_x += content_rect.Width - image_width - 4;
1096 image_y += content_rect.Height - image_height - 4;
1104 imageRectangle = new Rectangle (image_x + check_size, image_y, image_width, image_height);
1106 case TextImageRelation.ImageAboveText:
1107 content_rect.Inflate (-4, -4);
1108 LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle);
1110 case TextImageRelation.TextAboveImage:
1111 content_rect.Inflate (-4, -4);
1112 LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle);
1114 case TextImageRelation.ImageBeforeText:
1115 content_rect.Inflate (-4, -4);
1116 LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1118 case TextImageRelation.TextBeforeImage:
1119 content_rect.Inflate (-4, -4);
1120 LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1125 public override Size CalculateCheckBoxAutoSize (CheckBox checkBox)
1127 Size ret_size = Size.Empty;
1128 Size text_size = TextRenderer.MeasureTextInternal (checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering);
1129 Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size;
1131 // Pad the text size
1132 if (checkBox.Text.Length != 0) {
1133 text_size.Height += 4;
1134 text_size.Width += 4;
1137 switch (checkBox.TextImageRelation) {
1138 case TextImageRelation.Overlay:
1139 ret_size.Height = Math.Max (checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
1140 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1142 case TextImageRelation.ImageAboveText:
1143 case TextImageRelation.TextAboveImage:
1144 ret_size.Height = text_size.Height + image_size.Height;
1145 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1147 case TextImageRelation.ImageBeforeText:
1148 case TextImageRelation.TextBeforeImage:
1149 ret_size.Height = Math.Max (text_size.Height, image_size.Height);
1150 ret_size.Width = text_size.Width + image_size.Width;
1155 ret_size.Height += (checkBox.Padding.Vertical);
1156 ret_size.Width += (checkBox.Padding.Horizontal) + 15;
1158 // There seems to be a minimum height
1159 if (ret_size.Height == checkBox.Padding.Vertical)
1160 ret_size.Height += 14;
1165 public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
1166 StringFormat text_format;
1167 Rectangle client_rectangle;
1168 Rectangle text_rectangle;
1169 Rectangle checkbox_rectangle;
1170 int checkmark_size = CheckSize;
1171 int checkmark_space = 4;
1173 client_rectangle = checkbox.ClientRectangle;
1174 text_rectangle = client_rectangle;
1175 checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
1177 text_format = new StringFormat();
1178 text_format.Alignment = StringAlignment.Near;
1179 text_format.LineAlignment = StringAlignment.Center;
1180 if (checkbox.ShowKeyboardCuesInternal)
1181 text_format.HotkeyPrefix = HotkeyPrefix.Show;
1183 text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1185 /* Calculate the position of text and checkbox rectangle */
1186 if (checkbox.appearance!=Appearance.Button) {
1187 switch(checkbox.check_alignment) {
1188 case ContentAlignment.BottomCenter: {
1189 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1190 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1191 text_rectangle.X=client_rectangle.X;
1192 text_rectangle.Width=client_rectangle.Width;
1193 text_rectangle.Height=client_rectangle.Height-checkbox_rectangle.Y-checkmark_space;
1197 case ContentAlignment.BottomLeft: {
1198 checkbox_rectangle.X=client_rectangle.Left;
1199 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1200 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1201 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1205 case ContentAlignment.BottomRight: {
1206 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1207 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1208 text_rectangle.X=client_rectangle.X;
1209 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1213 case ContentAlignment.MiddleCenter: {
1214 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1215 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1216 text_rectangle.X=client_rectangle.X;
1217 text_rectangle.Width=client_rectangle.Width;
1222 case ContentAlignment.MiddleLeft: {
1223 checkbox_rectangle.X=client_rectangle.Left;
1224 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1225 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1226 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1230 case ContentAlignment.MiddleRight: {
1231 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1232 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1233 text_rectangle.X=client_rectangle.X;
1234 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1238 case ContentAlignment.TopCenter: {
1239 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1240 checkbox_rectangle.Y=client_rectangle.Top;
1241 text_rectangle.X=client_rectangle.X;
1242 text_rectangle.Width=client_rectangle.Width;
1243 text_rectangle.Y=checkmark_size+checkmark_space;
1244 text_rectangle.Height=client_rectangle.Height-checkmark_size-checkmark_space;
1248 case ContentAlignment.TopLeft: {
1249 checkbox_rectangle.X=client_rectangle.Left;
1250 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1251 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1255 case ContentAlignment.TopRight: {
1256 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1257 text_rectangle.X=client_rectangle.X;
1258 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1263 text_rectangle.X=client_rectangle.X;
1264 text_rectangle.Width=client_rectangle.Width;
1267 /* Set the horizontal alignment of our text */
1268 switch(checkbox.text_alignment) {
1269 case ContentAlignment.BottomLeft:
1270 case ContentAlignment.MiddleLeft:
1271 case ContentAlignment.TopLeft: {
1272 text_format.Alignment=StringAlignment.Near;
1276 case ContentAlignment.BottomCenter:
1277 case ContentAlignment.MiddleCenter:
1278 case ContentAlignment.TopCenter: {
1279 text_format.Alignment=StringAlignment.Center;
1283 case ContentAlignment.BottomRight:
1284 case ContentAlignment.MiddleRight:
1285 case ContentAlignment.TopRight: {
1286 text_format.Alignment=StringAlignment.Far;
1291 /* Set the vertical alignment of our text */
1292 switch(checkbox.text_alignment) {
1293 case ContentAlignment.TopLeft:
1294 case ContentAlignment.TopCenter:
1295 case ContentAlignment.TopRight: {
1296 text_format.LineAlignment=StringAlignment.Near;
1300 case ContentAlignment.BottomLeft:
1301 case ContentAlignment.BottomCenter:
1302 case ContentAlignment.BottomRight: {
1303 text_format.LineAlignment=StringAlignment.Far;
1307 case ContentAlignment.MiddleLeft:
1308 case ContentAlignment.MiddleCenter:
1309 case ContentAlignment.MiddleRight: {
1310 text_format.LineAlignment=StringAlignment.Center;
1315 ButtonState state = ButtonState.Normal;
1316 if (checkbox.FlatStyle == FlatStyle.Flat) {
1317 state |= ButtonState.Flat;
1320 if (checkbox.Checked) {
1321 state |= ButtonState.Checked;
1324 if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) {
1325 state |= ButtonState.Checked;
1326 state |= ButtonState.Pushed;
1329 // finally make sure the pushed and inavtive states are rendered
1330 if (!checkbox.Enabled) {
1331 state |= ButtonState.Inactive;
1333 else if (checkbox.is_pressed) {
1334 state |= ButtonState.Pushed;
1339 CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
1341 if ((checkbox.image != null) || (checkbox.image_list != null))
1342 ButtonBase_DrawImage(checkbox, dc);
1344 CheckBox_DrawText(checkbox, text_rectangle, dc, text_format);
1346 if (checkbox.Focused && checkbox.Enabled && checkbox.appearance != Appearance.Button && checkbox.Text != String.Empty && checkbox.ShowFocusCues) {
1347 SizeF text_size = dc.MeasureString (checkbox.Text, checkbox.Font);
1349 Rectangle focus_rect = Rectangle.Empty;
1350 focus_rect.X = text_rectangle.X;
1351 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
1352 focus_rect.Size = text_size.ToSize ();
1353 CheckBox_DrawFocus (checkbox, dc, focus_rect);
1356 text_format.Dispose ();
1359 protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )
1361 Brush brush = checkbox.BackColor.ToArgb () == ColorControl.ToArgb () ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor);
1362 dc.FillRectangle (brush, checkbox.ClientRectangle);
1363 // render as per normal button
1364 if (checkbox.appearance==Appearance.Button) {
1365 ButtonBase_DrawButton (checkbox, dc);
1367 if ((checkbox.Focused) && checkbox.Enabled)
1368 ButtonBase_DrawFocus(checkbox, dc);
1370 // establish if we are rendering a flat style of some sort
1371 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
1372 DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
1374 CPDrawCheckBox (dc, checkbox_rectangle, state);
1379 protected virtual void CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format )
1381 DrawCheckBox_and_RadioButtonText (checkbox, text_rectangle, dc,
1382 text_format, checkbox.Appearance, checkbox.Checked);
1385 protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
1387 DrawInnerFocusRectangle (dc, text_rectangle, checkbox.BackColor);
1390 // renders a checkBox with the Flat and Popup FlatStyle
1391 protected virtual void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox)
1395 Rectangle checkbox_rectangle;
1396 Rectangle fill_rectangle;
1400 // set up our rectangles first
1401 if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) {
1402 // clip one pixel from bottom right for non popup rendered checkboxes
1403 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0));
1404 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 // clip two pixels from bottom right for non popup rendered checkboxes
1407 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0));
1408 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));
1412 // if disabled render in disabled state
1413 if (checkbox.Enabled) {
1414 // process the state of the checkbox
1415 if (checkbox.is_entered || checkbox.Capture) {
1416 // decide on which background color to use
1417 if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) {
1418 graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1419 } else if (checkbox.FlatStyle == FlatStyle.Flat) {
1420 if (!checkbox.is_pressed) {
1421 graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1423 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1425 // use regular window background color
1426 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1429 // render the outer border
1430 if (checkbox.FlatStyle == FlatStyle.Flat) {
1431 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1433 // draw sunken effect
1434 CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, checkbox.BackColor);
1437 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1439 if (checkbox.FlatStyle == FlatStyle.Flat) {
1440 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1442 // draw the outer border
1443 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ControlPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid);
1447 if (checkbox.FlatStyle == FlatStyle.Popup) {
1448 graphics.FillRectangle(SystemBrushes.Control, fill_rectangle);
1451 // draw disabled state,
1452 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid);
1455 if (checkbox.Checked) {
1456 /* Need to draw a check-mark */
1458 /* Make sure we've got at least a line width of 1 */
1459 lineWidth = Math.Max(3, fill_rectangle.Width/3);
1460 Scale=Math.Max(1, fill_rectangle.Width/9);
1462 // flat style check box is rendered inside a rectangle shifted down by one
1463 rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height);
1464 if (checkbox.Enabled) {
1465 pen=ResPool.GetPen(checkbox.ForeColor);
1467 pen=SystemPens.ControlDark;
1470 for (int i=0; i<lineWidth; i++) {
1471 graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
1472 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);
1477 private void DrawCheckBox_and_RadioButtonText (ButtonBase button_base, Rectangle text_rectangle, Graphics dc,
1478 StringFormat text_format, Appearance appearance, bool ischecked)
1480 // offset the text if it's pressed and a button
1481 if (appearance == Appearance.Button) {
1482 if (ischecked || (button_base.Capture && button_base.FlatStyle != FlatStyle.Flat)) {
1483 text_rectangle.X ++;
1484 text_rectangle.Y ++;
1487 text_rectangle.Inflate (-4, -4);
1490 /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
1492 // Windows seems to not wrap text in certain situations, this matches as close as I could get it
1493 if ((float)(button_base.Font.Height * 1.5f) > text_rectangle.Height) {
1494 text_format.FormatFlags |= StringFormatFlags.NoWrap;
1496 if (button_base.Enabled) {
1497 dc.DrawString (button_base.Text, button_base.Font, ResPool.GetSolidBrush (button_base.ForeColor), text_rectangle, text_format);
1498 } else if (button_base.FlatStyle == FlatStyle.Flat || button_base.FlatStyle == FlatStyle.Popup) {
1499 dc.DrawString (button_base.Text, button_base.Font, SystemBrushes.ControlDarkDark, text_rectangle, text_format);
1501 CPDrawStringDisabled (dc, button_base.Text, button_base.Font, button_base.BackColor, text_rectangle, text_format);
1504 #endregion // CheckBox
1506 #region CheckedListBox
1508 public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e)
1510 Color back_color, fore_color;
1511 Rectangle item_rect = e.Bounds;
1516 if ((e.State & DrawItemState.Checked) == DrawItemState.Checked) {
1517 state = ButtonState.Checked;
1518 if ((e.State & DrawItemState.Inactive) == DrawItemState.Inactive)
1519 state |= ButtonState.Inactive;
1521 state = ButtonState.Normal;
1523 if (ctrl.ThreeDCheckBoxes == false)
1524 state |= ButtonState.Flat;
1526 Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, CheckSize, CheckSize);
1527 ControlPaint.DrawCheckBox (e.Graphics,
1528 item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
1529 checkbox_rect.Width, checkbox_rect.Height,
1532 item_rect.X += checkbox_rect.Right;
1533 item_rect.Width -= checkbox_rect.Right;
1536 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1537 back_color = ColorHighlight;
1538 fore_color = ColorHighlightText;
1541 back_color = e.BackColor;
1542 fore_color = e.ForeColor;
1545 e.Graphics.FillRectangle (ResPool.GetSolidBrush
1546 (back_color), item_rect);
1548 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1549 ResPool.GetSolidBrush (fore_color),
1550 item_rect, ctrl.StringFormat);
1552 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1553 CPDrawFocusRectangle (e.Graphics, item_rect,
1554 fore_color, back_color);
1558 #endregion // CheckedListBox
1561 public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e)
1563 Color back_color, fore_color;
1564 Rectangle text_draw = e.Bounds;
1565 StringFormat string_format = new StringFormat ();
1566 string_format.FormatFlags = StringFormatFlags.LineLimit;
1568 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1569 back_color = ColorHighlight;
1570 fore_color = ColorHighlightText;
1573 back_color = e.BackColor;
1574 fore_color = e.ForeColor;
1578 fore_color = ColorInactiveCaptionText;
1580 e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
1582 if (e.Index != -1) {
1583 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1584 ResPool.GetSolidBrush (fore_color),
1585 text_draw, string_format);
1588 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1589 CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
1592 string_format.Dispose ();
1595 public override void DrawFlatStyleComboButton (Graphics graphics, Rectangle rectangle, ButtonState state)
1597 Point[] arrow = new Point[3];
1607 rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
1608 centerX=rect.Left+rect.Width/2;
1609 centerY=rect.Top+rect.Height/2;
1610 shiftX=Math.Max(1, rect.Width/8);
1611 shiftY=Math.Max(1, rect.Height/8);
1613 if ((state & ButtonState.Pushed)!=0) {
1620 P1=new Point(rect.Left + 1, centerY);
1621 P2=new Point(rect.Right - 1, centerY);
1622 P3=new Point(centerX, rect.Bottom - 1);
1628 /* Draw the arrow */
1629 if ((state & ButtonState.Inactive)!=0) {
1630 /* Move away from the shadow */
1631 arrow[0].X += 1; arrow[0].Y += 1;
1632 arrow[1].X += 1; arrow[1].Y += 1;
1633 arrow[2].X += 1; arrow[2].Y += 1;
1635 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
1641 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
1643 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
1646 public override void ComboBoxDrawNormalDropDownButton (ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state)
1648 CPDrawComboButton (g, area, state);
1650 public override bool ComboBoxNormalDropDownButtonHasTransparentBackground (ComboBox comboBox, ButtonState state)
1654 public override bool ComboBoxDropDownButtonHasHotElementStyle (ComboBox comboBox)
1658 public override void ComboBoxDrawBackground (ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style)
1660 if (!comboBox.Enabled)
1661 g.FillRectangle (ResPool.GetSolidBrush (ColorControl), comboBox.ClientRectangle);
1663 if (comboBox.DropDownStyle == ComboBoxStyle.Simple)
1664 g.FillRectangle (ResPool.GetSolidBrush (comboBox.Parent.BackColor), comboBox.ClientRectangle);
1666 if (style == FlatStyle.Popup && (comboBox.Entered || comboBox.Focused)) {
1667 Rectangle area = comboBox.TextArea;
1670 g.DrawRectangle (ResPool.GetPen (SystemColors.ControlDark), area);
1671 g.DrawLine (ResPool.GetPen (SystemColors.ControlDark), comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Top, comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Bottom);
1673 bool is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup;
1674 if (!is_flat && clippingArea.IntersectsWith (comboBox.TextArea))
1675 ControlPaint.DrawBorder3D (g, comboBox.TextArea, Border3DStyle.Sunken);
1677 public override bool CombBoxBackgroundHasHotElementStyle (ComboBox comboBox)
1684 public override int DataGridPreferredColumnWidth { get { return 75;} }
1685 public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} }
1686 public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} }
1687 public override Color DataGridAlternatingBackColor { get { return ColorWindow;} }
1688 public override Color DataGridBackColor { get { return ColorWindow;} }
1689 public override Color DataGridBackgroundColor { get { return ColorAppWorkspace;} }
1690 public override Color DataGridCaptionBackColor { get { return ColorActiveCaption;} }
1691 public override Color DataGridCaptionForeColor { get { return ColorActiveCaptionText;} }
1692 public override Color DataGridGridLineColor { get { return ColorControl;} }
1693 public override Color DataGridHeaderBackColor { get { return ColorControl;} }
1694 public override Color DataGridHeaderForeColor { get { return ColorControlText;} }
1695 public override Color DataGridLinkColor { get { return ColorHotTrack;} }
1696 public override Color DataGridLinkHoverColor { get { return ColorHotTrack;} }
1697 public override Color DataGridParentRowsBackColor { get { return ColorControl;} }
1698 public override Color DataGridParentRowsForeColor { get { return ColorWindowText;} }
1699 public override Color DataGridSelectionBackColor { get { return ColorActiveCaption;} }
1700 public override Color DataGridSelectionForeColor { get { return ColorActiveCaptionText;} }
1702 public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
1704 DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
1705 DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid);
1706 DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid);
1707 DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid);
1709 // Paint scrollBar corner
1710 if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) {
1712 Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.VScrollBar.Width,
1713 grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.HScrollBar.Height,
1714 grid.VScrollBar.Width, grid.HScrollBar.Height);
1716 if (pe.ClipRectangle.IntersectsWith (corner)) {
1717 pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1723 public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
1725 Rectangle bounds = clip;
1726 bounds.Intersect (grid.caption_area);
1729 g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor), bounds);
1732 g.DrawLine (ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor),
1733 bounds.X, bounds.Y + bounds.Height -1,
1734 bounds.X + bounds.Width, bounds.Y + bounds.Height -1);
1737 if (grid.CaptionText != String.Empty) {
1738 Rectangle text_rect = grid.caption_area;
1739 text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2;
1740 text_rect.Height = grid.CaptionFont.Height;
1742 g.DrawString (grid.CaptionText, grid.CaptionFont,
1743 ResPool.GetSolidBrush (grid.CaptionForeColor),
1748 if (bounds.IntersectsWith (grid.back_button_rect)) {
1749 g.DrawImage (grid.back_button_image, grid.back_button_rect);
1750 if (grid.back_button_mouseover) {
1751 CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1756 if (bounds.IntersectsWith (grid.parent_rows_button_rect)) {
1757 g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
1758 if (grid.parent_rows_button_mouseover) {
1759 CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1764 public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
1766 if (!grid.CurrentTableStyle.ColumnHeadersVisible)
1769 Rectangle columns_area = grid.column_headers_area;
1771 // Paint corner shared between row and column header
1772 if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1773 Rectangle rect_bloc = grid.column_headers_area;
1774 rect_bloc.Width = grid.RowHeaderWidth;
1775 if (clip.IntersectsWith (rect_bloc)) {
1777 g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
1779 CPDrawBorder3D (g, rect_bloc, Border3DStyle.RaisedInner,
1780 Border3DSide.Left | Border3DSide.Right |
1781 Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Middle,
1782 grid.CurrentTableStyle.CurrentHeaderBackColor);
1785 columns_area.X += grid.RowHeaderWidth;
1786 columns_area.Width -= grid.RowHeaderWidth;
1789 // Set column painting
1790 Rectangle rect_columnhdr = new Rectangle ();
1792 Region current_clip;
1793 Region prev_clip = g.Clip;
1794 rect_columnhdr.Y = columns_area.Y;
1795 rect_columnhdr.Height = columns_area.Height;
1797 int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
1798 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
1799 if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
1802 col_pixel = grid.GetColumnStartingPixel (column);
1803 rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
1804 rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
1806 if (clip.IntersectsWith (rect_columnhdr) == false)
1809 current_clip = new Region (rect_columnhdr);
1810 current_clip.Intersect (columns_area);
1811 current_clip.Intersect (prev_clip);
1812 g.Clip = current_clip;
1814 DataGridPaintColumnHeader (g, rect_columnhdr, grid, column);
1816 current_clip.Dispose ();
1821 Rectangle not_usedarea = grid.column_headers_area;
1822 not_usedarea.X = (column_cnt == 0) ? grid.RowHeaderWidth : rect_columnhdr.X + rect_columnhdr.Width;
1823 not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - not_usedarea.X;
1824 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
1827 public override void DataGridPaintColumnHeader (Graphics g, Rectangle bounds, DataGrid grid, int col)
1830 g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.HeaderBackColor), bounds);
1833 if (!grid.FlatMode) {
1834 g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1835 bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1838 g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1839 bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height);
1841 g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1842 bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 3);
1845 if (col == (grid.VisibleColumnCount -1)) {
1846 g.DrawLine (ResPool.GetPen (ColorControlDark),
1847 bounds.X + bounds.Width - 1, bounds.Y,
1848 bounds.X + bounds.Width - 1, bounds.Y + bounds.Height);
1850 g.DrawLine (ResPool.GetPen (ColorControlDark),
1851 bounds.X + bounds.Width - 1, bounds.Y + 2,
1852 bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 3);
1855 g.DrawLine (ResPool.GetPen (ColorControlDark),
1856 bounds.X, bounds.Y + bounds.Height - 1,
1857 bounds.X + bounds.Width, bounds.Y + bounds.Height - 1);
1863 DataGridColumnStyle style = grid.CurrentTableStyle.GridColumnStyles[col];
1865 if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No)
1869 StringFormat format = new StringFormat ();
1870 format.FormatFlags |= StringFormatFlags.NoWrap;
1871 format.LineAlignment = StringAlignment.Center;
1872 format.Trimming = StringTrimming.Character;
1874 g.DrawString (style.HeaderText, grid.CurrentTableStyle.HeaderFont,
1875 ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1879 if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) {
1880 Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2));
1882 if (style.ArrowDrawingMode == DataGridColumnStyle.ArrowDrawing.Ascending) {
1883 g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y);
1884 g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6);
1885 g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y);
1887 g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6);
1888 g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y);
1889 g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6);
1894 public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
1896 Rectangle rect_row = new Rectangle ();
1898 rect_row.X = grid.ParentRowsArea.X;
1899 rect_row.Width = grid.ParentRowsArea.Width;
1900 rect_row.Height = (grid.CaptionFont.Height + 3);
1902 object[] parentRows = grid.data_source_stack.ToArray();
1904 Region current_clip;
1905 Region prev_clip = g.Clip;
1906 for (int row = 0; row < parentRows.Length; row++) {
1907 rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
1909 if (clip.IntersectsWith (rect_row) == false)
1912 current_clip = new Region (rect_row);
1913 current_clip.Intersect (prev_clip);
1914 g.Clip = current_clip;
1916 DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
1918 current_clip.Dispose ();
1924 public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
1927 g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1930 Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
1931 // set up some standard string formating variables
1932 StringFormat text_format = new StringFormat();
1933 text_format.LineAlignment = StringAlignment.Center;
1934 text_format.Alignment = StringAlignment.Near;
1936 string table_name = "";
1937 if (row.view is DataRowView)
1938 table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": ";
1941 Rectangle text_rect;
1944 text_size = g.MeasureString (table_name, bold_font).ToSize();
1945 text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
1947 g.DrawString (table_name,
1948 bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1950 foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
1951 if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
1954 text_rect.X += text_rect.Size.Width + 5;
1956 string text = String.Format ("{0}: {1}",
1958 pd.GetValue (row.view));
1960 text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
1961 text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
1964 grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1968 if (!grid.FlatMode) {
1969 CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner,
1970 Border3DSide.Left | Border3DSide.Right |
1971 Border3DSide.Top | Border3DSide.Bottom);
1975 public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid)
1977 Point[] arrow = new Point[3];
1979 int centerX, centerY, shiftX;
1982 rect = new Rectangle (bounds.X + bounds.Width /4,
1983 bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2);
1985 centerX = rect.Left + rect.Width / 2;
1986 centerY = rect.Top + rect.Height / 2;
1987 shiftX = Math.Max (1, rect.Width / 8);
1990 P1 = new Point (centerX, rect.Top - 1);
1991 P2 = new Point (centerX, rect.Bottom);
1992 P3 = new Point (rect.Right, centerY);
1997 g.FillPolygon (ResPool.GetSolidBrush
1998 (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding);
2001 public override void DataGridPaintRowHeaderStar (Graphics g, Rectangle bounds, DataGrid grid)
2003 int x = bounds.X + 4;
2004 int y = bounds.Y + 3;
2005 Pen pen = ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor);
2007 g.DrawLine (pen, x + 4, y, x + 4, y + 8);
2008 g.DrawLine (pen, x, y + 4, x + 8, y + 4);
2009 g.DrawLine (pen, x + 1, y + 1, x + 7, y + 7);
2010 g.DrawLine (pen, x + 7, y + 1, x + 1, y + 7);
2013 public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
2015 bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1;
2016 bool is_current_row = row == grid.CurrentCell.RowNumber;
2019 g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), bounds);
2022 if (is_current_row) {
2023 if (grid.IsChanging) {
2024 g.DrawString ("...", grid.Font,
2025 ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
2028 Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
2029 DataGridPaintRowHeaderArrow (g, rect, grid);
2032 else if (is_add_row) {
2033 DataGridPaintRowHeaderStar (g, bounds, grid);
2036 if (!grid.FlatMode && !is_add_row) {
2037 CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner,
2038 Border3DSide.Left | Border3DSide.Right |
2039 Border3DSide.Top | Border3DSide.Bottom);
2043 public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)
2045 Rectangle rect_row = new Rectangle ();
2046 Rectangle not_usedarea = new Rectangle ();
2048 int rowcnt = grid.VisibleRowCount;
2050 bool showing_add_row = false;
2052 if (grid.RowsCount < grid.DataGridRows.Length) {
2053 /* the table has an add row */
2055 if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) {
2056 showing_add_row = true;
2060 rect_row.Width = cells.Width + grid.RowHeadersArea.Width;
2061 for (int r = 0; r < rowcnt; r++) {
2062 int row = grid.FirstVisibleRow + r;
2063 if (row == grid.DataGridRows.Length - 1)
2064 rect_row.Height = grid.DataGridRows[row].Height;
2066 rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset;
2067 rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset;
2068 if (clip.IntersectsWith (rect_row)) {
2069 if (grid.CurrentTableStyle.HasRelations
2070 && !(showing_add_row && row == grid.DataGridRows.Length - 1))
2071 DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
2073 DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid);
2078 // the rowcnt == 0 check is needed because
2079 // otherwise we'd draw over the caption on
2080 // empty datasources (since rect_row would be
2083 not_usedarea.Y = cells.Y;
2085 not_usedarea.Y = rect_row.Y + rect_row.Height;
2086 not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
2087 not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
2089 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
2092 public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2093 Rectangle clip, DataGrid grid)
2095 Rectangle rect_header;
2096 Rectangle icon_bounds = new Rectangle ();
2097 Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
2099 /* paint the header if it's visible and intersects the clip */
2100 if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2101 rect_header = row_rect;
2102 rect_header.Width = grid.RowHeaderWidth;
2103 row_rect.X += grid.RowHeaderWidth;
2104 if (clip.IntersectsWith (rect_header)) {
2105 DataGridPaintRowHeader (g, rect_header, row, grid);
2108 icon_bounds = rect_header;
2109 icon_bounds.X += icon_bounds.Width / 2;
2111 icon_bounds.Width = 8;
2112 icon_bounds.Height = 8;
2114 g.DrawRectangle (pen, icon_bounds);
2116 /* the - part of the icon */
2118 icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
2119 icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
2121 if (!grid.IsExpanded (row)) {
2122 /* the | part of the icon */
2124 icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
2125 icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
2129 Rectangle nested_rect = row_rect;
2131 if (grid.DataGridRows[row].IsExpanded)
2132 nested_rect.Height -= grid.DataGridRows[row].RelationHeight;
2134 DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
2136 if (grid.DataGridRows[row].IsExpanded) {
2137 // XXX we should create this in the
2138 // datagrid and cache it for use by
2139 // the theme instead of doing it each
2140 // time through here
2141 string[] relations = grid.CurrentTableStyle.Relations;
2142 StringBuilder relation_builder = new StringBuilder ("");
2144 for (int i = 0; i < relations.Length; i ++) {
2146 relation_builder.Append ("\n");
2148 relation_builder.Append (relations[i]);
2150 string relation_text = relation_builder.ToString ();
2152 StringFormat string_format = new StringFormat ();
2153 string_format.FormatFlags |= StringFormatFlags.NoWrap;
2156 //Region prev_clip = g.Clip;
2157 //Region current_clip;
2158 Rectangle rect_cell = row_rect;
2160 rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
2161 rect_cell.Y += nested_rect.Height;
2162 rect_cell.Height = grid.DataGridRows[row].RelationHeight;
2164 rect_cell.Width = 0;
2165 int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2166 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2167 if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2169 rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
2171 rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width);
2173 g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
2177 /* draw the line leading from the +/- to the relation area */
2178 Rectangle outline = grid.DataGridRows[row].relation_area;
2179 outline.Y = rect_cell.Y;
2183 icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
2184 icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
2187 icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
2188 outline.X, outline.Y + outline.Height / 2);
2190 g.DrawRectangle (pen, outline);
2192 g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
2193 outline, string_format);
2195 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2196 Rectangle not_usedarea = new Rectangle ();
2197 not_usedarea.X = rect_cell.X + rect_cell.Width;
2198 not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2199 not_usedarea.Y = row_rect.Y;
2200 not_usedarea.Height = row_rect.Height;
2201 if (clip.IntersectsWith (not_usedarea))
2202 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2208 public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2209 Rectangle clip, DataGrid grid)
2211 Rectangle rect_cell = new Rectangle ();
2213 Color backcolor, forecolor;
2214 Brush backBrush, foreBrush;
2215 Rectangle not_usedarea = Rectangle.Empty;
2217 rect_cell.Y = row_rect.Y;
2218 rect_cell.Height = row_rect.Height;
2220 if (grid.IsSelected (row)) {
2221 backcolor = grid.SelectionBackColor;
2222 forecolor = grid.SelectionForeColor;
2225 backcolor = grid.BackColor;
2227 backcolor = grid.AlternatingBackColor;
2230 forecolor = grid.ForeColor;
2234 backBrush = ResPool.GetSolidBrush (backcolor);
2235 foreBrush = ResPool.GetSolidBrush (forecolor);
2237 // PaintCells at row, column
2238 int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2239 DataGridCell current_cell = grid.CurrentCell;
2241 if (column_cnt > 0) {
2242 Region prev_clip = g.Clip;
2243 Region current_clip;
2245 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2246 if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2249 col_pixel = grid.GetColumnStartingPixel (column);
2251 rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
2252 rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
2254 if (clip.IntersectsWith (rect_cell)) {
2255 current_clip = new Region (rect_cell);
2256 current_clip.Intersect (row_rect);
2257 current_clip.Intersect (prev_clip);
2258 g.Clip = current_clip;
2260 Brush colBackBrush = backBrush;
2261 Brush colForeBrush = foreBrush;
2263 // If we are in the precise cell we are editing, then use the normal colors
2264 // even if we are selected.
2265 if (grid.is_editing && column == current_cell.ColumnNumber && row == current_cell.RowNumber) {
2266 colBackBrush = ResPool.GetSolidBrush (grid.BackColor);
2267 colForeBrush = ResPool.GetSolidBrush (grid.ForeColor);
2271 grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell,
2275 grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
2278 grid.RightToLeft == RightToLeft.Yes);
2281 current_clip.Dispose ();
2287 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2288 not_usedarea.X = rect_cell.X + rect_cell.Width;
2289 not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2290 not_usedarea.Y = row_rect.Y;
2291 not_usedarea.Height = row_rect.Height;
2295 not_usedarea = row_rect;
2298 if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea))
2299 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2303 public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2304 Rectangle clip, DataGrid grid)
2306 /* paint the header if it's visible and intersects the clip */
2307 if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2308 Rectangle rect_header = row_rect;
2309 rect_header.Width = grid.RowHeaderWidth;
2310 row_rect.X += grid.RowHeaderWidth;
2311 if (clip.IntersectsWith (rect_header)) {
2312 DataGridPaintRowHeader (g, rect_header, row, grid);
2316 DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
2319 #endregion // Datagrid
2321 #region DataGridView
2322 #region DataGridViewHeaderCell
2323 #region DataGridViewRowHeaderCell
2324 public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2329 public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell)
2334 public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2340 #region DataGridViewColumnHeaderCell
2341 public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2346 public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2352 public override bool DataGridViewHeaderCellHasPressedStyle (DataGridView dataGridView)
2357 public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView)
2364 #region DateTimePicker
2365 protected virtual void DateTimePickerDrawBorder (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2367 this.CPDrawBorder3D (g, dateTimePicker.ClientRectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dateTimePicker.BackColor);
2370 protected virtual void DateTimePickerDrawDropDownButton (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2372 ButtonState state = dateTimePicker.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
2373 g.FillRectangle (ResPool.GetSolidBrush (ColorControl), dateTimePicker.drop_down_arrow_rect);
2374 this.CPDrawComboButton (
2376 dateTimePicker.drop_down_arrow_rect,
2380 public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp)
2383 if (!clip_rectangle.IntersectsWith (dtp.ClientRectangle))
2386 // draw the outer border
2387 Rectangle button_bounds = dtp.ClientRectangle;
2388 DateTimePickerDrawBorder (dtp, dc, clip_rectangle);
2390 // deflate by the border width
2391 if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
2392 button_bounds.Inflate (-2,-2);
2393 if (!dtp.ShowUpDown) {
2394 DateTimePickerDrawDropDownButton (dtp, dc, clip_rectangle);
2396 ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal;
2397 ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal;
2398 Rectangle up_bounds = dtp.drop_down_arrow_rect;
2399 Rectangle down_bounds = dtp.drop_down_arrow_rect;
2401 up_bounds.Height = up_bounds.Height / 2;
2402 down_bounds.Y = up_bounds.Height;
2403 down_bounds.Height = dtp.Height - up_bounds.Height;
2404 if (down_bounds.Height > up_bounds.Height)
2407 down_bounds.Height -= 1;
2410 up_bounds.Inflate (-1, -1);
2411 down_bounds.Inflate (-1, -1);
2413 ControlPaint.DrawScrollButton (dc, up_bounds, ScrollButton.Up, up_state);
2414 ControlPaint.DrawScrollButton (dc, down_bounds, ScrollButton.Down, down_state);
2418 // render the date part
2419 if (!clip_rectangle.IntersectsWith (dtp.date_area_rect))
2422 // fill the background
2423 dc.FillRectangle (SystemBrushes.Window, dtp.date_area_rect);
2425 // Update date_area_rect if we are drawing the checkbox
2426 Rectangle date_area_rect = dtp.date_area_rect;
2427 if (dtp.ShowCheckBox) {
2428 Rectangle check_box_rect = dtp.CheckBoxRect;
2429 date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2;
2430 date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2;
2432 ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal;
2433 CPDrawCheckBox(dc, check_box_rect, bs);
2435 if (dtp.is_checkbox_selected)
2436 CPDrawFocusRectangle (dc, check_box_rect, dtp.foreground_color, dtp.background_color);
2439 // render each text part
2440 using (StringFormat text_format = StringFormat.GenericTypographic)
2442 text_format.LineAlignment = StringAlignment.Near;
2443 text_format.Alignment = StringAlignment.Near;
2444 text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
2445 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2447 // Calculate the rectangles for each part
2448 if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty)
2451 for (int i = 0; i < dtp.part_data.Length; i++)
2453 DateTimePicker.PartData fd = dtp.part_data[i];
2454 RectangleF text_rect = new RectangleF();
2455 string text = fd.GetText(dtp.Value);
2456 text_rect.Size = gr.MeasureString (text, dtp.Font, 250, text_format);
2458 text_rect.Width = Math.Max (dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width);
2461 text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right;
2463 text_rect.X = date_area_rect.X;
2466 text_rect.Inflate (1, 0);
2467 fd.drawing_rectangle = text_rect;
2471 // draw the text part
2472 Brush text_brush = ResPool.GetSolidBrush (dtp.ShowCheckBox && dtp.Checked == false ?
2473 SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false
2474 RectangleF clip_rectangleF = clip_rectangle;
2476 for (int i = 0; i < dtp.part_data.Length; i++)
2478 DateTimePicker.PartData fd = dtp.part_data [i];
2481 if (!clip_rectangleF.IntersectsWith (fd.drawing_rectangle))
2484 text = dtp.editing_part_index == i ? dtp.editing_text : fd.GetText (dtp.Value);
2486 PointF text_position = new PointF ();
2488 RectangleF text_rect;
2490 text_size = dc.MeasureString (text, dtp.Font, 250, text_format);
2491 text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2;
2492 text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2;
2493 text_rect = new RectangleF (text_position, text_size);
2494 text_rect = RectangleF.Intersect (text_rect, date_area_rect);
2496 if (text_rect.IsEmpty)
2499 if (text_rect.Right >= date_area_rect.Right)
2500 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2502 text_format.FormatFlags |= StringFormatFlags.NoClip;
2505 dc.FillRectangle (SystemBrushes.Highlight, text_rect);
2506 dc.DrawString (text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format);
2509 dc.DrawString (text, dtp.Font, text_brush, text_rect, text_format);
2512 if (fd.drawing_rectangle.Right > date_area_rect.Right)
2513 break; // the next part would be not be visible, so don't draw anything more.
2518 public override bool DateTimePickerBorderHasHotElementStyle {
2524 public override Rectangle DateTimePickerGetDropDownButtonArea (DateTimePicker dateTimePicker)
2526 Rectangle rect = dateTimePicker.ClientRectangle;
2527 rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2;
2528 if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) {
2529 rect.Width = SystemInformation.VerticalScrollBarWidth;
2531 rect.Width = Math.Max (rect.Width - 2, 0);
2534 rect.Inflate (0, -2);
2538 public override Rectangle DateTimePickerGetDateArea (DateTimePicker dateTimePicker)
2540 Rectangle rect = dateTimePicker.ClientRectangle;
2541 if (dateTimePicker.ShowUpDown) {
2542 // set the space to the left of the up/down button
2543 if (rect.Width > (DateTimePicker.up_down_width + 4)) {
2544 rect.Width -= (DateTimePicker.up_down_width + 4);
2549 // set the space to the left of the up/down button
2550 // TODO make this use up down button
2551 if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) {
2552 rect.Width -= SystemInformation.VerticalScrollBarWidth;
2558 rect.Inflate (-2, -2);
2561 public override bool DateTimePickerDropDownButtonHasHotElementStyle {
2566 #endregion // DateTimePicker
2569 public override void DrawGroupBox (Graphics dc, Rectangle area, GroupBox box) {
2570 StringFormat text_format;
2575 dc.FillRectangle (GetControlBackBrush (box.BackColor), box.ClientRectangle);
2577 text_format = new StringFormat();
2578 text_format.HotkeyPrefix = HotkeyPrefix.Show;
2580 size = dc.MeasureString (box.Text, box.Font);
2583 if (size.Width > 0) {
2584 width = ((int) size.Width) + 7;
2586 if (width > box.Width - 16)
2587 width = box.Width - 16;
2590 y = box.Font.Height / 2;
2592 // Clip the are that the text will be in
2593 Region prev_clip = dc.Clip;
2594 dc.SetClip (new Rectangle (10, 0, width, box.Font.Height), CombineMode.Exclude);
2596 CPDrawBorder3D (dc, new Rectangle (0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor);
2597 dc.Clip = prev_clip;
2600 if (box.Text.Length != 0) {
2602 dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format);
2604 CPDrawStringDisabled (dc, box.Text, box.Font, box.BackColor,
2605 new RectangleF (10, 0, width, box.Font.Height), text_format);
2609 text_format.Dispose ();
2612 public override Size GroupBoxDefaultSize {
2614 return new Size (200,100);
2620 public override Size HScrollBarDefaultSize {
2622 return new Size (80, this.ScrollBarButtonSize);
2626 #endregion // HScrollBar
2630 public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
2632 Color back_color, fore_color;
2634 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
2635 back_color = ColorHighlight;
2636 fore_color = ColorHighlightText;
2638 back_color = e.BackColor;
2639 fore_color = e.ForeColor;
2642 e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
2644 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
2645 ResPool.GetSolidBrush (fore_color),
2646 e.Bounds, ctrl.StringFormat);
2648 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
2649 CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
2656 public override void DrawListViewItems (Graphics dc, Rectangle clip, ListView control)
2658 bool details = control.View == View.Details;
2659 int first = control.FirstVisibleIndex;
2660 int lastvisibleindex = control.LastVisibleIndex;
2662 if (control.VirtualMode)
2663 control.OnCacheVirtualItems (new CacheVirtualItemsEventArgs (first, lastvisibleindex));
2665 for (int i = first; i <= lastvisibleindex; i++) {
2666 ListViewItem item = control.GetItemAtDisplayIndex (i);
2667 if (clip.IntersectsWith (item.Bounds)) {
2668 bool owner_draw = false;
2669 if (control.OwnerDraw)
2670 owner_draw = DrawListViewItemOwnerDraw (dc, item, i);
2673 DrawListViewItem (dc, control, item);
2674 if (control.View == View.Details)
2675 DrawListViewSubItems (dc, control, item);
2680 if (control.UsingGroups) {
2681 // Use InternalCount instead of Count to take into account Default Group as needed
2682 for (int i = 0; i < control.Groups.InternalCount; i++) {
2683 ListViewGroup group = control.Groups.GetInternalGroup (i);
2684 if (group.ItemCount > 0 && clip.IntersectsWith (group.HeaderBounds))
2685 DrawListViewGroupHeader (dc, control, group);
2689 ListViewInsertionMark insertion_mark = control.InsertionMark;
2690 int insertion_mark_index = insertion_mark.Index;
2691 if (Application.VisualStylesEnabled && insertion_mark.Bounds != Rectangle.Empty &&
2692 (control.View != View.Details && control.View != View.List) &&
2693 insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) {
2695 Brush brush = ResPool.GetSolidBrush (insertion_mark.Color);
2696 dc.FillRectangle (brush, insertion_mark.Line);
2697 dc.FillPolygon (brush, insertion_mark.TopTriangle);
2698 dc.FillPolygon (brush, insertion_mark.BottomTriangle);
2701 // draw the gridlines
2702 if (details && control.GridLines && !control.UsingGroups) {
2703 Size control_size = control.ClientSize;
2704 int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
2705 0 : control.header_control.Height;
2707 // draw vertical gridlines
2708 foreach (ColumnHeader col in control.Columns) {
2709 int column_right = col.Rect.Right - control.h_marker;
2710 dc.DrawLine (SystemPens.Control,
2712 column_right, control_size.Height);
2715 // draw horizontal gridlines
2716 int item_height = control.ItemSize.Height;
2717 if (item_height == 0)
2718 item_height = control.Font.Height + 2;
2720 int y = top + item_height - (control.v_marker % item_height); // scroll bar offset
2721 while (y < control_size.Height) {
2722 dc.DrawLine (SystemPens.Control, 0, y, control_size.Width, y);
2727 // Draw corner between the two scrollbars
2728 if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) {
2729 Rectangle rect = new Rectangle ();
2730 rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
2731 rect.Width = control.v_scroll.Width;
2732 rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height;
2733 rect.Height = control.h_scroll.Height;
2734 dc.FillRectangle (SystemBrushes.Control, rect);
2737 Rectangle box_select_rect = control.item_control.BoxSelectRectangle;
2738 if (!box_select_rect.Size.IsEmpty)
2739 dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect);
2743 public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
2745 bool details = (control.View == View.Details);
2747 // border is drawn directly in the Paint method
2748 if (details && control.HeaderStyle != ColumnHeaderStyle.None) {
2749 dc.FillRectangle (SystemBrushes.Control,
2750 0, 0, control.TotalWidth, control.Font.Height + 5);
2751 if (control.Columns.Count > 0) {
2752 foreach (ColumnHeader col in control.Columns) {
2753 Rectangle rect = col.Rect;
2754 rect.X -= control.h_marker;
2756 bool owner_draw = false;
2757 if (control.OwnerDraw)
2758 owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect);
2762 ListViewDrawColumnHeaderBackground (control, col, dc, rect, clip);
2765 if (rect.Width <= 0)
2769 if (control.SmallImageList == null)
2772 image_index = col.ImageKey == String.Empty ? col.ImageIndex : control.SmallImageList.Images.IndexOfKey (col.ImageKey);
2774 if (image_index > -1 && image_index < control.SmallImageList.Images.Count) {
2775 int image_width = control.SmallImageList.ImageSize.Width + 5;
2776 int text_width = (int)dc.MeasureString (col.Text, control.Font).Width;
2777 int x_origin = rect.X;
2778 int y_origin = rect.Y + ((rect.Height - control.SmallImageList.ImageSize.Height) / 2);
2780 switch (col.TextAlign) {
2781 case HorizontalAlignment.Left:
2783 case HorizontalAlignment.Right:
2784 x_origin = rect.Right - (text_width + image_width);
2786 case HorizontalAlignment.Center:
2787 x_origin = (rect.Width - (text_width + image_width)) / 2 + rect.X;
2791 if (x_origin < rect.X)
2794 control.SmallImageList.Draw (dc, new Point (x_origin, y_origin), image_index);
2795 rect.X += image_width;
2796 rect.Width -= image_width;
2799 dc.DrawString (col.Text, control.Font, SystemBrushes.ControlText, rect, col.Format);
2801 int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker;
2802 if (right < control.Right) {
2803 Rectangle rect = control.Columns [0].Rect;
2805 rect.Width = control.Right - right;
2806 ListViewDrawUnusedHeaderBackground (control, dc, rect, clip);
2812 protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)
2815 if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2816 state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal;
2818 state = ButtonState.Flat;
2819 CPDrawButton (g, area, state);
2822 protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)
2825 if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2826 state = ButtonState.Normal;
2828 state = ButtonState.Flat;
2829 CPDrawButton (g, area, state);
2832 public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x)
2834 Rectangle rect = col.Rect;
2835 rect.X -= view.h_marker;
2836 Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B);
2837 dc.FillRectangle (ResPool.GetSolidBrush (color), rect);
2840 if (rect.Width <= 0)
2842 color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B);
2843 dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format);
2844 dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
2847 protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
2849 ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
2851 state |= ListViewItemStates.Selected;
2853 DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
2854 bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
2855 control.OnDrawColumnHeader (args);
2857 return !args.DrawDefault;
2860 protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
2862 ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
2864 item_state |= ListViewItemStates.Selected;
2866 item_state |= ListViewItemStates.Focused;
2868 DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
2869 item, item.Bounds, index, item_state);
2870 item.ListView.OnDrawItem (args);
2872 if (args.DrawDefault)
2875 if (item.ListView.View == View.Details) {
2876 int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
2878 // Do system drawing for subitems if no owner draw is done
2879 for (int j = 0; j < count; j++) {
2880 if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j)) {
2881 if (j == 0) // The first sub item contains the main item semantics
2882 DrawListViewItem (dc, item.ListView, item);
2884 DrawListViewSubItem (dc, item.ListView, item, j);
2892 protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
2894 Rectangle rect_checkrect = item.CheckRectReal;
2895 Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2896 Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2897 Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);
2899 // Tile view doesn't support CheckBoxes
2900 if (control.CheckBoxes && control.View != View.Tile) {
2901 if (control.StateImageList == null) {
2902 // Make sure we've got at least a line width of 1
2903 int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2904 int scale = Math.Max (1, rect_checkrect.Width / 12);
2906 // set the checkbox background
2907 dc.FillRectangle (SystemBrushes.Window,
2909 // define a rectangle inside the border area
2910 Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2911 rect_checkrect.Y + 2,
2912 rect_checkrect.Width - 4,
2913 rect_checkrect.Height - 4);
2914 Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2915 dc.DrawRectangle (pen, rect);
2917 // Need to draw a check-mark
2919 Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2920 // adjustments to get the check-mark at the right place
2921 rect.X ++; rect.Y ++;
2922 // following logic is taken from DrawFrameControl method
2923 int x_offset = rect.Width / 5;
2924 int y_offset = rect.Height / 3;
2925 for (int i = 0; i < check_wd; i++) {
2926 dc.DrawLine (check_pen, rect.Left + x_offset,
2927 rect.Top + y_offset + i,
2928 rect.Left + x_offset + 2 * scale,
2929 rect.Top + y_offset + 2 * scale + i);
2930 dc.DrawLine (check_pen,
2931 rect.Left + x_offset + 2 * scale,
2932 rect.Top + y_offset + 2 * scale + i,
2933 rect.Left + x_offset + 6 * scale,
2934 rect.Top + y_offset - 2 * scale + i);
2941 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
2943 simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
2945 if (simage_idx > -1)
2946 control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
2950 ImageList image_list = control.View == View.LargeIcon || control.View == View.Tile ? control.LargeImageList : control.SmallImageList;
2951 if (image_list != null) {
2954 if (item.ImageKey != String.Empty)
2955 idx = image_list.Images.IndexOfKey (item.ImageKey);
2957 idx = item.ImageIndex;
2959 if (idx > -1 && idx < image_list.Images.Count) {
2960 // Draw a thumbnail image if it exists for a FileViewListViewItem, otherwise draw
2961 // the standard icon. See https://bugzilla.xamarin.com/show_bug.cgi?id=28025.
2962 var fi = item as System.Windows.Forms.FileViewListViewItem;
2963 if (fi != null && fi.FSEntry != null && fi.FSEntry.Image != null)
2964 dc.DrawImage(fi.FSEntry.Image, icon_rect);
2966 image_list.Draw(dc, icon_rect.Location, idx);
2970 // draw the item text
2971 // format for the item text
2972 StringFormat format = new StringFormat ();
2973 if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2974 format.LineAlignment = StringAlignment.Near;
2976 format.LineAlignment = StringAlignment.Center;
2977 if (control.View == View.LargeIcon)
2978 format.Alignment = StringAlignment.Center;
2980 format.Alignment = StringAlignment.Near;
2982 if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2983 format.FormatFlags = StringFormatFlags.LineLimit;
2985 format.FormatFlags = StringFormatFlags.NoWrap;
2987 if ((control.View == View.LargeIcon && !item.Focused) || control.View == View.Details || control.View == View.Tile)
2988 format.Trimming = StringTrimming.EllipsisCharacter;
2990 Rectangle highlight_rect = text_rect;
2991 if (control.View == View.Details) { // Adjustments for Details view
2992 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2994 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2995 highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2998 if (item.Selected && control.Focused)
2999 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
3000 else if (item.Selected && !control.HideSelection)
3001 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
3003 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
3006 !control.Enabled ? SystemBrushes.ControlLight :
3007 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
3008 this.ResPool.GetSolidBrush (item.ForeColor);
3010 // Tile view renders its Text in a different fashion
3011 if (control.View == View.Tile && Application.VisualStylesEnabled) {
3012 // Item.Text is drawn using its first subitem's bounds
3013 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
3015 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
3016 for (int i = 1; i < count; i++) {
3017 ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
3018 if (sub_item.Text == null || sub_item.Text.Length == 0)
3021 Brush itemBrush = item.Selected && control.Focused ?
3022 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
3023 dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
3027 if (item.Text != null && item.Text.Length > 0) {
3028 Font font = item.Font;
3030 if (control.HotTracking && item.Hot)
3031 font = item.HotFont;
3033 if (item.Selected && control.Focused)
3034 dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
3036 dc.DrawString (item.Text, font, textBrush, text_rect, format);
3039 if (item.Focused && control.Focused) {
3040 Rectangle focus_rect = highlight_rect;
3041 if (control.FullRowSelect && control.View == View.Details) {
3043 foreach (ColumnHeader col in control.Columns)
3045 focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
3047 if (control.ShowFocusCues) {
3049 CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
3051 CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
3058 protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item)
3060 int columns_count = control.Columns.Count;
3061 int count = Math.Min (item.SubItems.Count, columns_count);
3062 // 0th item already done (in this case)
3063 for (int i = 1; i < count; i++)
3064 DrawListViewSubItem (dc, control, item, i);
3066 // Fill in selection for remaining columns if Column.Count > SubItems.Count
3067 Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label);
3068 if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3069 for (int index = count; index < columns_count; index++) {
3070 ColumnHeader col = control.Columns [index];
3071 sub_item_rect.X = col.Rect.X - control.h_marker;
3072 sub_item_rect.Width = col.Wd;
3073 dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control,
3079 protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
3081 ListViewItem.ListViewSubItem subItem = item.SubItems [index];
3082 ColumnHeader col = control.Columns [index];
3083 StringFormat format = new StringFormat ();
3084 format.Alignment = col.Format.Alignment;
3085 format.LineAlignment = StringAlignment.Center;
3086 format.FormatFlags = StringFormatFlags.NoWrap;
3087 format.Trimming = StringTrimming.EllipsisCharacter;
3089 Rectangle sub_item_rect = subItem.Bounds;
3090 Rectangle sub_item_text_rect = sub_item_rect;
3091 sub_item_text_rect.X += 3;
3092 sub_item_text_rect.Width -= ListViewItemPaddingWidth;
3094 SolidBrush sub_item_back_br = null;
3095 SolidBrush sub_item_fore_br = null;
3096 Font sub_item_font = null;
3098 if (item.UseItemStyleForSubItems) {
3099 sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
3100 sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
3102 // Hot tracking for subitems only applies when UseStyle is true
3103 if (control.HotTracking && item.Hot)
3104 sub_item_font = item.HotFont;
3106 sub_item_font = item.Font;
3108 sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
3109 sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
3110 sub_item_font = subItem.Font;
3113 if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3115 if (control.Focused) {
3116 bg = SystemBrushes.Highlight;
3117 text = SystemBrushes.HighlightText;
3119 bg = SystemBrushes.Control;
3120 text = sub_item_fore_br;
3124 dc.FillRectangle (bg, sub_item_rect);
3125 if (subItem.Text != null && subItem.Text.Length > 0)
3126 dc.DrawString (subItem.Text, sub_item_font,
3127 text, sub_item_text_rect, format);
3129 dc.FillRectangle (sub_item_back_br, sub_item_rect);
3130 if (subItem.Text != null && subItem.Text.Length > 0)
3131 dc.DrawString (subItem.Text, sub_item_font,
3133 sub_item_text_rect, format);
3139 protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
3141 ListView control = item.ListView;
3142 ListViewItem.ListViewSubItem subitem = item.SubItems [index];
3144 DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item,
3145 subitem, item.Index, index, control.Columns [index], state);
3146 control.OnDrawSubItem (args);
3148 return !args.DrawDefault;
3151 protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
3153 Rectangle text_bounds = group.HeaderBounds;
3154 Rectangle header_bounds = group.HeaderBounds;
3155 text_bounds.Offset (8, 0);
3156 text_bounds.Inflate (-8, 0);
3157 int text_height = control.Font.Height + 2; // add a tiny padding between the text and the group line
3159 Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
3160 Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0),
3161 SystemColors.Desktop, Color.White);
3162 Pen pen = new Pen (brush);
3164 StringFormat sformat = new StringFormat ();
3165 switch (group.HeaderAlignment) {
3166 case HorizontalAlignment.Left:
3167 sformat.Alignment = StringAlignment.Near;
3169 case HorizontalAlignment.Center:
3170 sformat.Alignment = StringAlignment.Center;
3172 case HorizontalAlignment.Right:
3173 sformat.Alignment = StringAlignment.Far;
3177 sformat.LineAlignment = StringAlignment.Near;
3178 dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
3179 dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_height, header_bounds.Left + ListViewGroupLineWidth,
3180 header_bounds.Top + text_height);
3188 public override bool ListViewHasHotHeaderStyle {
3195 public override int ListViewGetHeaderHeight (ListView listView, Font font)
3197 return ListViewGetHeaderHeight (font);
3200 static int ListViewGetHeaderHeight (Font font)
3202 return font.Height + 5;
3205 public static int ListViewGetHeaderHeight ()
3207 return ListViewGetHeaderHeight (ThemeEngine.Current.DefaultFont);
3210 public override Size ListViewCheckBoxSize {
3211 get { return new Size (16, 16); }
3214 public override int ListViewColumnHeaderHeight {
3218 public override int ListViewDefaultColumnWidth {
3222 public override int ListViewVerticalSpacing {
3226 public override int ListViewEmptyColumnWidth {
3230 public override int ListViewHorizontalSpacing {
3234 public override int ListViewItemPaddingWidth {
3238 public override Size ListViewDefaultSize {
3239 get { return new Size (121, 97); }
3242 public override int ListViewGroupHeight {
3246 public int ListViewGroupLineWidth {
3250 public override int ListViewTileWidthFactor {
3254 public override int ListViewTileHeightFactor {
3257 #endregion // ListView
3261 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3266 if (item.Visible == false) {
3272 if (item.Separator == true) {
3273 item.Height = SEPARATOR_HEIGHT;
3274 item.Width = SEPARATOR_MIN_WIDTH;
3278 if (item.MeasureEventDefined) {
3279 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3280 item.PerformMeasureItem (mi);
3281 item.Height = mi.ItemHeight;
3282 item.Width = mi.ItemWidth;
3286 size = dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3287 item.Width = (int) size.Width;
3288 item.Height = (int) size.Height;
3291 if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3292 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3293 size = dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3294 item.Width += MENU_TAB_SPACE + (int) size.Width;
3297 item.Width += 4 + (MenuCheckSize.Width * 2);
3299 item.Width += MENU_BAR_ITEMS_SPACE;
3303 if (item.Height < MenuHeight)
3304 item.Height = MenuHeight;
3308 // Updates the menu rect and returns the height
3309 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3315 foreach (MenuItem item in menu.MenuItems) {
3317 CalcItemSize (dc, item, y, x, true);
3319 if (x + item.Width > width) {
3327 item.MenuBar = true;
3329 if (y + item.Height > menu.Height)
3330 menu.Height = item.Height + y;
3337 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3345 while (start < menu.MenuItems.Count) {
3348 for (i = start; i < menu.MenuItems.Count; i++) {
3349 MenuItem item = menu.MenuItems [i];
3351 if ((i != start) && (item.Break || item.BarBreak))
3354 CalcItemSize (dc, item, y, x, false);
3357 if (item.Width > max)
3361 // Replace the -1 by the menu width (separators)
3362 for (n = start; n < i; n++, start++)
3363 menu.MenuItems [n].Width = max;
3365 if (y > menu.Height)
3377 menu.Width += SM_CXBORDER;
3378 menu.Height += SM_CYBORDER;
3381 // Draws a menu bar in a window
3382 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3384 if (menu.Height == 0)
3385 CalcMenuBarSize (dc, menu, rect.Width);
3387 bool keynav = (menu as MainMenu).tracker.hotkey_active;
3388 HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3389 string_format_menu_menubar_text.HotkeyPrefix = hp;
3390 string_format_menu_text.HotkeyPrefix = hp;
3392 rect.Height = menu.Height;
3393 dc.FillRectangle (SystemBrushes.Menu, rect);
3395 for (int i = 0; i < menu.MenuItems.Count; i++) {
3396 MenuItem item = menu.MenuItems [i];
3397 Rectangle item_rect = item.bounds;
3398 item_rect.X += rect.X;
3399 item_rect.Y += rect.Y;
3400 item.MenuHeight = menu.Height;
3401 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status));
3405 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3408 if (color.R == 0 && color.G == 0 && color.B == 0)
3409 bg_color = Color.White;
3411 bg_color = Color.Black;
3413 Bitmap bmp = new Bitmap (size.Width, size.Height);
3414 Graphics gr = Graphics.FromImage (bmp);
3415 Rectangle rect = new Rectangle (Point.Empty, size);
3416 gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3417 CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3418 bmp.MakeTransparent (bg_color);
3424 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3426 StringFormat string_format;
3427 Rectangle rect_text = e.Bounds;
3429 if (item.Visible == false)
3433 string_format = string_format_menu_menubar_text;
3435 string_format = string_format_menu_text;
3437 if (item.Separator == true) {
3438 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3440 e.Graphics.DrawLine (SystemPens.ControlDark,
3441 e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3443 e.Graphics.DrawLine (SystemPens.ControlLight,
3444 e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3450 rect_text.X += MenuCheckSize.Width;
3452 if (item.BarBreak) { /* Draw vertical break bar*/
3453 Rectangle rect = e.Bounds;
3456 rect.Height = item.MenuHeight - 6;
3458 e.Graphics.DrawLine (SystemPens.ControlDark,
3459 rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3461 e.Graphics.DrawLine (SystemPens.ControlLight,
3462 rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3467 Brush brush_text = null;
3468 Brush brush_back = null;
3470 if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3471 color_text = ColorHighlightText;
3472 color_back = ColorHighlight;
3473 brush_text = SystemBrushes.HighlightText;
3474 brush_back = SystemBrushes.Highlight;
3476 color_text = ColorMenuText;
3477 color_back = ColorMenu;
3478 brush_text = ResPool.GetSolidBrush (ColorMenuText);
3479 brush_back = SystemBrushes.Menu;
3482 /* Draw background */
3484 e.Graphics.FillRectangle (brush_back, e.Bounds);
3487 e.Graphics.DrawString (item.Text, e.Font,
3489 rect_text, string_format);
3492 Border3DStyle border_style = Border3DStyle.Adjust;
3493 if ((item.Status & DrawItemState.HotLight) != 0)
3494 border_style = Border3DStyle.RaisedInner;
3495 else if ((item.Status & DrawItemState.Selected) != 0)
3496 border_style = Border3DStyle.SunkenOuter;
3498 if (border_style != Border3DStyle.Adjust)
3499 CPDrawBorder3D(e.Graphics, e.Bounds, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3502 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3503 e.Graphics.DrawString (item.Text, e.Font, Brushes.White,
3504 new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3509 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3512 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3513 string str = item.GetShortCutText ();
3514 Rectangle rect = rect_text;
3516 rect.Width -= item.XTab;
3519 e.Graphics.DrawString (str, e.Font, brush_text, rect, string_format_menu_shortcut);
3521 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3522 e.Graphics.DrawString (str, e.Font, Brushes.White,
3523 new RectangleF(rect.X + 1, rect.Y + 1, rect.Width, rect_text.Height),
3524 string_format_menu_shortcut);
3527 e.Graphics.DrawString (str, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect, string_format_menu_shortcut);
3532 if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3534 int cx = MenuCheckSize.Width;
3535 int cy = MenuCheckSize.Height;
3536 Bitmap bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3539 e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3540 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3542 ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3543 e.Bounds.Y + ((e.Bounds.Height - cy) /2), color_back);
3549 /* Draw checked or radio */
3550 if (item.MenuBar == false && item.Checked) {
3552 Rectangle area = e.Bounds;
3553 int cx = MenuCheckSize.Width;
3554 int cy = MenuCheckSize.Height;
3555 Bitmap bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3557 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3563 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3565 // Fill rectangle area
3566 dc.FillRectangle (SystemBrushes.Menu, cliparea);
3568 // Draw menu borders
3569 CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3572 for (int i = 0; i < menu.MenuItems.Count; i++) {
3573 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3574 MenuItem item = menu.MenuItems [i];
3575 item.MenuHeight = menu.Height;
3576 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3583 #region MonthCalendar
3585 // draw the month calendar
3586 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc)
3588 Rectangle client_rectangle = mc.ClientRectangle;
3589 Size month_size = mc.SingleMonthSize;
3590 // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3591 Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3592 Size date_cell_size = (Size)((object)mc.date_cell_size);
3594 // draw the singlecalendars
3597 // adjust for the position of the specific month
3598 for (int i=0; i < mc.CalendarDimensions.Height; i++)
3602 y_offset += month_size.Height + calendar_spacing.Height;
3604 // now adjust for x position
3605 for (int j=0; j < mc.CalendarDimensions.Width; j++)
3609 x_offset += month_size.Width + calendar_spacing.Width;
3616 Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3617 if (month_rect.IntersectsWith (clip_rectangle)) {
3629 Rectangle bottom_rect = new Rectangle (
3631 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3632 client_rectangle.Width,
3633 date_cell_size.Height + 2);
3634 // draw the today date if it's set
3635 if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle))
3637 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3639 int today_offset = 5;
3640 if (mc.ShowTodayCircle)
3642 Rectangle today_circle_rect = new Rectangle (
3643 client_rectangle.X + 5,
3644 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3645 date_cell_size.Width,
3646 date_cell_size.Height);
3647 DrawTodayCircle (dc, today_circle_rect);
3648 today_offset += date_cell_size.Width + 5;
3650 // draw today's date
3651 StringFormat text_format = new StringFormat();
3652 text_format.LineAlignment = StringAlignment.Center;
3653 text_format.Alignment = StringAlignment.Near;
3654 Rectangle today_rect = new Rectangle (
3655 today_offset + client_rectangle.X,
3656 Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3657 Math.Max(client_rectangle.Width - today_offset, 0),
3658 date_cell_size.Height);
3659 dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3660 text_format.Dispose ();
3666 if (mc.owner == null)
3667 border_brush = GetControlBackBrush (mc.BackColor);
3669 border_brush = SystemBrushes.ControlDarkDark;
3671 // finally paint the borders of the calendars as required
3672 for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3673 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3674 dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3675 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3676 dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3678 Rectangle rect = new Rectangle (
3679 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3681 calendar_spacing.Width,
3682 client_rectangle.Height);
3683 if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3684 dc.FillRectangle (border_brush, rect);
3688 for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3689 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3690 dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3691 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3692 dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3694 Rectangle rect = new Rectangle (
3696 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3697 client_rectangle.Width,
3698 calendar_spacing.Height);
3699 if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3700 dc.FillRectangle (border_brush, rect);
3705 // draw the drop down border if need
3706 if (mc.owner != null) {
3707 Rectangle bounds = mc.ClientRectangle;
3708 if (clip_rectangle.Contains (mc.Location)) {
3709 // find out if top or left line to draw
3710 if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3712 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3714 if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3715 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3718 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3719 // find out if bottom or right line to draw
3720 if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3721 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3723 if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3724 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3730 // darws a single part of the month calendar (with one month)
3731 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col)
3733 // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3734 Size title_size = (Size)((object)mc.title_size);
3735 Size date_cell_size = (Size)((object)mc.date_cell_size);
3736 DateTime current_month = (DateTime)((object)mc.current_month);
3737 DateTime sunday = new DateTime(2006, 10, 1);
3739 // draw the title back ground
3740 DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3741 Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3742 if (title_rect.IntersectsWith (clip_rectangle)) {
3743 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3745 string title_text = this_month.ToString ("MMMM yyyy");
3746 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3748 if (mc.ShowYearUpDown) {
3749 Rectangle year_rect;
3750 Rectangle upRect, downRect;
3751 ButtonState upState, downState;
3753 mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3754 dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3755 dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3757 upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3758 downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3760 ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3761 ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3764 // draw previous and next buttons if it's time
3765 if (row == 0 && col == 0)
3767 // draw previous button
3768 DrawMonthCalendarButton (
3774 (System.Drawing.Size)((object)mc.button_size),
3777 if (row == 0 && col == mc.CalendarDimensions.Width-1)
3780 DrawMonthCalendarButton (
3786 (System.Drawing.Size)((object)mc.button_size),
3791 // set the week offset and draw week nums if needed
3792 int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3793 Rectangle day_name_rect = new Rectangle(
3795 rectangle.Y + title_size.Height,
3796 (7 + col_offset) * date_cell_size.Width,
3797 date_cell_size.Height);
3798 if (day_name_rect.IntersectsWith (clip_rectangle)) {
3799 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3800 // draw the day names
3801 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3802 for (int i=0; i < 7; i++)
3804 int position = i - (int) first_day_of_week;
3807 position = 7 + position;
3810 Rectangle day_rect = new Rectangle(
3811 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3813 date_cell_size.Width,
3814 date_cell_size.Height);
3815 dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3818 // draw the vertical divider
3819 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3821 ResPool.GetPen (mc.ForeColor),
3822 rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3823 rectangle.Y + vert_divider_y,
3824 rectangle.Right - mc.divider_line_offset,
3825 rectangle.Y + vert_divider_y);
3829 // draw the actual date items in the grid (including the week numbers)
3830 Rectangle date_rect = new Rectangle (
3832 rectangle.Y + title_size.Height + date_cell_size.Height,
3833 date_cell_size.Width,
3834 date_cell_size.Height);
3835 int month_row_count = 0;
3836 bool draw_week_num_divider = false;
3837 DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3838 for (int i=0; i < 6; i++)
3840 // establish if this row is in our clip_area
3841 Rectangle row_rect = new Rectangle (
3843 rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3844 date_cell_size.Width * 7,
3845 date_cell_size.Height);
3846 if (mc.ShowWeekNumbers) {
3847 row_rect.Width += date_cell_size.Width;
3850 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3852 dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3854 // establish if this is a valid week to draw
3855 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3856 month_row_count = i;
3859 // draw the week number if required
3860 if (mc.ShowWeekNumbers && month_row_count == i) {
3861 if (!draw_week_num_divider) {
3862 draw_week_num_divider = draw_row;
3864 // get the week for this row
3865 int week = mc.GetWeekOfYear (current_date);
3871 ResPool.GetSolidBrush (mc.TitleBackColor),
3873 mc.centered_format);
3875 date_rect.Offset(date_cell_size.Width, 0);
3878 // only draw the days if we have to
3879 if(month_row_count == i) {
3880 for (int j=0; j < 7; j++)
3883 DrawMonthCalendarDate (
3894 current_date = current_date.AddDays(1);
3895 date_rect.Offset(date_cell_size.Width, 0);
3898 // shift the rectangle down one row
3899 int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3900 date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3904 // month_row_count is zero based, so add one
3907 // draw week numbers if required
3908 if (draw_week_num_divider) {
3911 ResPool.GetPen (mc.ForeColor),
3912 rectangle.X + date_cell_size.Width - 1,
3913 rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3914 rectangle.X + date_cell_size.Width - 1,
3915 rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3919 // draws the pervious or next button
3920 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous)
3922 const int arrow_width = 4;
3923 const int arrow_height = 7;
3925 bool is_clicked = false;
3926 Rectangle button_rect;
3927 PointF arrow_center;
3928 PointF [] arrow_path = new PointF [3];
3930 // prepare the button
3933 is_clicked = mc.is_previous_clicked;
3935 button_rect = new Rectangle (
3936 rectangle.X + 1 + x_offset,
3937 rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3938 Math.Max(button_size.Width - 1, 0),
3939 Math.Max(button_size.Height - 1, 0));
3941 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f),
3942 rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3944 arrow_center.X += 1;
3945 arrow_center.Y += 1;
3948 arrow_path [0].X = arrow_center.X;
3949 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3950 arrow_path [1].X = arrow_center.X;
3951 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3952 arrow_path [2].X = arrow_center.X - arrow_width;
3953 arrow_path [2].Y = arrow_center.Y + 0.5f;
3957 is_clicked = mc.is_next_clicked;
3959 button_rect = new Rectangle (
3960 rectangle.Right - 1 - x_offset - button_size.Width,
3961 rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3962 Math.Max(button_size.Width - 1, 0),
3963 Math.Max(button_size.Height - 1, 0));
3965 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f),
3966 rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3968 arrow_center.X += 1;
3969 arrow_center.Y += 1;
3972 arrow_path [0].X = arrow_center.X - arrow_width;
3973 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3974 arrow_path [1].X = arrow_center.X - arrow_width;
3975 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3976 arrow_path [2].X = arrow_center.X;
3977 arrow_path [2].Y = arrow_center.Y + 0.5f;
3980 // fill the background
3981 dc.FillRectangle (SystemBrushes.Control, button_rect);
3984 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3987 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3990 dc.FillPolygon (SystemBrushes.ControlText, arrow_path);
3991 //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3995 // draws one day in the calendar grid
3996 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3997 Color date_color = mc.ForeColor;
3998 Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
4000 // find out if we are the lead of the first calendar or the trail of the last calendar
4001 if (date.Year != month.Year || date.Month != month.Month) {
4002 DateTime check_date = month.AddMonths (-1);
4003 // check if it's the month before
4004 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
4005 date_color = mc.TrailingForeColor;
4007 // check if it's the month after
4008 check_date = month.AddMonths (1);
4009 if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
4010 date_color = mc.TrailingForeColor;
4016 date_color = mc.ForeColor;
4019 const int inflate = -1;
4021 if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
4022 // see if the date is in the start of selection
4023 date_color = mc.BackColor;
4024 // draw the left hand of the back ground
4025 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4026 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
4027 } else if (date == mc.SelectionStart.Date) {
4028 // see if the date is in the start of selection
4029 date_color = mc.BackColor;
4030 // draw the left hand of the back ground
4031 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4032 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
4033 // fill the other side as a straight rect
4034 if (date < mc.SelectionEnd.Date)
4036 // use rectangle instead of rectangle to go all the way to edge of rect
4037 selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
4038 selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
4039 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4041 } else if (date == mc.SelectionEnd.Date) {
4042 // see if it is the end of selection
4043 date_color = mc.BackColor;
4044 // draw the left hand of the back ground
4045 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4046 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
4047 // fill the other side as a straight rect
4048 if (date > mc.SelectionStart.Date) {
4049 selection_rect.X = rectangle.X;
4050 selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
4051 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4053 } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
4054 // now see if it's in the middle
4055 date_color = mc.BackColor;
4056 // draw the left hand of the back ground
4057 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
4058 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4061 // establish if it's a bolded font
4062 Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
4064 // just draw the date now
4065 dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
4067 // today circle if needed
4068 if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
4069 DrawTodayCircle (dc, interior);
4072 // draw the selection grid
4073 if (mc.is_date_clicked && mc.clicked_date == date) {
4074 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
4075 dc.DrawRectangle (pen, interior);
4079 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
4080 Color circle_color = Color.FromArgb (248, 0, 0);
4081 // draw the left hand of the circle
4082 Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
4083 Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
4084 Point [] curve_points = new Point [3];
4085 curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
4086 curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
4087 curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
4089 Pen pen = ResPool.GetSizedPen(circle_color, 2);
4090 dc.DrawArc (pen, lhs_circle_rect, 90, 180);
4091 dc.DrawArc (pen, rhs_circle_rect, 270, 180);
4092 dc.DrawCurve (pen, curve_points);
4093 dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
4096 #endregion // MonthCalendar
4099 public override Size PanelDefaultSize {
4101 return new Size (200, 100);
4107 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
4108 Rectangle client = pb.ClientRectangle;
4110 client = new Rectangle (client.Left + pb.Padding.Left, client.Top + pb.Padding.Top, client.Width - pb.Padding.Horizontal, client.Height - pb.Padding.Vertical);
4112 // FIXME - instead of drawing the whole picturebox every time
4113 // intersect the clip rectangle with the drawn picture and only draw what's needed,
4114 // Also, we only need a background fill where no image goes
4115 if (pb.Image != null) {
4116 switch (pb.SizeMode) {
4117 case PictureBoxSizeMode.StretchImage:
4118 dc.DrawImage (pb.Image, client.Left, client.Top, client.Width, client.Height);
4121 case PictureBoxSizeMode.CenterImage:
4122 dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
4125 case PictureBoxSizeMode.Zoom:
4128 if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
4129 image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
4131 image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
4133 dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
4138 dc.DrawImage (pb.Image, client.Left, client.Top, pb.Image.Width, pb.Image.Height);
4146 public override Size PictureBoxDefaultSize {
4148 return new Size (100, 50);
4151 #endregion // PictureBox
4153 #region PrintPreviewControl
4154 public override int PrintPreviewControlPadding {
4158 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
4160 int page_width, page_height;
4161 int padding = PrintPreviewControlPadding;
4162 PreviewPageInfo[] pis = preview.page_infos;
4164 if (preview.AutoZoom) {
4165 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
4166 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
4168 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
4170 /* try to lay things out using the width to determine the size */
4171 page_width = width_available / preview.Columns;
4172 page_height = (int)(page_width / image_ratio);
4174 /* does the height fit? */
4175 if (page_height * (preview.Rows + 1) > height_available) {
4176 /* no, lay things out via the height */
4177 page_height = height_available / (preview.Rows + 1);
4178 page_width = (int)(page_height * image_ratio);
4182 page_width = (int)(pis[0].Image.Width * preview.Zoom);
4183 page_height = (int)(pis[0].Image.Height * preview.Zoom);
4186 return new Size (page_width, page_height);
4189 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
4192 PreviewPageInfo[] pis = preview.page_infos;
4198 int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
4199 int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
4201 Rectangle viewport = preview.ViewPort;
4203 pe.Graphics.Clip = new Region (viewport);
4205 /* center things if we can */
4206 int off_x = viewport.Width / 2 - width / 2;
4207 if (off_x < 0) off_x = 0;
4208 int off_y = viewport.Height / 2 - height / 2;
4209 if (off_y < 0) off_y = 0;
4211 page_y = off_y + padding - preview.vbar_value;
4213 if (preview.StartPage > 0) {
4214 int p = preview.StartPage - 1;
4215 for (int py = 0; py < preview.Rows + 1; py ++) {
4216 page_x = off_x + padding - preview.hbar_value;
4217 for (int px = 0; px < preview.Columns; px ++) {
4218 if (p >= pis.Length)
4220 Image image = preview.image_cache[p];
4222 image = pis[p].Image;
4223 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4225 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4227 page_x += padding + page_size.Width;
4230 page_y += padding + page_size.Height;
4234 #endregion // PrintPreviewControl
4237 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
4239 Rectangle client_area = ctrl.client_area;
4242 CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4246 int max_blocks = int.MaxValue;
4247 int start_pixel = client_area.X;
4248 draw_mode = (int) ctrl.Style;
4250 switch (draw_mode) {
4251 case 1: { // Continuous
4253 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4254 dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4258 if (XplatUI.ThemesEnabled) {
4259 int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4260 double percent_done = (double) ms_diff / ProgressBarMarqueeSpeedScaling
4261 % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4263 start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4269 Rectangle block_rect;
4270 int space_betweenblocks = ProgressBarChunkSpacing;
4274 int block_count = 0;
4276 block_width = ProgressBarGetChunkSize (client_area.Height);
4277 block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0!
4278 barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4279 increment = block_width + space_betweenblocks;
4281 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4283 if (max_blocks != int.MaxValue) {
4284 if (block_count >= max_blocks)
4286 if (block_rect.X > client_area.Width)
4287 block_rect.X -= client_area.Width;
4289 if ((block_rect.X - client_area.X) >= barpos_pixels)
4293 if (clip_rect.IntersectsWith (block_rect) == true) {
4294 dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), block_rect);
4297 block_rect.X += increment;
4305 public const int ProgressBarChunkSpacing = 2;
4307 public static int ProgressBarGetChunkSize ()
4309 return ProgressBarGetChunkSize (ProgressBarDefaultHeight);
4312 static int ProgressBarGetChunkSize (int progressBarClientAreaHeight)
4314 int size = (progressBarClientAreaHeight * 2) / 3;
4318 const int ProgressBarDefaultHeight = 23;
4320 public override Size ProgressBarDefaultSize {
4322 return new Size (100, ProgressBarDefaultHeight);
4326 public const double ProgressBarMarqueeSpeedScaling = 15;
4328 #endregion // ProgressBar
4331 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4332 StringFormat text_format;
4333 Rectangle client_rectangle;
4334 Rectangle text_rectangle;
4335 Rectangle radiobutton_rectangle;
4336 int radiobutton_size = 13;
4337 int radiobutton_space = 4;
4339 client_rectangle = radio_button.ClientRectangle;
4340 text_rectangle = client_rectangle;
4341 radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4343 text_format = new StringFormat();
4344 text_format.Alignment = StringAlignment.Near;
4345 text_format.LineAlignment = StringAlignment.Center;
4346 text_format.HotkeyPrefix = HotkeyPrefix.Show;
4348 /* Calculate the position of text and checkbox rectangle */
4349 if (radio_button.appearance!=Appearance.Button) {
4350 switch(radio_button.radiobutton_alignment) {
4351 case ContentAlignment.BottomCenter: {
4352 radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4353 radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4354 text_rectangle.X=client_rectangle.X;
4355 text_rectangle.Width=client_rectangle.Width;
4356 text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4360 case ContentAlignment.BottomLeft: {
4361 radiobutton_rectangle.X=client_rectangle.Left;
4362 radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4363 text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4364 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4368 case ContentAlignment.BottomRight: {
4369 radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4370 radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4371 text_rectangle.X=client_rectangle.X;
4372 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4376 case ContentAlignment.MiddleCenter: {
4377 radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4378 radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4379 text_rectangle.X=client_rectangle.X;
4380 text_rectangle.Width=client_rectangle.Width;
4385 case ContentAlignment.MiddleLeft: {
4386 radiobutton_rectangle.X=client_rectangle.Left;
4387 radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4388 text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4389 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4393 case ContentAlignment.MiddleRight: {
4394 radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4395 radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4396 text_rectangle.X=client_rectangle.X;
4397 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4401 case ContentAlignment.TopCenter: {
4402 radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4403 radiobutton_rectangle.Y=client_rectangle.Top;
4404 text_rectangle.X=client_rectangle.X;
4405 text_rectangle.Y=radiobutton_size+radiobutton_space;
4406 text_rectangle.Width=client_rectangle.Width;
4407 text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4411 case ContentAlignment.TopLeft: {
4412 radiobutton_rectangle.X=client_rectangle.Left;
4413 radiobutton_rectangle.Y=client_rectangle.Top;
4414 text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4415 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4419 case ContentAlignment.TopRight: {
4420 radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4421 radiobutton_rectangle.Y=client_rectangle.Top;
4422 text_rectangle.X=client_rectangle.X;
4423 text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4428 text_rectangle.X=client_rectangle.X;
4429 text_rectangle.Width=client_rectangle.Width;
4432 /* Set the horizontal alignment of our text */
4433 switch(radio_button.text_alignment) {
4434 case ContentAlignment.BottomLeft:
4435 case ContentAlignment.MiddleLeft:
4436 case ContentAlignment.TopLeft: {
4437 text_format.Alignment=StringAlignment.Near;
4441 case ContentAlignment.BottomCenter:
4442 case ContentAlignment.MiddleCenter:
4443 case ContentAlignment.TopCenter: {
4444 text_format.Alignment=StringAlignment.Center;
4448 case ContentAlignment.BottomRight:
4449 case ContentAlignment.MiddleRight:
4450 case ContentAlignment.TopRight: {
4451 text_format.Alignment=StringAlignment.Far;
4456 /* Set the vertical alignment of our text */
4457 switch(radio_button.text_alignment) {
4458 case ContentAlignment.TopLeft:
4459 case ContentAlignment.TopCenter:
4460 case ContentAlignment.TopRight: {
4461 text_format.LineAlignment=StringAlignment.Near;
4465 case ContentAlignment.BottomLeft:
4466 case ContentAlignment.BottomCenter:
4467 case ContentAlignment.BottomRight: {
4468 text_format.LineAlignment=StringAlignment.Far;
4472 case ContentAlignment.MiddleLeft:
4473 case ContentAlignment.MiddleCenter:
4474 case ContentAlignment.MiddleRight: {
4475 text_format.LineAlignment=StringAlignment.Center;
4480 ButtonState state = ButtonState.Normal;
4481 if (radio_button.FlatStyle == FlatStyle.Flat) {
4482 state |= ButtonState.Flat;
4485 if (radio_button.Checked) {
4486 state |= ButtonState.Checked;
4489 if (!radio_button.Enabled) {
4490 state |= ButtonState.Inactive;
4494 RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4496 if ((radio_button.image != null) || (radio_button.image_list != null))
4497 ButtonBase_DrawImage(radio_button, dc);
4499 RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4501 if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4502 SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4504 Rectangle focus_rect = Rectangle.Empty;
4505 focus_rect.X = text_rectangle.X;
4506 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4507 focus_rect.Size = text_size.ToSize ();
4509 RadioButton_DrawFocus (radio_button, dc, focus_rect);
4512 text_format.Dispose ();
4515 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4517 dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4519 if (radio_button.appearance==Appearance.Button) {
4520 ButtonBase_DrawButton (radio_button, dc);
4522 if ((radio_button.Focused) && radio_button.Enabled)
4523 ButtonBase_DrawFocus(radio_button, dc);
4525 // establish if we are rendering a flat style of some sort
4526 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4527 DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4529 CPDrawRadioButton(dc, radiobutton_rectangle, state);
4534 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4536 DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc,
4537 text_format, radio_button.Appearance, radio_button.Checked);
4540 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4542 DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4546 // renders a radio button with the Flat and Popup FlatStyle
4547 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4551 if (radio_button.Enabled) {
4553 // draw the outer flatstyle arcs
4554 if (radio_button.FlatStyle == FlatStyle.Flat) {
4555 graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4557 // fill in the area depending on whether or not the mouse is hovering
4558 if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4559 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4561 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4564 // must be a popup radio button
4566 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4568 if (radio_button.is_entered || radio_button.Capture) {
4569 // draw the popup 3d button knob
4570 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4572 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4573 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4576 // just draw lighter flatstyle outer circle
4577 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4582 // fill control background color regardless of actual backcolor
4583 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4584 // draw the ark as control dark
4585 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4589 if (radio_button.Checked) {
4590 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4592 Pen dot_pen = SystemPens.ControlDarkDark;
4593 Brush dot_brush = SystemBrushes.ControlDarkDark;
4595 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4596 dot_pen = SystemPens.ControlDark;
4597 dot_brush = SystemBrushes.ControlDark;
4600 if (rectangle.Height > 13) {
4601 graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4603 int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4604 int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4606 graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4607 graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4609 graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4610 graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4615 public override Size RadioButtonDefaultSize {
4617 return new Size (104,24);
4621 public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4623 // Draw Button Background
4624 if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4625 glyphArea.Height -= 2;
4626 glyphArea.Width -= 2;
4629 DrawRadioButtonGlyph (g, rb, glyphArea);
4631 // If we have an image, draw it
4632 if (imageBounds.Size != Size.Empty)
4633 DrawRadioButtonImage (g, rb, imageBounds);
4635 if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4636 DrawRadioButtonFocus (g, rb, textBounds);
4638 // If we have text, draw it
4639 if (textBounds != Rectangle.Empty)
4640 DrawRadioButtonText (g, rb, textBounds);
4643 public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4646 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4647 else if (rb.InternalSelected)
4648 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4649 else if (rb.Entered)
4650 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4651 else if (!rb.Enabled)
4652 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4654 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4657 public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4659 ControlPaint.DrawFocusRectangle (g, focusArea);
4662 public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4665 g.DrawImage (rb.Image, imageBounds);
4667 CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4670 public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4673 TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4675 DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4678 public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4680 Size ret_size = Size.Empty;
4681 Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4682 Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4684 // Pad the text size
4685 if (rb.Text.Length != 0) {
4686 text_size.Height += 4;
4687 text_size.Width += 4;
4690 switch (rb.TextImageRelation) {
4691 case TextImageRelation.Overlay:
4692 ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4693 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4695 case TextImageRelation.ImageAboveText:
4696 case TextImageRelation.TextAboveImage:
4697 ret_size.Height = text_size.Height + image_size.Height;
4698 ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4700 case TextImageRelation.ImageBeforeText:
4701 case TextImageRelation.TextBeforeImage:
4702 ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4703 ret_size.Width = text_size.Width + image_size.Width;
4708 ret_size.Height += (rb.Padding.Vertical);
4709 ret_size.Width += (rb.Padding.Horizontal) + 15;
4711 // There seems to be a minimum height
4712 if (ret_size.Height == rb.Padding.Vertical)
4713 ret_size.Height += 14;
4718 public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4720 CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4722 #endregion // RadioButton
4725 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4727 int scrollbutton_width = bar.scrollbutton_width;
4728 int scrollbutton_height = bar.scrollbutton_height;
4729 Rectangle first_arrow_area;
4730 Rectangle second_arrow_area;
4731 Rectangle thumb_pos;
4733 thumb_pos = bar.ThumbPos;
4736 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4737 bar.FirstArrowArea = first_arrow_area;
4739 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4740 bar.SecondArrowArea = second_arrow_area;
4742 thumb_pos.Width = bar.Width;
4743 bar.ThumbPos = thumb_pos;
4745 Brush VerticalBrush;
4746 /* Background, upper track */
4747 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4748 VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4750 VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4751 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4752 if (clip.IntersectsWith (UpperTrack))
4753 dc.FillRectangle (VerticalBrush, UpperTrack);
4755 /* Background, lower track */
4756 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4757 VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4759 VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4760 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4761 if (clip.IntersectsWith (LowerTrack))
4762 dc.FillRectangle (VerticalBrush, LowerTrack);
4765 if (clip.IntersectsWith (first_arrow_area))
4766 CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4767 if (clip.IntersectsWith (second_arrow_area))
4768 CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4770 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4771 bar.FirstArrowArea = first_arrow_area;
4773 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4774 bar.SecondArrowArea = second_arrow_area;
4776 thumb_pos.Height = bar.Height;
4777 bar.ThumbPos = thumb_pos;
4779 Brush HorizontalBrush;
4780 //Background, left track
4781 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4782 HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4784 HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4785 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4786 if (clip.IntersectsWith (LeftTrack))
4787 dc.FillRectangle (HorizontalBrush, LeftTrack);
4789 //Background, right track
4790 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4791 HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4793 HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4794 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4795 if (clip.IntersectsWith (RightTrack))
4796 dc.FillRectangle (HorizontalBrush, RightTrack);
4799 if (clip.IntersectsWith (first_arrow_area))
4800 CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4801 if (clip.IntersectsWith (second_arrow_area))
4802 CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4806 ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);
4809 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4811 if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4812 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4815 public override int ScrollBarButtonSize {
4819 public override bool ScrollBarHasHotElementStyles {
4825 public override bool ScrollBarHasPressedThumbStyle {
4831 public override bool ScrollBarHasHoverArrowButtonStyle {
4836 #endregion // ScrollBar
4839 public override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4840 Rectangle area = sb.ClientRectangle;
4841 int horz_border = 2;
4842 int vert_border = 2;
4844 Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4845 Graphics dc = Graphics.FromImage (backbuffer);
4847 DrawStatusBarBackground (dc, clip, sb);
4849 if (!sb.ShowPanels && sb.Text != String.Empty) {
4850 string text = sb.Text;
4851 StringFormat string_format = new StringFormat ();
4852 string_format.Trimming = StringTrimming.Character;
4853 string_format.FormatFlags = StringFormatFlags.NoWrap;
4855 if (text.Length > 127)
4856 text = text.Substring (0, 127);
4858 if (text [0] == '\t') {
4859 string_format.Alignment = StringAlignment.Center;
4860 text = text.Substring (1);
4861 if (text [0] == '\t') {
4862 string_format.Alignment = StringAlignment.Far;
4863 text = text.Substring (1);
4867 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4868 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4869 string_format.Dispose ();
4870 } else if (sb.ShowPanels) {
4871 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4872 int prev_x = area.X + horz_border;
4873 int y = area.Y + vert_border;
4874 for (int i = 0; i < sb.Panels.Count; i++) {
4875 Rectangle pr = new Rectangle (prev_x, y,
4876 sb.Panels [i].Width, area.Height);
4877 prev_x += pr.Width + StatusBarHorzGapWidth;
4878 if (pr.IntersectsWith (clip))
4879 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4884 DrawStatusBarSizingGrip (dc, clip, sb, area);
4886 real_dc.DrawImage (backbuffer, 0, 0);
4888 backbuffer.Dispose ();
4892 protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4894 bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4896 Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4897 dc.FillRectangle (brush, clip);
4900 protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4902 area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4903 CPDrawSizeGrip (dc, ColorControl, area);
4906 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4907 Brush br_forecolor, StatusBarPanel panel) {
4908 int border_size = 3; // this is actually const, even if the border style is none
4909 int icon_width = 16;
4911 area.Height -= border_size;
4913 DrawStatusBarPanelBackground (dc, area, panel);
4915 if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4916 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4917 dc, panel.Parent.Font, area, index, DrawItemState.Default,
4918 panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4919 panel.Parent.OnDrawItemInternal (e);
4923 string text = panel.Text;
4924 StringFormat string_format = new StringFormat ();
4925 string_format.Trimming = StringTrimming.Character;
4926 string_format.FormatFlags = StringFormatFlags.NoWrap;
4929 if (text != null && text.Length > 0 && text [0] == '\t') {
4930 string_format.Alignment = StringAlignment.Center;
4931 text = text.Substring (1);
4932 if (text [0] == '\t') {
4933 string_format.Alignment = StringAlignment.Far;
4934 text = text.Substring (1);
4938 Rectangle string_rect = Rectangle.Empty;
4942 int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4944 switch (panel.Alignment) {
4945 case HorizontalAlignment.Right:
4946 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4947 x = area.Right - len - 4;
4948 string_rect = new Rectangle (x, y,
4949 area.Right - x - border_size,
4950 area.Bottom - y - border_size);
4951 if (panel.Icon != null) {
4952 icon_x = x - icon_width - 2;
4955 case HorizontalAlignment.Center:
4956 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4957 x = area.Left + ((panel.Width - len) / 2);
4959 string_rect = new Rectangle (x, y,
4960 area.Right - x - border_size,
4961 area.Bottom - y - border_size);
4963 if (panel.Icon != null) {
4964 icon_x = x - icon_width - 2;
4970 int left = area.Left + border_size;;
4971 if (panel.Icon != null) {
4972 icon_x = area.Left + 2;
4973 left = icon_x + icon_width + 2;
4977 string_rect = new Rectangle (x, y,
4978 area.Right - x - border_size,
4979 area.Bottom - y - border_size);
4983 RectangleF clip_bounds = dc.ClipBounds;
4985 dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);
4986 dc.SetClip (clip_bounds);
4988 if (panel.Icon != null) {
4989 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4993 protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4995 if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4996 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4997 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4998 border_style = Border3DStyle.RaisedInner;
5000 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
5004 public override int StatusBarSizeGripWidth {
5008 public override int StatusBarHorzGapWidth {
5012 public override Size StatusBarDefaultSize {
5014 return new Size (100, 22);
5017 #endregion // StatusBar
5021 #region TabControl settings
5023 public override Size TabControlDefaultItemSize {
5024 get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
5027 public override Point TabControlDefaultPadding {
5028 get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
5031 public override int TabControlMinimumTabWidth {
5032 get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
5035 public override Rectangle TabControlSelectedDelta {
5036 get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
5039 public override int TabControlSelectedSpacing {
5040 get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
5043 public override int TabPanelOffsetX {
5044 get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
5047 public override int TabPanelOffsetY {
5048 get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
5051 public override int TabControlColSpacing {
5052 get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
5055 public override Point TabControlImagePadding {
5056 get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
5059 public override int TabControlScrollerWidth {
5060 get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
5064 public override Size TabControlGetSpacing (TabControl tab)
5067 return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
5069 throw new Exception ("Invalid Appearance value: " + tab.Appearance);
5074 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
5076 ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
5079 public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
5081 return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
5084 public override Rectangle TabControlGetPanelRect (TabControl tab)
5086 return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
5092 public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
5094 if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
5095 g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
5097 g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
5101 public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
5106 public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
5113 public override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control)
5115 StringFormat format = new StringFormat ();
5116 format.Trimming = StringTrimming.EllipsisCharacter;
5117 format.LineAlignment = StringAlignment.Center;
5118 if (control.ShowKeyboardCuesInternal)
5119 format.HotkeyPrefix = HotkeyPrefix.Show;
5121 format.HotkeyPrefix = HotkeyPrefix.Hide;
5123 if (control.TextAlign == ToolBarTextAlign.Underneath)
5124 format.Alignment = StringAlignment.Center;
5126 format.Alignment = StringAlignment.Near;
5128 if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
5129 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5132 if (control.Divider && clip_rectangle.Y < 2) {
5133 if (clip_rectangle.Y < 1) {
5134 dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
5136 dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5139 foreach (ToolBarItem item in control.items)
5140 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
5141 DrawToolBarButton (dc, control, item, format);
5146 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5148 bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
5150 DrawToolBarButtonBorder (dc, item, is_flat);
5152 switch (item.Button.Style) {
5153 case ToolBarButtonStyle.DropDownButton:
5154 if (control.DropDownArrows)
5155 DrawToolBarDropDownArrow (dc, item, is_flat);
5156 DrawToolBarButtonContents (dc, control, item, format);
5159 case ToolBarButtonStyle.Separator:
5161 DrawToolBarSeparator (dc, item);
5164 case ToolBarButtonStyle.ToggleButton:
5165 DrawToolBarToggleButtonBackground (dc, item);
5166 DrawToolBarButtonContents (dc, control, item, format);
5170 DrawToolBarButtonContents (dc, control, item, format);
5175 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
5177 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
5179 if (item.Button.Style == ToolBarButtonStyle.Separator)
5182 Border3DStyle style;
5185 if (item.Button.Pushed || item.Pressed)
5186 style = Border3DStyle.SunkenOuter;
5187 else if (item.Hilight)
5188 style = Border3DStyle.RaisedInner;
5193 if (item.Button.Pushed || item.Pressed)
5194 style = Border3DStyle.Sunken;
5196 style = Border3DStyle.Raised;
5199 Rectangle rect = item.Rectangle;
5200 if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5201 rect.Width -= ToolBarDropDownWidth;
5203 CPDrawBorder3D (dc, rect, style, all_sides);
5206 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5208 Rectangle area = item.Rectangle;
5209 int offset = (int) SystemPens.Control.Width + 1;
5210 dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5211 dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5214 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5217 Rectangle area = item.Rectangle;
5218 area.X += ToolBarImageGripWidth;
5219 area.Y += ToolBarImageGripWidth;
5220 area.Width -= 2 * ToolBarImageGripWidth;
5221 area.Height -= 2 * ToolBarImageGripWidth;
5223 if (item.Button.Pushed)
5224 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5225 else if (item.Button.PartialPush)
5226 brush = SystemBrushes.ControlLight;
5228 brush = SystemBrushes.Control;
5230 dc.FillRectangle (brush, area);
5233 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5235 Rectangle rect = item.Rectangle;
5236 rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5237 rect.Width = ToolBarDropDownWidth;
5241 CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5242 else if (item.Button.Pushed || item.Pressed)
5243 CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5244 else if (item.Hilight)
5245 CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5248 CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5249 else if (item.Button.Pushed || item.Pressed)
5250 CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5252 CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5255 PointF [] vertices = new PointF [3];
5256 PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5258 // Increase vertical and horizontal position by 1 when button is pressed
5259 if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5264 vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5265 vertices [0].Y = ddCenter.Y;
5266 vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5267 vertices [1].Y = ddCenter.Y;
5268 vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5269 vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5270 dc.FillPolygon (SystemBrushes.ControlText, vertices);
5273 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5275 if (item.Button.Image != null) {
5276 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5277 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5279 // Increase vertical and horizontal position by 1 when button is pressed
5280 if (item.Pressed || item.Button.Pushed) {
5285 if (item.Button.Enabled)
5286 dc.DrawImage (item.Button.Image, x, y);
5288 CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5291 Rectangle text_rect = item.TextRectangle;
5292 if (text_rect.Width <= 0 || text_rect.Height <= 0)
5295 if (item.Pressed || item.Button.Pushed) {
5300 if (item.Button.Enabled)
5301 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5303 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5306 // Grip width for the ToolBar
5307 public override int ToolBarGripWidth {
5311 // Grip width for the Image on the ToolBarButton
5312 public override int ToolBarImageGripWidth {
5316 // width of the separator
5317 public override int ToolBarSeparatorWidth {
5321 // width of the dropdown arrow rect
5322 public override int ToolBarDropDownWidth {
5326 // width for the dropdown arrow on the ToolBarButton
5327 public override int ToolBarDropDownArrowWidth {
5331 // height for the dropdown arrow on the ToolBarButton
5332 public override int ToolBarDropDownArrowHeight {
5336 public override Size ToolBarDefaultSize {
5338 return new Size (100, 42);
5342 public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5344 return toolBar.Appearance == ToolBarAppearance.Flat;
5347 public override bool ToolBarHasHotCheckedElementStyles {
5352 #endregion // ToolBar
5355 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5357 ToolTipDrawBackground (dc, clip_rectangle, control);
5359 TextFormatFlags flags = TextFormatFlags.HidePrefix;
5361 Color foreground = control.ForeColor;
5362 if (control.title.Length > 0) {
5363 Font bold_font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
5364 TextRenderer.DrawTextInternal (dc, control.title, bold_font, control.title_rect,
5365 foreground, flags, false);
5366 bold_font.Dispose ();
5369 if (control.icon != null)
5370 dc.DrawIcon (control.icon, control.icon_rect);
5372 TextRenderer.DrawTextInternal (dc, control.Text, control.Font, control.text_rect, foreground, flags, false);
5375 protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5377 Brush back_brush = ResPool.GetSolidBrush (control.BackColor);
5378 dc.FillRectangle (back_brush, control.ClientRectangle);
5379 dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5382 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5384 Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5387 Rectangle text_rect = new Rectangle (Point.Empty, size);
5388 text_rect.Inflate (-2, -1);
5389 tt.text_rect = text_rect;
5390 tt.icon_rect = tt.title_rect = Rectangle.Empty;
5392 Size title_size = Size.Empty;
5393 if (tt.title.Length > 0) {
5394 Font bold_font = new Font (tt.Font, tt.Font.Style | FontStyle.Bold);
5395 title_size = TextRenderer.MeasureTextInternal (tt.title, bold_font, false);
5396 bold_font.Dispose ();
5399 Size icon_size = Size.Empty;
5400 if (tt.icon != null)
5401 icon_size = new Size (size.Height, size.Height);
5403 if (icon_size != Size.Empty || title_size != Size.Empty) {
5405 int top_area_width = 0;
5406 int top_area_height = icon_size.Height > title_size.Height ? icon_size.Height : title_size.Height;
5407 Size text_size = size;
5408 Point location = new Point (padding, padding);
5410 if (icon_size != Size.Empty) {
5411 tt.icon_rect = new Rectangle (location, icon_size);
5412 top_area_width = icon_size.Width + padding;
5415 if (title_size != Size.Empty) {
5416 Rectangle title_rect = new Rectangle (location, new Size (title_size.Width, top_area_height));
5417 if (icon_size != Size.Empty)
5418 title_rect.X += icon_size.Width + padding;
5420 tt.title_rect = title_rect;
5421 top_area_width += title_size.Width;
5424 tt.text_rect = new Rectangle (new Point (location.X, location.Y + top_area_height + padding),
5427 size.Height += padding + top_area_height;
5428 if (top_area_width > size.Width)
5429 size.Width = top_area_width;
5432 size.Width += padding * 2;
5433 size.Height += padding * 2;
5439 public override bool ToolTipTransparentBackground {
5444 #endregion // ToolTip
5446 #region BalloonWindow
5447 NotifyIcon.BalloonWindow balloon_window;
5449 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5451 Control control = Control.FromHandle(handle);
5453 if (control == null)
5456 if (balloon_window != null) {
5457 balloon_window.Close ();
5458 balloon_window.Dispose ();
5461 balloon_window = new NotifyIcon.BalloonWindow (handle);
5462 balloon_window.Title = title;
5463 balloon_window.Text = text;
5464 balloon_window.Icon = icon;
5465 balloon_window.Timeout = timeout;
5466 balloon_window.Show ();
5469 public override void HideBalloonWindow (IntPtr handle)
5471 if (balloon_window == null || balloon_window.OwnerHandle != handle)
5474 balloon_window.Close ();
5475 balloon_window.Dispose ();
5476 balloon_window = null;
5479 private const int balloon_iconsize = 16;
5480 private const int balloon_bordersize = 8;
5482 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control)
5484 Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5485 Rectangle rect = control.ClientRectangle;
5486 int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5488 // Rectangle borders and background.
5489 dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5490 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5494 switch (control.Icon) {
5495 case ToolTipIcon.Info: {
5496 image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5500 case ToolTipIcon.Warning: {
5501 image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5505 case ToolTipIcon.Error: {
5506 image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5516 if (control.Icon != ToolTipIcon.None)
5517 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5520 Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0),
5521 rect.Y + balloon_bordersize,
5522 rect.Width - ((3 * balloon_bordersize) + iconsize),
5523 rect.Height - (2 * balloon_bordersize));
5525 Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5526 dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5529 Rectangle textrect = new Rectangle (rect.X + balloon_bordersize,
5530 rect.Y + balloon_bordersize,
5531 rect.Width - (2 * balloon_bordersize),
5532 rect.Height - (2 * balloon_bordersize));
5534 StringFormat textformat = control.Format;
5535 textformat.LineAlignment = StringAlignment.Far;
5536 dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5539 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5541 Rectangle deskrect = Screen.GetWorkingArea (control);
5542 SizeF maxsize = new SizeF (250, 200);
5544 SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5545 SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5547 if (titlesize.Height < balloon_iconsize)
5548 titlesize.Height = balloon_iconsize;
5550 Rectangle rect = new Rectangle ();
5551 rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5552 rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5553 rect.X = deskrect.Width - rect.Width - 2;
5554 rect.Y = deskrect.Height - rect.Height - 2;
5558 #endregion // BalloonWindow
5561 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5563 int result = tb.Value;
5564 int value_pos = tb.Value;
5565 float pixels_betweenticks;
5566 Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5567 Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5569 GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5571 /* Convert thumb position from mouse position to value*/
5572 if (tb.Orientation == Orientation.Vertical) {
5573 value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5575 if (value_pos + tb.Minimum > tb.Maximum)
5576 value_pos = tb.Maximum - tb.Minimum;
5577 else if (value_pos + tb.Minimum < tb.Minimum)
5580 result = value_pos + tb.Minimum;
5582 value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5584 if (value_pos + tb.Minimum > tb.Maximum)
5585 value_pos = tb.Maximum - tb.Minimum;
5586 else if (value_pos + tb.Minimum < tb.Minimum)
5589 result = value_pos + tb.Minimum;
5595 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 thumb_area = Rectangle.Empty;
5598 thumb_pos = Rectangle.Empty;
5600 if (tb.Orientation == Orientation.Vertical) {
5601 toptick_startpoint = new Point ();
5602 bottomtick_startpoint = new Point ();
5603 channel_startpoint = new Point ();
5605 const int space_from_right = 8;
5606 const int space_from_left = 8;
5607 const int space_from_bottom = 11;
5608 Rectangle area = tb.ClientRectangle;
5610 switch (tb.TickStyle) {
5611 case TickStyle.BottomRight:
5612 case TickStyle.None:
5613 channel_startpoint.Y = 8;
5614 channel_startpoint.X = 9;
5615 bottomtick_startpoint.Y = 13;
5616 bottomtick_startpoint.X = 24;
5618 case TickStyle.TopLeft:
5619 channel_startpoint.Y = 8;
5620 channel_startpoint.X = 19;
5621 toptick_startpoint.Y = 13;
5622 toptick_startpoint.X = 8;
5624 case TickStyle.Both:
5625 channel_startpoint.Y = 8;
5626 channel_startpoint.X = 18;
5627 bottomtick_startpoint.Y = 13;
5628 bottomtick_startpoint.X = 32;
5629 toptick_startpoint.Y = 13;
5630 toptick_startpoint.X = 8;
5636 thumb_area.X = area.X + channel_startpoint.X;
5637 thumb_area.Y = area.Y + channel_startpoint.Y;
5638 thumb_area.Height = area.Height - space_from_right - space_from_left;
5639 thumb_area.Width = TrackBarVerticalTrackWidth;
5641 pixel_len = thumb_area.Height - 11;
5642 if (tb.Maximum == tb.Minimum) {
5643 pixels_betweenticks = 0;
5645 pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5648 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5650 toptick_startpoint = new Point ();
5651 bottomtick_startpoint = new Point ();
5652 channel_startpoint = new Point ();
5654 const int space_from_right = 8;
5655 const int space_from_left = 8;
5656 Rectangle area = tb.ClientRectangle;
5658 switch (tb.TickStyle) {
5659 case TickStyle.BottomRight:
5660 case TickStyle.None:
5661 channel_startpoint.X = 8;
5662 channel_startpoint.Y = 9;
5663 bottomtick_startpoint.X = 13;
5664 bottomtick_startpoint.Y = 24;
5666 case TickStyle.TopLeft:
5667 channel_startpoint.X = 8;
5668 channel_startpoint.Y = 19;
5669 toptick_startpoint.X = 13;
5670 toptick_startpoint.Y = 8;
5672 case TickStyle.Both:
5673 channel_startpoint.X = 8;
5674 channel_startpoint.Y = 18;
5675 bottomtick_startpoint.X = 13;
5676 bottomtick_startpoint.Y = 32;
5677 toptick_startpoint.X = 13;
5678 toptick_startpoint.Y = 8;
5684 thumb_area.X = area.X + channel_startpoint.X;
5685 thumb_area.Y = area.Y + channel_startpoint.Y;
5686 thumb_area.Width = area.Width - space_from_right - space_from_left;
5687 thumb_area.Height = TrackBarHorizontalTrackHeight;
5689 pixel_len = thumb_area.Width - 11;
5690 if (tb.Maximum == tb.Minimum) {
5691 pixels_betweenticks = 0;
5693 pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5696 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5699 thumb_pos.Size = TrackBarGetThumbSize (tb);
5702 protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5704 return TrackBarGetThumbSize ();
5707 public static Size TrackBarGetThumbSize ()
5709 /* Draw thumb fixed 10x22 size */
5710 return new Size (10, 22);
5713 public const int TrackBarVerticalTrackWidth = 4;
5715 public const int TrackBarHorizontalTrackHeight = 4;
5718 protected interface ITrackBarTickPainter
5720 void Paint (float x1, float y1, float x2, float y2);
5723 class TrackBarTickPainter : ITrackBarTickPainter
5725 readonly Graphics g;
5727 public TrackBarTickPainter (Graphics g, Pen pen)
5732 public void Paint (float x1, float y1, float x2, float y2)
5734 g.DrawLine (pen, x1, y1, x2, y2);
5737 protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5739 return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5743 #region DrawTrackBar_Vertical
5744 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5745 ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5746 float ticks, int value_pos, bool mouse_value) {
5748 Point toptick_startpoint = new Point ();
5749 Point bottomtick_startpoint = new Point ();
5750 Point channel_startpoint = new Point ();
5752 float pixels_betweenticks;
5753 Rectangle area = tb.ClientRectangle;
5755 GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5758 TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5762 switch (tb.TickStyle) {
5763 case TickStyle.BottomRight:
5764 case TickStyle.None:
5765 thumb_pos.X = channel_startpoint.X - 8;
5766 TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5768 case TickStyle.TopLeft:
5769 thumb_pos.X = channel_startpoint.X - 10;
5770 TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5773 thumb_pos.X = area.X + 10;
5774 TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5779 pixel_len = thumb_area.Height - 11;
5780 pixels_betweenticks = pixel_len / ticks;
5782 thumb_area.X = thumb_pos.X;
5783 thumb_area.Y = channel_startpoint.Y;
5784 thumb_area.Width = thumb_pos.Height;
5787 if (pixels_betweenticks <= 0)
5789 if (tb.TickStyle == TickStyle.None)
5791 Region outside = new Region (area);
5792 outside.Exclude (thumb_area);
5794 if (outside.IsVisible (clip_rectangle)) {
5795 ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5797 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5798 float x = area.X + bottomtick_startpoint.X;
5799 for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {
5800 float y = area.Y + bottomtick_startpoint.Y + inc;
5801 tick_painter.Paint (
5803 x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5807 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5808 float x = area.X + toptick_startpoint.X;
5809 for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {
5810 float y = area.Y + toptick_startpoint.Y + inc;
5811 tick_painter.Paint (
5812 x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5823 protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5825 dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5826 1, thumb_area.Height);
5828 dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5829 1, thumb_area.Height);
5831 dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5832 1, thumb_area.Height);
5837 protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5839 Pen pen = SystemPens.ControlLightLight;
5840 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5841 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5842 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5844 pen = SystemPens.ControlDark;
5845 dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5846 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5848 pen = SystemPens.ControlDarkDark;
5849 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5850 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5852 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5853 dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5854 dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5855 dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5858 protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5860 Pen pen = SystemPens.ControlLightLight;
5861 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5862 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5864 pen = SystemPens.ControlDark;
5865 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5866 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5867 dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5869 pen = SystemPens.ControlDarkDark;
5870 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5871 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5872 dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5874 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5875 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5876 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5877 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5880 protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5882 Pen pen = SystemPens.ControlLightLight;
5883 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5884 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5886 pen = SystemPens.ControlDark;
5887 dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5888 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5890 pen = SystemPens.ControlDarkDark;
5891 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5892 dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5894 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5899 protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5901 return GetTrackBarTickPainter (g);
5906 #region DrawTrackBar_Horizontal
5910 Does not matter the size of the control, Win32 always draws:
5911 - Ticks starting from pixel 13, 8
5912 - Channel starting at pos 8, 19 and ends at Width - 8
5913 - Autosize makes always the control 45 pixels high
5914 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5917 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5918 ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5919 float ticks, int value_pos, bool mouse_value) {
5920 Point toptick_startpoint = new Point ();
5921 Point bottomtick_startpoint = new Point ();
5922 Point channel_startpoint = new Point ();
5924 float pixels_betweenticks;
5925 Rectangle area = tb.ClientRectangle;
5927 GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5930 TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5934 switch (tb.TickStyle) {
5935 case TickStyle.BottomRight:
5936 case TickStyle.None:
5937 thumb_pos.Y = channel_startpoint.Y - 8;
5938 TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5940 case TickStyle.TopLeft:
5941 thumb_pos.Y = channel_startpoint.Y - 10;
5942 TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5945 thumb_pos.Y = area.Y + 10;
5946 TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5951 pixel_len = thumb_area.Width - 11;
5952 pixels_betweenticks = pixel_len / ticks;
5954 thumb_area.Y = thumb_pos.Y;
5955 thumb_area.X = channel_startpoint.X;
5956 thumb_area.Height = thumb_pos.Height;
5958 if (pixels_betweenticks <= 0)
5960 if (tb.TickStyle == TickStyle.None)
5962 Region outside = new Region (area);
5963 outside.Exclude (thumb_area);
5965 if (outside.IsVisible (clip_rectangle)) {
5966 ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5968 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5969 float y = area.Y + bottomtick_startpoint.Y;
5970 for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {
5971 float x = area.X + bottomtick_startpoint.X + inc;
5972 tick_painter.Paint (
5974 x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5978 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5979 float y = area.Y + toptick_startpoint.Y;
5980 for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {
5981 float x = area.X + toptick_startpoint.X + inc;
5982 tick_painter.Paint (
5983 x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2),
5994 protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5996 dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5997 thumb_area.Width, 1);
5999 dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
6000 thumb_area.Width, 1);
6002 dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
6003 thumb_area.Width, 1);
6008 protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6010 Pen pen = SystemPens.ControlLightLight;
6011 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
6012 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
6013 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
6015 pen = SystemPens.ControlDark;
6016 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
6017 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
6019 pen = SystemPens.ControlDarkDark;
6020 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
6021 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
6023 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
6024 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
6025 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
6026 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
6029 protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6031 Pen pen = SystemPens.ControlLightLight;
6032 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
6033 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
6035 pen = SystemPens.ControlDark;
6036 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
6037 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
6038 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
6040 pen = SystemPens.ControlDarkDark;
6041 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
6042 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
6043 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
6045 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
6046 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
6047 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
6048 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
6051 protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6053 Pen pen = SystemPens.ControlLightLight;
6054 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
6055 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
6057 pen = SystemPens.ControlDark;
6058 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
6059 dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
6061 pen = SystemPens.ControlDarkDark;
6062 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
6063 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
6065 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
6070 protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
6072 return GetTrackBarTickPainter (g);
6077 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb)
6082 float ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
6084 Rectangle thumb_pos = tb.ThumbPos;
6085 Rectangle thumb_area = tb.ThumbArea;
6087 if (tb.thumb_pressed) {
6088 value_pos = tb.thumb_mouseclick;
6091 value_pos = tb.Value - tb.Minimum;
6092 mouse_value = false;
6095 area = tb.ClientRectangle;
6098 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
6099 } else if (tb.thumb_pressed == true) {
6100 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
6102 br_thumb = SystemBrushes.Control;
6106 /* Control Background */
6107 if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
6108 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
6110 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
6114 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
6117 if (tb.Orientation == Orientation.Vertical) {
6118 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6119 br_thumb, ticks, value_pos, mouse_value);
6122 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6123 br_thumb, ticks, value_pos, mouse_value);
6126 tb.ThumbPos = thumb_pos;
6127 tb.ThumbArea = thumb_area;
6130 public override Size TrackBarDefaultSize {
6132 return new Size (104, 42);
6136 public override bool TrackBarHasHotThumbStyle {
6141 #endregion // TrackBar
6144 public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
6146 ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
6149 public override bool UpDownBaseHasHotButtonStyle {
6157 public override Size VScrollBarDefaultSize {
6159 return new Size (this.ScrollBarButtonSize, 80);
6162 #endregion // VScrollBar
6165 public override Size TreeViewDefaultSize {
6167 return new Size (121, 97);
6171 public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
6173 int height = treeView.ActualItemHeight - 2;
6174 dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
6176 dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
6178 if (node.IsExpanded) {
6179 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6181 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6182 dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
6187 #region Managed window
6188 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
6190 if (wm.IsToolWindow && !wm.IsMinimized)
6191 return SystemInformation.ToolWindowCaptionHeight;
6192 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6194 return SystemInformation.CaptionHeight;
6197 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
6199 if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) ||
6206 public override int ManagedWindowIconWidth (InternalWindowManager wm)
6208 return ManagedWindowTitleBarHeight (wm) - 5;
6211 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
6213 TitleButtons buttons = wm.TitleButtons;
6214 Form form = wm.form;
6216 buttons.HelpButton.Visible = form.HelpButton;
6218 foreach (TitleButton button in buttons) {
6219 button.Visible = false;
6222 switch (form.FormBorderStyle) {
6223 case FormBorderStyle.None:
6224 if (form.WindowState != FormWindowState.Normal)
6225 goto case FormBorderStyle.Sizable;
6227 case FormBorderStyle.FixedToolWindow:
6228 case FormBorderStyle.SizableToolWindow:
6229 buttons.CloseButton.Visible = true;
6230 if (form.WindowState != FormWindowState.Normal)
6231 goto case FormBorderStyle.Sizable;
6233 case FormBorderStyle.FixedSingle:
6234 case FormBorderStyle.Fixed3D:
6235 case FormBorderStyle.FixedDialog:
6236 case FormBorderStyle.Sizable:
6237 switch (form.WindowState) {
6238 case FormWindowState.Normal:
6239 buttons.MinimizeButton.Visible = true;
6240 buttons.MaximizeButton.Visible = true;
6241 buttons.RestoreButton.Visible = false;
6243 case FormWindowState.Maximized:
6244 buttons.MinimizeButton.Visible = true;
6245 buttons.MaximizeButton.Visible = false;
6246 buttons.RestoreButton.Visible = true;
6248 case FormWindowState.Minimized:
6249 buttons.MinimizeButton.Visible = false;
6250 buttons.MaximizeButton.Visible = true;
6251 buttons.RestoreButton.Visible = true;
6254 buttons.CloseButton.Visible = true;
6258 // Respect MinimizeBox/MaximizeBox
6259 if (form.MinimizeBox == false && form.MaximizeBox == false) {
6260 buttons.MinimizeButton.Visible = false;
6261 buttons.MaximizeButton.Visible = false;
6262 } else if (form.MinimizeBox == false)
6263 buttons.MinimizeButton.State = ButtonState.Inactive;
6264 else if (form.MaximizeBox == false)
6265 buttons.MaximizeButton.State = ButtonState.Inactive;
6267 int bw = ManagedWindowBorderWidth (wm);
6268 Size btsize = ManagedWindowButtonSize (wm);
6269 int btw = btsize.Width;
6270 int bth = btsize.Height;
6272 int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton;
6274 if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6275 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6278 if (buttons.MaximizeButton.Visible) {
6279 buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6282 if (buttons.RestoreButton.Visible) {
6283 buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6287 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6289 } else if (wm.IsToolWindow) {
6290 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6295 protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm)
6297 Form form = wm.Form;
6298 int tbheight = ManagedWindowTitleBarHeight (wm);
6299 int bdwidth = ManagedWindowBorderWidth (wm);
6300 Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6301 Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6302 Color color = ThemeEngine.Current.ColorControlDark;
6303 Color color2 = Color.FromArgb (255, 192, 192, 192);
6305 Pen pen = ResPool.GetPen (ColorControl);
6306 Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6307 ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6308 // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6309 borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6310 for (int i = 2; i < bdwidth; i++) {
6311 dc.DrawRectangle (pen, borders);
6312 borders.Inflate (-1, -1);
6316 bool draw_titlebar_enabled = false;
6317 if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6318 draw_titlebar_enabled = false;
6319 } else if (wm.IsActive && !wm.IsMaximized) {
6320 draw_titlebar_enabled = true;
6322 if (draw_titlebar_enabled) {
6323 color = titlebar_color;
6324 color2 = titlebar_color2;
6327 Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6329 // HACK: For now always draw the titlebar until we get updates better
6330 if (tb.Width > 0 && tb.Height > 0) {
6331 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6333 dc.FillRectangle (gradient, tb);
6337 if (!wm.IsMinimized)
6338 // Draw the line just beneath the title bar
6339 dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6340 tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6341 tbheight + bdwidth - 1);
6345 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6348 Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6349 dc.FillRectangle (Brushes.Black, clip);
6351 Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm);
6353 Form form = wm.Form;
6355 Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6356 if (icon.IntersectsWith (clip))
6357 dc.DrawIcon (form.Icon, icon);
6358 const int SpacingBetweenIconAndCaption = 2;
6359 tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ;
6360 tb.X = icon.Right + SpacingBetweenIconAndCaption;
6363 foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6364 tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form));
6366 const int SpacingBetweenCaptionAndLeftMostButton = 3;
6367 tb.Width -= SpacingBetweenCaptionAndLeftMostButton;
6369 string window_caption = form.Text;
6370 window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6372 if (window_caption != null && window_caption != string.Empty) {
6373 StringFormat format = new StringFormat ();
6374 format.FormatFlags = StringFormatFlags.NoWrap;
6375 format.Trimming = StringTrimming.EllipsisCharacter;
6376 format.LineAlignment = StringAlignment.Center;
6378 if (tb.IntersectsWith (clip))
6379 dc.DrawString (window_caption, WindowBorderFont,
6380 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6385 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6387 int height = ManagedWindowTitleBarHeight (wm);
6388 if (!wm.IsMaximized && !wm.IsMinimized) {
6389 if (wm.IsToolWindow)
6390 return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6392 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6395 height = SystemInformation.CaptionHeight;
6397 return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6401 private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6403 if (!button.Visible) {
6404 return int.MaxValue;
6407 if (button.Rectangle.IntersectsWith (clip)) {
6408 ManagedWindowDrawTitleButton (dc, button, clip, form);
6410 return button.Rectangle.Left;
6413 protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6415 dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6417 ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6418 button.Caption, button.State);
6421 public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6423 int bw = ManagedWindowBorderWidth (wm);
6424 return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6427 public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm)
6429 Size result = SystemInformation.MenuButtonSize;
6435 public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form)
6440 public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)
6442 dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6443 ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6444 button.Caption, button.State);
6447 public override void ManagedWindowOnSizeInitializedOrChanged (Form form)
6452 #region ControlPaint
6453 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6454 ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6455 Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6456 int bottomWidth, ButtonBorderStyle bottomStyle) {
6457 DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6458 DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6459 DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6460 DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6463 public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6464 ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6465 Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6466 int bottomWidth, ButtonBorderStyle bottomStyle) {
6467 DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6468 DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6469 DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6470 DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6473 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6474 CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6477 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6480 Pen penTopLeftInner;
6482 Pen penBottomRightInner;
6483 Rectangle rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6484 bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6486 if ((style & Border3DStyle.Adjust) != 0) {
6493 penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6495 CPColor cpcolor = CPColor.Empty;
6497 if (!is_ColorControl)
6498 cpcolor = ResPool.GetCPColor (control_color);
6501 case Border3DStyle.Raised:
6502 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6503 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6504 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6506 case Border3DStyle.Sunken:
6507 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6508 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6509 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6511 case Border3DStyle.Etched:
6512 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6513 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6515 case Border3DStyle.RaisedOuter:
6516 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6518 case Border3DStyle.SunkenOuter:
6519 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6520 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6522 case Border3DStyle.RaisedInner:
6523 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6524 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6526 case Border3DStyle.SunkenInner:
6527 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6529 case Border3DStyle.Flat:
6530 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6532 case Border3DStyle.Bump:
6533 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6539 bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6541 if ((sides & Border3DSide.Middle) != 0) {
6542 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6543 graphics.FillRectangle (brush, rect);
6546 if ((sides & Border3DSide.Left) != 0) {
6547 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6548 if ((rect.Width > 2) && inner)
6549 graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6552 if ((sides & Border3DSide.Top) != 0) {
6553 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6554 if ((rect.Height > 2) && inner)
6555 graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6558 if ((sides & Border3DSide.Right) != 0) {
6559 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6560 if ((rect.Width > 3) && inner)
6561 graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6564 if ((sides & Border3DSide.Bottom) != 0) {
6565 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6566 if ((rect.Height > 3) && inner)
6567 graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6571 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6573 CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6576 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6578 // sadly enough, the rectangle gets always filled with a hatchbrush
6579 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6580 Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6581 ColorControl.G, ColorControl.B),
6583 rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6585 if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6586 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6588 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6590 if ((state & ButtonState.Flat) == ButtonState.Flat) {
6591 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6593 if ((state & ButtonState.Checked) == ButtonState.Checked) {
6594 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6597 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6598 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6601 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6602 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6605 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6606 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6608 if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6610 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6611 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6614 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6615 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6618 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6619 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6621 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6623 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6624 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6627 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6628 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6631 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6632 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6637 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6638 Rectangle captionRect;
6641 CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6643 if (rectangle.Width<rectangle.Height) {
6644 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6646 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6649 if ((state & ButtonState.Pushed)!=0) {
6650 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6653 /* Make sure we've got at least a line width of 1 */
6654 lineWidth=Math.Max(1, captionRect.Width/7);
6657 case CaptionButton.Close: {
6660 if ((state & ButtonState.Inactive)!=0) {
6661 pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6662 DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6664 pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6665 DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6668 pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6669 DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6674 case CaptionButton.Help:
6675 case CaptionButton.Maximize:
6676 case CaptionButton.Minimize:
6677 case CaptionButton.Restore: {
6678 if ((state & ButtonState.Inactive)!=0) {
6679 DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6681 DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6684 DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6691 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6693 CPDrawCheckBoxInternal (dc, rectangle, state, false /* mixed */);
6696 private void CPDrawCheckBoxInternal (Graphics dc, Rectangle rectangle, ButtonState state, bool mixed)
6698 Pen check_pen = (mixed) ? Pens.Gray : Pens.Black;
6700 Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6702 if ((state & ButtonState.All) == ButtonState.All) {
6704 cb_rect.Height -= 2;
6706 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6707 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6709 check_pen = SystemPens.ControlDark;
6711 if ((state & ButtonState.Flat) == ButtonState.Flat) {
6713 cb_rect.Height -= 2;
6715 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6716 dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6718 dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6719 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6722 cb_rect.Height -= 1;
6724 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6726 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6727 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6729 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6731 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6732 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6733 Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6734 ColorControl.G, ColorControl.B),
6735 ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6737 dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6739 Pen pen = SystemPens.ControlDark;
6740 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6741 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6743 pen = SystemPens.ControlDarkDark;
6744 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6745 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6747 pen = SystemPens.ControlLightLight;
6748 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6749 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6751 // oh boy, matching ms is like fighting against windmills
6752 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6753 Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6754 ColorControl.G, ColorControl.B), ColorControl))) {
6755 dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6756 dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6759 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6760 check_pen = SystemPens.ControlDark;
6763 if ((state & ButtonState.Checked) == ButtonState.Checked) {
6764 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6766 if (check_size < 7) {
6767 int lineWidth = Math.Max (3, check_size / 3);
6768 int Scale = Math.Max (1, check_size / 9);
6770 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,
6771 check_size, check_size);
6773 for (int i = 0; i < lineWidth; i++) {
6774 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6775 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);
6778 int lineWidth = Math.Max (3, check_size / 3) + 1;
6780 int x_half = cb_rect.Width / 2;
6781 int y_half = cb_rect.Height / 2;
6783 Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2),
6784 check_size, check_size);
6786 int gradient_left = check_size / 3;
6787 int gradient_right = check_size - gradient_left - 1;
6790 for (int i = 0; i < lineWidth; i++) {
6791 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6792 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i - 1 - gradient_right);
6798 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6799 Point[] arrow = new Point[3];
6809 if ((state & ButtonState.Checked)!=0) {
6810 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);
6813 if ((state & ButtonState.Flat)!=0) {
6814 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6816 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6817 // this needs to render like a pushed button - jba
6818 // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6819 Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6820 graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6822 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6826 rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6827 centerX=rect.Left+rect.Width/2;
6828 centerY=rect.Top+rect.Height/2;
6829 shiftX=Math.Max(1, rect.Width/8);
6830 shiftY=Math.Max(1, rect.Height/8);
6832 if ((state & ButtonState.Pushed)!=0) {
6839 P1=new Point(rect.Left, centerY);
6840 P2=new Point(rect.Right, centerY);
6841 P3=new Point(centerX, rect.Bottom);
6847 /* Draw the arrow */
6848 if ((state & ButtonState.Inactive)!=0) {
6849 /* Move away from the shadow */
6850 arrow[0].X += 1; arrow[0].Y += 1;
6851 arrow[1].X += 1; arrow[1].Y += 1;
6852 arrow[2].X += 1; arrow[2].Y += 1;
6854 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6860 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6862 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6867 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6869 Pen pen = Pens.Black;
6870 Rectangle rect = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1); // Dunno why, but MS does it that way, too
6874 graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6875 graphics.DrawRectangle (pen, rect);
6877 X = rect.X + rect.Width / 2;
6878 Y = rect.Y + rect.Height / 2;
6880 /* Draw the cross */
6881 graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6882 graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6884 /* Draw 'arrows' for vertical lines */
6885 graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6886 graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6888 /* Draw 'arrows' for horizontal lines */
6889 graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6890 graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6893 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6894 // make a rectange to trace around border of the button
6895 Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6897 Color outerColor = foreColor;
6898 // adjust focus color according to the flatstyle
6899 if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6900 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;
6903 // draw the outer rectangle
6904 graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);
6906 // draw the inner rectangle
6907 if (button.FlatStyle == FlatStyle.Popup) {
6908 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6910 // draw a flat inner rectangle
6911 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6912 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));
6916 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6918 // make a rectange to trace around border of the button
6919 Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6921 #if NotUntilCairoIsFixed
6922 Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6923 DashStyle oldStyle; // used for caching old penstyle
6924 Pen pen = ResPool.GetPen (colorBackInverted);
6926 oldStyle = pen.DashStyle;
6927 pen.DashStyle = DashStyle.Dot;
6929 graphics.DrawRectangle (pen, trace_rectangle);
6930 pen.DashStyle = oldStyle;
6932 CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6937 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor)
6939 Rectangle rect = rectangle;
6943 if (backColor.GetBrightness () >= 0.5) {
6944 foreColor = Color.Transparent;
6945 backColor = Color.Black;
6948 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6949 foreColor = Color.Black;
6952 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6953 pen = new Pen (brush, 1);
6958 graphics.DrawRectangle (pen, rect);
6962 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6967 if (primary == true) {
6969 if (enabled == true) {
6972 sb = SystemBrushes.Control;
6976 if (enabled == true) {
6979 sb = SystemBrushes.Control;
6982 graphics.FillRectangle (sb, rectangle);
6983 graphics.DrawRectangle (pen, rectangle);
6987 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6993 ControlPaint.Color2HBS(backColor, out h, out b, out s);
6996 foreColor=Color.Black;
6998 foreColor=Color.White;
7001 // still not perfect. it seems that ms calculates the position of the first dot or line
7003 using (Pen pen = new Pen (foreColor)) {
7004 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
7006 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
7007 graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
7011 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
7013 Microsoft seems to ignore the background and simply make
7014 the image grayscale. At least when having > 256 colors on
7018 if (imagedisabled_attributes == null) {
7019 imagedisabled_attributes = new ImageAttributes ();
7020 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
7021 // This table would create a perfect grayscale image, based on luminance
7022 // new float[]{0.3f,0.3f,0.3f,0,0},
7023 // new float[]{0.59f,0.59f,0.59f,0,0},
7024 // new float[]{0.11f,0.11f,0.11f,0,0},
7025 // new float[]{0,0,0,1,0,0},
7026 // new float[]{0,0,0,0,1,0},
7027 // new float[]{0,0,0,0,0,1}
7029 // This table generates a image that is grayscaled and then
7030 // brightened up. Seems to match MS close enough.
7031 new float[]{0.2f,0.2f,0.2f,0,0},
7032 new float[]{0.41f,0.41f,0.41f,0,0},
7033 new float[]{0.11f,0.11f,0.11f,0,0},
7034 new float[]{0.15f,0.15f,0.15f,1,0,0},
7035 new float[]{0.15f,0.15f,0.15f,0,1,0},
7036 new float[]{0.15f,0.15f,0.15f,0,0,1}
7039 imagedisabled_attributes.SetColorMatrix (colorMatrix);
7042 graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
7047 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
7052 penBorder = ResPool.GetSizedPen (Color.White, 2);
7053 penInside = ResPool.GetPen (Color.Black);
7055 penBorder = ResPool.GetSizedPen (Color.Black, 2);
7056 penInside = ResPool.GetPen (Color.White);
7058 penBorder.Alignment=PenAlignment.Inset;
7059 penInside.Alignment=PenAlignment.Inset;
7061 graphics.DrawRectangle(penBorder, rectangle);
7062 graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
7066 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
7070 if (backColor != Color.Empty)
7071 graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
7073 Brush brush = ResPool.GetSolidBrush (color);
7076 case MenuGlyph.Arrow: {
7077 float height = rectangle.Height * 0.7f;
7078 float width = height / 2.0f;
7080 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
7082 PointF [] vertices = new PointF [3];
7083 vertices [0].X = ddCenter.X;
7084 vertices [0].Y = ddCenter.Y - (height / 2.0f);
7085 vertices [1].X = ddCenter.X;
7086 vertices [1].Y = ddCenter.Y + (height / 2.0f);
7087 vertices [2].X = ddCenter.X + width + 0.1f;
7088 vertices [2].Y = ddCenter.Y;
7090 graphics.FillPolygon (brush, vertices);
7095 case MenuGlyph.Bullet: {
7097 lineWidth=Math.Max(2, rectangle.Width/3);
7098 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
7100 graphics.FillEllipse(brush, rect);
7105 case MenuGlyph.Checkmark: {
7107 Pen pen = ResPool.GetPen (color);
7108 lineWidth = Math.Max (2, rectangle.Width / 6);
7109 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
7111 int Scale = Math.Max (1, rectangle.Width / 12);
7112 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
7114 for (int i=0; i<lineWidth; i++) {
7115 graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
7116 graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
7124 public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
7126 CPDrawCheckBoxInternal (graphics, rectangle, state, true /* mixed */);
7129 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
7131 CPColor cpcolor = ResPool.GetCPColor (ColorControl);
7133 Color dot_color = Color.Black;
7135 Color top_left_outer = Color.Black;
7136 Color top_left_inner = Color.Black;
7137 Color bottom_right_outer = Color.Black;
7138 Color bottom_right_inner = Color.Black;
7140 int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height * 0.9f) : (int)(rectangle.Width * 0.9f);
7141 int radius = ellipse_diameter / 2;
7143 Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
7147 if ((state & ButtonState.All) == ButtonState.All) {
7148 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
7149 ColorControl.G, ColorControl.B), ColorControl);
7150 dot_color = cpcolor.Dark;
7152 if ((state & ButtonState.Flat) == ButtonState.Flat) {
7153 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7154 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7156 brush = SystemBrushes.ControlLightLight;
7158 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7159 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7161 brush = SystemBrushes.ControlLightLight;
7163 top_left_outer = cpcolor.Dark;
7164 top_left_inner = cpcolor.DarkDark;
7165 bottom_right_outer = cpcolor.Light;
7166 bottom_right_inner = Color.Transparent;
7168 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
7169 dot_color = cpcolor.Dark;
7172 dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
7174 int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
7176 dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
7177 dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
7178 dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
7180 if (bottom_right_inner != Color.Transparent)
7181 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7183 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)) {
7184 dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7187 if ((state & ButtonState.Checked) == ButtonState.Checked) {
7188 int inflate = line_width * 4;
7189 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
7190 if (rectangle.Height > 13) {
7194 dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
7196 Pen pen = ResPool.GetPen (dot_color);
7197 dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
7198 dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
7200 dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
7201 dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
7206 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
7211 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
7216 /* Scroll button: regular button + direction arrow */
7217 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
7219 DrawScrollButtonPrimitive (dc, area, state);
7221 bool fill_rect = true;
7224 if ((state & ButtonState.Pushed) != 0)
7228 Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
7230 Point [] arrow = new Point [3];
7231 for (int i = 0; i < 3; i++)
7232 arrow [i] = new Point ();
7234 Pen pen = SystemPens.ControlText;
7236 if ((state & ButtonState.Inactive) != 0) {
7237 pen = SystemPens.ControlDark;
7242 case ScrollButton.Down:
7243 int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7244 int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7248 int triangle_height;
7250 if (rect.Height < 8) {
7251 triangle_height = 2;
7253 } else if (rect.Height == 11) {
7254 triangle_height = 3;
7256 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7259 arrow [0].X = rect.X + x_middle;
7260 arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
7262 arrow [1].X = arrow [0].X + triangle_height - 1;
7263 arrow [1].Y = arrow [0].Y - triangle_height + 1;
7264 arrow [2].X = arrow [0].X - triangle_height + 1;
7265 arrow [2].Y = arrow [1].Y;
7267 dc.DrawPolygon (pen, arrow);
7269 if ((state & ButtonState.Inactive) != 0) {
7270 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
7271 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
7275 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
7276 dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
7283 case ScrollButton.Up:
7284 x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7285 y_middle = (int)Math.Round (rect.Height / 2.0f);
7292 if (rect.Height < 8) {
7293 triangle_height = 2;
7295 } else if (rect.Height == 11) {
7296 triangle_height = 3;
7298 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7301 arrow [0].X = rect.X + x_middle;
7302 arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7304 arrow [1].X = arrow [0].X + triangle_height - 1;
7305 arrow [1].Y = arrow [0].Y + triangle_height - 1;
7306 arrow [2].X = arrow [0].X - triangle_height + 1;
7307 arrow [2].Y = arrow [1].Y;
7309 dc.DrawPolygon (pen, arrow);
7311 if ((state & ButtonState.Inactive) != 0) {
7312 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7316 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7317 dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7324 case ScrollButton.Left:
7325 y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7331 if (rect.Width < 8) {
7334 } else if (rect.Width == 11) {
7337 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7340 arrow [0].X = rect.Left + triangle_width - 1;
7341 arrow [0].Y = rect.Y + y_middle;
7343 if (arrow [0].X - 1 == rect.X)
7346 arrow [1].X = arrow [0].X + triangle_width - 1;
7347 arrow [1].Y = arrow [0].Y - triangle_width + 1;
7348 arrow [2].X = arrow [1].X;
7349 arrow [2].Y = arrow [0].Y + triangle_width - 1;
7351 dc.DrawPolygon (pen, arrow);
7353 if ((state & ButtonState.Inactive) != 0) {
7354 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7358 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7359 dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7366 case ScrollButton.Right:
7367 y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7371 if (rect.Width < 8) {
7374 } else if (rect.Width == 11) {
7377 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7380 arrow [0].X = rect.Right - triangle_width - 1;
7381 arrow [0].Y = rect.Y + y_middle;
7383 if (arrow [0].X - 1 == rect.X)
7386 arrow [1].X = arrow [0].X - triangle_width + 1;
7387 arrow [1].Y = arrow [0].Y - triangle_width + 1;
7388 arrow [2].X = arrow [1].X;
7389 arrow [2].Y = arrow [0].Y + triangle_width - 1;
7391 dc.DrawPolygon (pen, arrow);
7393 if ((state & ButtonState.Inactive) != 0) {
7394 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7395 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7399 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7400 dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7409 public override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7415 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7417 Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7418 Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7420 for (int i = 2; i < bounds.Width - 2; i += 4) {
7421 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7422 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7423 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7427 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7429 CPColor cpcolor = ResPool.GetCPColor (color);
7431 layoutRectangle.Offset (1, 1);
7432 TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7434 layoutRectangle.Offset (-1, -1);
7435 TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7438 public override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7440 CPColor cpcolor = ResPool.GetCPColor (color);
7442 dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight),
7443 new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7445 dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7448 public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7450 CPColor cpcolor = ResPool.GetCPColor (color);
7452 layoutRectangle.Offset (1, 1);
7453 TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7455 layoutRectangle.Offset (-1, -1);
7456 TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7459 public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7461 graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7464 private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7465 int width, Color color, ButtonBorderStyle style, Border3DSide side)
7467 DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY,
7468 width, color, style, side);
7471 private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7472 int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7477 case ButtonBorderStyle.Solid:
7478 case ButtonBorderStyle.Inset:
7479 case ButtonBorderStyle.Outset:
7480 pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7482 case ButtonBorderStyle.Dashed:
7483 pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7485 case ButtonBorderStyle.Dotted:
7486 pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7489 case ButtonBorderStyle.None:
7494 case ButtonBorderStyle.Outset: {
7496 int hue, brightness, saturation;
7497 int brightnessSteps;
7498 int brightnessDownSteps;
7500 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7502 brightnessDownSteps=brightness/width;
7503 if (brightness>127) {
7504 brightnessSteps=Math.Max(6, (160-brightness)/width);
7506 brightnessSteps=(127-brightness)/width;
7509 for (int i=0; i<width; i++) {
7511 case Border3DSide.Left: {
7512 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7513 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7514 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7518 case Border3DSide.Right: {
7519 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7520 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7521 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7525 case Border3DSide.Top: {
7526 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7527 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7528 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7532 case Border3DSide.Bottom: {
7533 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7534 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7535 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7543 case ButtonBorderStyle.Inset: {
7545 int hue, brightness, saturation;
7546 int brightnessSteps;
7547 int brightnessDownSteps;
7549 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7551 brightnessDownSteps=brightness/width;
7552 if (brightness>127) {
7553 brightnessSteps=Math.Max(6, (160-brightness)/width);
7555 brightnessSteps=(127-brightness)/width;
7558 for (int i=0; i<width; i++) {
7560 case Border3DSide.Left: {
7561 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7562 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7563 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7567 case Border3DSide.Right: {
7568 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7569 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7570 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7574 case Border3DSide.Top: {
7575 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7576 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7577 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7581 case Border3DSide.Bottom: {
7582 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7583 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7584 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7593 I decided to have the for-loop duplicated for speed reasons;
7594 that way we only have to switch once (as opposed to have the
7595 for-loop around the switch)
7599 case Border3DSide.Left: {
7600 for (int i=0; i<width; i++) {
7601 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7606 case Border3DSide.Right: {
7607 for (int i=0; i<width; i++) {
7608 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7613 case Border3DSide.Top: {
7614 for (int i=0; i<width; i++) {
7615 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7620 case Border3DSide.Bottom: {
7621 for (int i=0; i<width; i++) {
7622 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7633 This function actually draws the various caption elements.
7634 This way we can scale them nicely, no matter what size, and they
7635 still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7638 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7640 case CaptionButton.Close: {
7642 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);
7643 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);
7646 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7647 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7651 case CaptionButton.Help: {
7652 StringFormat sf = new StringFormat();
7653 Font font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7655 sf.Alignment=StringAlignment.Center;
7656 sf.LineAlignment=StringAlignment.Center;
7659 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7667 case CaptionButton.Maximize: {
7668 /* Top 'caption bar' line */
7669 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7670 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);
7673 /* Left side line */
7674 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7675 graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7678 /* Right side line */
7679 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7680 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);
7684 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7685 graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7690 case CaptionButton.Minimize: {
7692 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7693 graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7698 case CaptionButton.Restore: {
7699 /** First 'window' **/
7700 /* Top 'caption bar' line */
7701 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7702 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);
7705 /* Left side line */
7706 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7707 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);
7710 /* Right side line */
7711 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7712 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);
7716 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7717 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);
7720 /** Second 'window' **/
7721 /* Top 'caption bar' line */
7722 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7723 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);
7726 /* Left side line */
7727 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7728 graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7731 /* Right side line */
7732 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7733 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);
7737 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7738 graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7747 /* Generic scroll button */
7748 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7749 if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7750 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7751 area.Y + 1, area.Width - 2 , area.Height - 2);
7753 dc.DrawRectangle (SystemPens.ControlDark, area.X,
7754 area.Y, area.Width, area.Height);
7759 Brush sb_control = SystemBrushes.Control;
7760 Brush sb_lightlight = SystemBrushes.ControlLightLight;
7761 Brush sb_dark = SystemBrushes.ControlDark;
7762 Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7764 dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7765 dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7767 dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7768 dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7771 dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7774 dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7777 dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7778 area.Y + 1, 1, area.Height -3);
7780 dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7781 area.Y, 1, area.Height - 1);
7783 dc.FillRectangle (sb_control, area.X + 2,
7784 area.Y + 2, area.Width - 4, area.Height - 4);
7788 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7789 switch (border_style){
7790 case BorderStyle.Fixed3D:
7791 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7792 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7793 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width ,
7794 area.Y + area.Height - 1);
7795 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1,
7796 area.Y + area.Height);
7798 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7799 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7800 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7801 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7803 case BorderStyle.FixedSingle:
7804 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7806 case BorderStyle.None:
7812 #endregion // ControlPaint