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