diff options
Diffstat (limited to 'source/ShiftUI/Theming')
26 files changed, 21631 insertions, 0 deletions
diff --git a/source/ShiftUI/Theming/Default/.gitattributes b/source/ShiftUI/Theming/Default/.gitattributes new file mode 100644 index 0000000..fdf3545 --- /dev/null +++ b/source/ShiftUI/Theming/Default/.gitattributes @@ -0,0 +1,5 @@ +/ButtonPainter.cs -crlf +/CheckBoxPainter.cs -crlf +/RadioButtonPainter.cs -crlf +/TabWidgetPainter.cs -crlf +/ToolStripPainter.cs -crlf diff --git a/source/ShiftUI/Theming/Default/ButtonPainter.cs b/source/ShiftUI/Theming/Default/ButtonPainter.cs new file mode 100644 index 0000000..366b17d --- /dev/null +++ b/source/ShiftUI/Theming/Default/ButtonPainter.cs @@ -0,0 +1,189 @@ +// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007 Novell, Inc.
+//
+// Authors:
+// Andreia Gaita ([email protected])
+
+using System;
+using System.Drawing;
+
+namespace ShiftUI.Theming.Default
+{
+ /// <summary>
+ /// Summary description for Button.
+ /// </summary>
+ internal class ButtonPainter
+ {
+ public ButtonPainter ()
+ {
+
+ }
+
+ protected SystemResPool ResPool { get { return ThemeEngine.Current.ResPool; } }
+
+ #region Buttons
+ #region Standard Button
+ public virtual void Draw (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) {
+ bool is_themecolor = backColor.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb () || backColor == Color.Empty ? true : false;
+ CPColor cpcolor = is_themecolor ? CPColor.Empty : ResPool.GetCPColor (backColor);
+ Pen pen;
+
+ switch (state) {
+ case ButtonThemeState.Normal:
+ case ButtonThemeState.Entered:
+ case ButtonThemeState.Disabled:
+ pen = is_themecolor ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
+ g.DrawLine (pen, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 2);
+ g.DrawLine (pen, bounds.X + 1, bounds.Y, bounds.Right - 2, bounds.Y);
+
+ pen = is_themecolor ? SystemPens.Control : ResPool.GetPen (backColor);
+ g.DrawLine (pen, bounds.X + 1, bounds.Y + 1, bounds.X + 1, bounds.Bottom - 3);
+ g.DrawLine (pen, bounds.X + 2, bounds.Y + 1, bounds.Right - 3, bounds.Y + 1);
+
+ pen = is_themecolor ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
+ g.DrawLine (pen, bounds.X + 1, bounds.Bottom - 2, bounds.Right - 2, bounds.Bottom - 2);
+ g.DrawLine (pen, bounds.Right - 2, bounds.Y + 1, bounds.Right - 2, bounds.Bottom - 3);
+
+ pen = is_themecolor ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
+ g.DrawLine (pen, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1);
+ g.DrawLine (pen, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 2);
+ break;
+ case ButtonThemeState.Pressed:
+ g.DrawRectangle (ResPool.GetPen (foreColor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
+
+ bounds.Inflate (-1, -1);
+ pen = is_themecolor ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
+ g.DrawRectangle (pen, bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
+ break;
+ case ButtonThemeState.Default:
+ g.DrawRectangle (ResPool.GetPen (foreColor), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
+
+ bounds.Inflate (-1, -1);
+ pen = is_themecolor ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
+ g.DrawLine (pen, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 2);
+ g.DrawLine (pen, bounds.X + 1, bounds.Y, bounds.Right - 2, bounds.Y);
+
+ pen = is_themecolor ? SystemPens.Control : ResPool.GetPen (backColor);
+ g.DrawLine (pen, bounds.X + 1, bounds.Y + 1, bounds.X + 1, bounds.Bottom - 3);
+ g.DrawLine (pen, bounds.X + 2, bounds.Y + 1, bounds.Right - 3, bounds.Y + 1);
+
+ pen = is_themecolor ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
+ g.DrawLine (pen, bounds.X + 1, bounds.Bottom - 2, bounds.Right - 2, bounds.Bottom - 2);
+ g.DrawLine (pen, bounds.Right - 2, bounds.Y + 1, bounds.Right - 2, bounds.Bottom - 3);
+
+ pen = is_themecolor ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
+ g.DrawLine (pen, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1);
+ g.DrawLine (pen, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 2);
+ break;
+ }
+ }
+ #endregion
+
+ #region FlatStyle Button
+ public virtual void DrawFlat (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor, FlatButtonAppearance appearance) {
+ bool is_themecolor = backColor.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb () || backColor == Color.Empty ? true : false;
+ CPColor cpcolor = is_themecolor ? CPColor.Empty : ResPool.GetCPColor (backColor);
+ Pen pen;
+
+ switch (state) {
+ case ButtonThemeState.Normal:
+ case ButtonThemeState.Disabled:
+ // This will just use the BackColor
+ break;
+ case ButtonThemeState.Entered:
+ case ButtonThemeState.Default | ButtonThemeState.Entered:
+ if (appearance.MouseOverBackColor != Color.Empty)
+ g.FillRectangle (ResPool.GetSolidBrush (appearance.MouseOverBackColor), bounds);
+ else
+ g.FillRectangle (ResPool.GetSolidBrush (ChangeIntensity (backColor, .9F)), bounds);
+ break;
+ case ButtonThemeState.Pressed:
+ if (appearance.MouseDownBackColor != Color.Empty)
+ g.FillRectangle (ResPool.GetSolidBrush (appearance.MouseDownBackColor), bounds);
+ else
+ g.FillRectangle (ResPool.GetSolidBrush (ChangeIntensity (backColor, .95F)), bounds);
+ break;
+ case ButtonThemeState.Default:
+ if (appearance.CheckedBackColor != Color.Empty)
+ g.FillRectangle (ResPool.GetSolidBrush (appearance.CheckedBackColor), bounds);
+ break;
+ }
+
+ if (appearance.BorderColor == Color.Empty)
+ pen = is_themecolor ? SystemPens.ControlDarkDark : ResPool.GetSizedPen (cpcolor.DarkDark, appearance.BorderSize);
+ else
+ pen = ResPool.GetSizedPen (appearance.BorderColor, appearance.BorderSize);
+
+ bounds.Width -= 1;
+ bounds.Height -= 1;
+
+ if (appearance.BorderSize > 0)
+ g.DrawRectangle (pen, bounds);
+ }
+ #endregion
+
+ #region Popup Button
+ public virtual void DrawPopup (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) {
+ bool is_themecolor = backColor.ToArgb () == ThemeEngine.Current.ColorControl.ToArgb () || backColor == Color.Empty ? true : false;
+ CPColor cpcolor = is_themecolor ? CPColor.Empty : ResPool.GetCPColor (backColor);
+ Pen pen;
+
+ switch (state) {
+ case ButtonThemeState.Normal:
+ case ButtonThemeState.Disabled:
+ case ButtonThemeState.Pressed:
+ case ButtonThemeState.Default:
+ pen = is_themecolor ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
+
+ bounds.Width -= 1;
+ bounds.Height -= 1;
+ g.DrawRectangle (pen, bounds);
+
+ if (state == ButtonThemeState.Default || state == ButtonThemeState.Pressed) {
+ bounds.Inflate (-1, -1);
+ g.DrawRectangle (pen, bounds);
+ }
+ break;
+ case ButtonThemeState.Entered:
+ pen = is_themecolor ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
+ g.DrawLine (pen, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 2);
+ g.DrawLine (pen, bounds.X + 1, bounds.Y, bounds.Right - 2, bounds.Y);
+
+ pen = is_themecolor ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
+ g.DrawLine (pen, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1);
+ g.DrawLine (pen, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 2);
+ break;
+ }
+ }
+ #endregion
+ #endregion
+
+ private static Color ChangeIntensity (Color baseColor, float percent)
+ {
+ int H, I, S;
+
+ WidgetPaint.Color2HBS (baseColor, out H, out I, out S);
+ int NewIntensity = Math.Min (255, (int)(I * percent));
+
+ return WidgetPaint.HBS2Color (H, NewIntensity, S);
+ }
+ }
+}
diff --git a/source/ShiftUI/Theming/Default/CheckBoxPainter.cs b/source/ShiftUI/Theming/Default/CheckBoxPainter.cs new file mode 100644 index 0000000..a759fbf --- /dev/null +++ b/source/ShiftUI/Theming/Default/CheckBoxPainter.cs @@ -0,0 +1,357 @@ +// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007 Novell, Inc.
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Theming.Default
+{
+ /// <summary>
+ /// Summary description for Button.
+ /// </summary>
+ internal class CheckBoxPainter
+ {
+ public CheckBoxPainter ()
+ {
+ }
+
+ protected SystemResPool ResPool { get { return ThemeEngine.Current.ResPool; } }
+
+ public void PaintCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, ElementState state, FlatStyle style, CheckState checkState)
+ {
+ switch (style) {
+ case FlatStyle.Standard:
+ case FlatStyle.System:
+ switch (state) {
+ case ElementState.Normal:
+ DrawNormalCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Hot:
+ DrawHotCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Pressed:
+ DrawPressedCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Disabled:
+ DrawDisabledCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ }
+ break;
+ case FlatStyle.Flat:
+ switch (state) {
+ case ElementState.Normal:
+ DrawFlatNormalCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Hot:
+ DrawFlatHotCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Pressed:
+ DrawFlatPressedCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Disabled:
+ DrawFlatDisabledCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ }
+ break;
+ case FlatStyle.Popup:
+ switch (state) {
+ case ElementState.Normal:
+ DrawPopupNormalCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Hot:
+ DrawPopupHotCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Pressed:
+ DrawPopupPressedCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ case ElementState.Disabled:
+ DrawPopupDisabledCheckBox (g, bounds, backColor, foreColor, checkState);
+ break;
+ }
+ break;
+ }
+ }
+
+ #region Standard
+ public virtual void DrawNormalCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ int check_box_visible_size = (bounds.Height > bounds.Width) ? bounds.Width : bounds.Height;
+ int x_pos = Math.Max (0, bounds.X + (bounds.Width / 2) - check_box_visible_size / 2);
+ int y_pos = Math.Max (0, bounds.Y + (bounds.Height / 2) - check_box_visible_size / 2);
+
+ Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
+
+ g.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
+
+ Pen pen = SystemPens.ControlDark;
+ g.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
+ g.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
+
+ pen = SystemPens.ControlDarkDark;
+ g.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
+ g.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
+
+ pen = SystemPens.ControlLightLight;
+ g.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 1);
+ g.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
+
+ // oh boy, matching ms is like fighting against windmills
+ using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
+ Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
+ ColorControl.G, ColorControl.B), ColorControl))) {
+ g.DrawLine (h_pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
+ g.DrawLine (h_pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 2);
+ }
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDark);
+ }
+
+ public virtual void DrawHotCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ DrawNormalCheckBox (g, bounds, backColor, foreColor, state);
+ }
+
+ public virtual void DrawPressedCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ int check_box_visible_size = (bounds.Height > bounds.Width) ? bounds.Width : bounds.Height;
+ int x_pos = Math.Max (0, bounds.X + (bounds.Width / 2) - check_box_visible_size / 2);
+ int y_pos = Math.Max (0, bounds.Y + (bounds.Height / 2) - check_box_visible_size / 2);
+
+ Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
+
+ g.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
+ Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
+ ColorControl.G, ColorControl.B),
+ ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
+
+ Pen pen = SystemPens.ControlDark;
+ g.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
+ g.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
+
+ pen = SystemPens.ControlDarkDark;
+ g.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
+ g.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
+
+ pen = SystemPens.ControlLightLight;
+ g.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 1);
+ g.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
+
+ // oh boy, matching ms is like fighting against windmills
+ using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
+ Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
+ ColorControl.G, ColorControl.B), ColorControl))) {
+ g.DrawLine (h_pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
+ g.DrawLine (h_pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 2);
+ }
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawDisabledCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ DrawPressedCheckBox (g, bounds, backColor, foreColor, CheckState.Unchecked);
+
+ if (state == CheckState.Checked || state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDark);
+ }
+ #endregion
+
+ #region FlatStyle
+ public virtual void DrawFlatNormalCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ Rectangle checkbox_rectangle;
+ Rectangle fill_rectangle;
+
+ // set up our rectangles first
+ // clip two pixels from bottom right for non popup rendered checkboxes
+ checkbox_rectangle = new Rectangle (bounds.X, bounds.Y, Math.Max (bounds.Width - 2, 0), Math.Max (bounds.Height - 2, 0));
+ 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));
+
+ g.FillRectangle (ResPool.GetSolidBrush (WidgetPaint.LightLight (backColor)), fill_rectangle);
+ WidgetPaint.DrawBorder (g, checkbox_rectangle, foreColor, ButtonBorderStyle.Solid);
+
+ bounds.Offset (-1, 0);
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawFlatHotCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ Rectangle checkbox_rectangle;
+ Rectangle fill_rectangle;
+
+ // set up our rectangles first
+ // clip two pixels from bottom right for non popup rendered checkboxes
+ checkbox_rectangle = new Rectangle (bounds.X, bounds.Y, Math.Max (bounds.Width - 2, 0), Math.Max (bounds.Height - 2, 0));
+ 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));
+
+ g.FillRectangle (ResPool.GetSolidBrush (backColor), fill_rectangle);
+ WidgetPaint.DrawBorder (g, checkbox_rectangle, foreColor, ButtonBorderStyle.Solid);
+
+ bounds.Offset (-1, 0);
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawFlatPressedCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ DrawFlatNormalCheckBox (g, bounds, backColor, foreColor, state);
+ }
+
+ public virtual void DrawFlatDisabledCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ Rectangle checkbox_rectangle;
+
+ checkbox_rectangle = new Rectangle (bounds.X, bounds.Y, Math.Max (bounds.Width - 2, 0), Math.Max (bounds.Height - 2, 0));
+
+ WidgetPaint.DrawBorder (g, checkbox_rectangle, foreColor, ButtonBorderStyle.Solid);
+
+ bounds.Offset (-1, 0);
+
+ if (state == CheckState.Checked || state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+ #endregion
+
+ #region Popup
+ public virtual void DrawPopupNormalCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ DrawFlatNormalCheckBox (g, bounds, backColor, foreColor, state);
+ }
+
+ public virtual void DrawPopupHotCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ Rectangle checkbox_rectangle;
+ Rectangle fill_rectangle;
+
+ // clip one pixel from bottom right for non popup rendered checkboxes
+ checkbox_rectangle = new Rectangle (bounds.X, bounds.Y, Math.Max (bounds.Width - 1, 0), Math.Max (bounds.Height - 1, 0));
+ 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));
+
+ g.FillRectangle (ResPool.GetSolidBrush (WidgetPaint.LightLight (backColor)), fill_rectangle);
+
+ // draw sunken effect
+ ThemeEngine.Current.CPDrawBorder3D (g, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, backColor);
+
+ bounds.Offset (-1, 0);
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawPopupPressedCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ Rectangle checkbox_rectangle;
+ Rectangle fill_rectangle;
+
+ // clip one pixel from bottom right for non popup rendered checkboxes
+ checkbox_rectangle = new Rectangle (bounds.X, bounds.Y, Math.Max (bounds.Width - 1, 0), Math.Max (bounds.Height - 1, 0));
+ 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));
+
+ g.FillRectangle (ResPool.GetSolidBrush (backColor), fill_rectangle);
+
+ // draw sunken effect
+ ThemeEngine.Current.CPDrawBorder3D (g, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, backColor);
+
+ bounds.Offset (-1, 0);
+
+ if (state == CheckState.Checked)
+ DrawCheck (g, bounds, Color.Black);
+ else if (state == CheckState.Indeterminate)
+ DrawCheck (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawPopupDisabledCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state)
+ {
+ DrawFlatDisabledCheckBox (g, bounds, backColor, foreColor, state);
+ }
+ #endregion
+
+ #region Check
+ public virtual void DrawCheck (Graphics g, Rectangle bounds, Color checkColor)
+ {
+ int check_size = (bounds.Height > bounds.Width) ? bounds.Width / 2 : bounds.Height / 2;
+
+ Pen check_pen = ResPool.GetPen (checkColor);
+
+ if (check_size < 7) {
+ int lineWidth = Math.Max (3, check_size / 3);
+ int Scale = Math.Max (1, check_size / 9);
+
+ Rectangle rect = new Rectangle (bounds.X + (bounds.Width / 2) - (check_size / 2) - 1, bounds.Y + (bounds.Height / 2) - (check_size / 2) - 1,
+ check_size, check_size);
+
+ for (int i = 0; i < lineWidth; i++) {
+ g.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
+ g.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);
+ }
+ } else {
+ int lineWidth = Math.Max (3, check_size / 3) + 1;
+
+ int x_half = bounds.Width / 2;
+ int y_half = bounds.Height / 2;
+
+ Rectangle rect = new Rectangle (bounds.X + x_half - (check_size / 2) - 1, bounds.Y + y_half - (check_size / 2),
+ check_size, check_size);
+
+ int gradient_left = check_size / 3;
+ int gradient_right = check_size - gradient_left - 1;
+
+ for (int i = 0; i < lineWidth; i++) {
+ g.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
+ g.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i - 1 - gradient_right);
+ }
+ }
+ }
+ #endregion
+
+ #region Private Methods
+ private int Clamp (int value, int lower, int upper)
+ {
+ if (value < lower) return lower;
+ else if (value > upper) return upper;
+ else return value;
+ }
+
+ private Color ColorControl {
+ get { return SystemColors.Control; }
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Theming/Default/LabelPainter.cs b/source/ShiftUI/Theming/Default/LabelPainter.cs new file mode 100644 index 0000000..15ca995 --- /dev/null +++ b/source/ShiftUI/Theming/Default/LabelPainter.cs @@ -0,0 +1,57 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Everaldo Canuto ([email protected]) + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace ShiftUI.Theming.Default +{ + internal class LabelPainter + { + public LabelPainter () + { + } + + public virtual void Draw (Graphics dc, Rectangle client_rectangle, Label label) + { + Rectangle rect = label.PaddingClientRectangle; + + label.DrawImage (dc, label.Image, rect, label.ImageAlign); + + if (label.Enabled) { + dc.DrawString (label.Text, label.Font, + ThemeEngine.Current.ResPool.GetSolidBrush (label.ForeColor), + rect, label.string_format); + } else { + WidgetPaint.DrawStringDisabled ( + dc, label.Text, label.Font, label.BackColor, rect, label.string_format); + } + } + + public virtual Size DefaultSize { + get { return new Size (100, 23); } + } + } +}
\ No newline at end of file diff --git a/source/ShiftUI/Theming/Default/LinkLabelPainter.cs b/source/ShiftUI/Theming/Default/LinkLabelPainter.cs new file mode 100644 index 0000000..6ac39a0 --- /dev/null +++ b/source/ShiftUI/Theming/Default/LinkLabelPainter.cs @@ -0,0 +1,120 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Everaldo Canuto ([email protected]) + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; + +namespace ShiftUI.Theming.Default +{ + internal class LinkLabelPainter + { + public LinkLabelPainter () + { + } + + private Color GetPieceColor (LinkLabel label, LinkLabel.Piece piece, int i) + { + if (!label.Enabled) + return label.DisabledLinkColor; + + if (piece.link == null) + return label.ForeColor; + + if (!piece.link.Enabled) + return label.DisabledLinkColor; + + if (piece.link.Active) + return label.ActiveLinkColor; + + if ((label.LinkVisited && i == 0) || piece.link.Visited) + return label.VisitedLinkColor; + + return label.LinkColor; + } + + public virtual void Draw (Graphics dc, Rectangle clip_rectangle, LinkLabel label) + { + Rectangle client_rect = label.PaddingClientRectangle; + + label.DrawImage (dc, label.Image, client_rect, label.ImageAlign); + + if (label.pieces == null) + return; + + // Paint all text as disabled. + if (!label.Enabled) { + dc.SetClip (clip_rectangle); + ThemeEngine.Current.CPDrawStringDisabled ( + dc, label.Text, label.Font, label.BackColor, client_rect, label.string_format); + return; + } + + Font font, link_font = ThemeEngine.Current.GetLinkFont (label); + + Region text_region = new Region (new Rectangle()); + + // Draw links. + for (int i = 0; i < label.pieces.Length; i ++) { + LinkLabel.Piece piece = label.pieces[i]; + + if (piece.link == null) { + text_region.Union (piece.region); + continue; + } + + Color color = GetPieceColor (label, piece, i); + + if ( (label.LinkBehavior == LinkBehavior.AlwaysUnderline) || + (label.LinkBehavior == LinkBehavior.SystemDefault) || + ((label.LinkBehavior == LinkBehavior.HoverUnderline) && piece.link.Hovered) ) + font = link_font; + else + font = label.Font; + + dc.Clip = piece.region; + dc.Clip.Intersect (clip_rectangle); + dc.DrawString (label.Text, font, + ThemeEngine.Current.ResPool.GetSolidBrush (color), + client_rect, label.string_format); + + // Draw focus rectangle + if ((piece.link != null) && piece.link.Focused) { + foreach (RectangleF rect in piece.region.GetRegionScans (dc.Transform)) + WidgetPaint.DrawFocusRectangle (dc, Rectangle.Round (rect), label.ForeColor, label.BackColor); + } + } + + // Draw normal text (without links). + if (!text_region.IsEmpty (dc)) { + dc.Clip = text_region; + dc.Clip.Intersect (clip_rectangle); + if (!dc.Clip.IsEmpty (dc)) + dc.DrawString(label.Text, label.Font, + ThemeEngine.Current.ResPool.GetSolidBrush(label.ForeColor), + client_rect, label.string_format); + } + } + } +}
\ No newline at end of file diff --git a/source/ShiftUI/Theming/Default/RadioButtonPainter.cs b/source/ShiftUI/Theming/Default/RadioButtonPainter.cs new file mode 100644 index 0000000..83885ed --- /dev/null +++ b/source/ShiftUI/Theming/Default/RadioButtonPainter.cs @@ -0,0 +1,239 @@ +// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007 Novell, Inc.
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace ShiftUI.Theming.Default
+{
+ /// <summary>
+ /// Summary description for Button.
+ /// </summary>
+ internal class RadioButtonPainter
+ {
+ public RadioButtonPainter ()
+ {
+ }
+
+ protected SystemResPool ResPool { get { return ThemeEngine.Current.ResPool; } }
+
+ public void PaintRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, ElementState state, FlatStyle style, bool isChecked)
+ {
+ switch (style) {
+ case FlatStyle.Standard:
+ case FlatStyle.System:
+ switch (state) {
+ case ElementState.Normal:
+ DrawNormalRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Hot:
+ DrawHotRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Pressed:
+ DrawPressedRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Disabled:
+ DrawDisabledRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ }
+ break;
+ case FlatStyle.Flat:
+ switch (state) {
+ case ElementState.Normal:
+ DrawFlatNormalRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Hot:
+ DrawFlatHotRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Pressed:
+ DrawFlatPressedRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Disabled:
+ DrawFlatDisabledRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ }
+ break;
+ case FlatStyle.Popup:
+ switch (state) {
+ case ElementState.Normal:
+ DrawPopupNormalRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Hot:
+ DrawPopupHotRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Pressed:
+ DrawPopupPressedRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ case ElementState.Disabled:
+ DrawPopupDisabledRadioButton (g, bounds, backColor, foreColor, isChecked);
+ break;
+ }
+ break;
+ }
+ }
+
+ #region Standard
+ public virtual void DrawNormalRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ ButtonState bs = ButtonState.Normal;
+
+ if (isChecked)
+ bs |= ButtonState.Checked;
+
+ WidgetPaint.DrawRadioButton (g, bounds, bs);
+ }
+
+ public virtual void DrawHotRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ DrawNormalRadioButton (g, bounds, backColor, foreColor, isChecked);
+ }
+
+ public virtual void DrawPressedRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ ButtonState bs = ButtonState.Pushed;
+
+ if (isChecked)
+ bs |= ButtonState.Checked;
+
+ WidgetPaint.DrawRadioButton (g, bounds, bs);
+ }
+
+ public virtual void DrawDisabledRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ ButtonState bs = ButtonState.Inactive;
+
+ if (isChecked)
+ bs |= ButtonState.Checked;
+
+ WidgetPaint.DrawRadioButton (g, bounds, bs);
+ }
+ #endregion
+
+ #region FlatStyle
+ public virtual void DrawFlatNormalRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.DrawArc (SystemPens.ControlDarkDark, bounds, 0, 359);
+ g.FillPie (SystemBrushes.ControlLightLight, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawFlatHotRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.DrawArc (SystemPens.ControlDarkDark, bounds, 0, 359);
+ g.FillPie (SystemBrushes.ControlLight, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawFlatPressedRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.DrawArc (SystemPens.ControlDarkDark, bounds, 0, 359);
+ g.FillPie (SystemBrushes.ControlLightLight, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawFlatDisabledRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.FillPie (SystemBrushes.Control, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+ g.DrawArc (SystemPens.ControlDark, bounds, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDark);
+ }
+ #endregion
+
+ #region Popup
+ public virtual void DrawPopupNormalRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.FillPie (SystemBrushes.ControlLightLight, bounds, 0, 359);
+ g.DrawArc (SystemPens.ControlDark, bounds, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawPopupHotRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.FillPie (SystemBrushes.ControlLightLight, bounds, 0, 359);
+ g.DrawArc (SystemPens.ControlLight, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+
+ g.DrawArc (SystemPens.ControlDark, bounds, 135, 180);
+ g.DrawArc (SystemPens.ControlLightLight, bounds, 315, 180);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawPopupPressedRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.FillPie (SystemBrushes.ControlLightLight, bounds, 0, 359);
+ g.DrawArc (SystemPens.ControlLight, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+
+ g.DrawArc (SystemPens.ControlDark, bounds, 135, 180);
+ g.DrawArc (SystemPens.ControlLightLight, bounds, 315, 180);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+
+ public virtual void DrawPopupDisabledRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked)
+ {
+ g.FillPie (SystemBrushes.Control, bounds.X + 1, bounds.Y + 1, bounds.Width - 2, bounds.Height - 2, 0, 359);
+ g.DrawArc (SystemPens.ControlDark, bounds, 0, 359);
+
+ if (isChecked)
+ DrawFlatRadioGlyphDot (g, bounds, SystemColors.ControlDarkDark);
+ }
+ #endregion
+
+ #region Glyph
+ protected void DrawFlatRadioGlyphDot (Graphics g, Rectangle bounds, Color dotColor)
+ {
+ int lineWidth = Math.Max (1, Math.Min (bounds.Width, bounds.Height) / 3);
+
+ Pen dot_pen = ResPool.GetPen (dotColor);
+ Brush dot_brush = ResPool.GetSolidBrush (dotColor);
+
+ if (bounds.Height > 13) {
+ g.FillPie (dot_brush, bounds.X + lineWidth, bounds.Y + lineWidth, bounds.Width - lineWidth * 2, bounds.Height - lineWidth * 2, 0, 359);
+ } else {
+ int x_half_pos = (bounds.Width / 2) + bounds.X;
+ int y_half_pos = (bounds.Height / 2) + bounds.Y;
+
+ g.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
+ g.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
+
+ g.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
+ g.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Theming/Default/TabControlPainter.cs b/source/ShiftUI/Theming/Default/TabControlPainter.cs new file mode 100644 index 0000000..2ecdacd --- /dev/null +++ b/source/ShiftUI/Theming/Default/TabControlPainter.cs @@ -0,0 +1,507 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Andreia Gaita ([email protected]) + +using System; +using System.Drawing; +using System.Drawing.Text; +using ShiftUI; +using ShiftUI.VisualStyles; + +namespace ShiftUI.Theming.Default +{ + /// <summary> + /// Summary description for TabWidget. + /// </summary> + internal class TabWidgetPainter { + protected SystemResPool ResPool { get { return ThemeEngine.Current.ResPool; } } + + #region private + + private Size defaultItemSize; + private Point defaultPadding; + private int minimumTabWidth; + private Rectangle selectedTabDelta; + + private Point tabPanelOffset; + + private int selectedSpacing; + + private Size rowSpacingNormal; + private Size rowSpacingButtons; + private Size rowSpacingFlatButtons; + private int scrollerWidth; + private Point focusRectSpacing; + private Rectangle tabPageSpacing; + private int colSpacing; + private int flatButtonSpacing; + + private Point imagePadding; + + private StringFormat defaultFormatting; + + private Rectangle borderThickness; + + #endregion + + #region Properties + + public virtual Size DefaultItemSize { + get { return defaultItemSize; } + set { defaultItemSize = value; } + } + + public virtual Point DefaultPadding { + get { return defaultPadding; } + set { defaultPadding = value; } + } + + public virtual int MinimumTabWidth { + get { return minimumTabWidth; } + set { minimumTabWidth = value; } + } + + public virtual Rectangle SelectedTabDelta { + get { return selectedTabDelta; } + set { selectedTabDelta = value; } + } + + public virtual Point TabPanelOffset { + get { return tabPanelOffset; } + set { tabPanelOffset = value; } + } + + public virtual int SelectedSpacing { + get { return selectedSpacing; } + set { selectedSpacing = value; } + } + + public virtual Size RowSpacingNormal { + get { return rowSpacingNormal; } + set { rowSpacingNormal = value; } + } + + public virtual Size RowSpacingButtons { + get { return rowSpacingButtons; } + set { rowSpacingButtons = value; } + } + + public virtual Size RowSpacingFlatButtons { + get { return rowSpacingFlatButtons; } + set { rowSpacingFlatButtons = value; } + } + + public virtual Point FocusRectSpacing { + get { return focusRectSpacing; } + set { focusRectSpacing = value; } + } + + public virtual int ColSpacing { + get { return colSpacing; } + set { colSpacing = value; } + } + + public virtual int FlatButtonSpacing { + get { return flatButtonSpacing; } + set { flatButtonSpacing = value; } + } + + public virtual Rectangle TabPageSpacing { + get { return tabPageSpacing; } + set { tabPageSpacing = value; } + } + + public virtual Point ImagePadding { + get { return imagePadding; } + set { imagePadding = value; } + } + + public virtual StringFormat DefaultFormatting { + get { return defaultFormatting; } + set { defaultFormatting = value; } + } + + public virtual Rectangle BorderThickness { + get { return borderThickness; } + set { borderThickness = value; } + } + + public virtual int ScrollerWidth { + get { return scrollerWidth; } + set { scrollerWidth = value; } + } + + public virtual Size RowSpacing (ShiftUI.TabWidget tab) { + switch (tab.Appearance) { + case TabAppearance.Normal: + return rowSpacingNormal; + case TabAppearance.Buttons: + return rowSpacingButtons; + case TabAppearance.FlatButtons: + return rowSpacingFlatButtons; + default: + throw new Exception ("Invalid Appearance value: " + tab.Appearance); + } + } + #endregion + + public TabWidgetPainter () + { + defaultItemSize = new Size (42, 16); + defaultPadding = new Point (6, 3); + selectedTabDelta = new Rectangle (2, 2, 4, 3); + selectedSpacing = 0; + + rowSpacingNormal = new Size (0, 0); + rowSpacingButtons = new Size (3, 3); + rowSpacingFlatButtons = new Size (9, 3); + + colSpacing = 0; + + minimumTabWidth = 42; + scrollerWidth = 17; + focusRectSpacing = new Point (2, 2); + tabPanelOffset = new Point (4, 0); + flatButtonSpacing = 8; + tabPageSpacing = new Rectangle (4, 2, 3, 4); + + imagePadding = new Point (2, 3); + + defaultFormatting = new StringFormat(); + // Horizontal Alignment is handled in the Draw method + defaultFormatting.Alignment = StringAlignment.Near; + defaultFormatting.LineAlignment = StringAlignment.Center; + defaultFormatting.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip; + defaultFormatting.HotkeyPrefix = HotkeyPrefix.Show; + + borderThickness = new Rectangle (1, 1, 2, 2); + } + + public virtual Rectangle GetLeftScrollRect (ShiftUI.TabWidget tab) + { + switch (tab.Alignment) { + case TabAlignment.Top: + return new Rectangle (tab.ClientRectangle.Right - (scrollerWidth * 2), tab.ClientRectangle.Top + 1, scrollerWidth, scrollerWidth); + default: + Rectangle panel_rect = GetTabPanelRect (tab); + return new Rectangle (tab.ClientRectangle.Right - (scrollerWidth * 2), panel_rect.Bottom + 2, scrollerWidth, scrollerWidth); + } + } + + public virtual Rectangle GetRightScrollRect (ShiftUI.TabWidget tab) + { + switch (tab.Alignment) { + case TabAlignment.Top: + return new Rectangle (tab.ClientRectangle.Right - (scrollerWidth), tab.ClientRectangle.Top + 1, scrollerWidth, scrollerWidth); + default: + Rectangle panel_rect = GetTabPanelRect (tab); + return new Rectangle (tab.ClientRectangle.Right - (scrollerWidth), panel_rect.Bottom + 2, scrollerWidth, scrollerWidth); + } + } + + public Rectangle GetDisplayRectangle (ShiftUI.TabWidget tab) + { + Rectangle ext = GetTabPanelRect (tab); + // Account for border size + return new Rectangle (ext.Left + tabPageSpacing.X, ext.Top + tabPageSpacing.Y, + ext.Width - tabPageSpacing.X - tabPageSpacing.Width, ext.Height - tabPageSpacing.Y - tabPageSpacing.Height); + } + + public Rectangle GetTabPanelRect (ShiftUI.TabWidget tab) + { + // Offset the tab page (panel) from the top corner + Rectangle res = tab.ClientRectangle; + + if (tab.TabCount == 0) + return res; + + int spacing = RowSpacing (tab).Height; + int tabOffset = (tab.ItemSize.Height + spacing - selectedTabDelta.Height) * tab.RowCount + selectedTabDelta.Y; + switch (tab.Alignment) { + case TabAlignment.Top: + res.Y += tabOffset; + res.Height -= tabOffset; + break; + case TabAlignment.Bottom: + res.Height -= tabOffset; + break; + case TabAlignment.Left: + res.X += tabOffset; + res.Width -= tabOffset; + break; + case TabAlignment.Right: + res.Width -= tabOffset; + break; + } + + return res; + } + + public virtual void Draw (Graphics dc, Rectangle area, TabWidget tab) + { + DrawBackground (dc, area, tab); + + int start = 0; + int end = tab.TabPages.Count; + int delta = 1; + + if (tab.Alignment == TabAlignment.Top) { + start = end; + end = 0; + delta = -1; + } + + if (tab.SizeMode == TabSizeMode.Fixed) + defaultFormatting.Alignment = StringAlignment.Center; + else + defaultFormatting.Alignment = StringAlignment.Near; + + int counter = start; + for (; counter != end; counter += delta) { + for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) { + if (i == tab.SelectedIndex) + continue; + if (counter != tab.TabPages[i].Row) + continue; + Rectangle rect = tab.GetTabRect (i); + if (!rect.IntersectsWith (area)) + continue; + DrawTab (dc, tab.TabPages[i], tab, rect, false); + } + } + + if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) { + Rectangle rect = tab.GetTabRect (tab.SelectedIndex); + if (rect.IntersectsWith (area)) + DrawTab (dc, tab.TabPages[tab.SelectedIndex], tab, rect, true); + } + + if (tab.ShowSlider) { + Rectangle right = GetRightScrollRect (tab); + Rectangle left = GetLeftScrollRect (tab); + DrawScrollButton (dc, right, area, ScrollButton.Right, tab.RightSliderState); + DrawScrollButton (dc, left, area, ScrollButton.Left, tab.LeftSliderState); + } + } + + protected virtual void DrawScrollButton (Graphics dc, Rectangle bounds, Rectangle clippingArea, ScrollButton button, PushButtonState state) + { + WidgetPaint.DrawScrollButton (dc, bounds, button, GetButtonState (state)); + } + + static ButtonState GetButtonState (PushButtonState state) + { + switch (state) { + case PushButtonState.Pressed: + return ButtonState.Pushed; + default: + return ButtonState.Normal; + } + } + + protected virtual void DrawBackground (Graphics dc, Rectangle area, TabWidget tab) + { + Brush brush = SystemBrushes.Control; + dc.FillRectangle (brush, area); + Rectangle panel_rect = GetTabPanelRect (tab); + + if (tab.Appearance == TabAppearance.Normal) { + WidgetPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top); + WidgetPaint.DrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom); + } + } + + protected virtual int DrawTab (Graphics dc, ShiftUI.TabPage page, ShiftUI.TabWidget tab, Rectangle bounds, bool is_selected) + { + Rectangle interior; + int res = bounds.Width; + + dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds); + + if (tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons) { + // Separators + if (tab.Appearance == TabAppearance.FlatButtons) { + int width = bounds.Width; + bounds.Width += (flatButtonSpacing - 2); + res = bounds.Width; + if (tab.Alignment == TabAlignment.Top || tab.Alignment == TabAlignment.Bottom) + ThemeEngine.Current.CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Right); + else + ThemeEngine.Current.CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Top); + bounds.Width = width; + } + + if (is_selected) { + ThemeEngine.Current.CPDrawBorder3D (dc, bounds, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom); + } else if (tab.Appearance != TabAppearance.FlatButtons) { + ThemeEngine.Current.CPDrawBorder3D (dc, bounds, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom); + } + + + } else { + CPColor cpcolor = ResPool.GetCPColor (tab.BackColor); + + Pen light = ResPool.GetPen (cpcolor.LightLight); + + switch (tab.Alignment) { + + case TabAlignment.Top: + + dc.DrawLine (light, bounds.Left, bounds.Bottom - 1, bounds.Left, bounds.Top + 3); + dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 2, bounds.Top); + dc.DrawLine (light, bounds.Left + 2, bounds.Top, bounds.Right - 3, bounds.Top); + + dc.DrawLine (SystemPens.ControlDark, bounds.Right - 2, bounds.Top + 1, bounds.Right - 2, bounds.Bottom - 1); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 2, bounds.Top + 1, bounds.Right - 1, bounds.Top + 2); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 1, bounds.Top + 2, bounds.Right - 1, bounds.Bottom - 1); + break; + + case TabAlignment.Bottom: + + dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 2); + dc.DrawLine (light, bounds.Left, bounds.Bottom - 2, bounds.Left + 3, bounds.Bottom); + + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 3, bounds.Bottom, bounds.Right - 3, bounds.Bottom); + dc.DrawLine (SystemPens.ControlDark, bounds.Left + 3, bounds.Bottom - 1, bounds.Right - 3, bounds.Bottom - 1); + + dc.DrawLine (SystemPens.ControlDark, bounds.Right - 2, bounds.Bottom - 1, bounds.Right - 2, bounds.Top + 1); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 2, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 2); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Top + 1); + + break; + + case TabAlignment.Left: + + dc.DrawLine (light, bounds.Left - 2, bounds.Top, bounds.Right, bounds.Top); + dc.DrawLine (light, bounds.Left, bounds.Top + 2, bounds.Left - 2, bounds.Top); + dc.DrawLine (light, bounds.Left, bounds.Top + 2, bounds.Left, bounds.Bottom - 2); + + dc.DrawLine (SystemPens.ControlDark, bounds.Left, bounds.Bottom - 2, bounds.Left + 2, bounds.Bottom - 1); + + dc.DrawLine (SystemPens.ControlDark, bounds.Left + 2, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 2, bounds.Bottom, bounds.Right, bounds.Bottom); + + break; + + default: // TabAlignment.Right + + dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Right - 3, bounds.Top); + dc.DrawLine (light, bounds.Right - 3, bounds.Top, bounds.Right, bounds.Top + 3); + + dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 1); + dc.DrawLine (SystemPens.ControlDark, bounds.Left, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1); + + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom - 3); + dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left, bounds.Bottom, bounds.Right - 3, bounds.Bottom); + + break; + } + } + + Point padding = tab.Padding; + interior = new Rectangle (bounds.Left + padding.X - 1, // substract a little offset + bounds.Top + padding.Y, + bounds.Width - (padding.X * 2), + bounds.Height - (padding.Y * 2)); + + if (tab.DrawMode == TabDrawMode.Normal && page.Text != null) { + if (tab.Alignment == TabAlignment.Left) { + dc.TranslateTransform (bounds.Left, bounds.Bottom); + dc.RotateTransform (-90); + dc.DrawString (page.Text, tab.Font, + SystemBrushes.ControlText, + tab.Padding.X - 2, // drawstring adds some extra unwanted leading spaces, so trimming + tab.Padding.Y, + defaultFormatting); + dc.ResetTransform (); + } else if (tab.Alignment == TabAlignment.Right) { + dc.TranslateTransform (bounds.Right, bounds.Top); + dc.RotateTransform (90); + dc.DrawString (page.Text, tab.Font, + SystemBrushes.ControlText, + tab.Padding.X - 2, // drawstring adds some extra unwanted leading spaces, so trimming + tab.Padding.Y, + defaultFormatting); + dc.ResetTransform (); + } else { + Rectangle str_rect = interior; + + if (is_selected) { + // Reduce the interior size to match the inner size of non-selected tabs + str_rect.X += selectedTabDelta.X; + str_rect.Y += selectedTabDelta.Y; + str_rect.Width -= selectedTabDelta.Width; + str_rect.Height -= selectedTabDelta.Height; + + str_rect.Y -= selectedTabDelta.Y; // Move up the text / image of the selected tab + } + + if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) { + int image_x; + if (tab.SizeMode != TabSizeMode.Fixed) { + image_x = str_rect.X; + } + else { + image_x = str_rect.X + (str_rect.Width - tab.ImageList.ImageSize.Width) / 2; + if (page.Text != null) { + SizeF textSize = dc.MeasureString(page.Text, page.Font, str_rect.Size); + image_x -= (int)(textSize.Width / 2); + } + } + int image_y = str_rect.Y + (str_rect.Height - tab.ImageList.ImageSize.Height) / 2; + tab.ImageList.Draw (dc, new Point (image_x, image_y), page.ImageIndex); + str_rect.X += tab.ImageList.ImageSize.Width + 2; + str_rect.Width -= tab.ImageList.ImageSize.Width + 2; + } + dc.DrawString (page.Text, tab.Font, + SystemBrushes.ControlText, + str_rect, + defaultFormatting); + + } + } else if (page.Text != null) { + DrawItemState state = DrawItemState.None; + if (page == tab.SelectedTab) + state |= DrawItemState.Selected; + DrawItemEventArgs e = new DrawItemEventArgs (dc, + tab.Font, bounds, tab.IndexForTabPage (page), + state, page.ForeColor, page.BackColor); + tab.OnDrawItemInternal (e); + return res; + } + + // TabWidget ignores the value of ShowFocusCues + if (page.Parent.Focused && is_selected) { + Rectangle focus_rect = bounds; + focus_rect.Inflate (-2, -2); + ThemeEngine.Current.CPDrawFocusRectangle (dc, focus_rect, tab.BackColor, tab.ForeColor); + } + + return res; + } + + public virtual bool HasHotElementStyles (TabWidget tabWidget) { + return false; + } + } +} diff --git a/source/ShiftUI/Theming/Default/ToolStripPainter.cs b/source/ShiftUI/Theming/Default/ToolStripPainter.cs new file mode 100644 index 0000000..4876dd5 --- /dev/null +++ b/source/ShiftUI/Theming/Default/ToolStripPainter.cs @@ -0,0 +1,189 @@ +// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007 Novell, Inc.
+//
+// Authors:
+// Jonathan Pobst ([email protected])
+
+using System;
+using System.Drawing;
+
+namespace ShiftUI.Theming.Default
+{
+ internal class ToolStripPainter
+ {
+ public ToolStripPainter ()
+ {
+ }
+
+ protected SystemResPool ResPool { get { return ThemeEngine.Current.ResPool; } }
+
+ #region Painting
+ public virtual void OnRenderButtonBackground (ToolStripItemRenderEventArgs e)
+ {
+ if (e.Item.Enabled == false)
+ return;
+
+ Rectangle paint_here = new Rectangle (0, 0, e.Item.Width, e.Item.Height);
+
+ ToolStripButton tsb = e.Item as ToolStripButton;
+
+ if (e.Item.Pressed || (tsb != null && tsb.Checked))
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.SunkenOuter);
+ else if (e.Item.Selected)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), paint_here);
+ }
+
+ public virtual void OnRenderDropDownButtonBackground (ToolStripItemRenderEventArgs e)
+ {
+ if (e.Item.Enabled == false)
+ return;
+
+ Rectangle paint_here = new Rectangle (0, 0, e.Item.Width, e.Item.Height);
+
+ if (e.Item.Pressed)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.SunkenOuter);
+ else if (e.Item.Selected)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), paint_here);
+ }
+
+ public virtual void OnRenderGrip (ToolStripGripRenderEventArgs e)
+ {
+ if (e.GripStyle == ToolStripGripStyle.Hidden)
+ return;
+
+ if (e.GripDisplayStyle == ToolStripGripDisplayStyle.Vertical) {
+ e.Graphics.DrawLine (Pens.White, 0, 2, 1, 2);
+ e.Graphics.DrawLine (Pens.White, 0, 2, 0, e.GripBounds.Height - 3);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 2, 2, 2, e.GripBounds.Height - 3);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 2, e.GripBounds.Height - 3, 0, e.GripBounds.Height - 3);
+ }
+ else {
+ e.Graphics.DrawLine (Pens.White, 2, 0, e.GripBounds.Width - 3, 0);
+ e.Graphics.DrawLine (Pens.White, 2, 0, 2, 1);
+ e.Graphics.DrawLine (SystemPens.ControlDark, e.GripBounds.Width - 3, 0, e.GripBounds.Width - 3, 2);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 2, 2, e.GripBounds.Width - 3, 2);
+ }
+ }
+
+ public virtual void OnRenderMenuItemBackground (ToolStripItemRenderEventArgs e)
+ {
+ ToolStripMenuItem tsmi = (ToolStripMenuItem)e.Item;
+ Rectangle paint_here = new Rectangle (Point.Empty, tsmi.Size);
+
+ if (tsmi.IsOnDropDown) {
+ // Drop down menu item
+ if (e.Item.Selected || e.Item.Pressed)
+ e.Graphics.FillRectangle (SystemBrushes.Highlight, paint_here);
+ } else {
+ // Top level menu item
+ if (e.Item.Pressed)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.SunkenOuter);
+ else if (e.Item.Selected)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), paint_here);
+ }
+ }
+
+ public virtual void OnRenderOverflowButtonBackground (ToolStripItemRenderEventArgs e)
+ {
+ Rectangle paint_here = new Rectangle (Point.Empty, e.Item.Size);
+
+ if (e.Item.Pressed)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.SunkenOuter);
+ else if (e.Item.Selected)
+ WidgetPaint.DrawBorder3D (e.Graphics, paint_here, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), paint_here);
+
+ // Paint the arrow
+ ToolStripRenderer.DrawDownArrow (e.Graphics, SystemPens.ControlText, e.Item.Width / 2 - 3, e.Item.Height / 2 - 1);
+ }
+
+ public virtual void OnRenderSeparator (ToolStripSeparatorRenderEventArgs e)
+ {
+ if (e.Vertical) {
+ e.Graphics.DrawLine (Pens.White, 4, 3, 4, e.Item.Height - 1);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 3, 3, 3, e.Item.Height - 1);
+ } else {
+ if (!e.Item.IsOnDropDown) {
+ e.Graphics.DrawLine (Pens.White, 2, 4, e.Item.Right - 1, 4);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 2, 3, e.Item.Right - 1, 3);
+ } else {
+ e.Graphics.DrawLine (Pens.White, 3, 4, e.Item.Right - 4, 4);
+ e.Graphics.DrawLine (SystemPens.ControlDark, 3, 3, e.Item.Right - 4, 3);
+ }
+ }
+ }
+
+ public virtual void OnRenderSplitButtonBackground (ToolStripItemRenderEventArgs e)
+ {
+ ToolStripSplitButton tssb = (ToolStripSplitButton)e.Item;
+
+ Rectangle button_part = new Rectangle (Point.Empty, tssb.ButtonBounds.Size);
+ Point drop_start = new Point (tssb.Width - tssb.DropDownButtonBounds.Width, 0);
+ Rectangle drop_part = new Rectangle (drop_start, tssb.DropDownButtonBounds.Size);
+
+ // Regular button part
+ if (tssb.ButtonPressed)
+ WidgetPaint.DrawBorder3D (e.Graphics, button_part, Border3DStyle.SunkenOuter);
+ else if (tssb.ButtonSelected)
+ WidgetPaint.DrawBorder3D (e.Graphics, button_part, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), button_part);
+
+ // Drop down button part
+ if (tssb.DropDownButtonPressed || tssb.ButtonPressed)
+ WidgetPaint.DrawBorder3D (e.Graphics, drop_part, Border3DStyle.SunkenOuter);
+ else if (tssb.DropDownButtonSelected || tssb.ButtonSelected)
+ WidgetPaint.DrawBorder3D (e.Graphics, drop_part, Border3DStyle.RaisedInner);
+ else if (e.Item.BackColor != Widget.DefaultBackColor && e.Item.BackColor != Color.Empty)
+ e.Graphics.FillRectangle (ResPool.GetSolidBrush (e.Item.BackColor), drop_part);
+ }
+
+ public virtual void OnRenderToolStripBackground (ToolStripRenderEventArgs e)
+ {
+ if (e.ToolStrip.BackgroundImage == null)
+ e.Graphics.Clear (e.BackColor);
+
+ if (e.ToolStrip is StatusStrip)
+ e.Graphics.DrawLine (Pens.White, e.AffectedBounds.Left, e.AffectedBounds.Top, e.AffectedBounds.Right, e.AffectedBounds.Top);
+ }
+
+ public virtual void OnRenderToolStripBorder (ToolStripRenderEventArgs e)
+ {
+ if (e.ToolStrip is StatusStrip)
+ return;
+
+ if (e.ToolStrip is ToolStripDropDown)
+ WidgetPaint.DrawBorder3D (e.Graphics, e.AffectedBounds, Border3DStyle.Raised);
+ else {
+ e.Graphics.DrawLine (SystemPens.ControlDark, new Point (e.ToolStrip.Left, e.ToolStrip.Height - 2), new Point (e.ToolStrip.Right, e.ToolStrip.Height - 2));
+ e.Graphics.DrawLine (Pens.White, new Point (e.ToolStrip.Left, e.ToolStrip.Height - 1), new Point (e.ToolStrip.Right, e.ToolStrip.Height - 1));
+ }
+ }
+ #endregion
+ }
+}
diff --git a/source/ShiftUI/Theming/Nice/.gitattributes b/source/ShiftUI/Theming/Nice/.gitattributes new file mode 100644 index 0000000..2ea73f7 --- /dev/null +++ b/source/ShiftUI/Theming/Nice/.gitattributes @@ -0,0 +1 @@ +/TabWidgetPainter.cs -crlf diff --git a/source/ShiftUI/Theming/Nice/TabControlPainter.cs b/source/ShiftUI/Theming/Nice/TabControlPainter.cs new file mode 100644 index 0000000..17b71db --- /dev/null +++ b/source/ShiftUI/Theming/Nice/TabControlPainter.cs @@ -0,0 +1,38 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Andreia Gaita ([email protected]) + +using System; +using System.Drawing; +using ShiftUI; + +namespace ShiftUI.Theming.Nice +{ + /// <summary> + /// Summary description for TabWidget. + /// </summary> + internal class TabWidgetPainter: Default.TabWidgetPainter + { + + } +} diff --git a/source/ShiftUI/Theming/ShiftOS.cs b/source/ShiftUI/Theming/ShiftOS.cs new file mode 100644 index 0000000..7950c18 --- /dev/null +++ b/source/ShiftUI/Theming/ShiftOS.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftUI.ShiftOS +{ + public abstract class Skin + { + #region Button + public int ButtonBorderWidth = 2; + public Color ButtonBorderColor = Color.Black; + public Color ButtonBackColor = Color.White; + public Color ButtonBackColor_Pressed = Color.Gray; + public Color ButtonBackColor_Checked = Color.Black; + #endregion + + #region Global + public Color SelectionHighlight = Color.Black; + public string DefaultFont = "Microsoft Sans Serif"; + public Color VisualStyleBorderColor = Color.Black; + public int VisualStyleBorderWidth = 2; + public int DefaultFontSize = 9; + public FontStyle DefaultFontStyle = FontStyle.Regular; + public Color WindowBackColor = Color.Gray; + public Color DefaultForeColor = Color.Black; + #endregion + + #region ScrollBar + public int ScrollbarWidth = 24; + #endregion + + #region 3D borders + public Color Border3DTopLeftInner = Color.LightGray; + public Color Border3DBottomRight = Color.DarkGray; + public Color Border3DBottomRightInner = Color.Gray; + #endregion + + #region CheckBox + public Color CheckBoxCheckColor = Color.Black; + public Color CheckBoxBorderColor = Color.Black; + public Color CheckBoxBackgroundColor = Color.White; + public int CheckBoxBorderWidth = 2; + #endregion + + #region MessageBox + public Color MessageBox_BottomPanel = Color.Gray; + #endregion + + #region ProgressBar + + public Color ProgressBar_BackgroundColor = Color.Gray; + public Color ProgressBar_BlockColor = Color.Black; + + #endregion + + #region ListView + public Color ListViewBackground = Color.White; + #endregion + + // No reason to have ShiftOS deal with window borders itself + // when I can do it inside ShiftUI. + #region Form + public int titlebarlayout = 3; + public int borderleftlayout = 3; + public int borderrightlayout = 3; + public int borderbottomlayout = 3; + public int closebtnlayout = 3; + public int rollbtnlayout = 3; + public int minbtnlayout = 3; + public int rightcornerlayout = 3; + public int leftcornerlayout = 3; + // Late entry: need to fix window code to include this + public int bottomleftcornerlayout = 3; + public int bottomrightcornerlayout = 3; + public Color bottomleftcornercolour = Color.Gray; + + public Color bottomrightcornercolour = Color.Gray; + + public bool enablebordercorners = false; + // settings + public Size closebtnsize = new Size(22, 22); + public Size rollbtnsize = new Size(22, 22); + public Size minbtnsize = new Size(22, 22); + public int titlebarheight = 30; + public int titlebariconsize = 16; + public int closebtnfromtop = 5; + public int closebtnfromside = 2; + public int rollbtnfromtop = 5; + public int rollbtnfromside = 26; + public int minbtnfromtop = 5; + public int minbtnfromside = 52; + public int borderwidth = 2; + public bool enablecorners = false; + public int titlebarcornerwidth = 5; + public int titleiconfromside = 4; + public int titleiconfromtop = 4; + //colours + public Color titlebarcolour = Color.Gray; + public Color borderleftcolour = Color.Gray; + public Color borderrightcolour = Color.Gray; + public Color borderbottomcolour = Color.Gray; + public Color closebtncolour = Color.Black; + public Color closebtnhovercolour = Color.Black; + public Color closebtnclickcolour = Color.Black; + public Color rollbtncolour = Color.Black; + public Color rollbtnhovercolour = Color.Black; + public Color rollbtnclickcolour = Color.Black; + public Color minbtncolour = Color.Black; + public Color minbtnhovercolour = Color.Black; + public Color minbtnclickcolour = Color.Black; + public Color rightcornercolour = Color.Gray; + public Color leftcornercolour = Color.Gray; + // Text + public string titletextfontfamily = "Microsoft Sans Serif"; + public int titletextfontsize = 10; + public FontStyle titletextfontstyle = FontStyle.Bold; + public string titletextpos = "Left"; + public int titletextfromtop = 3; + public int titletextfromside = 24; + + public Color titletextcolour = Color.White; + + #endregion + } + + public class DefaultSkin : Skin + { + + } +} diff --git a/source/ShiftUI/Theming/ThemeElements.cs b/source/ShiftUI/Theming/ThemeElements.cs new file mode 100644 index 0000000..e1bd740 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElements.cs @@ -0,0 +1,223 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// Everaldo Canuto <[email protected]> + +using System; +using System.Drawing; +using System.Reflection; + +namespace ShiftUI.Theming +{ + internal class MemphisThemeElements + { + private static ThemeElementsDefault theme; + public static ThemeElementsDefault CurrentTheme + { + get { return theme; } + } + + static MemphisThemeElements() + { + Init(); + } + + public static void Init() + { + theme = LoadTheme("memphis"); + } + + private static ThemeElementsDefault LoadTheme(string themeName) + { + return new ThemeElementsMemphis(); + } + + #region Buttons + public static void DrawButton(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + theme.ButtonPainter.Draw(g, bounds, state, backColor, foreColor); + } + + public static void DrawFlatButton(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor, FlatButtonAppearance appearance) + { + theme.ButtonPainter.DrawFlat(g, bounds, state, backColor, foreColor, appearance); + } + + public static void DrawPopupButton(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + theme.ButtonPainter.DrawPopup(g, bounds, state, backColor, foreColor); + } + #endregion + + #region Painters + + public virtual Default.ButtonPainter ButtonPainter + { + get { return theme.ButtonPainter; } + } + + public static Default.LabelPainter LabelPainter + { + get { return theme.LabelPainter; } + } + + public static Default.LinkLabelPainter LinkLabelPainter + { + get { return theme.LinkLabelPainter; } + } + + public virtual Default.TabWidgetPainter TabWidgetPainter + { + get { return theme.TabWidgetPainter; } + } + + public virtual Default.CheckBoxPainter CheckBoxPainter + { + get { return theme.CheckBoxPainter; } + } + + public virtual Default.RadioButtonPainter RadioButtonPainter + { + get { return theme.RadioButtonPainter; } + } + + public virtual Default.ToolStripPainter ToolStripPainter + { + get { return theme.ToolStripPainter; } + } + + #endregion + } + + + internal class ThemeElements + { + private static ThemeElementsDefault theme; + public static ThemeElementsDefault CurrentTheme { + get { return theme; } + } + + static ThemeElements () + { + string theme_var; + + theme_var = Environment.GetEnvironmentVariable ("MONO_THEME"); + + if (theme_var == null) + theme_var = "win32"; + else + theme_var = theme_var.ToLower (); + + theme = LoadTheme (theme_var); + + } + + private static ThemeElementsDefault LoadTheme (string themeName) + { + if (themeName == "visualstyles") + if (Application.VisualStylesEnabled) + return new ThemeElementsVisualStyles (); + else + return new ThemeElementsDefault (); + Assembly ass = Assembly.GetExecutingAssembly (); + string iname = typeof(ThemeElements).FullName; + string assemblyname = iname + themeName; + Type type = ass.GetType (assemblyname, false, true); + if (type != null) { + object o = ass.CreateInstance (type.FullName); + if (o != null) + return (ThemeElementsDefault) o; + } + return new ThemeElementsDefault (); + } + + #region Buttons + public static void DrawButton (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + theme.ButtonPainter.Draw (g, bounds, state, backColor, foreColor); + } + + public static void DrawFlatButton (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor, FlatButtonAppearance appearance) + { + theme.ButtonPainter.DrawFlat (g, bounds, state, backColor, foreColor, appearance); + } + + public static void DrawPopupButton (Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + theme.ButtonPainter.DrawPopup (g, bounds, state, backColor, foreColor); + } + #endregion + + #region Painters + + public virtual Default.ButtonPainter ButtonPainter { + get { return theme.ButtonPainter; } + } + + public static Default.LabelPainter LabelPainter { + get { return theme.LabelPainter; } + } + + public static Default.LinkLabelPainter LinkLabelPainter { + get { return theme.LinkLabelPainter; } + } + + public virtual Default.TabWidgetPainter TabWidgetPainter { + get { return theme.TabWidgetPainter; } + } + + public virtual Default.CheckBoxPainter CheckBoxPainter { + get { return theme.CheckBoxPainter; } + } + + public virtual Default.RadioButtonPainter RadioButtonPainter { + get { return theme.RadioButtonPainter; } + } + + public virtual Default.ToolStripPainter ToolStripPainter { + get { return theme.ToolStripPainter; } + } + + #endregion + } + + #region Internal Enums + [Flags] + internal enum ButtonThemeState + { + Normal = 1, + Entered = 2, + Pressed = 4, + Disabled = 8, + Default = 16 + } + + internal enum ElementState + { + Normal = 1, + Hot = 2, + Pressed = 3, + Disabled = 4 + } + #endregion +}
\ No newline at end of file diff --git a/source/ShiftUI/Theming/ThemeElementsClearlooks.cs b/source/ShiftUI/Theming/ThemeElementsClearlooks.cs new file mode 100644 index 0000000..8a1375e --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsClearlooks.cs @@ -0,0 +1,35 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Andreia Gaita ([email protected]) + +using System; + +namespace ShiftUI.Theming +{ + /// <summary> + /// Summary description for ThemeElementsClearlooks. + /// </summary> + internal class ThemeElementsClearlooks: ThemeElementsDefault + { + } +} diff --git a/source/ShiftUI/Theming/ThemeElementsDefault.cs b/source/ShiftUI/Theming/ThemeElementsDefault.cs new file mode 100644 index 0000000..02126d6 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsDefault.cs @@ -0,0 +1,95 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Jonathan Pobst ([email protected]) +// Andreia Gaita ([email protected]) + +using System; + +namespace ShiftUI.Theming +{ + internal class ThemeElementsDefault + { + protected Default.TabWidgetPainter tabWidgetPainter; + public virtual Default.TabWidgetPainter TabWidgetPainter { + get { + if (tabWidgetPainter == null) + tabWidgetPainter = new Default.TabWidgetPainter (); + return tabWidgetPainter; + } + } + + protected Default.ButtonPainter buttonPainter; + public virtual Default.ButtonPainter ButtonPainter { + get { + if (buttonPainter == null) + buttonPainter = new Default.ButtonPainter (); + return buttonPainter; + } + } + + protected Default.LabelPainter labelPainter; + public virtual Default.LabelPainter LabelPainter { + get { + if (labelPainter == null) + labelPainter = new Default.LabelPainter (); + return labelPainter; + } + } + + protected Default.LinkLabelPainter linklabelPainter; + public virtual Default.LinkLabelPainter LinkLabelPainter { + get { + if (linklabelPainter == null) + linklabelPainter = new Default.LinkLabelPainter (); + return linklabelPainter; + } + } + + protected Default.ToolStripPainter toolStripPainter; + public virtual Default.ToolStripPainter ToolStripPainter { + get { + if (toolStripPainter == null) + toolStripPainter = new Default.ToolStripPainter (); + return toolStripPainter; + } + } + + protected Default.CheckBoxPainter checkBoxPainter; + public virtual Default.CheckBoxPainter CheckBoxPainter { + get { + if (checkBoxPainter == null) + checkBoxPainter = new Default.CheckBoxPainter (); + return checkBoxPainter; + } + } + + protected Default.RadioButtonPainter radioButtonPainter; + public virtual Default.RadioButtonPainter RadioButtonPainter { + get { + if (radioButtonPainter == null) + radioButtonPainter = new Default.RadioButtonPainter (); + return radioButtonPainter; + } + } + } +} diff --git a/source/ShiftUI/Theming/ThemeElementsGtk.cs b/source/ShiftUI/Theming/ThemeElementsGtk.cs new file mode 100644 index 0000000..97582d3 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsGtk.cs @@ -0,0 +1,35 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Andreia Gaita ([email protected]) + +using System; + +namespace ShiftUI.Theming +{ + /// <summary> + /// Summary description for ThemeElementsGtk. + /// </summary> + internal class ThemeElementsGtk: ThemeElementsDefault + { + } +} diff --git a/source/ShiftUI/Theming/ThemeElementsMemphis.cs b/source/ShiftUI/Theming/ThemeElementsMemphis.cs new file mode 100644 index 0000000..b91bd8b --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsMemphis.cs @@ -0,0 +1,279 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftUI.Theming.Default; +using System.Drawing; +using ShiftUI.ShiftOS; +using System.Drawing.Drawing2D; + +namespace ShiftUI.Theming +{ + class ThemeElementsMemphis : ThemeElementsDefault + { + + public ThemeElementsMemphis() + { + } + + public override ButtonPainter ButtonPainter + { + get + { + return new Memphis.ButtonPainter(); + } + } + + public override CheckBoxPainter CheckBoxPainter + { + get + { + return new Memphis.CheckBoxPainter(); + } + } + } + + namespace Memphis + { + internal class CheckBoxPainter : Default.CheckBoxPainter + { + #region Standard + public override void DrawNormalCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + int check_box_visible_size = (bounds.Height > bounds.Width) ? bounds.Width : bounds.Height; + int x_pos = Math.Max(0, bounds.X + (bounds.Width / 2) - check_box_visible_size / 2); + int y_pos = Math.Max(0, bounds.Y + (bounds.Height / 2) - check_box_visible_size / 2); + + Rectangle rect = new Rectangle(x_pos, y_pos, check_box_visible_size, check_box_visible_size); + + g.FillRectangle(new SolidBrush(Application.CurrentSkin.CheckBoxBackgroundColor), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + + Pen pen = new Pen(Application.CurrentSkin.Border3DTopLeftInner, 1); + g.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + g.DrawLine(pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = new Pen(Application.CurrentSkin.Border3DBottomRight, 1); + g.DrawLine(pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3); + g.DrawLine(pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1); + + pen = new Pen(Application.CurrentSkin.Border3DTopLeftInner, 1); + g.DrawLine(pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 1); + g.DrawLine(pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + + // oh boy, matching ms is like fighting against windmills + using (Pen h_pen = new Pen(Application.CurrentSkin.CheckBoxCheckColor)) + { + g.DrawLine(h_pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + g.DrawLine(h_pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 2); + } + + if (state == CheckState.Checked) + DrawCheck(g, bounds, Application.CurrentSkin.CheckBoxCheckColor); + else if (state == CheckState.Indeterminate) + DrawCheck(g, bounds, Application.CurrentSkin.CheckBoxCheckColor); + } + + public override void DrawHotCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawNormalCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawPressedCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + int check_box_visible_size = (bounds.Height > bounds.Width) ? bounds.Width : bounds.Height; + int x_pos = Math.Max(0, bounds.X + (bounds.Width / 2) - check_box_visible_size / 2); + int y_pos = Math.Max(0, bounds.Y + (bounds.Height / 2) - check_box_visible_size / 2); + + Rectangle rect = new Rectangle(x_pos, y_pos, check_box_visible_size, check_box_visible_size); + + g.FillRectangle(new SolidBrush(Application.CurrentSkin.CheckBoxCheckColor), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + + Pen pen = new Pen(Application.CurrentSkin.Border3DBottomRightInner, 1); + g.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + g.DrawLine(pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = new Pen(Application.CurrentSkin.Border3DBottomRight, 1); + g.DrawLine(pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3); + g.DrawLine(pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1); + + pen = new Pen(Application.CurrentSkin.Border3DTopLeftInner, 1); + g.DrawLine(pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 1); + g.DrawLine(pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + + // oh boy, matching ms is like fighting against windmills + using (Pen h_pen = new Pen(Application.CurrentSkin.CheckBoxCheckColor)) + { + g.DrawLine(h_pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + g.DrawLine(h_pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 2); + } + + if (state == CheckState.Checked) + DrawCheck(g, bounds, Application.CurrentSkin.CheckBoxCheckColor); + else if (state == CheckState.Indeterminate) + DrawCheck(g, bounds, Application.CurrentSkin.CheckBoxCheckColor); + } + + public override void DrawDisabledCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawPressedCheckBox(g, bounds, backColor, foreColor, CheckState.Unchecked); + + if (state == CheckState.Checked || state == CheckState.Indeterminate) + DrawCheck(g, bounds, SystemColors.ControlDark); + } + #endregion + + #region FlatStyle + public override void DrawFlatNormalCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawNormalCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawFlatHotCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawFlatNormalCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawFlatPressedCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawPressedCheckBox(g, bounds, backColor, foreColor, state); + } + +/* public override void DrawFlatDisabledCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + Rectangle checkbox_rectangle; + + checkbox_rectangle = new Rectangle(bounds.X, bounds.Y, Math.Max(bounds.Width - 2, 0), Math.Max(bounds.Height - 2, 0)); + + WidgetPaint.DrawBorder(g, checkbox_rectangle, foreColor, ButtonBorderStyle.Solid); + + bounds.Offset(-1, 0); + + if (state == CheckState.Checked || state == CheckState.Indeterminate) + DrawCheck(g, bounds, SystemColors.ControlDarkDark); + }*/ + #endregion + + #region Popup + public override void DrawPopupNormalCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawFlatNormalCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawPopupHotCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawFlatNormalCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawPopupPressedCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + DrawFlatPressedCheckBox(g, bounds, backColor, foreColor, state); + } + + public override void DrawPopupDisabledCheckBox(Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + } + #endregion + + #region Check + public override void DrawCheck(Graphics g, Rectangle bounds, Color checkColor) + { + int check_size = (bounds.Height > bounds.Width) ? bounds.Width / 2 : bounds.Height / 2; + + Pen check_pen = ResPool.GetPen(checkColor); + + if (check_size < 7) + { + int lineWidth = Math.Max(3, check_size / 3); + int Scale = Math.Max(1, check_size / 9); + + Rectangle rect = new Rectangle(bounds.X + (bounds.Width / 2) - (check_size / 2) - 1, bounds.Y + (bounds.Height / 2) - (check_size / 2) - 1, + check_size, check_size); + + for (int i = 0; i < lineWidth; i++) + { + g.DrawLine(check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i); + g.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); + } + } + else + { + int lineWidth = Math.Max(3, check_size / 3) + 1; + + int x_half = bounds.Width / 2; + int y_half = bounds.Height / 2; + + Rectangle rect = new Rectangle(bounds.X + x_half - (check_size / 2) - 1, bounds.Y + y_half - (check_size / 2), + check_size, check_size); + + int gradient_left = check_size / 3; + int gradient_right = check_size - gradient_left - 1; + + for (int i = 0; i < lineWidth; i++) + { + g.DrawLine(check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i); + g.DrawLine(check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i - 1 - gradient_right); + } + } + } + #endregion + + } + + internal class ButtonPainter : Default.ButtonPainter + { + + #region Buttons + #region Standard Button + public override void Draw(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + bool is_themecolor = backColor.ToArgb() == ThemeEngine.Current.ColorControl.ToArgb() || backColor == Color.Empty ? true : false; + CPColor cpcolor = is_themecolor ? CPColor.Empty : ResPool.GetCPColor(backColor); + Pen pen; + + switch (state) + { + case ButtonThemeState.Disabled: + case ButtonThemeState.Normal: + case ButtonThemeState.Entered: + case ButtonThemeState.Default: + pen = new Pen(foreColor, Application.CurrentSkin.ButtonBorderWidth); + g.DrawRectangle(pen, bounds); + break; + case ButtonThemeState.Pressed: + g.FillRectangle(new SolidBrush(backColor), bounds); + pen = new Pen(foreColor, Application.CurrentSkin.ButtonBorderWidth); + g.DrawRectangle(pen, bounds); + break; + } + } + #endregion + + #region FlatStyle Button + public override void DrawFlat(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor, FlatButtonAppearance appearance) + { + Draw(g, bounds, state, backColor, foreColor); + } + #endregion + + #region Popup Button + public override void DrawPopup(Graphics g, Rectangle bounds, ButtonThemeState state, Color backColor, Color foreColor) + { + Draw(g, bounds, state, backColor, foreColor); + } + #endregion + #endregion + + private static Color ChangeIntensity(Color baseColor, float percent) + { + int H, I, S; + + WidgetPaint.Color2HBS(baseColor, out H, out I, out S); + int NewIntensity = Math.Min(255, (int)(I * percent)); + + return WidgetPaint.HBS2Color(H, NewIntensity, S); + } + + } + } +} diff --git a/source/ShiftUI/Theming/ThemeElementsNice.cs b/source/ShiftUI/Theming/ThemeElementsNice.cs new file mode 100644 index 0000000..ff2ff45 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsNice.cs @@ -0,0 +1,43 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2007 Novell, Inc. +// +// Authors: +// Andreia Gaita ([email protected]) + +using System; + +namespace ShiftUI.Theming +{ + internal class ThemeElementsNice: ThemeElementsDefault + { + /* If we want to add a custom-themed Widget, add an override here + * like this: + + public override Default.TabWidgetPainter TabWidgetPainter { + get { + if (tabWidgetPainter == null) + tabWidgetPainter = (Default.TabWidgetPainter) new Nice.TabWidgetPainter (); + return tabWidgetPainter; + } + } + */ + } +} diff --git a/source/ShiftUI/Theming/ThemeElementsVisualStyles.cs b/source/ShiftUI/Theming/ThemeElementsVisualStyles.cs new file mode 100644 index 0000000..1e5bf1c --- /dev/null +++ b/source/ShiftUI/Theming/ThemeElementsVisualStyles.cs @@ -0,0 +1,59 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// +// Authors: +// George Giolfan ([email protected]) +using ShiftUI.Theming.Default; + +namespace ShiftUI.Theming +{ + class ThemeElementsVisualStyles : ThemeElementsDefault + { + public override CheckBoxPainter CheckBoxPainter { + get { + if (checkBoxPainter == null) + checkBoxPainter = new VisualStyles.CheckBoxPainter (); + return checkBoxPainter; + } + } + public override RadioButtonPainter RadioButtonPainter { + get { + if (radioButtonPainter == null) + radioButtonPainter = new VisualStyles.RadioButtonPainter (); + return radioButtonPainter; + } + } + public override ToolStripPainter ToolStripPainter { + get { + if (toolStripPainter == null) + toolStripPainter = new VisualStyles.ToolStripPainter (); + return toolStripPainter; + } + } + public override TabWidgetPainter TabWidgetPainter { + get { + if (tabWidgetPainter == null) + tabWidgetPainter = new VisualStyles.TabWidgetPainter (); + return tabWidgetPainter; + } + } + } +} diff --git a/source/ShiftUI/Theming/ThemeEngine.cs b/source/ShiftUI/Theming/ThemeEngine.cs new file mode 100644 index 0000000..89d2804 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeEngine.cs @@ -0,0 +1,62 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004-2006 Novell, Inc. +// +// Authors: +// Jordi Mas i Hernandez, [email protected] +// +// + + +using ShiftUI.Theming; +using System; + +namespace ShiftUI +{ + internal class ThemeEngine + { + static private Theme theme = null; + + static ThemeEngine () + { + string theme_var; + + theme_var = Environment.GetEnvironmentVariable("MONO_THEME"); + + if (theme_var == null) { + theme_var = "memphis"; //Screw win32. Memphis all the way! + } else { + theme_var = theme_var.ToLower (); + } + + if (Application.VisualStylesEnabled) { + theme = new ThemeSkinnable(); //ShiftOS skin engine will be moved into here, possibly. + } else { + theme = new ThemeWin32Classic (); + } + } + + + public static Theme Current { + get { return theme; } + } + + } +} diff --git a/source/ShiftUI/Theming/ThemeSkinnable.cs b/source/ShiftUI/Theming/ThemeSkinnable.cs new file mode 100644 index 0000000..5ea8a4d --- /dev/null +++ b/source/ShiftUI/Theming/ThemeSkinnable.cs @@ -0,0 +1,8348 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004-2006 Novell, Inc. +// +// Authors: +// Jordi Mas i Hernandez, [email protected] +// Peter Bartok, [email protected] +// John BouAntoun, [email protected] +// Marek Safar, [email protected] +// Alexander Olk, [email protected] +// + +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.Drawing.Text; +using System.Text; +using ShiftUI.Theming; +using System; + +namespace ShiftUI +{ + + internal class ThemeSkinnable : Theme + { + public void LoadSkin(ShiftOS.Skin skin) + { + Application.LoadSkin(skin); + MemphisThemeElements.Init(); + } + + public override Version Version + { + get + { + return new Version("0.0.1.alpha1"); + } + } + + /* Hardcoded colour values not exposed in the API constants in all configurations */ + protected static readonly Color arrow_color = Color.Black; + protected static readonly Color pen_ticks_color = Color.Black; + protected static StringFormat string_format_menu_text; + protected static StringFormat string_format_menu_shortcut; + protected static StringFormat string_format_menu_menubar_text; + static ImageAttributes imagedisabled_attributes; + Font window_border_font; + const int SEPARATOR_HEIGHT = 6; + const int SEPARATOR_MIN_WIDTH = 20; + const int SM_CXBORDER = 1; + const int SM_CYBORDER = 1; + const int MENU_TAB_SPACE = 8; // Pixels added to the width of an item because of a tabd + const int MENU_BAR_ITEMS_SPACE = 8; // Space between menu bar items + const int CheckSize = 13; + + #region Principal Theme Methods + public ThemeSkinnable() + { + if (Application.CurrentSkin == null) + Application.LoadSkin(new ShiftOS.DefaultSkin()); + ResetDefaults(); + } + + public override void ResetDefaults() + { + defaultWindowBackColor = Application.CurrentSkin.WindowBackColor; + defaultWindowForeColor = Application.CurrentSkin.DefaultForeColor; + window_border_font = new Font("Microsoft Sans Serif", 9, FontStyle.Bold); + + /* Menu string formats */ + string_format_menu_text = new StringFormat(); + string_format_menu_text.LineAlignment = StringAlignment.Center; + string_format_menu_text.Alignment = StringAlignment.Near; + string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show; + string_format_menu_text.SetTabStops(0f, new float[] { 50f }); + string_format_menu_text.FormatFlags |= StringFormatFlags.NoWrap; + + string_format_menu_shortcut = new StringFormat(); + string_format_menu_shortcut.LineAlignment = StringAlignment.Center; + string_format_menu_shortcut.Alignment = StringAlignment.Far; + + string_format_menu_menubar_text = new StringFormat(); + string_format_menu_menubar_text.LineAlignment = StringAlignment.Center; + string_format_menu_menubar_text.Alignment = StringAlignment.Center; + string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show; + } + + public override bool DoubleBufferingSupported + { + get { return true; } + } + + public override int HorizontalScrollBarHeight + { + get + { + return Application.CurrentSkin.ScrollbarWidth; + } + } + + public override int VerticalScrollBarWidth + { + get + { + return Application.CurrentSkin.ScrollbarWidth; + } + } + + public override Font WindowBorderFont + { + get + { + return window_border_font ?? (window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold)); + } + } + + #endregion // Principal Theme Methods + + #region Internal Methods + protected Brush GetControlBackBrush(Color c) + { + if (c.ToArgb() == DefaultControlBackColor.ToArgb()) + return SystemBrushes.Control; + return ResPool.GetSolidBrush(c); + } + + protected Brush GetControlForeBrush(Color c) + { + if (c.ToArgb() == DefaultControlForeColor.ToArgb()) + return SystemBrushes.ControlText; + return ResPool.GetSolidBrush(c); + } + #endregion // Internal Methods + + #region Widget + public override Font GetLinkFont(Widget control) + { + return new Font(control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Underline, control.Font.Unit); + } + #endregion // Widget + + #region OwnerDraw Support + public override void DrawOwnerDrawBackground(DrawItemEventArgs e) + { + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); + return; + } + + e.Graphics.FillRectangle(ResPool.GetSolidBrush(e.BackColor), e.Bounds); + } + + public override void DrawOwnerDrawFocusRectangle(DrawItemEventArgs e) + { + if (e.State == DrawItemState.Focus) + CPDrawFocusRectangle(e.Graphics, e.Bounds, e.ForeColor, e.BackColor); + } + #endregion // OwnerDraw Support + + #region Button + #region Standard Button Style + public override void DrawButton(Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + DrawButtonBackground(g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawButtonImage(g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawButtonFocus(g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawButtonText(g, b, textBounds); + } + + public virtual void DrawButtonBackground(Graphics g, Button button, Rectangle clipArea) + { + var fc = button.ForeColor; + if (fc == null) + fc = Application.CurrentSkin.DefaultForeColor; + + if (button.Pressed) + MemphisThemeElements.DrawButton(g, button.ClientRectangle, ButtonThemeState.Pressed, Application.CurrentSkin.ButtonBackColor_Pressed, fc); + else if (button.InternalSelected) + MemphisThemeElements.DrawButton(g, button.ClientRectangle, ButtonThemeState.Default, Application.CurrentSkin.ButtonBackColor, fc); + else if (button.Entered) + MemphisThemeElements.DrawButton(g, button.ClientRectangle, ButtonThemeState.Entered, Application.CurrentSkin.ButtonBackColor, fc); + else if (!button.Enabled) + MemphisThemeElements.DrawButton(g, button.ClientRectangle, ButtonThemeState.Disabled, Application.CurrentSkin.ButtonBackColor, fc); + else + MemphisThemeElements.DrawButton(g, button.ClientRectangle, ButtonThemeState.Normal, Application.CurrentSkin.ButtonBackColor, fc); + } + + public virtual void DrawButtonFocus(Graphics g, Button button) + { + WidgetPaint.DrawFocusRectangle(g, Rectangle.Inflate(button.ClientRectangle, -4, -4)); + } + + public virtual void DrawButtonImage(Graphics g, ButtonBase button, Rectangle imageBounds) + { + if (button.Enabled) + g.DrawImage(button.Image, imageBounds); + else + CPDrawImageDisabled(g, button.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawButtonText(Graphics g, ButtonBase button, Rectangle textBounds) + { + // Ensure that at least one line is going to get displayed. + // Line limit does not ensure that despite its description. + if (button.Font != null && button.Font.Height > 0) + textBounds.Height = Math.Max(textBounds.Height, button.Font.Height); + + if (button.Enabled) + TextRenderer.DrawTextInternal(g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering); + else + DrawStringDisabled20(g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering); + } + #endregion + + #region FlatStyle Button Style + public override void DrawFlatButton(Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (b.BackgroundImage == null) + DrawFlatButtonBackground(g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawFlatButtonImage(g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawFlatButtonFocus(g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawFlatButtonText(g, b, textBounds); + } + + public virtual void DrawFlatButtonBackground(Graphics g, ButtonBase button, Rectangle clipArea) + { + if (button.Pressed) + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance); + else if (button.InternalSelected) + { + if (button.Entered) + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance); + else + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance); + } + else if (button.Entered) + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance); + else if (!button.Enabled) + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance); + else + MemphisThemeElements.DrawFlatButton(g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance); + } + + public virtual void DrawFlatButtonFocus(Graphics g, ButtonBase button) + { + if (!button.Pressed) + { + Color focus_color = WidgetPaint.Dark(button.BackColor); + g.DrawRectangle(ResPool.GetPen(focus_color), new Rectangle(button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9)); + } + } + + public virtual void DrawFlatButtonImage(Graphics g, ButtonBase button, Rectangle imageBounds) + { + // No changes from Standard for image for this theme + DrawButtonImage(g, button, imageBounds); + } + + public virtual void DrawFlatButtonText(Graphics g, ButtonBase button, Rectangle textBounds) + { + // No changes from Standard for text for this theme + DrawButtonText(g, button, textBounds); + } + #endregion + + #region Popup Button Style + public override void DrawPopupButton(Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + DrawPopupButtonBackground(g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawPopupButtonImage(g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawPopupButtonFocus(g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawPopupButtonText(g, b, textBounds); + } + + public virtual void DrawPopupButtonBackground(Graphics g, Button button, Rectangle clipArea) + { + if (button.Pressed) + MemphisThemeElements.DrawPopupButton(g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor); + else if (button.Entered) + MemphisThemeElements.DrawPopupButton(g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor); + else if (button.InternalSelected) + MemphisThemeElements.DrawPopupButton(g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor); + else if (!button.Enabled) + MemphisThemeElements.DrawPopupButton(g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor); + else + MemphisThemeElements.DrawPopupButton(g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor); + } + + public virtual void DrawPopupButtonFocus(Graphics g, Button button) + { + // No changes from Standard for image for this theme + DrawButtonFocus(g, button); + } + + public virtual void DrawPopupButtonImage(Graphics g, Button button, Rectangle imageBounds) + { + // No changes from Standard for image for this theme + DrawButtonImage(g, button, imageBounds); + } + + public virtual void DrawPopupButtonText(Graphics g, Button button, Rectangle textBounds) + { + // No changes from Standard for image for this theme + DrawButtonText(g, button, textBounds); + } + #endregion + + #region Button Layout Calculations + public override Size CalculateButtonAutoSize(Button button) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal(button.Text, button.Font, button.UseCompatibleTextRendering); + Size image_size = button.Image == null ? Size.Empty : button.Image.Size; + + // Pad the text size + if (button.Text.Length != 0) + { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (button.TextImageRelation) + { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max(button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max(text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (button.Padding.Vertical + 6); + ret_size.Width += (button.Padding.Horizontal + 6); + + return ret_size; + } + + public override void CalculateButtonTextAndImageLayout(Graphics g, ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle) + { + Image image = button.Image; + string text = button.Text; + Rectangle content_rect = button.PaddingClientRectangle; + Size text_size = TextRenderer.MeasureTextInternal(g, text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering); + Size image_size = image == null ? Size.Empty : image.Size; + + textRectangle = Rectangle.Inflate(content_rect, -4, -4); + imageRectangle = Rectangle.Empty; + + bool displayEllipsis = (button.TextFormatFlags & (TextFormatFlags.EndEllipsis | TextFormatFlags.PathEllipsis | TextFormatFlags.WordEllipsis)) != 0; + + switch (button.TextImageRelation) + { + case TextImageRelation.Overlay: + // Overlay is easy, text always goes here + + // Image is dependent on ImageAlign + if (image == null) + { + if (button.Pressed) + textRectangle.Offset(1, 1); + return; + } + + int image_x = 0; + int image_y = 0; + int image_height = image.Height; + int image_width = image.Width; + + switch (button.ImageAlign) + { + case System.Drawing.ContentAlignment.TopLeft: + image_x = 5; + image_y = 5; + break; + case System.Drawing.ContentAlignment.TopCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = 5; + break; + case System.Drawing.ContentAlignment.TopRight: + image_x = content_rect.Width - image_width - 5; + image_y = 5; + break; + case System.Drawing.ContentAlignment.MiddleLeft: + image_x = 5; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleRight: + image_x = content_rect.Width - image_width - 4; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.BottomLeft: + image_x = 5; + image_y = content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomRight: + image_x = content_rect.Width - image_width - 4; + image_y = content_rect.Height - image_height - 4; + break; + default: + image_x = 5; + image_y = 5; + break; + } + + imageRectangle = new Rectangle(image_x, image_y, image_width, image_height); + break; + case TextImageRelation.ImageAboveText: + LayoutTextAboveOrBelowImage(textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextAboveImage: + LayoutTextAboveOrBelowImage(textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle); + break; + case TextImageRelation.ImageBeforeText: + LayoutTextBeforeOrAfterImage(textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextBeforeImage: + LayoutTextBeforeOrAfterImage(textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + } + if (button.Pressed) + textRectangle.Offset(1, 1); + } + + 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) + { + int element_spacing = 0; // Spacing between the Text and the Image + int total_width = textSize.Width + element_spacing + imageSize.Width; + + if (!textFirst) + element_spacing += 2; + + // If the text is too big, chop it down to the size we have available to it + if (total_width > totalArea.Width) + { + textSize.Width = totalArea.Width - element_spacing - imageSize.Width; + total_width = totalArea.Width; + } + + int excess_width = totalArea.Width - total_width; + int offset = 0; + + Rectangle final_text_rect; + Rectangle final_image_rect; + + HorizontalAlignment h_text = GetHorizontalAlignment(textAlign); + HorizontalAlignment h_image = GetHorizontalAlignment(imageAlign); + + if (h_image == HorizontalAlignment.Left) + offset = 0; + else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right) + offset = excess_width; + else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center)) + offset += (int)(excess_width / 3); + else + offset += (int)(2 * (excess_width / 3)); + + if (textFirst) + { + final_text_rect = new Rectangle(totalArea.Left + offset, AlignInRectangle(totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + final_image_rect = new Rectangle(final_text_rect.Right + element_spacing, AlignInRectangle(totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + } + else + { + final_image_rect = new Rectangle(totalArea.Left + offset, AlignInRectangle(totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + final_text_rect = new Rectangle(final_image_rect.Right + element_spacing, AlignInRectangle(totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + } + + textRect = final_text_rect; + imageRect = final_image_rect; + } + + 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) + { + int element_spacing = 0; // Spacing between the Text and the Image + int total_height = textSize.Height + element_spacing + imageSize.Height; + + if (textFirst) + element_spacing += 2; + + if (textSize.Width > totalArea.Width) + textSize.Width = totalArea.Width; + + // If the there isn't enough room and we're text first, cut out the image + if (total_height > totalArea.Height && textFirst) + { + imageSize = Size.Empty; + total_height = totalArea.Height; + } + + int excess_height = totalArea.Height - total_height; + int offset = 0; + + Rectangle final_text_rect; + Rectangle final_image_rect; + + VerticalAlignment v_text = GetVerticalAlignment(textAlign); + VerticalAlignment v_image = GetVerticalAlignment(imageAlign); + + if (v_image == VerticalAlignment.Top) + offset = 0; + else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom) + offset = excess_height; + else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center)) + offset += (int)(excess_height / 3); + else + offset += (int)(2 * (excess_height / 3)); + + if (textFirst) + { + var textHeight = excess_height >= 0 ? totalArea.Height - imageSize.Height - element_spacing : textSize.Height; + final_text_rect = new Rectangle(AlignInRectangle(totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textHeight); + final_image_rect = new Rectangle(AlignInRectangle(totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height); + } + else + { + final_image_rect = new Rectangle(AlignInRectangle(totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height); + var textHeight = excess_height >= 0 ? totalArea.Height - final_image_rect.Height : textSize.Height; + final_text_rect = new Rectangle(AlignInRectangle(totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textHeight); + + if (final_text_rect.Bottom > totalArea.Bottom) + { + final_text_rect.Y -= (final_text_rect.Bottom - totalArea.Bottom); + if (final_text_rect.Y < totalArea.Top) + final_text_rect.Y = totalArea.Top; + } + } + + if (displayEllipsis) + { + // Don't use more space than is available otherwise ellipsis won't show + if (final_text_rect.Height > totalArea.Bottom) + final_text_rect.Height = totalArea.Bottom - final_text_rect.Top; + } + + textRect = final_text_rect; + imageRect = final_image_rect; + } + + private HorizontalAlignment GetHorizontalAlignment(System.Drawing.ContentAlignment align) + { + switch (align) + { + case System.Drawing.ContentAlignment.BottomLeft: + case System.Drawing.ContentAlignment.MiddleLeft: + case System.Drawing.ContentAlignment.TopLeft: + return HorizontalAlignment.Left; + case System.Drawing.ContentAlignment.BottomCenter: + case System.Drawing.ContentAlignment.MiddleCenter: + case System.Drawing.ContentAlignment.TopCenter: + return HorizontalAlignment.Center; + case System.Drawing.ContentAlignment.BottomRight: + case System.Drawing.ContentAlignment.MiddleRight: + case System.Drawing.ContentAlignment.TopRight: + return HorizontalAlignment.Right; + } + + return HorizontalAlignment.Left; + } + + private enum VerticalAlignment + { + Top = 0, + Center = 1, + Bottom = 2 + } + + private VerticalAlignment GetVerticalAlignment(System.Drawing.ContentAlignment align) + { + switch (align) + { + case System.Drawing.ContentAlignment.TopLeft: + case System.Drawing.ContentAlignment.TopCenter: + case System.Drawing.ContentAlignment.TopRight: + return VerticalAlignment.Top; + case System.Drawing.ContentAlignment.MiddleLeft: + case System.Drawing.ContentAlignment.MiddleCenter: + case System.Drawing.ContentAlignment.MiddleRight: + return VerticalAlignment.Center; + case System.Drawing.ContentAlignment.BottomLeft: + case System.Drawing.ContentAlignment.BottomCenter: + case System.Drawing.ContentAlignment.BottomRight: + return VerticalAlignment.Bottom; + } + + return VerticalAlignment.Top; + } + + internal Rectangle AlignInRectangle(Rectangle outer, Size inner, System.Drawing.ContentAlignment align) + { + int x = 0; + int y = 0; + + if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft) + x = outer.X; + else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter) + x = Math.Max(outer.X + ((outer.Width - inner.Width) / 2), outer.Left); + else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight) + x = outer.Right - inner.Width; + if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight) + y = outer.Y; + else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight) + y = outer.Y + (outer.Height - inner.Height) / 2; + else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft) + y = outer.Bottom - inner.Height; + + return new Rectangle(x, y, Math.Min(inner.Width, outer.Width), Math.Min(inner.Height, outer.Height)); + } + #endregion + #endregion + + #region ButtonBase + public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) + { + // Draw the button: Draw border, etc. + ButtonBase_DrawButton(button, dc); + + // Draw the image + if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null))) + ButtonBase_DrawImage(button, dc); + + // Draw the focus rectangle + if (ShouldPaintFocusRectagle(button)) + ButtonBase_DrawFocus(button, dc); + + // Now the text + if (button.Text != null && button.Text != String.Empty) + ButtonBase_DrawText(button, dc); + } + + protected static bool ShouldPaintFocusRectagle(ButtonBase button) + { + return (button.Focused || button.paint_as_acceptbutton) && button.Enabled && button.ShowFocusCues; + } + + protected virtual void ButtonBase_DrawButton(ButtonBase button, Graphics dc) + { + Rectangle borderRectangle; + bool check_or_radio = false; + bool check_or_radio_checked = false; + + bool is_ColorControl = button.BackColor.ToArgb() == ColorControl.ToArgb() ? true : false; + + CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor(button.BackColor); + + if (button is CheckBox) + { + check_or_radio = true; + check_or_radio_checked = ((CheckBox)button).Checked; + } + else if (button is RadioButton) + { + check_or_radio = true; + check_or_radio_checked = ((RadioButton)button).Checked; + } + + if (button.Focused && button.Enabled && !check_or_radio) + { + // shrink the rectangle for the normal button drawing inside the focus rectangle + borderRectangle = Rectangle.Inflate(button.ClientRectangle, -1, -1); + } + else + { + borderRectangle = button.ClientRectangle; + } + + if (button.FlatStyle == FlatStyle.Popup) + { + if (!button.is_pressed && !button.is_entered && !check_or_radio_checked) + Internal_DrawButton(dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + else if (!button.is_pressed && button.is_entered && !check_or_radio_checked) + Internal_DrawButton(dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor); + else if (button.is_pressed || check_or_radio_checked) + Internal_DrawButton(dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + } + else if (button.FlatStyle == FlatStyle.Flat) + { + if (button.is_entered && !button.is_pressed && !check_or_radio_checked) + { + if ((button.image == null) && (button.image_list == null)) + { + Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush(cpcolor.Dark); + dc.FillRectangle(brush, borderRectangle); + } + } + else if (button.is_pressed || check_or_radio_checked) + { + if ((button.image == null) && (button.image_list == null)) + { + Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush(cpcolor.LightLight); + dc.FillRectangle(brush, borderRectangle); + } + + Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen(cpcolor.Dark); + dc.DrawRectangle(pen, borderRectangle.X + 4, borderRectangle.Y + 4, + borderRectangle.Width - 9, borderRectangle.Height - 9); + } + + Internal_DrawButton(dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor); + } + else + { + if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked) + Internal_DrawButton(dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor); + else + Internal_DrawButton(dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + } + } + + private void Internal_DrawButton(Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor) + { + switch (state) + { + case 0: // normal or normal disabled button + Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen(cpcolor.LightLight); + dc.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + dc.DrawLine(pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen(backcolor); + dc.DrawLine(pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3); + dc.DrawLine(pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1); + + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen(cpcolor.Dark); + dc.DrawLine(pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + dc.DrawLine(pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3); + + pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen(cpcolor.DarkDark); + dc.DrawLine(pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine(pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2); + break; + case 1: // popup button normal (or pressed normal or popup button) + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen(cpcolor.Dark); + dc.DrawRectangle(pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1); + break; + case 2: // popup button poped up + pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen(cpcolor.LightLight); + dc.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + dc.DrawLine(pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen(cpcolor.Dark); + dc.DrawLine(pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine(pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2); + break; + case 3: // flat button not entered + pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen(cpcolor.DarkDark); + dc.DrawRectangle(pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1); + break; + default: + break; + } + } + + protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc) + { + // Need to draw a picture + Image i; + int image_x; + int image_y; + int image_width; + int image_height; + + int width = button.ClientSize.Width; + int height = button.ClientSize.Height; + + if (button.ImageIndex != -1) + { // We use ImageIndex instead of image_index since it will return -1 if image_list is null + i = button.image_list.Images[button.ImageIndex]; + } + else + { + i = button.image; + } + + image_width = i.Width; + image_height = i.Height; + + switch (button.ImageAlign) + { + case ContentAlignment.TopLeft: + { + image_x = 5; + image_y = 5; + break; + } + + case ContentAlignment.TopCenter: + { + image_x = (width - image_width) / 2; + image_y = 5; + break; + } + + case ContentAlignment.TopRight: + { + image_x = width - image_width - 5; + image_y = 5; + break; + } + + case ContentAlignment.MiddleLeft: + { + image_x = 5; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.MiddleCenter: + { + image_x = (width - image_width) / 2; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.MiddleRight: + { + image_x = width - image_width - 4; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.BottomLeft: + { + image_x = 5; + image_y = height - image_height - 4; + break; + } + + case ContentAlignment.BottomCenter: + { + image_x = (width - image_width) / 2; + image_y = height - image_height - 4; + break; + } + + case ContentAlignment.BottomRight: + { + image_x = width - image_width - 4; + image_y = height - image_height - 4; + break; + } + + default: + { + image_x = 5; + image_y = 5; + break; + } + } + + dc.SetClip(new Rectangle(3, 3, width - 5, height - 5)); + + if (button.Enabled) + dc.DrawImage(i, image_x, image_y, image_width, image_height); + else + CPDrawImageDisabled(dc, i, image_x, image_y, ColorControl); + + dc.ResetClip(); + } + + protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc) + { + Color focus_color = button.ForeColor; + + int inflate_value = -3; + + if (!(button is CheckBox) && !(button is RadioButton)) + { + inflate_value = -4; + + if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) + focus_color = WidgetPaint.Dark(button.BackColor); + + dc.DrawRectangle(ResPool.GetPen(focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, + button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1); + } + + if (button.Focused) + { + Rectangle rect = Rectangle.Inflate(button.ClientRectangle, inflate_value, inflate_value); + WidgetPaint.DrawFocusRectangle(dc, rect); + } + } + + protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc) + { + Rectangle buttonRectangle = button.ClientRectangle; + Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4); + + if (button.is_pressed) + { + text_rect.X++; + text_rect.Y++; + } + + // Ensure that at least one line is going to get displayed. + // Line limit does not ensure that despite its description. + text_rect.Height = Math.Max(button.Font.Height, text_rect.Height); + + if (button.Enabled) + { + dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush(button.ForeColor), text_rect, button.text_format); + } + else + { + if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) + { + dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush(ColorGrayText), text_rect, button.text_format); + } + else + { + CPDrawStringDisabled(dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format); + } + } + } + + public override Size ButtonBaseDefaultSize + { + get + { + return new Size(75, 23); + } + } + #endregion // ButtonBase + + #region CheckBox + public override void DrawCheckBox(Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (cb.Appearance == Appearance.Button && cb.FlatStyle != FlatStyle.Flat) + ButtonBase_DrawButton(cb, g); + else if (cb.Appearance != Appearance.Button) + DrawCheckBoxGlyph(g, cb, glyphArea); + + // Draw the borders and such for a Flat CheckBox Button + if (cb.Appearance == Appearance.Button && cb.FlatStyle == FlatStyle.Flat) + DrawFlatButton(g, cb, textBounds, imageBounds, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawCheckBoxImage(g, cb, imageBounds); + + if (cb.Focused && cb.Enabled && cb.ShowFocusCues && textBounds != Rectangle.Empty) + DrawCheckBoxFocus(g, cb, textBounds); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawCheckBoxText(g, cb, textBounds); + } + + public virtual void DrawCheckBoxGlyph(Graphics g, CheckBox cb, Rectangle glyphArea) + { + if (cb.Pressed) + MemphisThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox(g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState); + else if (cb.InternalSelected) + MemphisThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox(g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState); + else if (cb.Entered) + MemphisThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox(g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState); + else if (!cb.Enabled) + MemphisThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox(g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState); + else + MemphisThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox(g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState); + } + + public virtual void DrawCheckBoxFocus(Graphics g, CheckBox cb, Rectangle focusArea) + { + WidgetPaint.DrawFocusRectangle(g, focusArea); + } + + public virtual void DrawCheckBoxImage(Graphics g, CheckBox cb, Rectangle imageBounds) + { + if (cb.Enabled) + g.DrawImage(cb.Image, imageBounds); + else + CPDrawImageDisabled(g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawCheckBoxText(Graphics g, CheckBox cb, Rectangle textBounds) + { + if (cb.Enabled) + TextRenderer.DrawTextInternal(g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering); + else + DrawStringDisabled20(g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering); + } + + public override void CalculateCheckBoxTextAndImageLayout(ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle) + { + int check_size = CheckSize; + + if (button is CheckBox) + check_size = (button as CheckBox).Appearance == Appearance.Normal ? check_size : 0; + + glyphArea = new Rectangle(button.Padding.Left, button.Padding.Top, check_size, check_size); + + Rectangle content_rect = button.PaddingClientRectangle; + ContentAlignment align = ContentAlignment.TopLeft; + + if (button is CheckBox) + align = (button as CheckBox).CheckAlign; + else if (button is RadioButton) + align = (button as RadioButton).CheckAlign; + + switch (align) + { + case ContentAlignment.BottomCenter: + glyphArea.Y += content_rect.Height - check_size - 2; + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.BottomLeft: + glyphArea.Y += content_rect.Height - check_size - 2; + content_rect.Width -= check_size; + content_rect.Offset(check_size, 0); + break; + case ContentAlignment.BottomRight: + glyphArea.Y += content_rect.Height - check_size - 2; + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + case ContentAlignment.MiddleCenter: + glyphArea.Y += (content_rect.Height - check_size) / 2; + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.MiddleLeft: + glyphArea.Y += (content_rect.Height - check_size) / 2; + content_rect.Width -= check_size; + content_rect.Offset(check_size, 0); + break; + case ContentAlignment.MiddleRight: + glyphArea.Y += (content_rect.Height - check_size) / 2; + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + case ContentAlignment.TopCenter: + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.TopLeft: + content_rect.Width -= check_size; + content_rect.Offset(check_size, 0); + break; + case ContentAlignment.TopRight: + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + } + + Image image = button.Image; + string text = button.Text; + + Size proposed = Size.Empty; + + // Force wrapping if we aren't AutoSize and our text is too long + if (!button.AutoSize) + proposed.Width = button.PaddingClientRectangle.Width - glyphArea.Width - 2; + + Size text_size = TextRenderer.MeasureTextInternal(text, button.Font, proposed, button.TextFormatFlags, button.UseCompatibleTextRendering); + + // Text can't be bigger than the content rectangle + text_size.Height = Math.Min(text_size.Height, content_rect.Height); + text_size.Width = Math.Min(text_size.Width, content_rect.Width); + + Size image_size = image == null ? Size.Empty : image.Size; + + textRectangle = Rectangle.Empty; + imageRectangle = Rectangle.Empty; + + switch (button.TextImageRelation) + { + case TextImageRelation.Overlay: + // Text is centered vertically, and 2 pixels to the right + textRectangle.X = content_rect.Left + 2; + textRectangle.Y = button.PaddingClientRectangle.Top + ((content_rect.Height - text_size.Height) / 2) - 1; + textRectangle.Size = text_size; + + // Image is dependent on ImageAlign + if (image == null) + return; + + int image_x = button.PaddingClientRectangle.Left; + int image_y = button.PaddingClientRectangle.Top; + int image_height = image.Height; + int image_width = image.Width; + + switch (button.ImageAlign) + { + case System.Drawing.ContentAlignment.TopLeft: + image_x += 5; + image_y += 5; + break; + case System.Drawing.ContentAlignment.TopCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += 5; + break; + case System.Drawing.ContentAlignment.TopRight: + image_x += content_rect.Width - image_width - 5; + image_y += 5; + break; + case System.Drawing.ContentAlignment.MiddleLeft: + image_x += 5; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleRight: + image_x += content_rect.Width - image_width - 4; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.BottomLeft: + image_x += 5; + image_y += content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomRight: + image_x += content_rect.Width - image_width - 4; + image_y += content_rect.Height - image_height - 4; + break; + default: + image_x += 5; + image_y += 5; + break; + } + + imageRectangle = new Rectangle(image_x + check_size, image_y, image_width, image_height); + break; + case TextImageRelation.ImageAboveText: + content_rect.Inflate(-4, -4); + LayoutTextAboveOrBelowImage(content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextAboveImage: + content_rect.Inflate(-4, -4); + LayoutTextAboveOrBelowImage(content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle); + break; + case TextImageRelation.ImageBeforeText: + content_rect.Inflate(-4, -4); + LayoutTextBeforeOrAfterImage(content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextBeforeImage: + content_rect.Inflate(-4, -4); + LayoutTextBeforeOrAfterImage(content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + } + } + + public override Size CalculateCheckBoxAutoSize(CheckBox checkBox) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal(checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering); + Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size; + + // Pad the text size + if (checkBox.Text.Length != 0) + { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (checkBox.TextImageRelation) + { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max(checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max(text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (checkBox.Padding.Vertical); + ret_size.Width += (checkBox.Padding.Horizontal) + 15; + + // There seems to be a minimum height + if (ret_size.Height == checkBox.Padding.Vertical) + ret_size.Height += 14; + + return ret_size; + } + + public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) + { + StringFormat text_format; + Rectangle client_rectangle; + Rectangle text_rectangle; + Rectangle checkbox_rectangle; + int checkmark_size = CheckSize; + int checkmark_space = 4; + + client_rectangle = checkbox.ClientRectangle; + text_rectangle = client_rectangle; + checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size); + + text_format = new StringFormat(); + text_format.Alignment = StringAlignment.Near; + text_format.LineAlignment = StringAlignment.Center; + if (checkbox.ShowKeyboardCuesInternal) + text_format.HotkeyPrefix = HotkeyPrefix.Show; + else + text_format.HotkeyPrefix = HotkeyPrefix.Hide; + + /* Calculate the position of text and checkbox rectangle */ + if (checkbox.appearance != Appearance.Button) + { + switch (checkbox.check_alignment) + { + case ContentAlignment.BottomCenter: + { + checkbox_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - checkmark_size / 2; + checkbox_rectangle.Y = client_rectangle.Bottom - checkmark_size; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + text_rectangle.Height = client_rectangle.Height - checkbox_rectangle.Y - checkmark_space; + break; + } + + case ContentAlignment.BottomLeft: + { + checkbox_rectangle.X = client_rectangle.Left; + checkbox_rectangle.Y = client_rectangle.Bottom - checkmark_size; + text_rectangle.X = client_rectangle.X + checkmark_size + checkmark_space; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.BottomRight: + { + checkbox_rectangle.X = client_rectangle.Right - checkmark_size; + checkbox_rectangle.Y = client_rectangle.Bottom - checkmark_size; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.MiddleCenter: + { + checkbox_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - checkmark_size / 2; + checkbox_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - checkmark_size / 2; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + break; + } + + default: + case ContentAlignment.MiddleLeft: + { + checkbox_rectangle.X = client_rectangle.Left; + checkbox_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - checkmark_size / 2; + text_rectangle.X = client_rectangle.X + checkmark_size + checkmark_space; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.MiddleRight: + { + checkbox_rectangle.X = client_rectangle.Right - checkmark_size; + checkbox_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - checkmark_size / 2; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.TopCenter: + { + checkbox_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - checkmark_size / 2; + checkbox_rectangle.Y = client_rectangle.Top; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + text_rectangle.Y = checkmark_size + checkmark_space; + text_rectangle.Height = client_rectangle.Height - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.TopLeft: + { + checkbox_rectangle.X = client_rectangle.Left; + text_rectangle.X = client_rectangle.X + checkmark_size + checkmark_space; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + + case ContentAlignment.TopRight: + { + checkbox_rectangle.X = client_rectangle.Right - checkmark_size; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - checkmark_size - checkmark_space; + break; + } + } + } + else + { + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + } + + /* Set the horizontal alignment of our text */ + switch (checkbox.text_alignment) + { + case ContentAlignment.BottomLeft: + case ContentAlignment.MiddleLeft: + case ContentAlignment.TopLeft: + { + text_format.Alignment = StringAlignment.Near; + break; + } + + case ContentAlignment.BottomCenter: + case ContentAlignment.MiddleCenter: + case ContentAlignment.TopCenter: + { + text_format.Alignment = StringAlignment.Center; + break; + } + + case ContentAlignment.BottomRight: + case ContentAlignment.MiddleRight: + case ContentAlignment.TopRight: + { + text_format.Alignment = StringAlignment.Far; + break; + } + } + + /* Set the vertical alignment of our text */ + switch (checkbox.text_alignment) + { + case ContentAlignment.TopLeft: + case ContentAlignment.TopCenter: + case ContentAlignment.TopRight: + { + text_format.LineAlignment = StringAlignment.Near; + break; + } + + case ContentAlignment.BottomLeft: + case ContentAlignment.BottomCenter: + case ContentAlignment.BottomRight: + { + text_format.LineAlignment = StringAlignment.Far; + break; + } + + case ContentAlignment.MiddleLeft: + case ContentAlignment.MiddleCenter: + case ContentAlignment.MiddleRight: + { + text_format.LineAlignment = StringAlignment.Center; + break; + } + } + + ButtonState state = ButtonState.Normal; + if (checkbox.FlatStyle == FlatStyle.Flat) + { + state |= ButtonState.Flat; + } + + if (checkbox.Checked) + { + state |= ButtonState.Checked; + } + + if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) + { + state |= ButtonState.Checked; + state |= ButtonState.Pushed; + } + + // finally make sure the pushed and inavtive states are rendered + if (!checkbox.Enabled) + { + state |= ButtonState.Inactive; + } + else if (checkbox.is_pressed) + { + state |= ButtonState.Pushed; + } + + // Start drawing + + CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle); + + if ((checkbox.image != null) || (checkbox.image_list != null)) + ButtonBase_DrawImage(checkbox, dc); + + CheckBox_DrawText(checkbox, text_rectangle, dc, text_format); + + if (checkbox.Focused && checkbox.Enabled && checkbox.appearance != Appearance.Button && checkbox.Text != String.Empty && checkbox.ShowFocusCues) + { + SizeF text_size = dc.MeasureString(checkbox.Text, checkbox.Font); + + Rectangle focus_rect = Rectangle.Empty; + focus_rect.X = text_rectangle.X; + focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2); + focus_rect.Size = text_size.ToSize(); + CheckBox_DrawFocus(checkbox, dc, focus_rect); + } + + text_format.Dispose(); + } + + protected virtual void CheckBox_DrawCheckBox(Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle) + { + Brush brush = checkbox.BackColor.ToArgb() == ColorControl.ToArgb() ? SystemBrushes.Control : ResPool.GetSolidBrush(checkbox.BackColor); + dc.FillRectangle(brush, checkbox.ClientRectangle); + // render as per normal button + if (checkbox.appearance == Appearance.Button) + { + ButtonBase_DrawButton(checkbox, dc); + + if ((checkbox.Focused) && checkbox.Enabled) + ButtonBase_DrawFocus(checkbox, dc); + } + else + { + // establish if we are rendering a flat style of some sort + if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) + { + DrawFlatStyleCheckBox(dc, checkbox_rectangle, checkbox); + } + else + { + CPDrawCheckBox(dc, checkbox_rectangle, state); + } + } + } + + protected virtual void CheckBox_DrawText(CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format) + { + DrawCheckBox_and_RadioButtonText(checkbox, text_rectangle, dc, + text_format, checkbox.Appearance, checkbox.Checked); + } + + protected virtual void CheckBox_DrawFocus(CheckBox checkbox, Graphics dc, Rectangle text_rectangle) + { + DrawInnerFocusRectangle(dc, text_rectangle, checkbox.BackColor); + } + + // renders a checkBox with the Flat and Popup FlatStyle + protected virtual void DrawFlatStyleCheckBox(Graphics graphics, Rectangle rectangle, CheckBox checkbox) + { + Pen pen; + Rectangle rect; + Rectangle checkbox_rectangle; + Rectangle fill_rectangle; + int lineWidth; + int Scale; + + // set up our rectangles first + if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) + { + // clip one pixel from bottom right for non popup rendered checkboxes + checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + 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)); + } + else + { + // clip two pixels from bottom right for non popup rendered checkboxes + checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0)); + 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)); + } + + + // if disabled render in disabled state + if (checkbox.Enabled) + { + // process the state of the checkbox + if (checkbox.is_entered || checkbox.Capture) + { + // decide on which background color to use + if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) + { + graphics.FillRectangle(ResPool.GetSolidBrush(checkbox.BackColor), fill_rectangle); + } + else if (checkbox.FlatStyle == FlatStyle.Flat) + { + if (!checkbox.is_pressed) + { + graphics.FillRectangle(ResPool.GetSolidBrush(checkbox.BackColor), fill_rectangle); + } + else + graphics.FillRectangle(ResPool.GetSolidBrush(WidgetPaint.LightLight(checkbox.BackColor)), fill_rectangle); + } + else + { + // use regular window background color + graphics.FillRectangle(ResPool.GetSolidBrush(WidgetPaint.LightLight(checkbox.BackColor)), fill_rectangle); + } + + // render the outer border + if (checkbox.FlatStyle == FlatStyle.Flat) + { + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid); + } + else + { + // draw sunken effect + CPDrawBorder3D(graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, checkbox.BackColor); + } + } + else + { + graphics.FillRectangle(ResPool.GetSolidBrush(WidgetPaint.LightLight(checkbox.BackColor)), fill_rectangle); + + if (checkbox.FlatStyle == FlatStyle.Flat) + { + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid); + } + else + { + // draw the outer border + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, WidgetPaint.DarkDark(checkbox.BackColor), ButtonBorderStyle.Solid); + } + } + } + else + { + if (checkbox.FlatStyle == FlatStyle.Popup) + { + graphics.FillRectangle(SystemBrushes.Control, fill_rectangle); + } + + // draw disabled state, + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid); + } + + if (checkbox.Checked) + { + /* Need to draw a check-mark */ + + /* Make sure we've got at least a line width of 1 */ + lineWidth = Math.Max(3, fill_rectangle.Width / 3); + Scale = Math.Max(1, fill_rectangle.Width / 9); + + // flat style check box is rendered inside a rectangle shifted down by one + rect = new Rectangle(fill_rectangle.X, fill_rectangle.Y + 1, fill_rectangle.Width, fill_rectangle.Height); + if (checkbox.Enabled) + { + pen = ResPool.GetPen(checkbox.ForeColor); + } + else + { + pen = SystemPens.ControlDark; + } + + for (int i = 0; i < lineWidth; i++) + { + graphics.DrawLine(pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i); + 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); + } + } + } + + private void DrawCheckBox_and_RadioButtonText(ButtonBase button_base, Rectangle text_rectangle, Graphics dc, + StringFormat text_format, Appearance appearance, bool ischecked) + { + // offset the text if it's pressed and a button + if (appearance == Appearance.Button) + { + if (ischecked || (button_base.Capture && button_base.FlatStyle != FlatStyle.Flat)) + { + text_rectangle.X++; + text_rectangle.Y++; + } + + text_rectangle.Inflate(-4, -4); + } + + /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */ + + // Windows seems to not wrap text in certain situations, this matches as close as I could get it + if ((float)(button_base.Font.Height * 1.5f) > text_rectangle.Height) + { + text_format.FormatFlags |= StringFormatFlags.NoWrap; + } + if (button_base.Enabled) + { + dc.DrawString(button_base.Text, button_base.Font, ResPool.GetSolidBrush(button_base.ForeColor), text_rectangle, text_format); + } + else if (button_base.FlatStyle == FlatStyle.Flat || button_base.FlatStyle == FlatStyle.Popup) + { + dc.DrawString(button_base.Text, button_base.Font, SystemBrushes.ControlDarkDark, text_rectangle, text_format); + } + else + { + CPDrawStringDisabled(dc, button_base.Text, button_base.Font, button_base.BackColor, text_rectangle, text_format); + } + } + #endregion // CheckBox + + #region CheckedListBox + + public override void DrawCheckedListBoxItem(CheckedListBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + Rectangle item_rect = e.Bounds; + ButtonState state; + + /* Draw checkbox */ + + if ((e.State & DrawItemState.Checked) == DrawItemState.Checked) + { + state = ButtonState.Checked; + if ((e.State & DrawItemState.Inactive) == DrawItemState.Inactive) + state |= ButtonState.Inactive; + } + else + state = ButtonState.Normal; + + if (ctrl.ThreeDCheckBoxes == false) + state |= ButtonState.Flat; + + Rectangle checkbox_rect = new Rectangle(2, (item_rect.Height - 11) / 2, CheckSize, CheckSize); + WidgetPaint.DrawCheckBox(e.Graphics, + item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y, + checkbox_rect.Width, checkbox_rect.Height, + state); + + item_rect.X += checkbox_rect.Right; + item_rect.Width -= checkbox_rect.Right; + + /* Draw text*/ + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } + else + { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + e.Graphics.FillRectangle(ResPool.GetSolidBrush + (back_color), item_rect); + + e.Graphics.DrawString(ctrl.GetItemText(ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush(fore_color), + item_rect, ctrl.StringFormat); + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + { + CPDrawFocusRectangle(e.Graphics, item_rect, + fore_color, back_color); + } + } + + #endregion // CheckedListBox + + #region ComboBox + public override void DrawComboBoxItem(ComboBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + Rectangle text_draw = e.Bounds; + StringFormat string_format = new StringFormat(); + string_format.FormatFlags = StringFormatFlags.LineLimit; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } + else + { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + if (!ctrl.Enabled) + fore_color = ColorInactiveCaptionText; + + e.Graphics.FillRectangle(ResPool.GetSolidBrush(back_color), e.Bounds); + + if (e.Index != -1) + { + e.Graphics.DrawString(ctrl.GetItemText(ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush(fore_color), + text_draw, string_format); + } + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + { + CPDrawFocusRectangle(e.Graphics, e.Bounds, fore_color, back_color); + } + + string_format.Dispose(); + } + + public override void DrawFlatStyleComboButton(Graphics graphics, Rectangle rectangle, ButtonState state) + { + Point[] arrow = new Point[3]; + Point P1; + Point P2; + Point P3; + int centerX; + int centerY; + int shiftX; + int shiftY; + Rectangle rect; + + rect = new Rectangle(rectangle.X + rectangle.Width / 4, rectangle.Y + rectangle.Height / 4, rectangle.Width / 2, rectangle.Height / 2); + centerX = rect.Left + rect.Width / 2; + centerY = rect.Top + rect.Height / 2; + shiftX = Math.Max(1, rect.Width / 8); + shiftY = Math.Max(1, rect.Height / 8); + + if ((state & ButtonState.Pushed) != 0) + { + shiftX++; + shiftY++; + } + + rect.Y -= shiftY; + centerY -= shiftY; + P1 = new Point(rect.Left + 1, centerY); + P2 = new Point(rect.Right - 1, centerY); + P3 = new Point(centerX, rect.Bottom - 1); + + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + /* Draw the arrow */ + if ((state & ButtonState.Inactive) != 0) + { + /* Move away from the shadow */ + arrow[0].X += 1; arrow[0].Y += 1; + arrow[1].X += 1; arrow[1].Y += 1; + arrow[2].X += 1; arrow[2].Y += 1; + + graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding); + + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding); + } + else + { + graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding); + } + } + public override void ComboBoxDrawNormalDropDownButton(ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state) + { + CPDrawComboButton(g, area, state); + } + public override bool ComboBoxNormalDropDownButtonHasTransparentBackground(ComboBox comboBox, ButtonState state) + { + return true; + } + public override bool ComboBoxDropDownButtonHasHotElementStyle(ComboBox comboBox) + { + return false; + } + public override void ComboBoxDrawBackground(ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style) + { + if (!comboBox.Enabled) + g.FillRectangle(ResPool.GetSolidBrush(ColorControl), comboBox.ClientRectangle); + + if (comboBox.DropDownStyle == ComboBoxStyle.Simple) + g.FillRectangle(ResPool.GetSolidBrush(comboBox.Parent.BackColor), comboBox.ClientRectangle); + + if (style == FlatStyle.Popup && (comboBox.Entered || comboBox.Focused)) + { + Rectangle area = comboBox.TextArea; + area.Height -= 1; + area.Width -= 1; + g.DrawRectangle(ResPool.GetPen(SystemColors.ControlDark), area); + g.DrawLine(ResPool.GetPen(SystemColors.ControlDark), comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Top, comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Bottom); + } + bool is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup; + if (!is_flat && clippingArea.IntersectsWith(comboBox.TextArea)) + WidgetPaint.DrawBorder3D(g, comboBox.TextArea, Border3DStyle.Sunken); + } + public override bool CombBoxBackgroundHasHotElementStyle(ComboBox comboBox) + { + return false; + } + #endregion ComboBox + + /* FIXME: NEIN. I will NOT port DataGrids over. + #region Datagrid + public override int DataGridPreferredColumnWidth { get { return 75;} } + public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} } + public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} } + public override Color DataGridAlternatingBackColor { get { return ColorWindow;} } + public override Color DataGridBackColor { get { return ColorWindow;} } + public override Color DataGridBackgroundColor { get { return ColorAppWorkspace;} } + public override Color DataGridCaptionBackColor { get { return ColorActiveCaption;} } + public override Color DataGridCaptionForeColor { get { return ColorActiveCaptionText;} } + public override Color DataGridGridLineColor { get { return ColorControl;} } + public override Color DataGridHeaderBackColor { get { return ColorControl;} } + public override Color DataGridHeaderForeColor { get { return ColorControlText;} } + public override Color DataGridLinkColor { get { return ColorHotTrack;} } + public override Color DataGridLinkHoverColor { get { return ColorHotTrack;} } + public override Color DataGridParentRowsBackColor { get { return ColorControl;} } + public override Color DataGridParentRowsForeColor { get { return ColorWindowText;} } + public override Color DataGridSelectionBackColor { get { return ColorActiveCaption;} } + public override Color DataGridSelectionForeColor { get { return ColorActiveCaptionText;} } + + public override void DataGridPaint (PaintEventArgs pe, DataGrid grid) + { + DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid); + + // Paint scrollBar corner + if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) { + + Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.VScrollBar.Width, + grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.HScrollBar.Height, + grid.VScrollBar.Width, grid.HScrollBar.Height); + + if (pe.ClipRectangle.IntersectsWith (corner)) { + pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), + corner); + } + } + } + + public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid) + { + Rectangle bounds = clip; + bounds.Intersect (grid.caption_area); + + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor), bounds); + + // Bottom line + g.DrawLine (ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds.X, bounds.Y + bounds.Height -1, + bounds.X + bounds.Width, bounds.Y + bounds.Height -1); + + // Caption text + if (grid.CaptionText != String.Empty) { + Rectangle text_rect = grid.caption_area; + text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2; + text_rect.Height = grid.CaptionFont.Height; + + g.DrawString (grid.CaptionText, grid.CaptionFont, + ResPool.GetSolidBrush (grid.CaptionForeColor), + text_rect); + } + + // Back button + if (bounds.IntersectsWith (grid.back_button_rect)) { + g.DrawImage (grid.back_button_image, grid.back_button_rect); + if (grid.back_button_mouseover) { + CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides); + } + } + + // Rows button + if (bounds.IntersectsWith (grid.parent_rows_button_rect)) { + g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect); + if (grid.parent_rows_button_mouseover) { + CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides); + } + } + } + + public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid) + { + if (!grid.CurrentTableStyle.ColumnHeadersVisible) + return; + + Rectangle columns_area = grid.column_headers_area; + + // Paint corner shared between row and column header + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + Rectangle rect_bloc = grid.column_headers_area; + rect_bloc.Width = grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_bloc)) { + if (grid.FlatMode) + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc); + else + CPDrawBorder3D (g, rect_bloc, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Middle, + grid.CurrentTableStyle.CurrentHeaderBackColor); + } + + columns_area.X += grid.RowHeaderWidth; + columns_area.Width -= grid.RowHeaderWidth; + } + + // Set column painting + Rectangle rect_columnhdr = new Rectangle (); + int col_pixel; + Region current_clip; + Region prev_clip = g.Clip; + rect_columnhdr.Y = columns_area.Y; + rect_columnhdr.Height = columns_area.Height; + + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + + col_pixel = grid.GetColumnStartingPixel (column); + rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset; + rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width; + + if (clip.IntersectsWith (rect_columnhdr) == false) + continue; + + current_clip = new Region (rect_columnhdr); + current_clip.Intersect (columns_area); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + DataGridPaintColumnHeader (g, rect_columnhdr, grid, column); + + current_clip.Dispose (); + } + + g.Clip = prev_clip; + + Rectangle not_usedarea = grid.column_headers_area; + not_usedarea.X = (column_cnt == 0) ? grid.RowHeaderWidth : rect_columnhdr.X + rect_columnhdr.Width; + not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - not_usedarea.X; + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea); + } + + public override void DataGridPaintColumnHeader (Graphics g, Rectangle bounds, DataGrid grid, int col) + { + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.HeaderBackColor), bounds); + + // Paint Borders + if (!grid.FlatMode) { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y); + + if (col == 0) { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height); + } else { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 3); + } + + if (col == (grid.VisibleColumnCount -1)) { + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X + bounds.Width - 1, bounds.Y, + bounds.X + bounds.Width - 1, bounds.Y + bounds.Height); + } else { + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X + bounds.Width - 1, bounds.Y + 2, + bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 3); + } + + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X, bounds.Y + bounds.Height - 1, + bounds.X + bounds.Width, bounds.Y + bounds.Height - 1); + } + + bounds.X += 2; + bounds.Width -= 2; + + DataGridColumnStyle style = grid.CurrentTableStyle.GridColumnStyles[col]; + + if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) + bounds.Width -= 16; + + // Caption + StringFormat format = new StringFormat (); + format.FormatFlags |= StringFormatFlags.NoWrap; + format.LineAlignment = StringAlignment.Center; + format.Trimming = StringTrimming.Character; + + g.DrawString (style.HeaderText, grid.CurrentTableStyle.HeaderFont, + ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds, format); + + // Arrow (6 x 6) + if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) { + Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2)); + + if (style.ArrowDrawingMode == DataGridColumnStyle.ArrowDrawing.Ascending) { + g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y); + } else { + g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6); + } + } + } + + public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid) + { + Rectangle rect_row = new Rectangle (); + + rect_row.X = grid.ParentRowsArea.X; + rect_row.Width = grid.ParentRowsArea.Width; + rect_row.Height = (grid.CaptionFont.Height + 3); + + object[] parentRows = grid.data_source_stack.ToArray(); + + Region current_clip; + Region prev_clip = g.Clip; + for (int row = 0; row < parentRows.Length; row++) { + rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height; + + if (clip.IntersectsWith (rect_row) == false) + continue; + + current_clip = new Region (rect_row); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid); + + current_clip.Dispose (); + } + + g.Clip = prev_clip; + } + + public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid) + { + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), + bounds); + + Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold); + // set up some standard string formating variables + StringFormat text_format = new StringFormat(); + text_format.LineAlignment = StringAlignment.Center; + text_format.Alignment = StringAlignment.Near; + + string table_name = ""; + if (row.view is DataRowView) + table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": "; + // XXX else? + + Rectangle text_rect; + Size text_size; + + text_size = g.MeasureString (table_name, bold_font).ToSize(); + text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size); + + g.DrawString (table_name, + bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format); + + foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) { + if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType)) + continue; + + text_rect.X += text_rect.Size.Width + 5; + + string text = String.Format ("{0}: {1}", + pd.Name, + pd.GetValue (row.view)); + + text_rect.Size = g.MeasureString (text, grid.Font).ToSize(); + text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX + + g.DrawString (text, + grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format); + } + + // Paint Borders + if (!grid.FlatMode) { + CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom); + } + } + + public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) + { + Point[] arrow = new Point[3]; + Point P1, P2, P3; + int centerX, centerY, shiftX; + Rectangle rect; + + rect = new Rectangle (bounds.X + bounds.Width /4, + bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2); + + centerX = rect.Left + rect.Width / 2; + centerY = rect.Top + rect.Height / 2; + shiftX = Math.Max (1, rect.Width / 8); + rect.X -= shiftX; + centerX -= shiftX; + P1 = new Point (centerX, rect.Top - 1); + P2 = new Point (centerX, rect.Bottom); + P3 = new Point (rect.Right, centerY); + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + g.FillPolygon (ResPool.GetSolidBrush + (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding); + } + + public override void DataGridPaintRowHeaderStar (Graphics g, Rectangle bounds, DataGrid grid) + { + int x = bounds.X + 4; + int y = bounds.Y + 3; + Pen pen = ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor); + + g.DrawLine (pen, x + 4, y, x + 4, y + 8); + g.DrawLine (pen, x, y + 4, x + 8, y + 4); + g.DrawLine (pen, x + 1, y + 1, x + 7, y + 7); + g.DrawLine (pen, x + 7, y + 1, x + 1, y + 7); + } + + public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid) + { + bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1; + bool is_current_row = row == grid.CurrentCell.RowNumber; + + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), bounds); + + // Draw arrow + if (is_current_row) { + if (grid.IsChanging) { + g.DrawString ("..", grid.Font, + ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds); + } else { + Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18); + DataGridPaintRowHeaderArrow (g, rect, grid); + } + } + else if (is_add_row) { + DataGridPaintRowHeaderStar (g, bounds, grid); + } + + if (!grid.FlatMode && !is_add_row) { + CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom); + } + } + + public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid) + { + Rectangle rect_row = new Rectangle (); + Rectangle not_usedarea = new Rectangle (); + + int rowcnt = grid.VisibleRowCount; + + bool showing_add_row = false; + + if (grid.RowsCount < grid.DataGridRows.Length) { + /* the table has an add row + + if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) { + showing_add_row = true; + } + } + + rect_row.Width = cells.Width + grid.RowHeadersArea.Width; + for (int r = 0; r < rowcnt; r++) { + int row = grid.FirstVisibleRow + r; + if (row == grid.DataGridRows.Length - 1) + rect_row.Height = grid.DataGridRows[row].Height; + else + rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset; + rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset; + if (clip.IntersectsWith (rect_row)) { + if (grid.CurrentTableStyle.HasRelations + && !(showing_add_row && row == grid.DataGridRows.Length - 1)) + DataGridPaintRelationRow (g, row, rect_row, false, clip, grid); + else + DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid); + } + } + + not_usedarea.X = 0; + // the rowcnt == 0 check is needed because + // otherwise we'd draw over the caption on + // empty datasources (since rect_row would be + // Empty) + if (rowcnt == 0) + not_usedarea.Y = cells.Y; + else + not_usedarea.Y = rect_row.Y + rect_row.Height; + not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height; + not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width; + + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea); + } + + public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + Rectangle rect_header; + Rectangle icon_bounds = new Rectangle (); + Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor); + + /* paint the header if it's visible and intersects the clip + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + rect_header = row_rect; + rect_header.Width = grid.RowHeaderWidth; + row_rect.X += grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_header)) { + DataGridPaintRowHeader (g, rect_header, row, grid); + } + + icon_bounds = rect_header; + icon_bounds.X += icon_bounds.Width / 2; + icon_bounds.Y += 3; + icon_bounds.Width = 8; + icon_bounds.Height = 8; + + g.DrawRectangle (pen, icon_bounds); + + /* the - part of the icon + g.DrawLine (pen, + icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2, + icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2); + + if (!grid.IsExpanded (row)) { + /* the | part of the icon + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2); + } + } + + Rectangle nested_rect = row_rect; + + if (grid.DataGridRows[row].IsExpanded) + nested_rect.Height -= grid.DataGridRows[row].RelationHeight; + + DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid); + + if (grid.DataGridRows[row].IsExpanded) { + // XXX we should create this in the + // datagrid and cache it for use by + // the theme instead of doing it each + // time through here + string[] relations = grid.CurrentTableStyle.Relations; + StringBuilder relation_builder = new StringBuilder (""); + + for (int i = 0; i < relations.Length; i ++) { + if (i > 0) + relation_builder.Append ("\n"); + + relation_builder.Append (relations[i]); + } + string relation_text = relation_builder.ToString (); + + StringFormat string_format = new StringFormat (); + string_format.FormatFlags |= StringFormatFlags.NoWrap; + + + //Region prev_clip = g.Clip; + //Region current_clip; + Rectangle rect_cell = row_rect; + + rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset; + rect_cell.Y += nested_rect.Height; + rect_cell.Height = grid.DataGridRows[row].RelationHeight; + + rect_cell.Width = 0; + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width; + } + rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width); + + g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor), + rect_cell); + + + /* draw the line leading from the +/- to the relation area + Rectangle outline = grid.DataGridRows[row].relation_area; + outline.Y = rect_cell.Y; + outline.Height --; + + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height, + icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2); + + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2, + outline.X, outline.Y + outline.Height / 2); + + g.DrawRectangle (pen, outline); + + g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor), + outline, string_format); + + if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) { + Rectangle not_usedarea = new Rectangle (); + not_usedarea.X = rect_cell.X + rect_cell.Width; + not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width; + not_usedarea.Y = row_rect.Y; + not_usedarea.Height = row_rect.Height; + if (clip.IntersectsWith (not_usedarea)) + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), + not_usedarea); + } + } + } + + public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + Rectangle rect_cell = new Rectangle (); + int col_pixel; + Color backcolor, forecolor; + Brush backBrush, foreBrush; + Rectangle not_usedarea = Rectangle.Empty; + + rect_cell.Y = row_rect.Y; + rect_cell.Height = row_rect.Height; + + if (grid.IsSelected (row)) { + backcolor = grid.SelectionBackColor; + forecolor = grid.SelectionForeColor; + } else { + if (row % 2 == 0) { + backcolor = grid.BackColor; + } else { + backcolor = grid.AlternatingBackColor; + } + + forecolor = grid.ForeColor; + } + + + backBrush = ResPool.GetSolidBrush (backcolor); + foreBrush = ResPool.GetSolidBrush (forecolor); + + // PaintCells at row, column + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + DataGridCell current_cell = grid.CurrentCell; + + if (column_cnt > 0) { + Region prev_clip = g.Clip; + Region current_clip; + + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + + col_pixel = grid.GetColumnStartingPixel (column); + + rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset; + rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width; + + if (clip.IntersectsWith (rect_cell)) { + current_clip = new Region (rect_cell); + current_clip.Intersect (row_rect); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + Brush colBackBrush = backBrush; + Brush colForeBrush = foreBrush; + + // If we are in the precise cell we are editing, then use the normal colors + // even if we are selected. + if (grid.is_editing && column == current_cell.ColumnNumber && row == current_cell.RowNumber) { + colBackBrush = ResPool.GetSolidBrush (grid.BackColor); + colForeBrush = ResPool.GetSolidBrush (grid.ForeColor); + } + + if (is_newrow) { + grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, + colBackBrush, + colForeBrush); + } else { + grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row, + colBackBrush, + colForeBrush, + grid.RightToLeft == RightToLeft.Yes); + } + + current_clip.Dispose (); + } + } + + g.Clip = prev_clip; + + if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) { + not_usedarea.X = rect_cell.X + rect_cell.Width; + not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width; + not_usedarea.Y = row_rect.Y; + not_usedarea.Height = row_rect.Height; + } + } + else { + not_usedarea = row_rect; + } + + if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea)) + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), + not_usedarea); + } + + public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + /* paint the header if it's visible and intersects the clip + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + Rectangle rect_header = row_rect; + rect_header.Width = grid.RowHeaderWidth; + row_rect.X += grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_header)) { + DataGridPaintRowHeader (g, rect_header, row, grid); + } + } + + DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid); + } + + #endregion // Datagrid + + #region DataGridView + #region DataGridViewHeaderCell + #region DataGridViewRowHeaderCell + public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + + public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell) + { + return false; + } + + public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + #endregion + + #region DataGridViewColumnHeaderCell + public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + + public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + #endregion + + public override bool DataGridViewHeaderCellHasPressedStyle (DataGridView dataGridView) + { + return false; + } + + public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView) + { + return false; + } + #endregion + #endregion +*/ + + #region DateTimePicker + protected virtual void DateTimePickerDrawBorder(DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + this.CPDrawBorder3D(g, dateTimePicker.ClientRectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dateTimePicker.BackColor); + } + + protected virtual void DateTimePickerDrawDropDownButton(DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + ButtonState state = dateTimePicker.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal; + g.FillRectangle(ResPool.GetSolidBrush(ColorControl), dateTimePicker.drop_down_arrow_rect); + this.CPDrawComboButton( + g, + dateTimePicker.drop_down_arrow_rect, + state); + } + + public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp) + { + + if (!clip_rectangle.IntersectsWith(dtp.ClientRectangle)) + return; + + // draw the outer border + Rectangle button_bounds = dtp.ClientRectangle; + DateTimePickerDrawBorder(dtp, dc, clip_rectangle); + + // deflate by the border width + if (clip_rectangle.IntersectsWith(dtp.drop_down_arrow_rect)) + { + button_bounds.Inflate(-2, -2); + if (!dtp.ShowUpDown) + { + DateTimePickerDrawDropDownButton(dtp, dc, clip_rectangle); + } + else + { + ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal; + ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal; + Rectangle up_bounds = dtp.drop_down_arrow_rect; + Rectangle down_bounds = dtp.drop_down_arrow_rect; + + up_bounds.Height = up_bounds.Height / 2; + down_bounds.Y = up_bounds.Height; + down_bounds.Height = dtp.Height - up_bounds.Height; + if (down_bounds.Height > up_bounds.Height) + { + down_bounds.Y += 1; + down_bounds.Height -= 1; + } + + up_bounds.Inflate(-1, -1); + down_bounds.Inflate(-1, -1); + + WidgetPaint.DrawScrollButton(dc, up_bounds, ScrollButton.Up, up_state); + WidgetPaint.DrawScrollButton(dc, down_bounds, ScrollButton.Down, down_state); + } + } + + // render the date part + if (!clip_rectangle.IntersectsWith(dtp.date_area_rect)) + return; + + // fill the background + dc.FillRectangle(SystemBrushes.Window, dtp.date_area_rect); + + // Update date_area_rect if we are drawing the checkbox + Rectangle date_area_rect = dtp.date_area_rect; + if (dtp.ShowCheckBox) + { + Rectangle check_box_rect = dtp.CheckBoxRect; + date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2; + date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2; + + ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal; + CPDrawCheckBox(dc, check_box_rect, bs); + + if (dtp.is_checkbox_selected) + CPDrawFocusRectangle(dc, check_box_rect, dtp.foreground_color, dtp.background_color); + } + + // render each text part + using (StringFormat text_format = StringFormat.GenericTypographic) + { + text_format.LineAlignment = StringAlignment.Near; + text_format.Alignment = StringAlignment.Near; + text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; + text_format.FormatFlags &= ~StringFormatFlags.NoClip; + + // Calculate the rectangles for each part + if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty) + { + Graphics gr = dc; + for (int i = 0; i < dtp.part_data.Length; i++) + { + DateTimePicker.PartData fd = dtp.part_data[i]; + RectangleF text_rect = new RectangleF(); + string text = fd.GetText(dtp.Value); + text_rect.Size = gr.MeasureString(text, dtp.Font, 250, text_format); + if (!fd.is_literal) + text_rect.Width = Math.Max(dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width); + + if (i > 0) + { + text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right; + } + else + { + text_rect.X = date_area_rect.X; + } + text_rect.Y = 2; + text_rect.Inflate(1, 0); + fd.drawing_rectangle = text_rect; + } + } + + // draw the text part + Brush text_brush = ResPool.GetSolidBrush(dtp.ShowCheckBox && dtp.Checked == false ? + SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false + RectangleF clip_rectangleF = clip_rectangle; + + for (int i = 0; i < dtp.part_data.Length; i++) + { + DateTimePicker.PartData fd = dtp.part_data[i]; + string text; + + if (!clip_rectangleF.IntersectsWith(fd.drawing_rectangle)) + continue; + + text = dtp.editing_part_index == i ? dtp.editing_text : fd.GetText(dtp.Value); + + PointF text_position = new PointF(); + SizeF text_size; + RectangleF text_rect; + + text_size = dc.MeasureString(text, dtp.Font, 250, text_format); + text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2; + text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2; + text_rect = new RectangleF(text_position, text_size); + text_rect = RectangleF.Intersect(text_rect, date_area_rect); + + if (text_rect.IsEmpty) + break; + + if (text_rect.Right >= date_area_rect.Right) + text_format.FormatFlags &= ~StringFormatFlags.NoClip; + else + text_format.FormatFlags |= StringFormatFlags.NoClip; + + if (fd.Selected) + { + dc.FillRectangle(SystemBrushes.Highlight, text_rect); + dc.DrawString(text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format); + + } + else + { + dc.DrawString(text, dtp.Font, text_brush, text_rect, text_format); + } + + if (fd.drawing_rectangle.Right > date_area_rect.Right) + break; // the next part would be not be visible, so don't draw anything more. + } + } + } + + public override bool DateTimePickerBorderHasHotElementStyle + { + get + { + return false; + } + } + + public override Rectangle DateTimePickerGetDropDownButtonArea(DateTimePicker dateTimePicker) + { + Rectangle rect = dateTimePicker.ClientRectangle; + rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2; + if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) + { + rect.Width = SystemInformation.VerticalScrollBarWidth; + } + else + { + rect.Width = Math.Max(rect.Width - 2, 0); + } + + rect.Inflate(0, -2); + return rect; + } + + public override Rectangle DateTimePickerGetDateArea(DateTimePicker dateTimePicker) + { + Rectangle rect = dateTimePicker.ClientRectangle; + if (dateTimePicker.ShowUpDown) + { + // set the space to the left of the up/down button + if (rect.Width > (DateTimePicker.up_down_width + 4)) + { + rect.Width -= (DateTimePicker.up_down_width + 4); + } + else + { + rect.Width = 0; + } + } + else + { + // set the space to the left of the up/down button + // TODO make this use up down button + if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) + { + rect.Width -= SystemInformation.VerticalScrollBarWidth; + } + else + { + rect.Width = 0; + } + } + + rect.Inflate(-2, -2); + return rect; + } + public override bool DateTimePickerDropDownButtonHasHotElementStyle + { + get + { + return false; + } + } + #endregion // DateTimePicker + + #region GroupBox + public override void DrawGroupBox(Graphics dc, Rectangle area, GroupBox box) + { + StringFormat text_format; + SizeF size; + int width; + int y; + + dc.FillRectangle(GetControlBackBrush(box.BackColor), box.ClientRectangle); + + text_format = new StringFormat(); + text_format.HotkeyPrefix = HotkeyPrefix.Show; + + size = dc.MeasureString(box.Text, box.Font); + width = 0; + + if (size.Width > 0) + { + width = ((int)size.Width) + 7; + + if (width > box.Width - 16) + width = box.Width - 16; + } + + y = box.Font.Height / 2; + + // Clip the are that the text will be in + Region prev_clip = dc.Clip; + dc.SetClip(new Rectangle(10, 0, width, box.Font.Height), CombineMode.Exclude); + /* Draw group box*/ + CPDrawBorder3D(dc, new Rectangle(0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor); + dc.Clip = prev_clip; + + /* Text */ + if (box.Text.Length != 0) + { + if (box.Enabled) + { + dc.DrawString(box.Text, box.Font, ResPool.GetSolidBrush(box.ForeColor), 10, 0, text_format); + } + else + { + CPDrawStringDisabled(dc, box.Text, box.Font, box.BackColor, + new RectangleF(10, 0, width, box.Font.Height), text_format); + } + } + + text_format.Dispose(); + } + + public override Size GroupBoxDefaultSize + { + get + { + return new Size(200, 100); + } + } + #endregion + + #region HScrollBar + public override Size HScrollBarDefaultSize + { + get + { + return new Size(80, this.ScrollBarButtonSize); + } + } + + #endregion // HScrollBar + + #region ListBox + + public override void DrawListBoxItem(ListBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) + { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } + else + { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + e.Graphics.FillRectangle(ResPool.GetSolidBrush(back_color), e.Bounds); + + e.Graphics.DrawString(ctrl.GetItemText(ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush(fore_color), + e.Bounds, ctrl.StringFormat); + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + CPDrawFocusRectangle(e.Graphics, e.Bounds, fore_color, back_color); + } + + #endregion ListBox + + #region ListView + // Drawing + public override void DrawListViewItems(Graphics dc, Rectangle clip, ListView control) + { + bool details = control.View == View.Details; + int first = control.FirstVisibleIndex; + int lastvisibleindex = control.LastVisibleIndex; + + if (control.VirtualMode) + control.OnCacheVirtualItems(new CacheVirtualItemsEventArgs(first, lastvisibleindex)); + + for (int i = first; i <= lastvisibleindex; i++) + { + ListViewItem item = control.GetItemAtDisplayIndex(i); + if (clip.IntersectsWith(item.Bounds)) + { + bool owner_draw = false; + if (control.OwnerDraw) + owner_draw = DrawListViewItemOwnerDraw(dc, item, i); + if (!owner_draw) + { + DrawListViewItem(dc, control, item); + if (control.View == View.Details) + DrawListViewSubItems(dc, control, item); + } + } + } + + if (control.UsingGroups) + { + // Use InternalCount instead of Count to take into account Default Group as needed + for (int i = 0; i < control.Groups.InternalCount; i++) + { + ListViewGroup group = control.Groups.GetInternalGroup(i); + if (group.ItemCount > 0 && clip.IntersectsWith(group.HeaderBounds)) + DrawListViewGroupHeader(dc, control, group); + } + } + + ListViewInsertionMark insertion_mark = control.InsertionMark; + int insertion_mark_index = insertion_mark.Index; + if (Application.VisualStylesEnabled && insertion_mark.Bounds != Rectangle.Empty && + (control.View != View.Details && control.View != View.List) && + insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) + { + + Brush brush = ResPool.GetSolidBrush(insertion_mark.Color); + dc.FillRectangle(brush, insertion_mark.Line); + dc.FillPolygon(brush, insertion_mark.TopTriangle); + dc.FillPolygon(brush, insertion_mark.BottomTriangle); + } + + // draw the gridlines + if (details && control.GridLines && !control.UsingGroups) + { + Size control_size = control.ClientSize; + int top = (control.HeaderStyle == ColumnHeaderStyle.None) ? + 0 : control.header_control.Height; + + // draw vertical gridlines + foreach (ColumnHeader col in control.Columns) + { + int column_right = col.Rect.Right - control.h_marker; + dc.DrawLine(SystemPens.Control, + column_right, top, + column_right, control_size.Height); + } + + // draw horizontal gridlines + int item_height = control.ItemSize.Height; + if (item_height == 0) + item_height = control.Font.Height + 2; + + int y = top + item_height - (control.v_marker % item_height); // scroll bar offset + while (y < control_size.Height) + { + dc.DrawLine(SystemPens.Control, 0, y, control_size.Width, y); + y += item_height; + } + } + + // Draw corner between the two scrollbars + if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) + { + Rectangle rect = new Rectangle(); + rect.X = control.h_scroll.Location.X + control.h_scroll.Width; + rect.Width = control.v_scroll.Width; + rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height; + rect.Height = control.h_scroll.Height; + dc.FillRectangle(SystemBrushes.Control, rect); + } + + Rectangle box_select_rect = control.item_control.BoxSelectRectangle; + if (!box_select_rect.Size.IsEmpty) + dc.DrawRectangle(ResPool.GetDashPen(ColorControlText, DashStyle.Dot), box_select_rect); + + } + + public override void DrawListViewHeader(Graphics dc, Rectangle clip, ListView control) + { + bool details = (control.View == View.Details); + + // border is drawn directly in the Paint method + if (details && control.HeaderStyle != ColumnHeaderStyle.None) + { + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ListViewBackground), + 0, 0, control.TotalWidth, control.Font.Height + 5); + if (control.Columns.Count > 0) + { + foreach (ColumnHeader col in control.Columns) + { + Rectangle rect = col.Rect; + rect.X -= control.h_marker; + + bool owner_draw = false; + if (control.OwnerDraw) + owner_draw = DrawListViewColumnHeaderOwnerDraw(dc, control, col, rect); + if (owner_draw) + continue; + + ListViewDrawColumnHeaderBackground(control, col, dc, rect, clip); + rect.X += 5; + rect.Width -= 10; + if (rect.Width <= 0) + continue; + + int image_index; + if (control.SmallImageList == null) + image_index = -1; + else + image_index = col.ImageKey == String.Empty ? col.ImageIndex : control.SmallImageList.Images.IndexOfKey(col.ImageKey); + + if (image_index > -1 && image_index < control.SmallImageList.Images.Count) + { + int image_width = control.SmallImageList.ImageSize.Width + 5; + int text_width = (int)dc.MeasureString(col.Text, control.Font).Width; + int x_origin = rect.X; + int y_origin = rect.Y + ((rect.Height - control.SmallImageList.ImageSize.Height) / 2); + + switch (col.TextAlign) + { + case HorizontalAlignment.Left: + break; + case HorizontalAlignment.Right: + x_origin = rect.Right - (text_width + image_width); + break; + case HorizontalAlignment.Center: + x_origin = (rect.Width - (text_width + image_width)) / 2 + rect.X; + break; + } + + if (x_origin < rect.X) + x_origin = rect.X; + + control.SmallImageList.Draw(dc, new Point(x_origin, y_origin), image_index); + rect.X += image_width; + rect.Width -= image_width; + } + + dc.DrawString(col.Text, control.Font, SystemBrushes.ControlText, rect, col.Format); + } + int right = control.GetReorderedColumn(control.Columns.Count - 1).Rect.Right - control.h_marker; + if (right < control.Right) + { + Rectangle rect = control.Columns[0].Rect; + rect.X = right; + rect.Width = control.Right - right; + ListViewDrawUnusedHeaderBackground(control, dc, rect, clip); + } + } + } + } + + protected virtual void ListViewDrawColumnHeaderBackground(ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea) + { + ButtonState state; + if (listView.HeaderStyle == ColumnHeaderStyle.Clickable) + state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal; + else + state = ButtonState.Flat; + CPDrawButton(g, area, state); + } + + protected virtual void ListViewDrawUnusedHeaderBackground(ListView listView, Graphics g, Rectangle area, Rectangle clippingArea) + { + ButtonState state; + if (listView.HeaderStyle == ColumnHeaderStyle.Clickable) + state = ButtonState.Normal; + else + state = ButtonState.Flat; + CPDrawButton(g, area, state); + } + + public override void DrawListViewHeaderDragDetails(Graphics dc, ListView view, ColumnHeader col, int target_x) + { + Rectangle rect = col.Rect; + rect.X -= view.h_marker; + Color color = Color.FromArgb(0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B); + dc.FillRectangle(ResPool.GetSolidBrush(color), rect); + rect.X += 3; + rect.Width -= 8; + if (rect.Width <= 0) + return; + color = Color.FromArgb(0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B); + dc.DrawString(col.Text, view.Font, ResPool.GetSolidBrush(color), rect, col.Format); + dc.DrawLine(ResPool.GetSizedPen(ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height); + } + + protected virtual bool DrawListViewColumnHeaderOwnerDraw(Graphics dc, ListView control, ColumnHeader column, Rectangle bounds) + { + ListViewItemStates state = ListViewItemStates.ShowKeyboardCues; + if (column.Pressed) + state |= ListViewItemStates.Selected; + + DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs(dc, + bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont); + control.OnDrawColumnHeader(args); + + return !args.DrawDefault; + } + + protected virtual bool DrawListViewItemOwnerDraw(Graphics dc, ListViewItem item, int index) + { + ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues; + if (item.Selected) + item_state |= ListViewItemStates.Selected; + if (item.Focused) + item_state |= ListViewItemStates.Focused; + + DrawListViewItemEventArgs args = new DrawListViewItemEventArgs(dc, + item, item.Bounds, index, item_state); + item.ListView.OnDrawItem(args); + + if (args.DrawDefault) + return false; + + if (item.ListView.View == View.Details) + { + int count = Math.Min(item.ListView.Columns.Count, item.SubItems.Count); + + // Do system drawing for subitems if no owner draw is done + for (int j = 0; j < count; j++) + { + if (!DrawListViewSubItemOwnerDraw(dc, item, item_state, j)) + { + if (j == 0) // The first sub item contains the main item semantics + DrawListViewItem(dc, item.ListView, item); + else + DrawListViewSubItem(dc, item.ListView, item, j); + } + } + } + + return true; + } + + protected virtual void DrawListViewItem(Graphics dc, ListView control, ListViewItem item) + { + Rectangle rect_checkrect = item.CheckRectReal; + Rectangle icon_rect = item.GetBounds(ItemBoundsPortion.Icon); + Rectangle full_rect = item.GetBounds(ItemBoundsPortion.Entire); + Rectangle text_rect = item.GetBounds(ItemBoundsPortion.Label); + + // Tile view doesn't support CheckBoxes + if (control.CheckBoxes && control.View != View.Tile) + { + if (control.StateImageList == null) + { + // Make sure we've got at least a line width of 1 + int check_wd = Math.Max(3, rect_checkrect.Width / 6); + int scale = Math.Max(1, rect_checkrect.Width / 12); + + // set the checkbox background + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.CheckBoxBackgroundColor), + rect_checkrect); + // define a rectangle inside the border area + Rectangle rect = new Rectangle(rect_checkrect.X + 2, + rect_checkrect.Y + 2, + rect_checkrect.Width - 4, + rect_checkrect.Height - 4); + Pen pen = new Pen(new SolidBrush(Application.CurrentSkin.CheckBoxBorderColor), Application.CurrentSkin.CheckBoxBorderWidth); + dc.DrawRectangle(pen, rect); + + // Need to draw a check-mark + if (item.Checked) + { + Pen check_pen = new Pen(new SolidBrush(Application.CurrentSkin.CheckBoxCheckColor), 1); + // adjustments to get the check-mark at the right place + rect.X++; rect.Y++; + // following logic is taken from DrawFrameControl method + int x_offset = rect.Width / 5; + int y_offset = rect.Height / 3; + for (int i = 0; i < check_wd; i++) + { + dc.DrawLine(check_pen, rect.Left + x_offset, + rect.Top + y_offset + i, + rect.Left + x_offset + 2 * scale, + rect.Top + y_offset + 2 * scale + i); + dc.DrawLine(check_pen, + rect.Left + x_offset + 2 * scale, + rect.Top + y_offset + 2 * scale + i, + rect.Left + x_offset + 6 * scale, + rect.Top + y_offset - 2 * scale + i); + } + } + } + else + { + int simage_idx; + if (item.Checked) + simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1; + else + simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1; + + if (simage_idx > -1) + control.StateImageList.Draw(dc, rect_checkrect.Location, simage_idx); + } + } + + ImageList image_list = control.View == View.LargeIcon || control.View == View.Tile ? control.LargeImageList : control.SmallImageList; + if (image_list != null) + { + int idx; + + if (item.ImageKey != String.Empty) + idx = image_list.Images.IndexOfKey(item.ImageKey); + else + idx = item.ImageIndex; + + if (idx > -1 && idx < image_list.Images.Count) + { + // Draw a thumbnail image if it exists for a FileViewListViewItem, otherwise draw + // the standard icon. See https://bugzilla.xamarin.com/show_bug.cgi?id=28025. + image_list.Draw(dc, icon_rect.Location, idx); + } + } + + // draw the item text + // format for the item text + StringFormat format = new StringFormat(); + if (control.View == View.SmallIcon || control.View == View.LargeIcon) + format.LineAlignment = StringAlignment.Near; + else + format.LineAlignment = StringAlignment.Center; + if (control.View == View.LargeIcon) + format.Alignment = StringAlignment.Center; + else + format.Alignment = StringAlignment.Near; + + if (control.LabelWrap && control.View != View.Details && control.View != View.Tile) + format.FormatFlags = StringFormatFlags.LineLimit; + else + format.FormatFlags = StringFormatFlags.NoWrap; + + if ((control.View == View.LargeIcon && !item.Focused) || control.View == View.Details || control.View == View.Tile) + format.Trimming = StringTrimming.EllipsisCharacter; + + Rectangle highlight_rect = text_rect; + if (control.View == View.Details) + { // Adjustments for Details view + Size text_size = Size.Ceiling(dc.MeasureString(item.Text, item.Font)); + + if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds + highlight_rect.Width = Math.Min(text_size.Width + 4, text_rect.Width); + } + + if (item.Selected && control.Focused) + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.SelectionHighlight), highlight_rect); + else if (item.Selected && !control.HideSelection) + dc.FillRectangle(SystemBrushes.Control, highlight_rect); + else + dc.FillRectangle(ResPool.GetSolidBrush(item.BackColor), text_rect); + + Brush textBrush = + !control.Enabled ? SystemBrushes.ControlLight : + (item.Selected && control.Focused) ? SystemBrushes.HighlightText : + this.ResPool.GetSolidBrush(item.ForeColor); + + // Tile view renders its Text in a different fashion + if (control.View == View.Tile && Application.VisualStylesEnabled) + { + // Item.Text is drawn using its first subitem's bounds + dc.DrawString(item.Text, item.Font, textBrush, item.SubItems[0].Bounds, format); + + int count = Math.Min(control.Columns.Count, item.SubItems.Count); + for (int i = 1; i < count; i++) + { + ListViewItem.ListViewSubItem sub_item = item.SubItems[i]; + if (sub_item.Text == null || sub_item.Text.Length == 0) + continue; + + Brush itemBrush = item.Selected && control.Focused ? + SystemBrushes.HighlightText : GetControlForeBrush(sub_item.ForeColor); + dc.DrawString(sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format); + } + } + else + + if (item.Text != null && item.Text.Length > 0) + { + Font font = item.Font; + + if (control.HotTracking && item.Hot) + font = item.HotFont; + + if (item.Selected && control.Focused) + dc.DrawString(item.Text, font, textBrush, highlight_rect, format); + else + dc.DrawString(item.Text, font, textBrush, text_rect, format); + } + + if (item.Focused && control.Focused) + { + Rectangle focus_rect = highlight_rect; + if (control.FullRowSelect && control.View == View.Details) + { + int width = 0; + foreach (ColumnHeader col in control.Columns) + width += col.Width; + focus_rect = new Rectangle(0, full_rect.Y, width, full_rect.Height); + } + if (control.ShowFocusCues) + { + if (item.Selected) + CPDrawFocusRectangle(dc, focus_rect, ColorHighlightText, ColorHighlight); + else + CPDrawFocusRectangle(dc, focus_rect, control.ForeColor, control.BackColor); + } + } + + format.Dispose(); + } + + protected virtual void DrawListViewSubItems(Graphics dc, ListView control, ListViewItem item) + { + int columns_count = control.Columns.Count; + int count = Math.Min(item.SubItems.Count, columns_count); + // 0th item already done (in this case) + for (int i = 1; i < count; i++) + DrawListViewSubItem(dc, control, item, i); + + // Fill in selection for remaining columns if Column.Count > SubItems.Count + Rectangle sub_item_rect = item.GetBounds(ItemBoundsPortion.Label); + if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) + { + for (int index = count; index < columns_count; index++) + { + ColumnHeader col = control.Columns[index]; + sub_item_rect.X = col.Rect.X - control.h_marker; + sub_item_rect.Width = col.Wd; + dc.FillRectangle(control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control, + sub_item_rect); + } + } + } + + protected virtual void DrawListViewSubItem(Graphics dc, ListView control, ListViewItem item, int index) + { + ListViewItem.ListViewSubItem subItem = item.SubItems[index]; + ColumnHeader col = control.Columns[index]; + StringFormat format = new StringFormat(); + format.Alignment = col.Format.Alignment; + format.LineAlignment = StringAlignment.Center; + format.FormatFlags = StringFormatFlags.NoWrap; + format.Trimming = StringTrimming.EllipsisCharacter; + + Rectangle sub_item_rect = subItem.Bounds; + Rectangle sub_item_text_rect = sub_item_rect; + sub_item_text_rect.X += 3; + sub_item_text_rect.Width -= ListViewItemPaddingWidth; + + SolidBrush sub_item_back_br = null; + SolidBrush sub_item_fore_br = null; + Font sub_item_font = null; + + if (item.UseItemStyleForSubItems) + { + sub_item_back_br = ResPool.GetSolidBrush(item.BackColor); + sub_item_fore_br = ResPool.GetSolidBrush(item.ForeColor); + + // Hot tracking for subitems only applies when UseStyle is true + if (control.HotTracking && item.Hot) + sub_item_font = item.HotFont; + else + sub_item_font = item.Font; + } + else + { + sub_item_back_br = ResPool.GetSolidBrush(subItem.BackColor); + sub_item_fore_br = ResPool.GetSolidBrush(subItem.ForeColor); + sub_item_font = subItem.Font; + } + + if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) + { + Brush bg, text; + if (control.Focused) + { + bg = SystemBrushes.Highlight; + text = SystemBrushes.HighlightText; + } + else + { + bg = SystemBrushes.Control; + text = sub_item_fore_br; + + } + + dc.FillRectangle(bg, sub_item_rect); + if (subItem.Text != null && subItem.Text.Length > 0) + dc.DrawString(subItem.Text, sub_item_font, + text, sub_item_text_rect, format); + } + else + { + dc.FillRectangle(sub_item_back_br, sub_item_rect); + if (subItem.Text != null && subItem.Text.Length > 0) + dc.DrawString(subItem.Text, sub_item_font, + sub_item_fore_br, + sub_item_text_rect, format); + } + + format.Dispose(); + } + + protected virtual bool DrawListViewSubItemOwnerDraw(Graphics dc, ListViewItem item, ListViewItemStates state, int index) + { + ListView control = item.ListView; + ListViewItem.ListViewSubItem subitem = item.SubItems[index]; + + DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs(dc, subitem.Bounds, item, + subitem, item.Index, index, control.Columns[index], state); + control.OnDrawSubItem(args); + + return !args.DrawDefault; + } + + protected virtual void DrawListViewGroupHeader(Graphics dc, ListView control, ListViewGroup group) + { + Rectangle text_bounds = group.HeaderBounds; + Rectangle header_bounds = group.HeaderBounds; + text_bounds.Offset(8, 0); + text_bounds.Inflate(-8, 0); + int text_height = control.Font.Height + 2; // add a tiny padding between the text and the group line + + Font font = new Font(control.Font, control.Font.Style | FontStyle.Bold); + Brush brush = new LinearGradientBrush(new Point(header_bounds.Left, 0), new Point(header_bounds.Left + ListViewGroupLineWidth, 0), + SystemColors.Desktop, Color.White); + Pen pen = new Pen(brush); + + StringFormat sformat = new StringFormat(); + switch (group.HeaderAlignment) + { + case HorizontalAlignment.Left: + sformat.Alignment = StringAlignment.Near; + break; + case HorizontalAlignment.Center: + sformat.Alignment = StringAlignment.Center; + break; + case HorizontalAlignment.Right: + sformat.Alignment = StringAlignment.Far; + break; + } + + sformat.LineAlignment = StringAlignment.Near; + dc.DrawString(group.Header, font, SystemBrushes.ControlText, text_bounds, sformat); + dc.DrawLine(pen, header_bounds.Left, header_bounds.Top + text_height, header_bounds.Left + ListViewGroupLineWidth, + header_bounds.Top + text_height); + + sformat.Dispose(); + font.Dispose(); + pen.Dispose(); + brush.Dispose(); + } + + public override bool ListViewHasHotHeaderStyle + { + get + { + return false; + } + } + + // Sizing + public override int ListViewGetHeaderHeight(ListView listView, Font font) + { + return ListViewGetHeaderHeight(font); + } + + static int ListViewGetHeaderHeight(Font font) + { + return font.Height + 5; + } + + public static int ListViewGetHeaderHeight() + { + return ListViewGetHeaderHeight(ThemeEngine.Current.DefaultFont); + } + + public override Size ListViewCheckBoxSize + { + get { return new Size(16, 16); } + } + + public override int ListViewColumnHeaderHeight + { + get { return 16; } + } + + public override int ListViewDefaultColumnWidth + { + get { return 60; } + } + + public override int ListViewVerticalSpacing + { + get { return 22; } + } + + public override int ListViewEmptyColumnWidth + { + get { return 10; } + } + + public override int ListViewHorizontalSpacing + { + get { return 4; } + } + + public override int ListViewItemPaddingWidth + { + get { return 6; } + } + + public override Size ListViewDefaultSize + { + get { return new Size(121, 97); } + } + + public override int ListViewGroupHeight + { + get { return 20; } + } + + public int ListViewGroupLineWidth + { + get { return 200; } + } + + public override int ListViewTileWidthFactor + { + get { return 22; } + } + + public override int ListViewTileHeightFactor + { + get { return 3; } + } + #endregion // ListView + + #region Menus + + public override void CalcItemSize(Graphics dc, MenuItem item, int y, int x, bool menuBar) + { + item.X = x; + item.Y = y; + + if (item.Visible == false) + { + item.Width = 0; + item.Height = 0; + return; + } + + if (item.Separator == true) + { + item.Height = SEPARATOR_HEIGHT; + item.Width = SEPARATOR_MIN_WIDTH; + return; + } + + if (item.MeasureEventDefined) + { + MeasureItemEventArgs mi = new MeasureItemEventArgs(dc, item.Index); + item.PerformMeasureItem(mi); + item.Height = mi.ItemHeight; + item.Width = mi.ItemWidth; + return; + } + else + { + SizeF size; + size = dc.MeasureString(item.Text, MenuFont, int.MaxValue, string_format_menu_text); + item.Width = (int)size.Width; + item.Height = (int)size.Height; + + if (!menuBar) + { + if (item.Shortcut != Shortcut.None && item.ShowShortcut) + { + item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int)size.Width; + size = dc.MeasureString(" " + item.GetShortCutText(), MenuFont); + item.Width += MENU_TAB_SPACE + (int)size.Width; + } + + item.Width += 4 + (MenuCheckSize.Width * 2); + } + else + { + item.Width += MENU_BAR_ITEMS_SPACE; + x += item.Width; + } + + if (item.Height < MenuHeight) + item.Height = MenuHeight; + } + } + + // Updates the menu rect and returns the height + public override int CalcMenuBarSize(Graphics dc, Menu menu, int width) + { + int x = 0; + int y = 0; + menu.Height = 0; + + foreach (MenuItem item in menu.MenuItems) + { + + CalcItemSize(dc, item, y, x, true); + + if (x + item.Width > width) + { + item.X = 0; + y += item.Height; + item.Y = y; + x = 0; + } + + x += item.Width; + item.MenuBar = true; + + if (y + item.Height > menu.Height) + menu.Height = item.Height + y; + } + + menu.Width = width; + return menu.Height; + } + + public override void CalcPopupMenuSize(Graphics dc, Menu menu) + { + int x = 3; + int start = 0; + int i, n, y, max; + + menu.Height = 0; + + while (start < menu.MenuItems.Count) + { + y = 3; + max = 0; + for (i = start; i < menu.MenuItems.Count; i++) + { + MenuItem item = menu.MenuItems[i]; + + if ((i != start) && (item.Break || item.BarBreak)) + break; + + CalcItemSize(dc, item, y, x, false); + y += item.Height; + + if (item.Width > max) + max = item.Width; + } + + // Replace the -1 by the menu width (separators) + for (n = start; n < i; n++, start++) + menu.MenuItems[n].Width = max; + + if (y > menu.Height) + menu.Height = y; + + x += max; + } + + menu.Width = x; + + //space for border + menu.Width += 2; + menu.Height += 2; + + menu.Width += SM_CXBORDER; + menu.Height += SM_CYBORDER; + } + + // Draws a menu bar in a window + public override void DrawMenuBar(Graphics dc, Menu menu, Rectangle rect) + { + if (menu.Height == 0) + CalcMenuBarSize(dc, menu, rect.Width); + + bool keynav = (menu as MainMenu).tracker.hotkey_active; + HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide; + string_format_menu_menubar_text.HotkeyPrefix = hp; + string_format_menu_text.HotkeyPrefix = hp; + + rect.Height = menu.Height; + dc.FillRectangle(SystemBrushes.Menu, rect); + + for (int i = 0; i < menu.MenuItems.Count; i++) + { + MenuItem item = menu.MenuItems[i]; + Rectangle item_rect = item.bounds; + item_rect.X += rect.X; + item_rect.Y += rect.Y; + item.MenuHeight = menu.Height; + item.PerformDrawItem(new DrawItemEventArgs(dc, MenuFont, item_rect, i, item.Status)); + } + } + + protected Bitmap CreateGlyphBitmap(Size size, MenuGlyph glyph, Color color) + { + Color bg_color; + if (color.R == 0 && color.G == 0 && color.B == 0) + bg_color = Color.White; + else + bg_color = Color.Black; + + Bitmap bmp = new Bitmap(size.Width, size.Height); + Graphics gr = Graphics.FromImage(bmp); + Rectangle rect = new Rectangle(Point.Empty, size); + gr.FillRectangle(ResPool.GetSolidBrush(bg_color), rect); + CPDrawMenuGlyph(gr, rect, glyph, color, Color.Empty); + bmp.MakeTransparent(bg_color); + gr.Dispose(); + + return bmp; + } + + public override void DrawMenuItem(MenuItem item, DrawItemEventArgs e) + { + StringFormat string_format; + Rectangle rect_text = e.Bounds; + + if (item.Visible == false) + return; + + if (item.MenuBar) + string_format = string_format_menu_menubar_text; + else + string_format = string_format_menu_text; + + if (item.Separator == true) + { + int liney = e.Bounds.Y + (e.Bounds.Height / 2); + + e.Graphics.DrawLine(SystemPens.ControlDark, + e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney); + + e.Graphics.DrawLine(SystemPens.ControlLight, + e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1); + + return; + } + + if (!item.MenuBar) + rect_text.X += MenuCheckSize.Width; + + if (item.BarBreak) + { /* Draw vertical break bar*/ + Rectangle rect = e.Bounds; + rect.Y++; + rect.Width = 3; + rect.Height = item.MenuHeight - 6; + + e.Graphics.DrawLine(SystemPens.ControlDark, + rect.X, rect.Y, rect.X, rect.Y + rect.Height); + + e.Graphics.DrawLine(SystemPens.ControlLight, + rect.X + 1, rect.Y, rect.X + 1, rect.Y + rect.Height); + } + + Color color_text; + Color color_back; + Brush brush_text = null; + Brush brush_back = null; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) + { + color_text = ColorHighlightText; + color_back = ColorHighlight; + brush_text = SystemBrushes.HighlightText; + brush_back = SystemBrushes.Highlight; + } + else + { + color_text = ColorMenuText; + color_back = ColorMenu; + brush_text = ResPool.GetSolidBrush(ColorMenuText); + brush_back = SystemBrushes.Menu; + } + + /* Draw background */ + if (!item.MenuBar) + e.Graphics.FillRectangle(brush_back, e.Bounds); + + if (item.Enabled) + { + e.Graphics.DrawString(item.Text, e.Font, + brush_text, + rect_text, string_format); + + if (item.MenuBar) + { + Border3DStyle border_style = Border3DStyle.Adjust; + if ((item.Status & DrawItemState.HotLight) != 0) + border_style = Border3DStyle.RaisedInner; + else if ((item.Status & DrawItemState.Selected) != 0) + border_style = Border3DStyle.SunkenOuter; + + if (border_style != Border3DStyle.Adjust) + CPDrawBorder3D(e.Graphics, e.Bounds, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu); + } + } + else + { + if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) + { + e.Graphics.DrawString(item.Text, e.Font, Brushes.White, + new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height), + string_format); + + } + + e.Graphics.DrawString(item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format); + } + + if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) + { + string str = item.GetShortCutText(); + Rectangle rect = rect_text; + rect.X = item.XTab; + rect.Width -= item.XTab; + + if (item.Enabled) + { + e.Graphics.DrawString(str, e.Font, brush_text, rect, string_format_menu_shortcut); + } + else + { + if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) + { + e.Graphics.DrawString(str, e.Font, Brushes.White, + new RectangleF(rect.X + 1, rect.Y + 1, rect.Width, rect_text.Height), + string_format_menu_shortcut); + + } + e.Graphics.DrawString(str, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect, string_format_menu_shortcut); + } + } + + /* Draw arrow */ + if (item.MenuBar == false && (item.IsPopup || item.MdiList)) + { + + int cx = MenuCheckSize.Width; + int cy = MenuCheckSize.Height; + Bitmap bmp = CreateGlyphBitmap(new Size(cx, cy), MenuGlyph.Arrow, color_text); + + if (item.Enabled) + { + e.Graphics.DrawImage(bmp, e.Bounds.X + e.Bounds.Width - cx, + e.Bounds.Y + ((e.Bounds.Height - cy) / 2)); + } + else + { + WidgetPaint.DrawImageDisabled(e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx, + e.Bounds.Y + ((e.Bounds.Height - cy) / 2), color_back); + } + + bmp.Dispose(); + } + + /* Draw checked or radio */ + if (item.MenuBar == false && item.Checked) + { + + Rectangle area = e.Bounds; + int cx = MenuCheckSize.Width; + int cy = MenuCheckSize.Height; + Bitmap bmp = CreateGlyphBitmap(new Size(cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text); + + e.Graphics.DrawImage(bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2)); + + bmp.Dispose(); + } + } + + public override void DrawPopupMenu(Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect) + { + // Fill rectangle area + dc.FillRectangle(SystemBrushes.Menu, cliparea); + + + // Draw menu items + for (int i = 0; i < menu.MenuItems.Count; i++) + { + if (cliparea.IntersectsWith(menu.MenuItems[i].bounds)) + { + MenuItem item = menu.MenuItems[i]; + item.MenuHeight = menu.Height; + item.PerformDrawItem(new DrawItemEventArgs(dc, MenuFont, item.bounds, i, item.Status)); + } + } + } + + #endregion // Menus + + #region MonthCalendar + + // draw the month calendar + public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) + { + Rectangle client_rectangle = mc.ClientRectangle; + Size month_size = mc.SingleMonthSize; + // cache local copies of Marshal-by-ref internal members (gets around error CS0197) + Size calendar_spacing = (Size)((object)mc.calendar_spacing); + Size date_cell_size = (Size)((object)mc.date_cell_size); + + // draw the singlecalendars + int x_offset = 1; + int y_offset = 1; + // adjust for the position of the specific month + for (int i = 0; i < mc.CalendarDimensions.Height; i++) + { + if (i > 0) + { + y_offset += month_size.Height + calendar_spacing.Height; + } + // now adjust for x position + for (int j = 0; j < mc.CalendarDimensions.Width; j++) + { + if (j > 0) + { + x_offset += month_size.Width + calendar_spacing.Width; + } + else + { + x_offset = 1; + } + + Rectangle month_rect = new Rectangle(x_offset, y_offset, month_size.Width, month_size.Height); + if (month_rect.IntersectsWith(clip_rectangle)) + { + DrawSingleMonth( + dc, + clip_rectangle, + month_rect, + mc, + i, + j); + } + } + } + + Rectangle bottom_rect = new Rectangle( + client_rectangle.X, + Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0), + client_rectangle.Width, + date_cell_size.Height + 2); + // draw the today date if it's set + if (mc.ShowToday && bottom_rect.IntersectsWith(clip_rectangle)) + { + dc.FillRectangle(GetControlBackBrush(mc.BackColor), bottom_rect); + if (mc.ShowToday) + { + int today_offset = 5; + if (mc.ShowTodayCircle) + { + Rectangle today_circle_rect = new Rectangle( + client_rectangle.X + 5, + Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0), + date_cell_size.Width, + date_cell_size.Height); + DrawTodayCircle(dc, today_circle_rect); + today_offset += date_cell_size.Width + 5; + } + // draw today's date + StringFormat text_format = new StringFormat(); + text_format.LineAlignment = StringAlignment.Center; + text_format.Alignment = StringAlignment.Near; + Rectangle today_rect = new Rectangle( + today_offset + client_rectangle.X, + Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0), + Math.Max(client_rectangle.Width - today_offset, 0), + date_cell_size.Height); + dc.DrawString("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush(mc.ForeColor), today_rect, text_format); + text_format.Dispose(); + } + } + + Brush border_brush; + + if (mc.owner == null) + border_brush = GetControlBackBrush(mc.BackColor); + else + border_brush = SystemBrushes.ControlDarkDark; + + // finally paint the borders of the calendars as required + for (int i = 0; i <= mc.CalendarDimensions.Width; i++) + { + if (i == 0 && clip_rectangle.X == client_rectangle.X) + { + dc.FillRectangle(border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height); + } + else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) + { + dc.FillRectangle(border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height); + } + else + { + Rectangle rect = new Rectangle( + client_rectangle.X + (month_size.Width * i) + (calendar_spacing.Width * (i - 1)) + 1, + client_rectangle.Y, + calendar_spacing.Width, + client_rectangle.Height); + if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith(rect)) + { + dc.FillRectangle(border_brush, rect); + } + } + } + for (int i = 0; i <= mc.CalendarDimensions.Height; i++) + { + if (i == 0 && clip_rectangle.Y == client_rectangle.Y) + { + dc.FillRectangle(border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1); + } + else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) + { + dc.FillRectangle(border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1); + } + else + { + Rectangle rect = new Rectangle( + client_rectangle.X, + client_rectangle.Y + (month_size.Height * i) + (calendar_spacing.Height * (i - 1)) + 1, + client_rectangle.Width, + calendar_spacing.Height); + if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith(rect)) + { + dc.FillRectangle(border_brush, rect); + } + } + } + + // draw the drop down border if need + if (mc.owner != null) + { + Rectangle bounds = mc.ClientRectangle; + if (clip_rectangle.Contains(mc.Location)) + { + // find out if top or left line to draw + if (clip_rectangle.Contains(new Point(bounds.Left, bounds.Bottom))) + { + + dc.DrawLine(SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom - 1); + } + if (clip_rectangle.Contains(new Point(bounds.Right, bounds.Y))) + { + dc.DrawLine(SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right - 1, bounds.Y); + } + } + if (clip_rectangle.Contains(new Point(bounds.Right, bounds.Bottom))) + { + // find out if bottom or right line to draw + if (clip_rectangle.Contains(new Point(bounds.Left, bounds.Bottom))) + { + dc.DrawLine(SystemPens.ControlText, bounds.X, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1); + } + if (clip_rectangle.Contains(new Point(bounds.Right, bounds.Y))) + { + dc.DrawLine(SystemPens.ControlText, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1); + } + } + } + } + + // darws a single part of the month calendar (with one month) + private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) + { + // cache local copies of Marshal-by-ref internal members (gets around error CS0197) + Size title_size = (Size)((object)mc.title_size); + Size date_cell_size = (Size)((object)mc.date_cell_size); + DateTime current_month = (DateTime)((object)mc.current_month); + DateTime sunday = new DateTime(2006, 10, 1); + + // draw the title back ground + DateTime this_month = current_month.AddMonths(row * mc.CalendarDimensions.Width + col); + Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height); + if (title_rect.IntersectsWith(clip_rectangle)) + { + dc.FillRectangle(ResPool.GetSolidBrush(mc.TitleBackColor), title_rect); + // draw the title + string title_text = this_month.ToString("MMMM yyyy"); + dc.DrawString(title_text, mc.bold_font, ResPool.GetSolidBrush(mc.TitleForeColor), title_rect, mc.centered_format); + + if (mc.ShowYearUpDown) + { + Rectangle year_rect; + Rectangle upRect, downRect; + ButtonState upState, downState; + + mc.GetYearNameRectangles(title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect); + dc.FillRectangle(ResPool.GetSolidBrush(SystemColors.Control), year_rect); + dc.DrawString(this_month.ToString("yyyy"), mc.bold_font, ResPool.GetSolidBrush(Color.Black), year_rect, mc.centered_format); + + upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal; + downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal; + + WidgetPaint.DrawScrollButton(dc, upRect, ScrollButton.Up, upState); + WidgetPaint.DrawScrollButton(dc, downRect, ScrollButton.Down, downState); + } + + // draw previous and next buttons if it's time + if (row == 0 && col == 0) + { + // draw previous button + DrawMonthCalendarButton( + dc, + rectangle, + mc, + title_size, + mc.button_x_offset, + (System.Drawing.Size)((object)mc.button_size), + true); + } + if (row == 0 && col == mc.CalendarDimensions.Width - 1) + { + // draw next button + DrawMonthCalendarButton( + dc, + rectangle, + mc, + title_size, + mc.button_x_offset, + (System.Drawing.Size)((object)mc.button_size), + false); + } + } + + // set the week offset and draw week nums if needed + int col_offset = (mc.ShowWeekNumbers) ? 1 : 0; + Rectangle day_name_rect = new Rectangle( + rectangle.X, + rectangle.Y + title_size.Height, + (7 + col_offset) * date_cell_size.Width, + date_cell_size.Height); + if (day_name_rect.IntersectsWith(clip_rectangle)) + { + dc.FillRectangle(GetControlBackBrush(mc.BackColor), day_name_rect); + // draw the day names + DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek); + for (int i = 0; i < 7; i++) + { + int position = i - (int)first_day_of_week; + if (position < 0) + { + position = 7 + position; + } + // draw it + Rectangle day_rect = new Rectangle( + day_name_rect.X + ((i + col_offset) * date_cell_size.Width), + day_name_rect.Y, + date_cell_size.Width, + date_cell_size.Height); + dc.DrawString(sunday.AddDays(i + (int)first_day_of_week).ToString("ddd"), mc.Font, ResPool.GetSolidBrush(mc.TitleBackColor), day_rect, mc.centered_format); + } + + // draw the vertical divider + int vert_divider_y = Math.Max(title_size.Height + date_cell_size.Height - 1, 0); + dc.DrawLine( + ResPool.GetPen(mc.ForeColor), + rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset, + rectangle.Y + vert_divider_y, + rectangle.Right - mc.divider_line_offset, + rectangle.Y + vert_divider_y); + } + + + // draw the actual date items in the grid (including the week numbers) + Rectangle date_rect = new Rectangle( + rectangle.X, + rectangle.Y + title_size.Height + date_cell_size.Height, + date_cell_size.Width, + date_cell_size.Height); + int month_row_count = 0; + bool draw_week_num_divider = false; + DateTime current_date = mc.GetFirstDateInMonthGrid(new DateTime(this_month.Year, this_month.Month, 1)); + for (int i = 0; i < 6; i++) + { + // establish if this row is in our clip_area + Rectangle row_rect = new Rectangle( + rectangle.X, + rectangle.Y + title_size.Height + (date_cell_size.Height * (i + 1)), + date_cell_size.Width * 7, + date_cell_size.Height); + if (mc.ShowWeekNumbers) + { + row_rect.Width += date_cell_size.Width; + } + + bool draw_row = row_rect.IntersectsWith(clip_rectangle); + if (draw_row) + { + dc.FillRectangle(GetControlBackBrush(mc.BackColor), row_rect); + } + // establish if this is a valid week to draw + if (mc.IsValidWeekToDraw(this_month, current_date, row, col)) + { + month_row_count = i; + } + + // draw the week number if required + if (mc.ShowWeekNumbers && month_row_count == i) + { + if (!draw_week_num_divider) + { + draw_week_num_divider = draw_row; + } + // get the week for this row + int week = mc.GetWeekOfYear(current_date); + + if (draw_row) + { + dc.DrawString( + week.ToString(), + mc.Font, + ResPool.GetSolidBrush(mc.TitleBackColor), + date_rect, + mc.centered_format); + } + date_rect.Offset(date_cell_size.Width, 0); + } + + // only draw the days if we have to + if (month_row_count == i) + { + for (int j = 0; j < 7; j++) + { + if (draw_row) + { + DrawMonthCalendarDate( + dc, + date_rect, + mc, + current_date, + this_month, + row, + col); + } + + // move the day on + current_date = current_date.AddDays(1); + date_rect.Offset(date_cell_size.Width, 0); + } + + // shift the rectangle down one row + int offset = (mc.ShowWeekNumbers) ? -8 : -7; + date_rect.Offset(offset * date_cell_size.Width, date_cell_size.Height); + } + } + + // month_row_count is zero based, so add one + month_row_count++; + + // draw week numbers if required + if (draw_week_num_divider) + { + col_offset = 1; + dc.DrawLine( + ResPool.GetPen(mc.ForeColor), + rectangle.X + date_cell_size.Width - 1, + rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset, + rectangle.X + date_cell_size.Width - 1, + rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset); + } + } + + // draws the pervious or next button + private void DrawMonthCalendarButton(Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) + { + const int arrow_width = 4; + const int arrow_height = 7; + + bool is_clicked = false; + Rectangle button_rect; + PointF arrow_center; + PointF[] arrow_path = new PointF[3]; + + // prepare the button + if (is_previous) + { + is_clicked = mc.is_previous_clicked; + + button_rect = new Rectangle( + rectangle.X + 1 + x_offset, + rectangle.Y + 1 + ((title_size.Height - button_size.Height) / 2), + Math.Max(button_size.Width - 1, 0), + Math.Max(button_size.Height - 1, 0)); + + arrow_center = new PointF(button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), + rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1); + if (is_clicked) + { + arrow_center.X += 1; + arrow_center.Y += 1; + } + + arrow_path[0].X = arrow_center.X; + arrow_path[0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f; + arrow_path[1].X = arrow_center.X; + arrow_path[1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f; + arrow_path[2].X = arrow_center.X - arrow_width; + arrow_path[2].Y = arrow_center.Y + 0.5f; + } + else + { + is_clicked = mc.is_next_clicked; + + button_rect = new Rectangle( + rectangle.Right - 1 - x_offset - button_size.Width, + rectangle.Y + 1 + ((title_size.Height - button_size.Height) / 2), + Math.Max(button_size.Width - 1, 0), + Math.Max(button_size.Height - 1, 0)); + + arrow_center = new PointF(button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), + rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1); + if (is_clicked) + { + arrow_center.X += 1; + arrow_center.Y += 1; + } + + arrow_path[0].X = arrow_center.X - arrow_width; + arrow_path[0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f; + arrow_path[1].X = arrow_center.X - arrow_width; + arrow_path[1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f; + arrow_path[2].X = arrow_center.X; + arrow_path[2].Y = arrow_center.Y + 0.5f; + } + + // fill the background + dc.FillRectangle(SystemBrushes.Control, button_rect); + // draw the border + if (is_clicked) + { + dc.DrawRectangle(SystemPens.ControlDark, button_rect); + } + else + { + CPDrawBorder3D(dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom); + } + // draw the arrow + dc.FillPolygon(SystemBrushes.ControlText, arrow_path); + //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding); + } + + + // draws one day in the calendar grid + private void DrawMonthCalendarDate(Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) + { + Color date_color = mc.ForeColor; + Rectangle interior = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + + // find out if we are the lead of the first calendar or the trail of the last calendar + if (date.Year != month.Year || date.Month != month.Month) + { + DateTime check_date = month.AddMonths(-1); + // check if it's the month before + if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) + { + date_color = mc.TrailingForeColor; + } + else + { + // check if it's the month after + check_date = month.AddMonths(1); + if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height - 1 && col == mc.CalendarDimensions.Width - 1) + { + date_color = mc.TrailingForeColor; + } + else + { + return; + } + } + } + else + { + date_color = mc.ForeColor; + } + + const int inflate = -1; + + if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) + { + // see if the date is in the start of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate(rectangle, inflate, inflate); + dc.FillPie(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect, 0, 360); + } + else if (date == mc.SelectionStart.Date) + { + // see if the date is in the start of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate(rectangle, inflate, inflate); + dc.FillPie(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect, 90, 180); + // fill the other side as a straight rect + if (date < mc.SelectionEnd.Date) + { + // use rectangle instead of rectangle to go all the way to edge of rect + selection_rect.X = (int)Math.Floor((double)(rectangle.X + rectangle.Width / 2)); + selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0); + dc.FillRectangle(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect); + } + } + else if (date == mc.SelectionEnd.Date) + { + // see if it is the end of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate(rectangle, inflate, inflate); + dc.FillPie(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect, 270, 180); + // fill the other side as a straight rect + if (date > mc.SelectionStart.Date) + { + selection_rect.X = rectangle.X; + selection_rect.Width = rectangle.Width - (rectangle.Width / 2); + dc.FillRectangle(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect); + } + } + else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) + { + // now see if it's in the middle + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate(rectangle, 0, inflate); + dc.FillRectangle(ResPool.GetSolidBrush(mc.TitleBackColor), selection_rect); + } + + // establish if it's a bolded font + Font font = mc.IsBoldedDate(date) ? mc.bold_font : mc.Font; + + // just draw the date now + dc.DrawString(date.Day.ToString(), font, ResPool.GetSolidBrush(date_color), rectangle, mc.centered_format); + + // today circle if needed + if (mc.ShowTodayCircle && date == DateTime.Now.Date) + { + DrawTodayCircle(dc, interior); + } + + // draw the selection grid + if (mc.is_date_clicked && mc.clicked_date == date) + { + Pen pen = ResPool.GetDashPen(Color.Black, DashStyle.Dot); + dc.DrawRectangle(pen, interior); + } + } + + private void DrawTodayCircle(Graphics dc, Rectangle rectangle) + { + Color circle_color = Color.FromArgb(248, 0, 0); + // draw the left hand of the circle + Rectangle lhs_circle_rect = new Rectangle(rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0)); + Rectangle rhs_circle_rect = new Rectangle(rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0)); + Point[] curve_points = new Point[3]; + curve_points[0] = new Point(lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height / 12); + curve_points[1] = new Point(lhs_circle_rect.X + lhs_circle_rect.Width / 9, rhs_circle_rect.Y); + curve_points[2] = new Point(lhs_circle_rect.X + lhs_circle_rect.Width / 2 + 1, rhs_circle_rect.Y); + + Pen pen = ResPool.GetSizedPen(circle_color, 2); + dc.DrawArc(pen, lhs_circle_rect, 90, 180); + dc.DrawArc(pen, rhs_circle_rect, 270, 180); + dc.DrawCurve(pen, curve_points); + dc.DrawLine(ResPool.GetPen(circle_color), curve_points[2], new Point(curve_points[2].X, lhs_circle_rect.Y)); + } + + #endregion // MonthCalendar + + #region Panel + public override Size PanelDefaultSize + { + get + { + return new Size(200, 100); + } + } + #endregion // Panel + + #region PictureBox + public override void DrawPictureBox(Graphics dc, Rectangle clip, PictureBox pb) + { + Rectangle client = pb.ClientRectangle; + + client = new Rectangle(client.Left + pb.Padding.Left, client.Top + pb.Padding.Top, client.Width - pb.Padding.Horizontal, client.Height - pb.Padding.Vertical); + + // FIXME - instead of drawing the whole picturebox every time + // intersect the clip rectangle with the drawn picture and only draw what's needed, + // Also, we only need a background fill where no image goes + if (pb.Image != null) + { + switch (pb.SizeMode) + { + case PictureBoxSizeMode.StretchImage: + dc.DrawImage(pb.Image, client.Left, client.Top, client.Width, client.Height); + break; + + case PictureBoxSizeMode.CenterImage: + dc.DrawImage(pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2)); + break; + + case PictureBoxSizeMode.Zoom: + Size image_size; + + if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height)) + image_size = new Size(client.Width, (pb.Image.Height * client.Width) / pb.Image.Width); + else + image_size = new Size((pb.Image.Width * client.Height) / pb.Image.Height, client.Height); + + dc.DrawImage(pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height); + break; + + default: + // Normal, AutoSize + dc.DrawImage(pb.Image, client.Left, client.Top, pb.Image.Width, pb.Image.Height); + break; + } + + return; + } + } + + public override Size PictureBoxDefaultSize + { + get + { + return new Size(100, 50); + } + } + #endregion // PictureBox + + /* + #region PrintPreviewControl + public override int PrintPreviewControlPadding { + get { return 8; } + } + + public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview) + { + int page_width, page_height; + int padding = PrintPreviewControlPadding; + PreviewPageInfo[] pis = preview.page_infos; + + if (preview.AutoZoom) { + int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding; + int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding; + + float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height; + + /* try to lay things out using the width to determine the size + page_width = width_available / preview.Columns; + page_height = (int)(page_width / image_ratio); + + /* does the height fit? + if (page_height * (preview.Rows + 1) > height_available) { + /* no, lay things out via the height + page_height = height_available / (preview.Rows + 1); + page_width = (int)(page_height * image_ratio); + } + } + else { + page_width = (int)(pis[0].Image.Width * preview.Zoom); + page_height = (int)(pis[0].Image.Height * preview.Zoom); + } + + return new Size (page_width, page_height); + } + + public override void PrintPreviewWidgetPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size) + { + int padding = 8; + PreviewPageInfo[] pis = preview.page_infos; + if (pis == null) + return; + + int page_x, page_y; + + int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding; + int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding; + + Rectangle viewport = preview.ViewPort; + + pe.Graphics.Clip = new Region (viewport); + + /* center things if we can + int off_x = viewport.Width / 2 - width / 2; + if (off_x < 0) off_x = 0; + int off_y = viewport.Height / 2 - height / 2; + if (off_y < 0) off_y = 0; + + page_y = off_y + padding - preview.vbar_value; + + if (preview.StartPage > 0) { + int p = preview.StartPage - 1; + for (int py = 0; py < preview.Rows + 1; py ++) { + page_x = off_x + padding - preview.hbar_value; + for (int px = 0; px < preview.Columns; px ++) { + if (p >= pis.Length) + continue; + Image image = preview.image_cache[p]; + if (image == null) + image = pis[p].Image; + Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size); + + pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); + + page_x += padding + page_size.Width; + p++; + } + page_y += padding + page_size.Height; + } + } + } + #endregion // PrintPreviewControl*/ + + #region ProgressBar + public override void DrawProgressBar(Graphics dc, Rectangle clip_rect, ProgressBar ctrl) + { + Rectangle client_area = ctrl.client_area; + + /* Draw border */ + CPDrawBorder3D(dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl); + + /* Draw Blocks */ + int draw_mode = 0; + int max_blocks = int.MaxValue; + int start_pixel = client_area.X; + draw_mode = (int)ctrl.Style; + + switch (draw_mode) + { + case 1: + { // Continuous + int pixels_to_draw; + pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1)))); + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ProgressBar_BackgroundColor), new Rectangle(client_area.X, client_area.Y, pixels_to_draw, client_area.Height)); + break; + } + case 2: // Marquee + if (XplatUI.ThemesEnabled) + { + int ms_diff = (int)(DateTime.Now - ctrl.start).TotalMilliseconds; + double percent_done = (double)ms_diff / ProgressBarMarqueeSpeedScaling + % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed; + max_blocks = 5; + start_pixel = client_area.X + (int)(client_area.Width * percent_done); + } + + goto case 0; + case 0: + default: // Blocks + Rectangle block_rect; + int space_betweenblocks = ProgressBarChunkSpacing; + int block_width; + int increment; + int barpos_pixels; + int block_count = 0; + + block_width = ProgressBarGetChunkSize(client_area.Height); + block_width = Math.Max(block_width, 0); // block_width is used to break out the loop below, it must be >= 0! + barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max(ctrl.Maximum - ctrl.Minimum, 1))); + increment = block_width + space_betweenblocks; + + block_rect = new Rectangle(start_pixel, client_area.Y, block_width, client_area.Height); + while (true) + { + if (max_blocks != int.MaxValue) + { + if (block_count >= max_blocks) + break; + if (block_rect.X > client_area.Width) + block_rect.X -= client_area.Width; + } + else + { + if ((block_rect.X - client_area.X) >= barpos_pixels) + break; + } + + if (clip_rect.IntersectsWith(block_rect) == true) + { + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ProgressBar_BlockColor), block_rect); + } + + block_rect.X += increment; + block_count++; + } + break; + + } + } + + public const int ProgressBarChunkSpacing = 2; + + public static int ProgressBarGetChunkSize() + { + return ProgressBarGetChunkSize(ProgressBarDefaultHeight); + } + + static int ProgressBarGetChunkSize(int progressBarClientAreaHeight) + { + int size = (progressBarClientAreaHeight * 2) / 3; + return size; + } + + const int ProgressBarDefaultHeight = 23; + + public override Size ProgressBarDefaultSize + { + get + { + return new Size(100, ProgressBarDefaultHeight); + } + } + + public const double ProgressBarMarqueeSpeedScaling = 15; + + #endregion // ProgressBar + + #region RadioButton + public override void DrawRadioButton(Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) + { + StringFormat text_format; + Rectangle client_rectangle; + Rectangle text_rectangle; + Rectangle radiobutton_rectangle; + int radiobutton_size = 13; + int radiobutton_space = 4; + + client_rectangle = radio_button.ClientRectangle; + text_rectangle = client_rectangle; + radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size); + + text_format = new StringFormat(); + text_format.Alignment = StringAlignment.Near; + text_format.LineAlignment = StringAlignment.Center; + text_format.HotkeyPrefix = HotkeyPrefix.Show; + + /* Calculate the position of text and checkbox rectangle */ + if (radio_button.appearance != Appearance.Button) + { + switch (radio_button.radiobutton_alignment) + { + case ContentAlignment.BottomCenter: + { + radiobutton_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - radiobutton_size / 2; + radiobutton_rectangle.Y = client_rectangle.Bottom - radiobutton_size; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + text_rectangle.Height = client_rectangle.Height - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.BottomLeft: + { + radiobutton_rectangle.X = client_rectangle.Left; + radiobutton_rectangle.Y = client_rectangle.Bottom - radiobutton_size; + text_rectangle.X = client_rectangle.X + radiobutton_size + radiobutton_space; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.BottomRight: + { + radiobutton_rectangle.X = client_rectangle.Right - radiobutton_size; + radiobutton_rectangle.Y = client_rectangle.Bottom - radiobutton_size; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.MiddleCenter: + { + radiobutton_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - radiobutton_size / 2; + radiobutton_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - radiobutton_size / 2; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + break; + } + + default: + case ContentAlignment.MiddleLeft: + { + radiobutton_rectangle.X = client_rectangle.Left; + radiobutton_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - radiobutton_size / 2; + text_rectangle.X = client_rectangle.X + radiobutton_size + radiobutton_space; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.MiddleRight: + { + radiobutton_rectangle.X = client_rectangle.Right - radiobutton_size; + radiobutton_rectangle.Y = (client_rectangle.Bottom - client_rectangle.Top) / 2 - radiobutton_size / 2; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.TopCenter: + { + radiobutton_rectangle.X = (client_rectangle.Right - client_rectangle.Left) / 2 - radiobutton_size / 2; + radiobutton_rectangle.Y = client_rectangle.Top; + text_rectangle.X = client_rectangle.X; + text_rectangle.Y = radiobutton_size + radiobutton_space; + text_rectangle.Width = client_rectangle.Width; + text_rectangle.Height = client_rectangle.Height - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.TopLeft: + { + radiobutton_rectangle.X = client_rectangle.Left; + radiobutton_rectangle.Y = client_rectangle.Top; + text_rectangle.X = client_rectangle.X + radiobutton_size + radiobutton_space; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + + case ContentAlignment.TopRight: + { + radiobutton_rectangle.X = client_rectangle.Right - radiobutton_size; + radiobutton_rectangle.Y = client_rectangle.Top; + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width - radiobutton_size - radiobutton_space; + break; + } + } + } + else + { + text_rectangle.X = client_rectangle.X; + text_rectangle.Width = client_rectangle.Width; + } + + /* Set the horizontal alignment of our text */ + switch (radio_button.text_alignment) + { + case ContentAlignment.BottomLeft: + case ContentAlignment.MiddleLeft: + case ContentAlignment.TopLeft: + { + text_format.Alignment = StringAlignment.Near; + break; + } + + case ContentAlignment.BottomCenter: + case ContentAlignment.MiddleCenter: + case ContentAlignment.TopCenter: + { + text_format.Alignment = StringAlignment.Center; + break; + } + + case ContentAlignment.BottomRight: + case ContentAlignment.MiddleRight: + case ContentAlignment.TopRight: + { + text_format.Alignment = StringAlignment.Far; + break; + } + } + + /* Set the vertical alignment of our text */ + switch (radio_button.text_alignment) + { + case ContentAlignment.TopLeft: + case ContentAlignment.TopCenter: + case ContentAlignment.TopRight: + { + text_format.LineAlignment = StringAlignment.Near; + break; + } + + case ContentAlignment.BottomLeft: + case ContentAlignment.BottomCenter: + case ContentAlignment.BottomRight: + { + text_format.LineAlignment = StringAlignment.Far; + break; + } + + case ContentAlignment.MiddleLeft: + case ContentAlignment.MiddleCenter: + case ContentAlignment.MiddleRight: + { + text_format.LineAlignment = StringAlignment.Center; + break; + } + } + + ButtonState state = ButtonState.Normal; + if (radio_button.FlatStyle == FlatStyle.Flat) + { + state |= ButtonState.Flat; + } + + if (radio_button.Checked) + { + state |= ButtonState.Checked; + } + + if (!radio_button.Enabled) + { + state |= ButtonState.Inactive; + } + + // Start drawing + RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle); + + if ((radio_button.image != null) || (radio_button.image_list != null)) + ButtonBase_DrawImage(radio_button, dc); + + RadioButton_DrawText(radio_button, text_rectangle, dc, text_format); + + if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) + { + SizeF text_size = dc.MeasureString(radio_button.Text, radio_button.Font); + + Rectangle focus_rect = Rectangle.Empty; + focus_rect.X = text_rectangle.X; + focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2); + focus_rect.Size = text_size.ToSize(); + + RadioButton_DrawFocus(radio_button, dc, focus_rect); + } + + text_format.Dispose(); + } + + protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) + { + dc.FillRectangle(GetControlBackBrush(radio_button.BackColor), radio_button.ClientRectangle); + + if (radio_button.appearance == Appearance.Button) + { + ButtonBase_DrawButton(radio_button, dc); + + if ((radio_button.Focused) && radio_button.Enabled) + ButtonBase_DrawFocus(radio_button, dc); + } + else + { + // establish if we are rendering a flat style of some sort + if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) + { + DrawFlatStyleRadioButton(dc, radiobutton_rectangle, radio_button); + } + else + { + CPDrawRadioButton(dc, radiobutton_rectangle, state); + } + } + } + + protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format) + { + DrawCheckBox_and_RadioButtonText(radio_button, text_rectangle, dc, + text_format, radio_button.Appearance, radio_button.Checked); + } + + protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle) + { + DrawInnerFocusRectangle(dc, text_rectangle, radio_button.BackColor); + } + + + // renders a radio button with the Flat and Popup FlatStyle + protected virtual void DrawFlatStyleRadioButton(Graphics graphics, Rectangle rectangle, RadioButton radio_button) + { + int lineWidth; + + if (radio_button.Enabled) + { + + // draw the outer flatstyle arcs + if (radio_button.FlatStyle == FlatStyle.Flat) + { + graphics.DrawArc(SystemPens.ControlDarkDark, rectangle, 0, 359); + + // fill in the area depending on whether or not the mouse is hovering + if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) + { + graphics.FillPie(SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + } + else + { + graphics.FillPie(SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + } + } + else + { + // must be a popup radio button + // fill the control + graphics.FillPie(SystemBrushes.ControlLightLight, rectangle, 0, 359); + + if (radio_button.is_entered || radio_button.Capture) + { + // draw the popup 3d button knob + graphics.DrawArc(SystemPens.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + + graphics.DrawArc(SystemPens.ControlDark, rectangle, 135, 180); + graphics.DrawArc(SystemPens.ControlLightLight, rectangle, 315, 180); + + } + else + { + // just draw lighter flatstyle outer circle + graphics.DrawArc(SystemPens.ControlDark, rectangle, 0, 359); + } + } + } + else + { + // disabled + // fill control background color regardless of actual backcolor + graphics.FillPie(SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + // draw the ark as control dark + graphics.DrawArc(SystemPens.ControlDark, rectangle, 0, 359); + } + + // draw the check + if (radio_button.Checked) + { + lineWidth = Math.Max(1, Math.Min(rectangle.Width, rectangle.Height) / 3); + + Pen dot_pen = SystemPens.ControlDarkDark; + Brush dot_brush = SystemBrushes.ControlDarkDark; + + if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) + { + dot_pen = SystemPens.ControlDark; + dot_brush = SystemBrushes.ControlDark; + } + + if (rectangle.Height > 13) + { + graphics.FillPie(dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359); + } + else + { + int x_half_pos = (rectangle.Width / 2) + rectangle.X; + int y_half_pos = (rectangle.Height / 2) + rectangle.Y; + + graphics.DrawLine(dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos); + graphics.DrawLine(dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1); + + graphics.DrawLine(dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2); + graphics.DrawLine(dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2); + } + } + } + + public override Size RadioButtonDefaultSize + { + get + { + return new Size(104, 24); + } + } + + public override void DrawRadioButton(Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) + { + glyphArea.Height -= 2; + glyphArea.Width -= 2; + } + + DrawRadioButtonGlyph(g, rb, glyphArea); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawRadioButtonImage(g, rb, imageBounds); + + if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty) + DrawRadioButtonFocus(g, rb, textBounds); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawRadioButtonText(g, rb, textBounds); + } + + public virtual void DrawRadioButtonGlyph(Graphics g, RadioButton rb, Rectangle glyphArea) + { + if (rb.Pressed) + MemphisThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton(g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked); + else if (rb.InternalSelected) + MemphisThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton(g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked); + else if (rb.Entered) + MemphisThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton(g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked); + else if (!rb.Enabled) + MemphisThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton(g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked); + else + MemphisThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton(g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked); + } + + public virtual void DrawRadioButtonFocus(Graphics g, RadioButton rb, Rectangle focusArea) + { + WidgetPaint.DrawFocusRectangle(g, focusArea); + } + + public virtual void DrawRadioButtonImage(Graphics g, RadioButton rb, Rectangle imageBounds) + { + if (rb.Enabled) + g.DrawImage(rb.Image, imageBounds); + else + CPDrawImageDisabled(g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawRadioButtonText(Graphics g, RadioButton rb, Rectangle textBounds) + { + if (rb.Enabled) + TextRenderer.DrawTextInternal(g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering); + else + DrawStringDisabled20(g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering); + } + + public override Size CalculateRadioButtonAutoSize(RadioButton rb) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal(rb.Text, rb.Font, rb.UseCompatibleTextRendering); + Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size; + + // Pad the text size + if (rb.Text.Length != 0) + { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (rb.TextImageRelation) + { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max(rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max(text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max(text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (rb.Padding.Vertical); + ret_size.Width += (rb.Padding.Horizontal) + 15; + + // There seems to be a minimum height + if (ret_size.Height == rb.Padding.Vertical) + ret_size.Height += 14; + + return ret_size; + } + + public override void CalculateRadioButtonTextAndImageLayout(ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle) + { + CalculateCheckBoxTextAndImageLayout(b, offset, out glyphArea, out textRectangle, out imageRectangle); + } + #endregion // RadioButton + + #region ScrollBar + public override void DrawScrollBar(Graphics dc, Rectangle clip, ScrollBar bar) + { + int scrollbutton_width = bar.scrollbutton_width; + int scrollbutton_height = bar.scrollbutton_height; + Rectangle first_arrow_area; + Rectangle second_arrow_area; + Rectangle thumb_pos; + + thumb_pos = bar.ThumbPos; + + if (bar.vert) + { + first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Width = bar.Width; + bar.ThumbPos = thumb_pos; + + Brush VerticalBrush; + /* Background, upper track */ + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + VerticalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(255, 63, 63, 63), Color.Black); + else + VerticalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle UpperTrack = new Rectangle(0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom); + if (clip.IntersectsWith(UpperTrack)) + dc.FillRectangle(VerticalBrush, UpperTrack); + + /* Background, lower track */ + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + VerticalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(255, 63, 63, 63), Color.Black); + else + VerticalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle LowerTrack = new Rectangle(0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom); + if (clip.IntersectsWith(LowerTrack)) + dc.FillRectangle(VerticalBrush, LowerTrack); + + /* Buttons */ + if (clip.IntersectsWith(first_arrow_area)) + CPDrawScrollButton(dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state); + if (clip.IntersectsWith(second_arrow_area)) + CPDrawScrollButton(dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state); + } + else + { + first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle(bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Height = bar.Height; + bar.ThumbPos = thumb_pos; + + Brush HorizontalBrush; + //Background, left track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + HorizontalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(255, 63, 63, 63), Color.Black); + else + HorizontalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle LeftTrack = new Rectangle(0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height); + if (clip.IntersectsWith(LeftTrack)) + dc.FillRectangle(HorizontalBrush, LeftTrack); + + //Background, right track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + HorizontalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(255, 63, 63, 63), Color.Black); + else + HorizontalBrush = ResPool.GetHatchBrush(HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle RightTrack = new Rectangle(bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height); + if (clip.IntersectsWith(RightTrack)) + dc.FillRectangle(HorizontalBrush, RightTrack); + + /* Buttons */ + if (clip.IntersectsWith(first_arrow_area)) + CPDrawScrollButton(dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state); + if (clip.IntersectsWith(second_arrow_area)) + CPDrawScrollButton(dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state); + } + + /* Thumb */ + ScrollBar_DrawThumb(bar, thumb_pos, clip, dc); + } + + protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc) + { + if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos)) + DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal); + } + + public override int ScrollBarButtonSize + { + get { return 16; } + } + + public override bool ScrollBarHasHotElementStyles + { + get + { + return false; + } + } + + public override bool ScrollBarHasPressedThumbStyle + { + get + { + return false; + } + } + + public override bool ScrollBarHasHoverArrowButtonStyle + { + get + { + return false; + } + } + #endregion // ScrollBar + + #region StatusBar + public override void DrawStatusBar(Graphics real_dc, Rectangle clip, StatusBar sb) + { + Rectangle area = sb.ClientRectangle; + int horz_border = 2; + int vert_border = 2; + + Image backbuffer = new Bitmap(sb.ClientSize.Width, sb.ClientSize.Height, real_dc); + Graphics dc = Graphics.FromImage(backbuffer); + + DrawStatusBarBackground(dc, clip, sb); + + if (!sb.ShowPanels && sb.Text != String.Empty) + { + string text = sb.Text; + StringFormat string_format = new StringFormat(); + string_format.Trimming = StringTrimming.Character; + string_format.FormatFlags = StringFormatFlags.NoWrap; + + if (text.Length > 127) + text = text.Substring(0, 127); + + if (text[0] == '\t') + { + string_format.Alignment = StringAlignment.Center; + text = text.Substring(1); + if (text[0] == '\t') + { + string_format.Alignment = StringAlignment.Far; + text = text.Substring(1); + } + } + + dc.DrawString(text, sb.Font, ResPool.GetSolidBrush(sb.ForeColor), + new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format); + string_format.Dispose(); + } + else if (sb.ShowPanels) + { + Brush br_forecolor = GetControlForeBrush(sb.ForeColor); + int prev_x = area.X + horz_border; + int y = area.Y + vert_border; + for (int i = 0; i < sb.Panels.Count; i++) + { + Rectangle pr = new Rectangle(prev_x, y, + sb.Panels[i].Width, area.Height); + prev_x += pr.Width + StatusBarHorzGapWidth; + if (pr.IntersectsWith(clip)) + DrawStatusBarPanel(dc, pr, i, br_forecolor, sb.Panels[i]); + } + } + + if (sb.SizingGrip) + DrawStatusBarSizingGrip(dc, clip, sb, area); + + real_dc.DrawImage(backbuffer, 0, 0); + dc.Dispose(); + backbuffer.Dispose(); + + } + + protected virtual void DrawStatusBarBackground(Graphics dc, Rectangle clip, StatusBar sb) + { + bool is_color_control = sb.BackColor.ToArgb() == ColorControl.ToArgb(); + + Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush(sb.BackColor); + dc.FillRectangle(brush, clip); + } + + protected virtual void DrawStatusBarSizingGrip(Graphics dc, Rectangle clip, StatusBar sb, Rectangle area) + { + area = new Rectangle(area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16); + CPDrawSizeGrip(dc, ColorControl, area); + } + + protected virtual void DrawStatusBarPanel(Graphics dc, Rectangle area, int index, + Brush br_forecolor, StatusBarPanel panel) + { + int border_size = 3; // this is actually const, even if the border style is none + int icon_width = 16; + + area.Height -= border_size; + + DrawStatusBarPanelBackground(dc, area, panel); + + if (panel.Style == StatusBarPanelStyle.OwnerDraw) + { + StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs( + dc, panel.Parent.Font, area, index, DrawItemState.Default, + panel, panel.Parent.ForeColor, panel.Parent.BackColor); + panel.Parent.OnDrawItemInternal(e); + return; + } + + string text = panel.Text; + StringFormat string_format = new StringFormat(); + string_format.Trimming = StringTrimming.Character; + string_format.FormatFlags = StringFormatFlags.NoWrap; + + + if (text != null && text.Length > 0 && text[0] == '\t') + { + string_format.Alignment = StringAlignment.Center; + text = text.Substring(1); + if (text[0] == '\t') + { + string_format.Alignment = StringAlignment.Far; + text = text.Substring(1); + } + } + + Rectangle string_rect = Rectangle.Empty; + int x; + int len; + int icon_x = 0; + int y = (area.Height / 2 - (int)panel.Parent.Font.Size / 2) - 1; + + switch (panel.Alignment) + { + case HorizontalAlignment.Right: + len = (int)dc.MeasureString(text, panel.Parent.Font).Width; + x = area.Right - len - 4; + string_rect = new Rectangle(x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + if (panel.Icon != null) + { + icon_x = x - icon_width - 2; + } + break; + case HorizontalAlignment.Center: + len = (int)dc.MeasureString(text, panel.Parent.Font).Width; + x = area.Left + ((panel.Width - len) / 2); + + string_rect = new Rectangle(x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + + if (panel.Icon != null) + { + icon_x = x - icon_width - 2; + } + break; + + + default: + int left = area.Left + border_size; ; + if (panel.Icon != null) + { + icon_x = area.Left + 2; + left = icon_x + icon_width + 2; + } + + x = left; + string_rect = new Rectangle(x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + break; + } + + RectangleF clip_bounds = dc.ClipBounds; + dc.SetClip(area); + dc.DrawString(text, panel.Parent.Font, br_forecolor, string_rect, string_format); + dc.SetClip(clip_bounds); + + if (panel.Icon != null) + { + dc.DrawIcon(panel.Icon, new Rectangle(icon_x, y, icon_width, icon_width)); + } + } + + protected virtual void DrawStatusBarPanelBackground(Graphics dc, Rectangle area, StatusBarPanel panel) + { + if (panel.BorderStyle != StatusBarPanelBorderStyle.None) + { + Border3DStyle border_style = Border3DStyle.SunkenOuter; + if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised) + border_style = Border3DStyle.RaisedInner; + + CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor); + } + } + + public override int StatusBarSizeGripWidth + { + get { return 15; } + } + + public override int StatusBarHorzGapWidth + { + get { return 3; } + } + + public override Size StatusBarDefaultSize + { + get + { + return new Size(100, 22); + } + } + #endregion // StatusBar + + #region TabControl + + #region TabControl settings + + public override Size TabControlDefaultItemSize + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.DefaultItemSize; } + } + + public override Point TabControlDefaultPadding + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.DefaultPadding; } + } + + public override int TabControlMinimumTabWidth + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.MinimumTabWidth; } + } + + public override Rectangle TabWidgetselectedDelta + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.SelectedTabDelta; } + } + + public override int TabWidgetselectedSpacing + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.SelectedSpacing; } + } + + public override int TabPanelOffsetX + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.TabPanelOffset.X; } + } + + public override int TabPanelOffsetY + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.TabPanelOffset.Y; } + } + + public override int TabControlColSpacing + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.ColSpacing; } + } + + public override Point TabControlImagePadding + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.ImagePadding; } + } + + public override int TabWidgetscrollerWidth + { + get { return MemphisThemeElements.CurrentTheme.TabWidgetPainter.ScrollerWidth; } + } + + + public override Size TabControlGetSpacing(TabWidget tab) + { + try + { + return MemphisThemeElements.CurrentTheme.TabWidgetPainter.RowSpacing(tab); + } + catch + { + throw new Exception("Invalid Appearance value: " + tab.Appearance); + } + } + #endregion + + public override void DrawTabControl(Graphics dc, Rectangle area, TabWidget tab) + { + MemphisThemeElements.CurrentTheme.TabWidgetPainter.Draw(dc, area, tab); + } + + public override Rectangle TabControlGetDisplayRectangle(TabWidget tab) + { + return MemphisThemeElements.CurrentTheme.TabWidgetPainter.GetDisplayRectangle(tab); + } + + public override Rectangle TabControlGetPanelRect(TabWidget tab) + { + return MemphisThemeElements.CurrentTheme.TabWidgetPainter.GetTabPanelRect(tab); + } + + #endregion + + #region TextBox + public override void TextBoxBaseFillBackground(TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea) + { + if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) + { + g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea); + } + else + { + g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea); + } + } + + public override bool TextBoxBaseHandleWmNcPaint(TextBoxBase textBoxBase, ref Message m) + { + return false; + } + + public override bool TextBoxBaseShouldPaintBackground(TextBoxBase textBoxBase) + { + return true; + } + #endregion + + + #region ToolTip + public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) + { + ToolTipDrawBackground(dc, clip_rectangle, control); + + TextFormatFlags flags = TextFormatFlags.HidePrefix; + + Color foreground = control.ForeColor; + if (control.title.Length > 0) + { + Font bold_font = new Font(control.Font, control.Font.Style | FontStyle.Bold); + TextRenderer.DrawTextInternal(dc, control.title, bold_font, control.title_rect, + foreground, flags, false); + bold_font.Dispose(); + } + + if (control.icon != null) + dc.DrawIcon(control.icon, control.icon_rect); + + TextRenderer.DrawTextInternal(dc, control.Text, control.Font, control.text_rect, foreground, flags, false); + } + + protected virtual void ToolTipDrawBackground(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) + { + Brush back_brush = ResPool.GetSolidBrush(control.BackColor); + dc.FillRectangle(back_brush, control.ClientRectangle); + dc.DrawRectangle(SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1); + } + + public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) + { + Size size = TextRenderer.MeasureTextInternal(text, tt.Font, false); + size.Width += 4; + size.Height += 3; + Rectangle text_rect = new Rectangle(Point.Empty, size); + text_rect.Inflate(-2, -1); + tt.text_rect = text_rect; + tt.icon_rect = tt.title_rect = Rectangle.Empty; + + Size title_size = Size.Empty; + if (tt.title.Length > 0) + { + Font bold_font = new Font(tt.Font, tt.Font.Style | FontStyle.Bold); + title_size = TextRenderer.MeasureTextInternal(tt.title, bold_font, false); + bold_font.Dispose(); + } + + Size icon_size = Size.Empty; + if (tt.icon != null) + icon_size = new Size(size.Height, size.Height); + + if (icon_size != Size.Empty || title_size != Size.Empty) + { + int padding = 8; + int top_area_width = 0; + int top_area_height = icon_size.Height > title_size.Height ? icon_size.Height : title_size.Height; + Size text_size = size; + Point location = new Point(padding, padding); + + if (icon_size != Size.Empty) + { + tt.icon_rect = new Rectangle(location, icon_size); + top_area_width = icon_size.Width + padding; + } + + if (title_size != Size.Empty) + { + Rectangle title_rect = new Rectangle(location, new Size(title_size.Width, top_area_height)); + if (icon_size != Size.Empty) + title_rect.X += icon_size.Width + padding; + + tt.title_rect = title_rect; + top_area_width += title_size.Width; + } + + tt.text_rect = new Rectangle(new Point(location.X, location.Y + top_area_height + padding), + text_size); + + size.Height += padding + top_area_height; + if (top_area_width > size.Width) + size.Width = top_area_width; + + // margins + size.Width += padding * 2; + size.Height += padding * 2; + } + + return size; + } + + public override bool ToolTipTransparentBackground + { + get + { + return false; + } + } + #endregion // ToolTip + + #region BalloonWindow + NotifyIcon.BalloonWindow balloon_window; + + public override void ShowBalloonWindow(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon) + { + Widget control = Widget.FromHandle(handle); + + if (control == null) + return; + + if (balloon_window != null) + { + balloon_window.Close(); + balloon_window.Dispose(); + } + + balloon_window = new NotifyIcon.BalloonWindow(handle); + balloon_window.Title = title; + balloon_window.Text = text; + balloon_window.Icon = icon; + balloon_window.Timeout = timeout; + balloon_window.Show(); + } + + public override void HideBalloonWindow(IntPtr handle) + { + if (balloon_window == null || balloon_window.OwnerHandle != handle) + return; + + balloon_window.Close(); + balloon_window.Dispose(); + balloon_window = null; + } + + private const int balloon_iconsize = 16; + private const int balloon_bordersize = 8; + + public override void DrawBalloonWindow(Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) + { + Brush solidbrush = ResPool.GetSolidBrush(this.ColorInfoText); + Rectangle rect = control.ClientRectangle; + int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize; + + // Rectangle borders and background. + dc.FillRectangle(ResPool.GetSolidBrush(ColorInfo), rect); + dc.DrawRectangle(ResPool.GetPen(ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1); + + // Icon + Image image; + switch (control.Icon) + { + case ToolTipIcon.Info: + { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize); + break; + } + + case ToolTipIcon.Warning: + { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize); + break; + } + + case ToolTipIcon.Error: + { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize); + break; + } + + default: + { + image = null; + break; + } + } + + if (control.Icon != ToolTipIcon.None) + dc.DrawImage(image, new Rectangle(balloon_bordersize, balloon_bordersize, iconsize, iconsize)); + + // Title + Rectangle titlerect = new Rectangle(rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), + rect.Y + balloon_bordersize, + rect.Width - ((3 * balloon_bordersize) + iconsize), + rect.Height - (2 * balloon_bordersize)); + + Font titlefont = new Font(control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit); + dc.DrawString(control.Title, titlefont, solidbrush, titlerect, control.Format); + + // Text + Rectangle textrect = new Rectangle(rect.X + balloon_bordersize, + rect.Y + balloon_bordersize, + rect.Width - (2 * balloon_bordersize), + rect.Height - (2 * balloon_bordersize)); + + StringFormat textformat = control.Format; + textformat.LineAlignment = StringAlignment.Far; + dc.DrawString(control.Text, control.Font, solidbrush, textrect, textformat); + } + + public override Rectangle BalloonWindowRect(NotifyIcon.BalloonWindow control) + { + Rectangle deskrect = Screen.GetWorkingArea(control); + SizeF maxsize = new SizeF(250, 200); + + SizeF titlesize = TextRenderer.MeasureString(control.Title, control.Font, maxsize, control.Format); + SizeF textsize = TextRenderer.MeasureString(control.Text, control.Font, maxsize, control.Format); + + if (titlesize.Height < balloon_iconsize) + titlesize.Height = balloon_iconsize; + + Rectangle rect = new Rectangle(); + rect.Height = (int)(titlesize.Height + textsize.Height + (3 * balloon_bordersize)); + rect.Width = (int)((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize); + rect.X = deskrect.Width - rect.Width - 2; + rect.Y = deskrect.Height - rect.Height - 2; + + return rect; + } + #endregion // BalloonWindow + + #region TrackBar + public override int TrackBarValueFromMousePosition(int x, int y, TrackBar tb) + { + int result = tb.Value; + int value_pos = tb.Value; + float pixels_betweenticks; + Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty; + Point channel_startpoint = Point.Empty, na_point = Point.Empty; + + GetTrackBarDrawingInfo(tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point); + + /* Convert thumb position from mouse position to value*/ + if (tb.Orientation == Orientation.Vertical) + { + value_pos = (int)Math.Round(((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0); + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + else if (value_pos + tb.Minimum < tb.Minimum) + value_pos = 0; + + result = value_pos + tb.Minimum; + } + else + { + value_pos = (int)Math.Round(((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float)pixels_betweenticks), 0); + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + else if (value_pos + tb.Minimum < tb.Minimum) + value_pos = 0; + + result = value_pos + tb.Minimum; + } + + return result; + } + + 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) + { + thumb_area = Rectangle.Empty; + thumb_pos = Rectangle.Empty; + + if (tb.Orientation == Orientation.Vertical) + { + toptick_startpoint = new Point(); + bottomtick_startpoint = new Point(); + channel_startpoint = new Point(); + float pixel_len; + const int space_from_right = 8; + const int space_from_left = 8; + const int space_from_bottom = 11; + Rectangle area = tb.ClientRectangle; + + switch (tb.TickStyle) + { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.Y = 8; + channel_startpoint.X = 9; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.Y = 8; + channel_startpoint.X = 19; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + case TickStyle.Both: + channel_startpoint.Y = 8; + channel_startpoint.X = 18; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 32; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Height = area.Height - space_from_right - space_from_left; + thumb_area.Width = TrackBarVerticalTrackWidth; + + pixel_len = thumb_area.Height - 11; + if (tb.Maximum == tb.Minimum) + { + pixels_betweenticks = 0; + } + else + { + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + } + + thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum)); + } + else + { + toptick_startpoint = new Point(); + bottomtick_startpoint = new Point(); + channel_startpoint = new Point(); + float pixel_len; + const int space_from_right = 8; + const int space_from_left = 8; + Rectangle area = tb.ClientRectangle; + + switch (tb.TickStyle) + { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.X = 8; + channel_startpoint.Y = 9; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.X = 8; + channel_startpoint.Y = 19; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + case TickStyle.Both: + channel_startpoint.X = 8; + channel_startpoint.Y = 18; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 32; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Width = area.Width - space_from_right - space_from_left; + thumb_area.Height = TrackBarHorizontalTrackHeight; + + pixel_len = thumb_area.Width - 11; + if (tb.Maximum == tb.Minimum) + { + pixels_betweenticks = 0; + } + else + { + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + } + + thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum)); + } + + thumb_pos.Size = TrackBarGetThumbSize(tb); + } + + protected virtual Size TrackBarGetThumbSize(TrackBar trackBar) + { + return TrackBarGetThumbSize(); + } + + public static Size TrackBarGetThumbSize() + { + /* Draw thumb fixed 10x22 size */ + return new Size(10, 22); + } + + public const int TrackBarVerticalTrackWidth = 4; + + public const int TrackBarHorizontalTrackHeight = 4; + + #region Ticks + protected interface ITrackBarTickPainter + { + void Paint(float x1, float y1, float x2, float y2); + } + + class TrackBarTickPainter : ITrackBarTickPainter + { + readonly Graphics g; + readonly Pen pen; + public TrackBarTickPainter(Graphics g, Pen pen) + { + this.g = g; + this.pen = pen; + } + public void Paint(float x1, float y1, float x2, float y2) + { + g.DrawLine(pen, x1, y1, x2, y2); + } + } + protected virtual ITrackBarTickPainter GetTrackBarTickPainter(Graphics g) + { + return new TrackBarTickPainter(g, ResPool.GetPen(pen_ticks_color)); + } + #endregion + + #region DrawTrackBar_Vertical + private void 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) + { + + Point toptick_startpoint = new Point(); + Point bottomtick_startpoint = new Point(); + Point channel_startpoint = new Point(); + float pixel_len; + float pixels_betweenticks; + Rectangle area = tb.ClientRectangle; + + GetTrackBarDrawingInfo(tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint); + + #region Track + TrackBarDrawVerticalTrack(dc, thumb_area, channel_startpoint, clip_rectangle); + #endregion + + #region Thumb + switch (tb.TickStyle) + { + case TickStyle.BottomRight: + case TickStyle.None: + thumb_pos.X = channel_startpoint.X - 8; + TrackBarDrawVerticalThumbRight(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + case TickStyle.TopLeft: + thumb_pos.X = channel_startpoint.X - 10; + TrackBarDrawVerticalThumbLeft(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + default: + thumb_pos.X = area.X + 10; + TrackBarDrawVerticalThumb(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + } + #endregion + + pixel_len = thumb_area.Height - 11; + pixels_betweenticks = pixel_len / ticks; + + thumb_area.X = thumb_pos.X; + thumb_area.Y = channel_startpoint.Y; + thumb_area.Width = thumb_pos.Height; + + #region Ticks + if (pixels_betweenticks <= 0) + return; + if (tb.TickStyle == TickStyle.None) + return; + Region outside = new Region(area); + outside.Exclude(thumb_area); + + if (outside.IsVisible(clip_rectangle)) + { + ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter(dc); + + if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) + { + float x = area.X + bottomtick_startpoint.X; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) + { + float y = area.Y + bottomtick_startpoint.Y + inc; + tick_painter.Paint( + x, y, + x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y); + } + } + + if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) + { + float x = area.X + toptick_startpoint.X; + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) + { + float y = area.Y + toptick_startpoint.Y + inc; + tick_painter.Paint( + x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y, + x, y); + } + } + } + + outside.Dispose(); + #endregion + } + + #region Track + protected virtual void TrackBarDrawVerticalTrack(Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + dc.FillRectangle(SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y, + 1, thumb_area.Height); + + dc.FillRectangle(SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y, + 1, thumb_area.Height); + + dc.FillRectangle(SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y, + 1, thumb_area.Height); + } + #endregion + + #region Thumb + protected virtual void TrackBarDrawVerticalThumbRight(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y); + dc.DrawLine(pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9); + dc.DrawLine(pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10); + dc.DrawLine(pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5); + + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8); + dc.FillRectangle(br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6); + dc.FillRectangle(br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4); + dc.FillRectangle(br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2); + } + + protected virtual void TrackBarDrawVerticalThumbLeft(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y); + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9); + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5); + dc.DrawLine(pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10); + dc.DrawLine(pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5); + dc.DrawLine(pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10); + + dc.FillRectangle(br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8); + dc.FillRectangle(br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6); + dc.FillRectangle(br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4); + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2); + } + + protected virtual void TrackBarDrawVerticalThumb(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9); + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10); + dc.DrawLine(pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9); + + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8); + } + #endregion + + #region Ticks + protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter(Graphics g) + { + return GetTrackBarTickPainter(g); + } + #endregion + #endregion + + #region DrawTrackBar_Horizontal + /* + Horizontal trackbar + + Does not matter the size of the control, Win32 always draws: + - Ticks starting from pixel 13, 8 + - Channel starting at pos 8, 19 and ends at Width - 8 + - Autosize makes always the control 45 pixels high + - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum) + + */ + private void 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) + { + Point toptick_startpoint = new Point(); + Point bottomtick_startpoint = new Point(); + Point channel_startpoint = new Point(); + float pixel_len; + float pixels_betweenticks; + Rectangle area = tb.ClientRectangle; + + GetTrackBarDrawingInfo(tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint); + + #region Track + TrackBarDrawHorizontalTrack(dc, thumb_area, channel_startpoint, clip_rectangle); + #endregion + + #region Thumb + switch (tb.TickStyle) + { + case TickStyle.BottomRight: + case TickStyle.None: + thumb_pos.Y = channel_startpoint.Y - 8; + TrackBarDrawHorizontalThumbBottom(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + case TickStyle.TopLeft: + thumb_pos.Y = channel_startpoint.Y - 10; + TrackBarDrawHorizontalThumbTop(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + default: + thumb_pos.Y = area.Y + 10; + TrackBarDrawHorizontalThumb(dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + } + #endregion + + pixel_len = thumb_area.Width - 11; + pixels_betweenticks = pixel_len / ticks; + + thumb_area.Y = thumb_pos.Y; + thumb_area.X = channel_startpoint.X; + thumb_area.Height = thumb_pos.Height; + #region Ticks + if (pixels_betweenticks <= 0) + return; + if (tb.TickStyle == TickStyle.None) + return; + Region outside = new Region(area); + outside.Exclude(thumb_area); + + if (outside.IsVisible(clip_rectangle)) + { + ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter(dc); + + if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) + { + float y = area.Y + bottomtick_startpoint.Y; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) + { + float x = area.X + bottomtick_startpoint.X + inc; + tick_painter.Paint( + x, y, + x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2)); + } + } + + if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) + { + float y = area.Y + toptick_startpoint.Y; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) + { + float x = area.X + toptick_startpoint.X + inc; + tick_painter.Paint( + x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), + x, y); + } + } + } + + outside.Dispose(); + #endregion + } + + #region Track + protected virtual void TrackBarDrawHorizontalTrack(Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + dc.FillRectangle(SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y, + thumb_area.Width, 1); + + dc.FillRectangle(SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1, + thumb_area.Width, 1); + + dc.FillRectangle(SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3, + thumb_area.Width, 1); + } + #endregion + + #region Thumb + protected virtual void TrackBarDrawHorizontalThumbBottom(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15); + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16); + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5); + + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16); + dc.FillRectangle(br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1); + dc.FillRectangle(br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1); + dc.FillRectangle(br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1); + } + + protected virtual void TrackBarDrawHorizontalThumbTop(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16); + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y); + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16); + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20); + + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15); + dc.FillRectangle(br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1); + dc.FillRectangle(br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1); + dc.FillRectangle(br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1); + } + + protected virtual void TrackBarDrawHorizontalThumb(Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19); + + pen = SystemPens.ControlDark; + dc.DrawLine(pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19); + dc.DrawLine(pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20); + dc.DrawLine(pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20); + + dc.FillRectangle(br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18); + } + #endregion + + #region Ticks + protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter(Graphics g) + { + return GetTrackBarTickPainter(g); + } + #endregion + #endregion + + public override void DrawTrackBar(Graphics dc, Rectangle clip_rectangle, TrackBar tb) + { + Brush br_thumb; + int value_pos; + bool mouse_value; + float ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/ + Rectangle area; + Rectangle thumb_pos = tb.ThumbPos; + Rectangle thumb_area = tb.ThumbArea; + + if (tb.thumb_pressed) + { + value_pos = tb.thumb_mouseclick; + mouse_value = true; + } + else + { + value_pos = tb.Value - tb.Minimum; + mouse_value = false; + } + + area = tb.ClientRectangle; + + if (!tb.Enabled) + { + br_thumb = (Brush)ResPool.GetHatchBrush(HatchStyle.Percent50, ColorControlLightLight, ColorControlLight); + } + else if (tb.thumb_pressed == true) + { + br_thumb = (Brush)ResPool.GetHatchBrush(HatchStyle.Percent50, ColorControlLight, ColorControl); + } + else + { + br_thumb = SystemBrushes.Control; + } + + + /* Widget Background */ + if (tb.BackColor.ToArgb() == DefaultControlBackColor.ToArgb()) + { + dc.FillRectangle(SystemBrushes.Control, clip_rectangle); + } + else + { + dc.FillRectangle(ResPool.GetSolidBrush(tb.BackColor), clip_rectangle); + } + + if (tb.Focused) + { + CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor); + } + + if (tb.Orientation == Orientation.Vertical) + { + DrawTrackBar_Vertical(dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + br_thumb, ticks, value_pos, mouse_value); + + } + else + { + DrawTrackBar_Horizontal(dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + br_thumb, ticks, value_pos, mouse_value); + } + + tb.ThumbPos = thumb_pos; + tb.ThumbArea = thumb_area; + } + + public override Size TrackBarDefaultSize + { + get + { + return new Size(104, 42); + } + } + + public override bool TrackBarHasHotThumbStyle + { + get + { + return false; + } + } + #endregion // TrackBar + + #region UpDownBase + public override void UpDownBaseDrawButton(Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state) + { + WidgetPaint.DrawScrollButton(g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal); + } + + public override bool UpDownBaseHasHotButtonStyle + { + get + { + return false; + } + } + #endregion + + #region VScrollBar + public override Size VScrollBarDefaultSize + { + get + { + return new Size(this.ScrollBarButtonSize, 80); + } + } + #endregion // VScrollBar + + #region TreeView + public override Size TreeViewDefaultSize + { + get + { + return new Size(121, 97); + } + } + + public override void TreeViewDrawNodePlusMinus(TreeView treeView, TreeNode node, Graphics dc, int x, int middle) + { + int height = treeView.ActualItemHeight - 2; + dc.FillRectangle(ResPool.GetSolidBrush(treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height); + + dc.DrawRectangle(SystemPens.ControlDarkDark, x, middle - 4, 8, 8); + + if (node.IsExpanded) + { + dc.DrawLine(SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); + } + else + { + dc.DrawLine(SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); + dc.DrawLine(SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2); + } + } + #endregion + + #region Managed window + public override int ManagedWindowTitleBarHeight(InternalWindowManager wm) + { + if (wm.IsToolWindow && !wm.IsMinimized) + return SystemInformation.ToolWindowCaptionHeight; + if (wm.Form.FormBorderStyle == FormBorderStyle.None) + return 0; + return SystemInformation.CaptionHeight; + } + + public override int ManagedWindowBorderWidth(InternalWindowManager wm) + { + if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) || + wm.IsMinimized) + return 3; + else + return 4; + } + + public override int ManagedWindowIconWidth(InternalWindowManager wm) + { + return ManagedWindowTitleBarHeight(wm) - 5; + } + + public override void ManagedWindowSetButtonLocations(InternalWindowManager wm) + { + TitleButtons buttons = wm.TitleButtons; + Form form = wm.form; + + buttons.HelpButton.Visible = form.HelpButton; + + foreach (TitleButton button in buttons) + { + button.Visible = false; + } + + switch (form.FormBorderStyle) + { + case FormBorderStyle.None: + if (form.WindowState != FormWindowState.Normal) + goto case FormBorderStyle.Sizable; + break; + case FormBorderStyle.FixedToolWindow: + case FormBorderStyle.SizableToolWindow: + buttons.CloseButton.Visible = true; + if (form.WindowState != FormWindowState.Normal) + goto case FormBorderStyle.Sizable; + break; + case FormBorderStyle.FixedSingle: + case FormBorderStyle.Fixed3D: + case FormBorderStyle.FixedDialog: + case FormBorderStyle.Sizable: + switch (form.WindowState) + { + case FormWindowState.Normal: + buttons.MinimizeButton.Visible = true; + buttons.MaximizeButton.Visible = true; + buttons.RestoreButton.Visible = false; + break; + case FormWindowState.Maximized: + buttons.MinimizeButton.Visible = true; + buttons.MaximizeButton.Visible = false; + buttons.RestoreButton.Visible = true; + break; + case FormWindowState.Minimized: + buttons.MinimizeButton.Visible = false; + buttons.MaximizeButton.Visible = true; + buttons.RestoreButton.Visible = true; + break; + } + buttons.CloseButton.Visible = true; + break; + } + + // Respect MinimizeBox/MaximizeBox + if (form.MinimizeBox == false && form.MaximizeBox == false) + { + buttons.MinimizeButton.Visible = false; + buttons.MaximizeButton.Visible = false; + } + else if (form.MinimizeBox == false) + buttons.MinimizeButton.State = ButtonState.Inactive; + else if (form.MaximizeBox == false) + buttons.MaximizeButton.State = ButtonState.Inactive; + + int bw = ManagedWindowBorderWidth(wm); + Size btsize = ManagedWindowButtonSize(wm); + int btw = btsize.Width; + int bth = btsize.Height; + int top = bw + 2; + int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton; + + if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) + { + buttons.CloseButton.Rectangle = new Rectangle(left, top, btw, bth); + left -= 2 + btw; + + if (buttons.MaximizeButton.Visible) + { + buttons.MaximizeButton.Rectangle = new Rectangle(left, top, btw, bth); + left -= 2 + btw; + } + if (buttons.RestoreButton.Visible) + { + buttons.RestoreButton.Rectangle = new Rectangle(left, top, btw, bth); + left -= 2 + btw; + } + + buttons.MinimizeButton.Rectangle = new Rectangle(left, top, btw, bth); + left -= 2 + btw; + } + else if (wm.IsToolWindow) + { + buttons.CloseButton.Rectangle = new Rectangle(left, top, btw, bth); + left -= 2 + btw; + } + } + + protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders(Graphics dc, Rectangle clip, InternalWindowManager wm) + { + Form form = wm.Form; + int tbheight = ManagedWindowTitleBarHeight(wm); + int bdwidth = ManagedWindowBorderWidth(wm); + Color titlebar_color = Color.FromArgb(255, 10, 36, 106); + Color titlebar_color2 = Color.FromArgb(255, 166, 202, 240); + Color color = ThemeEngine.Current.ColorControlDark; + Color color2 = Color.FromArgb(255, 192, 192, 192); + + Pen pen = ResPool.GetPen(ColorControl); + Rectangle borders = new Rectangle(0, 0, form.Width, form.Height); + WidgetPaint.DrawBorder3D(dc, borders, Border3DStyle.Raised); + // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves + borders = new Rectangle(2, 2, form.Width - 5, form.Height - 5); + for (int i = 2; i < bdwidth; i++) + { + dc.DrawRectangle(pen, borders); + borders.Inflate(-1, -1); + } + + + bool draw_titlebar_enabled = false; + if (wm.Form.Parent != null && wm.Form.Parent is Form) + { + draw_titlebar_enabled = false; + } + else if (wm.IsActive && !wm.IsMaximized) + { + draw_titlebar_enabled = true; + } + if (draw_titlebar_enabled) + { + color = titlebar_color; + color2 = titlebar_color2; + } + + Rectangle tb = new Rectangle(bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1); + + // HACK: For now always draw the titlebar until we get updates better + if (tb.Width > 0 && tb.Height > 0) + { + using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush(tb, color, color2, LinearGradientMode.Horizontal)) + { + dc.FillRectangle(gradient, tb); + } + } + + if (!wm.IsMinimized) + // Draw the line just beneath the title bar + dc.DrawLine(ResPool.GetPen(SystemColors.Control), bdwidth, + tbheight + bdwidth - 1, form.Width - bdwidth - 1, + tbheight + bdwidth - 1); + return tb; + } + + public override void DrawManagedWindowDecorations(Graphics dc, Rectangle clip, InternalWindowManager wm) + { +#if debug + Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations"); + dc.FillRectangle (Brushes.Black, clip); +#endif + Rectangle tb = ManagedWindowDrawTitleBarAndBorders(dc, clip, wm); + + Form form = wm.Form; + if (wm.ShowIcon) + { + Rectangle icon = ManagedWindowGetTitleBarIconArea(wm); + if (icon.IntersectsWith(clip)) + dc.DrawIcon(form.Icon, icon); + const int SpacingBetweenIconAndCaption = 2; + tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X; + tb.X = icon.Right + SpacingBetweenIconAndCaption; + } + + foreach (TitleButton button in wm.TitleButtons.AllButtons) + { + tb.Width -= Math.Max(0, tb.Right - DrawTitleButton(dc, button, clip, form)); + } + const int SpacingBetweenCaptionAndLeftMostButton = 3; + tb.Width -= SpacingBetweenCaptionAndLeftMostButton; + + string window_caption = form.Text; + window_caption = window_caption.Replace(Environment.NewLine, string.Empty); + + if (window_caption != null && window_caption != string.Empty) + { + StringFormat format = new StringFormat(); + format.FormatFlags = StringFormatFlags.NoWrap; + format.Trimming = StringTrimming.EllipsisCharacter; + format.LineAlignment = StringAlignment.Center; + + if (tb.IntersectsWith(clip)) + dc.DrawString(window_caption, WindowBorderFont, + ThemeEngine.Current.ResPool.GetSolidBrush(Color.White), + tb, format); + } + } + + public override Size ManagedWindowButtonSize(InternalWindowManager wm) + { + int height = ManagedWindowTitleBarHeight(wm); + if (!wm.IsMaximized && !wm.IsMinimized) + { + if (wm.IsToolWindow) + return new Size(SystemInformation.ToolWindowCaptionButtonSize.Width - 2, + height - 5); + if (wm.Form.FormBorderStyle == FormBorderStyle.None) + return Size.Empty; + } + else + height = SystemInformation.CaptionHeight; + + return new Size(SystemInformation.CaptionButtonSize.Width - 2, + height - 5); + } + + private int DrawTitleButton(Graphics dc, TitleButton button, Rectangle clip, Form form) + { + if (!button.Visible) + { + return int.MaxValue; + } + + if (button.Rectangle.IntersectsWith(clip)) + { + ManagedWindowDrawTitleButton(dc, button, clip, form); + } + return button.Rectangle.Left; + } + + protected virtual void ManagedWindowDrawTitleButton(Graphics dc, TitleButton button, Rectangle clip, Form form) + { + dc.FillRectangle(SystemBrushes.Control, button.Rectangle); + + WidgetPaint.DrawCaptionButton(dc, button.Rectangle, + button.Caption, button.State); + } + + public override Rectangle ManagedWindowGetTitleBarIconArea(InternalWindowManager wm) + { + int bw = ManagedWindowBorderWidth(wm); + return new Rectangle(bw + 3, bw + 2, wm.IconWidth, wm.IconWidth); + } + + public override Size ManagedWindowGetMenuButtonSize(InternalWindowManager wm) + { + Size result = SystemInformation.MenuButtonSize; + result.Width -= 2; + result.Height -= 4; + return result; + } + + public override bool ManagedWindowTitleButtonHasHotElementStyle(TitleButton button, Form form) + { + return false; + } + + public override void ManagedWindowDrawMenuButton(Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm) + { + dc.FillRectangle(SystemBrushes.Control, button.Rectangle); + WidgetPaint.DrawCaptionButton(dc, button.Rectangle, + button.Caption, button.State); + } + + public override void ManagedWindowOnSizeInitializedOrChanged(Form form) + { + } + #endregion + + #region WidgetPaint + public override void 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) + { + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 1, leftWidth, leftColor, leftStyle, Border3DSide.Left); + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right - 1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top); + DrawBorderInternal(graphics, bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom - 1, rightWidth, rightColor, rightStyle, Border3DSide.Right); + DrawBorderInternal(graphics, bounds.Left, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom); + } + + public override void 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) + { + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 1, leftWidth, leftColor, leftStyle, Border3DSide.Left); + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right - 1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top); + DrawBorderInternal(graphics, bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom - 1, rightWidth, rightColor, rightStyle, Border3DSide.Right); + DrawBorderInternal(graphics, bounds.Left, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom); + } + + public override void CPDrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) + { + CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl); + } + + public override void CPDrawBorder3D(Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color) + { + var skin = Application.CurrentSkin; + Pen penTopLeft; + Pen penTopLeftInner; + Pen penBottomRight; + Pen penBottomRightInner; + Rectangle rect = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); + bool is_ColorControl = control_color.ToArgb() == ColorControl.ToArgb() ? true : false; + + if ((style & Border3DStyle.Adjust) != 0) + { + rect.Y -= 2; + rect.X -= 2; + rect.Width += 4; + rect.Height += 4; + } + + penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen(control_color); + + CPColor cpcolor = CPColor.Empty; + + if (!is_ColorControl) + cpcolor = ResPool.GetCPColor(control_color); + + switch (style) + { + case Border3DStyle.Raised: + penTopLeftInner = new Pen(skin.Border3DTopLeftInner); + penBottomRight = new Pen(skin.Border3DBottomRight); + penBottomRightInner = new Pen(skin.Border3DBottomRightInner); + break; + case Border3DStyle.Sunken: + penTopLeft = new Pen(skin.Border3DBottomRightInner); + penTopLeftInner = new Pen(skin.Border3DBottomRight); + penBottomRight = new Pen(skin.Border3DTopLeftInner); + break; + case Border3DStyle.Etched: + penTopLeft = new Pen(skin.Border3DBottomRightInner); + penTopLeftInner = new Pen(skin.Border3DTopLeftInner); + break; + case Border3DStyle.RaisedOuter: + penBottomRight = new Pen(skin.Border3DBottomRight); + break; + case Border3DStyle.SunkenOuter: + penTopLeft = new Pen(skin.Border3DBottomRightInner); + penBottomRight = new Pen(skin.Border3DTopLeftInner); + break; + case Border3DStyle.RaisedInner: + penTopLeft = new Pen(skin.Border3DTopLeftInner); + penBottomRight = new Pen(skin.Border3DBottomRightInner); + break; + case Border3DStyle.SunkenInner: + penTopLeft = new Pen(skin.Border3DBottomRight); + break; + case Border3DStyle.Flat: + penTopLeft = penBottomRight = new Pen(skin.DefaultForeColor); + break; + case Border3DStyle.Bump: + penTopLeftInner = penBottomRight = new Pen(skin.Border3DBottomRight); + break; + default: + break; + } + + bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter)); + + if ((sides & Border3DSide.Middle) != 0) + { + Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush(control_color); + graphics.FillRectangle(brush, rect); + } + + if ((sides & Border3DSide.Left) != 0) + { + graphics.DrawLine(penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top); + if ((rect.Width > 2) && inner) + graphics.DrawLine(penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top); + } + + if ((sides & Border3DSide.Top) != 0) + { + graphics.DrawLine(penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top); + if ((rect.Height > 2) && inner) + graphics.DrawLine(penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1); + } + + if ((sides & Border3DSide.Right) != 0) + { + graphics.DrawLine(penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1); + if ((rect.Width > 3) && inner) + graphics.DrawLine(penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2); + } + + if ((sides & Border3DSide.Bottom) != 0) + { + graphics.DrawLine(penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + if ((rect.Height > 3) && inner) + graphics.DrawLine(penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + } + } + + public override void CPDrawButton(Graphics dc, Rectangle rectangle, ButtonState state) + { + CPDrawButtonInternal(dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight); + } + + private void CPDrawButtonInternal(Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen) + { + // sadly enough, the rectangle gets always filled with a hatchbrush + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ButtonBackColor), + rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2); + + if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) + { + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ButtonBackColor_Checked), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); + + dc.DrawRectangle(new Pen(new SolidBrush(Application.CurrentSkin.ButtonBorderColor), Application.CurrentSkin.ButtonBorderWidth), rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); + } + else + if ((state & ButtonState.Flat) == ButtonState.Flat) + { + dc.DrawRectangle(new Pen(new SolidBrush(Application.CurrentSkin.ButtonBorderColor), Application.CurrentSkin.ButtonBorderWidth), rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); + } + else + if ((state & ButtonState.Checked) == ButtonState.Checked) + { + dc.FillRectangle(new SolidBrush(Application.CurrentSkin.ButtonBackColor_Checked), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); + + Pen pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DTopLeftInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + dc.DrawLine(pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRight)); + dc.DrawLine(pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); + dc.DrawLine(pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRightInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); + dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); + } + else + if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) + { + Pen pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DTopLeftInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + dc.DrawLine(pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRight)); + dc.DrawLine(pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); + dc.DrawLine(pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRightInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); + dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); + } + else + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) + { + Pen pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DTopLeftInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y); + dc.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRight)); + dc.DrawLine(pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2); + dc.DrawLine(pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3); + + pen = new Pen(new SolidBrush(Application.CurrentSkin.Border3DBottomRightInner)); + dc.DrawLine(pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1); + dc.DrawLine(pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2); + } + } + + + public override void CPDrawCaptionButton(Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) + { + Rectangle captionRect; + int lineWidth; + + CPDrawButtonInternal(graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight); + + if (rectangle.Width < rectangle.Height) + { + captionRect = new Rectangle(rectangle.X + 1, rectangle.Y + rectangle.Height / 2 - rectangle.Width / 2 + 1, rectangle.Width - 4, rectangle.Width - 4); + } + else + { + captionRect = new Rectangle(rectangle.X + rectangle.Width / 2 - rectangle.Height / 2 + 1, rectangle.Y + 1, rectangle.Height - 4, rectangle.Height - 4); + } + + if ((state & ButtonState.Pushed) != 0) + { + captionRect = new Rectangle(rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 3, rectangle.Height - 3); + } + + /* Make sure we've got at least a line width of 1 */ + lineWidth = Math.Max(1, captionRect.Width / 7); + + switch (button) + { + case CaptionButton.Close: + { + Pen pen; + + if ((state & ButtonState.Inactive) != 0) + { + pen = ResPool.GetSizedPen(ColorControlLight, lineWidth); + DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button); + + pen = ResPool.GetSizedPen(ColorControlDark, lineWidth); + DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button); + return; + } + else + { + pen = ResPool.GetSizedPen(ColorControlText, lineWidth); + DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button); + return; + } + } + + case CaptionButton.Help: + case CaptionButton.Maximize: + case CaptionButton.Minimize: + case CaptionButton.Restore: + { + if ((state & ButtonState.Inactive) != 0) + { + DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button); + + DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button); + return; + } + else + { + DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button); + return; + } + } + } + } + + public override void CPDrawCheckBox(Graphics dc, Rectangle rectangle, ButtonState state) + { + CPDrawCheckBoxInternal(dc, rectangle, state, false /* mixed */); + } + + private void CPDrawCheckBoxInternal(Graphics dc, Rectangle rectangle, ButtonState state, bool mixed) + { + Pen check_pen = (mixed) ? Pens.Gray : Pens.Black; + + Rectangle cb_rect = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); + + if ((state & ButtonState.All) == ButtonState.All) + { + cb_rect.Width -= 2; + cb_rect.Height -= 2; + + dc.FillRectangle(SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + dc.DrawRectangle(SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + + check_pen = SystemPens.ControlDark; + } + else + if ((state & ButtonState.Flat) == ButtonState.Flat) + { + cb_rect.Width -= 2; + cb_rect.Height -= 2; + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + dc.FillRectangle(SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + else + dc.FillRectangle(Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + dc.DrawRectangle(SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + } + else + { + cb_rect.Width -= 1; + cb_rect.Height -= 1; + + int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height; + + int x_pos = Math.Max(0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2); + int y_pos = Math.Max(0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2); + + Rectangle rect = new Rectangle(x_pos, y_pos, check_box_visible_size, check_box_visible_size); + + if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) + { + dc.FillRectangle(ResPool.GetHatchBrush(HatchStyle.Percent50, + Color.FromArgb(Clamp(ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), + ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + } + else + dc.FillRectangle(SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + + Pen pen = SystemPens.ControlDark; + dc.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom - 1); + dc.DrawLine(pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine(pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2); + dc.DrawLine(pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1); + + pen = SystemPens.ControlLightLight; + dc.DrawLine(pen, rect.Right, rect.Y, rect.Right, rect.Bottom); + dc.DrawLine(pen, rect.X, rect.Bottom, rect.Right, rect.Bottom); + + // oh boy, matching ms is like fighting against windmills + using (Pen h_pen = new Pen(ResPool.GetHatchBrush(HatchStyle.Percent50, + Color.FromArgb(Clamp(ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), ColorControl))) + { + dc.DrawLine(h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine(h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1); + } + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + check_pen = SystemPens.ControlDark; + } + + if ((state & ButtonState.Checked) == ButtonState.Checked) + { + int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2 : cb_rect.Height / 2; + + if (check_size < 7) + { + int lineWidth = Math.Max(3, check_size / 3); + int Scale = Math.Max(1, check_size / 9); + + 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, + check_size, check_size); + + for (int i = 0; i < lineWidth; i++) + { + dc.DrawLine(check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i); + 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); + } + } + else + { + int lineWidth = Math.Max(3, check_size / 3) + 1; + + int x_half = cb_rect.Width / 2; + int y_half = cb_rect.Height / 2; + + Rectangle rect = new Rectangle(cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), + check_size, check_size); + + int gradient_left = check_size / 3; + int gradient_right = check_size - gradient_left - 1; + + + for (int i = 0; i < lineWidth; i++) + { + dc.DrawLine(check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i); + dc.DrawLine(check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i - 1 - gradient_right); + } + } + } + } + + public override void CPDrawComboButton(Graphics graphics, Rectangle rectangle, ButtonState state) + { + Point[] arrow = new Point[3]; + Point P1; + Point P2; + Point P3; + int centerX; + int centerY; + int shiftX; + int shiftY; + Rectangle rect; + + if ((state & ButtonState.Checked) != 0) + { + graphics.FillRectangle(ResPool.GetHatchBrush(HatchStyle.Percent50, ColorControlLightLight, ColorControlLight), rectangle); + } + + if ((state & ButtonState.Flat) != 0) + { + WidgetPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid); + } + else + { + if ((state & (ButtonState.Pushed | ButtonState.Checked)) != 0) + { + // this needs to render like a pushed button - jba + // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl); + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + graphics.DrawRectangle(SystemPens.ControlDark, trace_rectangle); + } + else + { + CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl); + } + } + + rect = new Rectangle(rectangle.X + rectangle.Width / 4, rectangle.Y + rectangle.Height / 4, rectangle.Width / 2, rectangle.Height / 2); + centerX = rect.Left + rect.Width / 2; + centerY = rect.Top + rect.Height / 2; + shiftX = Math.Max(1, rect.Width / 8); + shiftY = Math.Max(1, rect.Height / 8); + + if ((state & ButtonState.Pushed) != 0) + { + shiftX++; + shiftY++; + } + + rect.Y -= shiftY; + centerY -= shiftY; + P1 = new Point(rect.Left, centerY); + P2 = new Point(rect.Right, centerY); + P3 = new Point(centerX, rect.Bottom); + + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + /* Draw the arrow */ + if ((state & ButtonState.Inactive) != 0) + { + /* Move away from the shadow */ + arrow[0].X += 1; arrow[0].Y += 1; + arrow[1].X += 1; arrow[1].Y += 1; + arrow[2].X += 1; arrow[2].Y += 1; + + graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding); + + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding); + } + else + { + graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding); + } + } + + public override void CPDrawContainerGrabHandle(Graphics graphics, Rectangle bounds) + { + Pen pen = Pens.Black; + Rectangle rect = new Rectangle(bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1); // Dunno why, but MS does it that way, too + int X; + int Y; + + graphics.FillRectangle(SystemBrushes.ControlLightLight, rect); + graphics.DrawRectangle(pen, rect); + + X = rect.X + rect.Width / 2; + Y = rect.Y + rect.Height / 2; + + /* Draw the cross */ + graphics.DrawLine(pen, X, rect.Y + 2, X, rect.Bottom - 2); + graphics.DrawLine(pen, rect.X + 2, Y, rect.Right - 2, Y); + + /* Draw 'arrows' for vertical lines */ + graphics.DrawLine(pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3); + graphics.DrawLine(pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3); + + /* Draw 'arrows' for horizontal lines */ + graphics.DrawLine(pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1); + graphics.DrawLine(pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1); + } + + public virtual void DrawFlatStyleFocusRectangle(Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) + { + // make a rectange to trace around border of the button + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + + Color outerColor = foreColor; + // adjust focus color according to the flatstyle + if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) + { + outerColor = (backColor.ToArgb() == ColorControl.ToArgb()) ? WidgetPaint.Dark(ColorControl) : ColorControlText; + } + + // draw the outer rectangle + graphics.DrawRectangle(ResPool.GetPen(outerColor), trace_rectangle); + + // draw the inner rectangle + if (button.FlatStyle == FlatStyle.Popup) + { + DrawInnerFocusRectangle(graphics, Rectangle.Inflate(rectangle, -4, -4), backColor); + } + else + { + // draw a flat inner rectangle + Pen pen = ResPool.GetPen(WidgetPaint.LightLight(backColor)); + graphics.DrawRectangle(pen, Rectangle.Inflate(trace_rectangle, -4, -4)); + } + } + + public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor) + { + // make a rectange to trace around border of the button + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + +#if NotUntilCairoIsFixed + Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255)); + DashStyle oldStyle; // used for caching old penstyle + Pen pen = ResPool.GetPen (colorBackInverted); + + oldStyle = pen.DashStyle; + pen.DashStyle = DashStyle.Dot; + + graphics.DrawRectangle (pen, trace_rectangle); + pen.DashStyle = oldStyle; +#else + CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor); +#endif + } + + + public override void CPDrawFocusRectangle(Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) + { + Rectangle rect = rectangle; + Pen pen; + HatchBrush brush; + + if (backColor.GetBrightness() >= 0.5) + { + foreColor = Color.Transparent; + backColor = Color.Black; + + } + else + { + backColor = Color.FromArgb(Math.Abs(backColor.R - 255), Math.Abs(backColor.G - 255), Math.Abs(backColor.B - 255)); + foreColor = Color.Black; + } + + brush = ResPool.GetHatchBrush(HatchStyle.Percent50, backColor, foreColor); + pen = new Pen(brush, 1); + + rect.Width--; + rect.Height--; + + graphics.DrawRectangle(pen, rect); + pen.Dispose(); + } + + public override void CPDrawGrabHandle(Graphics graphics, Rectangle rectangle, bool primary, bool enabled) + { + Brush sb; + Pen pen; + + if (primary == true) + { + pen = Pens.Black; + if (enabled == true) + { + sb = Brushes.White; + } + else + { + sb = SystemBrushes.Control; + } + } + else + { + pen = Pens.White; + if (enabled == true) + { + sb = Brushes.Black; + } + else + { + sb = SystemBrushes.Control; + } + } + graphics.FillRectangle(sb, rectangle); + graphics.DrawRectangle(pen, rectangle); + } + + + public override void CPDrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) + { + Color foreColor; + int h; + int b; + int s; + + WidgetPaint.Color2HBS(backColor, out h, out b, out s); + + if (b > 127) + { + foreColor = Color.Black; + } + else + { + foreColor = Color.White; + } + + // still not perfect. it seems that ms calculates the position of the first dot or line + + using (Pen pen = new Pen(foreColor)) + { + pen.DashPattern = new float[] { 1.0f, pixelsBetweenDots.Width - 1 }; + + for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height) + graphics.DrawLine(pen, area.X, y, area.Right - 1, y); + } + } + + public override void CPDrawImageDisabled(Graphics graphics, Image image, int x, int y, Color background) + { + /* + Microsoft seems to ignore the background and simply make + the image grayscale. At least when having > 256 colors on + the display. + */ + + if (imagedisabled_attributes == null) + { + imagedisabled_attributes = new ImageAttributes(); + ColorMatrix colorMatrix = new ColorMatrix(new float[][] { + // This table would create a perfect grayscale image, based on luminance + // new float[]{0.3f,0.3f,0.3f,0,0}, + // new float[]{0.59f,0.59f,0.59f,0,0}, + // new float[]{0.11f,0.11f,0.11f,0,0}, + // new float[]{0,0,0,1,0,0}, + // new float[]{0,0,0,0,1,0}, + // new float[]{0,0,0,0,0,1} + + // This table generates a image that is grayscaled and then + // brightened up. Seems to match MS close enough. + new float[]{0.2f,0.2f,0.2f,0,0}, + new float[]{0.41f,0.41f,0.41f,0,0}, + new float[]{0.11f,0.11f,0.11f,0,0}, + new float[]{0.15f,0.15f,0.15f,1,0,0}, + new float[]{0.15f,0.15f,0.15f,0,1,0}, + new float[]{0.15f,0.15f,0.15f,0,0,1} + }); + + imagedisabled_attributes.SetColorMatrix(colorMatrix); + } + + graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes); + + } + + + public override void CPDrawLockedFrame(Graphics graphics, Rectangle rectangle, bool primary) + { + Pen penBorder; + Pen penInside; + + if (primary) + { + penBorder = ResPool.GetSizedPen(Color.White, 2); + penInside = ResPool.GetPen(Color.Black); + } + else + { + penBorder = ResPool.GetSizedPen(Color.Black, 2); + penInside = ResPool.GetPen(Color.White); + } + penBorder.Alignment = PenAlignment.Inset; + penInside.Alignment = PenAlignment.Inset; + + graphics.DrawRectangle(penBorder, rectangle); + graphics.DrawRectangle(penInside, rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 5, rectangle.Height - 5); + } + + + public override void CPDrawMenuGlyph(Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) + { + Rectangle rect; + int lineWidth; + + if (backColor != Color.Empty) + graphics.FillRectangle(ResPool.GetSolidBrush(backColor), rectangle); + + Brush brush = ResPool.GetSolidBrush(color); + + switch (glyph) + { + case MenuGlyph.Arrow: + { + float height = rectangle.Height * 0.7f; + float width = height / 2.0f; + + PointF ddCenter = new PointF(rectangle.X + ((rectangle.Width - width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f)); + + PointF[] vertices = new PointF[3]; + vertices[0].X = ddCenter.X; + vertices[0].Y = ddCenter.Y - (height / 2.0f); + vertices[1].X = ddCenter.X; + vertices[1].Y = ddCenter.Y + (height / 2.0f); + vertices[2].X = ddCenter.X + width + 0.1f; + vertices[2].Y = ddCenter.Y; + + graphics.FillPolygon(brush, vertices); + + return; + } + + case MenuGlyph.Bullet: + { + + lineWidth = Math.Max(2, rectangle.Width / 3); + rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2); + + graphics.FillEllipse(brush, rect); + + return; + } + + case MenuGlyph.Checkmark: + { + + Pen pen = ResPool.GetPen(color); + lineWidth = Math.Max(2, rectangle.Width / 6); + rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2); + + int Scale = Math.Max(1, rectangle.Width / 12); + int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2)); + + for (int i = 0; i < lineWidth; i++) + { + graphics.DrawLine(pen, rect.Left + lineWidth / 2, top + i, rect.Left + lineWidth / 2 + 2 * Scale, top + 2 * Scale + i); + graphics.DrawLine(pen, rect.Left + lineWidth / 2 + 2 * Scale, top + 2 * Scale + i, rect.Left + lineWidth / 2 + 6 * Scale, top - 2 * Scale + i); + } + return; + } + } + + } + + public override void CPDrawMixedCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state) + { + CPDrawCheckBoxInternal(graphics, rectangle, state, true /* mixed */); + } + + public override void CPDrawRadioButton(Graphics dc, Rectangle rectangle, ButtonState state) + { + CPColor cpcolor = ResPool.GetCPColor(ColorControl); + + Color dot_color = Color.Black; + + Color top_left_outer = Color.Black; + Color top_left_inner = Color.Black; + Color bottom_right_outer = Color.Black; + Color bottom_right_inner = Color.Black; + + int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height * 0.9f) : (int)(rectangle.Width * 0.9f); + int radius = ellipse_diameter / 2; + + Rectangle rb_rect = new Rectangle(rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter); + + Brush brush = null; + + if ((state & ButtonState.All) == ButtonState.All) + { + brush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(Clamp(ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), ColorControl); + dot_color = cpcolor.Dark; + } + else + if ((state & ButtonState.Flat) == ButtonState.Flat) + { + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed)) + brush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(Clamp(ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl); + else + brush = SystemBrushes.ControlLightLight; + } + else + { + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed)) + brush = ResPool.GetHatchBrush(HatchStyle.Percent50, Color.FromArgb(Clamp(ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl); + else + brush = SystemBrushes.ControlLightLight; + + top_left_outer = cpcolor.Dark; + top_left_inner = cpcolor.DarkDark; + bottom_right_outer = cpcolor.Light; + bottom_right_inner = Color.Transparent; + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + dot_color = cpcolor.Dark; + } + + dc.FillEllipse(brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1); + + int line_width = Math.Max(1, (int)(ellipse_diameter * 0.08f)); + + dc.DrawArc(ResPool.GetSizedPen(top_left_outer, line_width), rb_rect, 135.0f, 180.0f); + dc.DrawArc(ResPool.GetSizedPen(top_left_inner, line_width), Rectangle.Inflate(rb_rect, -line_width, -line_width), 135.0f, 180.0f); + dc.DrawArc(ResPool.GetSizedPen(bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f); + + if (bottom_right_inner != Color.Transparent) + dc.DrawArc(ResPool.GetSizedPen(bottom_right_inner, line_width), Rectangle.Inflate(rb_rect, -line_width, -line_width), 315.0f, 180.0f); + else + 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)) + { + dc.DrawArc(h_pen, Rectangle.Inflate(rb_rect, -line_width, -line_width), 315.0f, 180.0f); + } + + if ((state & ButtonState.Checked) == ButtonState.Checked) + { + int inflate = line_width * 4; + Rectangle tmp = Rectangle.Inflate(rb_rect, -inflate, -inflate); + if (rectangle.Height > 13) + { + tmp.X += 1; + tmp.Y += 1; + tmp.Height -= 1; + dc.FillEllipse(ResPool.GetSolidBrush(dot_color), tmp); + } + else + { + Pen pen = ResPool.GetPen(dot_color); + dc.DrawLine(pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2)); + dc.DrawLine(pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1); + + dc.DrawLine(pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom); + dc.DrawLine(pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom); + } + } + } + + public override void CPDrawReversibleFrame(Rectangle rectangle, Color backColor, FrameStyle style) + { + + } + + + public override void CPDrawReversibleLine(Point start, Point end, Color backColor) + { + + } + + + /* Scroll button: regular button + direction arrow */ + public override void CPDrawScrollButton(Graphics dc, Rectangle area, ScrollButton type, ButtonState state) + { + DrawScrollButtonPrimitive(dc, area, state); + + bool fill_rect = true; + int offset = 0; + + if ((state & ButtonState.Pushed) != 0) + offset = 1; + + // skip the border + Rectangle rect = new Rectangle(area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4); + + Point[] arrow = new Point[3]; + for (int i = 0; i < 3; i++) + arrow[i] = new Point(); + + Pen pen = SystemPens.ControlText; + + if ((state & ButtonState.Inactive) != 0) + { + pen = SystemPens.ControlDark; + } + + switch (type) + { + default: + case ScrollButton.Down: + int x_middle = (int)Math.Round(rect.Width / 2.0f) - 1; + int y_middle = (int)Math.Round(rect.Height / 2.0f) - 1; + if (x_middle == 1) + x_middle = 2; + + int triangle_height; + + if (rect.Height < 8) + { + triangle_height = 2; + fill_rect = false; + } + else if (rect.Height == 11) + { + triangle_height = 3; + } + else + { + triangle_height = (int)Math.Round(rect.Height / 3.0f); + } + + arrow[0].X = rect.X + x_middle; + arrow[0].Y = rect.Y + y_middle + triangle_height / 2; + + arrow[1].X = arrow[0].X + triangle_height - 1; + arrow[1].Y = arrow[0].Y - triangle_height + 1; + arrow[2].X = arrow[0].X - triangle_height + 1; + arrow[2].Y = arrow[1].Y; + + dc.DrawPolygon(pen, arrow); + + if ((state & ButtonState.Inactive) != 0) + { + dc.DrawLine(SystemPens.ControlLightLight, arrow[1].X + 1, arrow[1].Y + 1, arrow[0].X + 1, arrow[0].Y + 1); + dc.DrawLine(SystemPens.ControlLightLight, arrow[1].X, arrow[1].Y + 1, arrow[0].X + 1, arrow[0].Y); + } + + if (fill_rect) + { + for (int i = 0; i < arrow[0].Y - arrow[1].Y; i++) + { + dc.DrawLine(pen, arrow[1].X, arrow[1].Y + i, arrow[2].X, arrow[1].Y + i); + arrow[1].X -= 1; + arrow[2].X += 1; + } + } + break; + + case ScrollButton.Up: + x_middle = (int)Math.Round(rect.Width / 2.0f) - 1; + y_middle = (int)Math.Round(rect.Height / 2.0f); + if (x_middle == 1) + x_middle = 2; + + if (y_middle == 1) + y_middle = 2; + + if (rect.Height < 8) + { + triangle_height = 2; + fill_rect = false; + } + else if (rect.Height == 11) + { + triangle_height = 3; + } + else + { + triangle_height = (int)Math.Round(rect.Height / 3.0f); + } + + arrow[0].X = rect.X + x_middle; + arrow[0].Y = rect.Y + y_middle - triangle_height / 2; + + arrow[1].X = arrow[0].X + triangle_height - 1; + arrow[1].Y = arrow[0].Y + triangle_height - 1; + arrow[2].X = arrow[0].X - triangle_height + 1; + arrow[2].Y = arrow[1].Y; + + dc.DrawPolygon(pen, arrow); + + if ((state & ButtonState.Inactive) != 0) + { + dc.DrawLine(SystemPens.ControlLightLight, arrow[1].X + 1, arrow[1].Y + 1, arrow[2].X + 1, arrow[1].Y + 1); + } + + if (fill_rect) + { + for (int i = 0; i < arrow[1].Y - arrow[0].Y; i++) + { + dc.DrawLine(pen, arrow[2].X, arrow[1].Y - i, arrow[1].X, arrow[1].Y - i); + arrow[1].X -= 1; + arrow[2].X += 1; + } + } + break; + + case ScrollButton.Left: + y_middle = (int)Math.Round(rect.Height / 2.0f) - 1; + if (y_middle == 1) + y_middle = 2; + + int triangle_width; + + if (rect.Width < 8) + { + triangle_width = 2; + fill_rect = false; + } + else if (rect.Width == 11) + { + triangle_width = 3; + } + else + { + triangle_width = (int)Math.Round(rect.Width / 3.0f); + } + + arrow[0].X = rect.Left + triangle_width - 1; + arrow[0].Y = rect.Y + y_middle; + + if (arrow[0].X - 1 == rect.X) + arrow[0].X += 1; + + arrow[1].X = arrow[0].X + triangle_width - 1; + arrow[1].Y = arrow[0].Y - triangle_width + 1; + arrow[2].X = arrow[1].X; + arrow[2].Y = arrow[0].Y + triangle_width - 1; + + dc.DrawPolygon(pen, arrow); + + if ((state & ButtonState.Inactive) != 0) + { + dc.DrawLine(SystemPens.ControlLightLight, arrow[1].X + 1, arrow[1].Y + 1, arrow[2].X + 1, arrow[2].Y + 1); + } + + if (fill_rect) + { + for (int i = 0; i < arrow[2].X - arrow[0].X; i++) + { + dc.DrawLine(pen, arrow[2].X - i, arrow[1].Y, arrow[2].X - i, arrow[2].Y); + arrow[1].Y += 1; + arrow[2].Y -= 1; + } + } + break; + + case ScrollButton.Right: + y_middle = (int)Math.Round(rect.Height / 2.0f) - 1; + if (y_middle == 1) + y_middle = 2; + + if (rect.Width < 8) + { + triangle_width = 2; + fill_rect = false; + } + else if (rect.Width == 11) + { + triangle_width = 3; + } + else + { + triangle_width = (int)Math.Round(rect.Width / 3.0f); + } + + arrow[0].X = rect.Right - triangle_width - 1; + arrow[0].Y = rect.Y + y_middle; + + if (arrow[0].X - 1 == rect.X) + arrow[0].X += 1; + + arrow[1].X = arrow[0].X - triangle_width + 1; + arrow[1].Y = arrow[0].Y - triangle_width + 1; + arrow[2].X = arrow[1].X; + arrow[2].Y = arrow[0].Y + triangle_width - 1; + + dc.DrawPolygon(pen, arrow); + + if ((state & ButtonState.Inactive) != 0) + { + dc.DrawLine(SystemPens.ControlLightLight, arrow[0].X + 1, arrow[0].Y + 1, arrow[2].X + 1, arrow[2].Y + 1); + dc.DrawLine(SystemPens.ControlLightLight, arrow[0].X, arrow[0].Y + 1, arrow[2].X + 1, arrow[2].Y); + } + + if (fill_rect) + { + for (int i = 0; i < arrow[0].X - arrow[1].X; i++) + { + dc.DrawLine(pen, arrow[2].X + i, arrow[1].Y, arrow[2].X + i, arrow[2].Y); + arrow[1].Y += 1; + arrow[2].Y -= 1; + } + } + break; + } + } + + public override void CPDrawSelectionFrame(Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, + Color backColor) + { + + } + + + public override void CPDrawSizeGrip(Graphics dc, Color backColor, Rectangle bounds) + { + Pen pen_dark = ResPool.GetPen(WidgetPaint.Dark(backColor)); + Pen pen_light_light = ResPool.GetPen(WidgetPaint.LightLight(backColor)); + + for (int i = 2; i < bounds.Width - 2; i += 4) + { + dc.DrawLine(pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1); + dc.DrawLine(pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i); + dc.DrawLine(pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1); + } + } + + private void DrawStringDisabled20(Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString) + { + CPColor cpcolor = ResPool.GetCPColor(color); + + layoutRectangle.Offset(1, 1); + TextRenderer.DrawTextInternal(g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString); + + layoutRectangle.Offset(-1, -1); + TextRenderer.DrawTextInternal(g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString); + } + + public override void CPDrawStringDisabled(Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format) + { + CPColor cpcolor = ResPool.GetCPColor(color); + + dc.DrawString(s, font, ResPool.GetSolidBrush(cpcolor.LightLight), + new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height), + format); + dc.DrawString(s, font, ResPool.GetSolidBrush(cpcolor.Dark), layoutRectangle, format); + } + + public override void CPDrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format) + { + CPColor cpcolor = ResPool.GetCPColor(color); + + layoutRectangle.Offset(1, 1); + TextRenderer.DrawText(dc, s, font, layoutRectangle, cpcolor.LightLight, format); + + layoutRectangle.Offset(-1, -1); + TextRenderer.DrawText(dc, s, font, layoutRectangle, cpcolor.Dark, format); + } + + public override void CPDrawVisualStyleBorder(Graphics graphics, Rectangle bounds) + { + graphics.DrawRectangle(new System.Drawing.Pen(new SolidBrush(Application.CurrentSkin.VisualStyleBorderColor), Application.CurrentSkin.VisualStyleBorderWidth), bounds); + } + + private static void DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY, + int width, Color color, ButtonBorderStyle style, Border3DSide side) + { + DrawBorderInternal(graphics, (float)startX, (float)startY, (float)endX, (float)endY, + width, color, style, side); + } + + private static void DrawBorderInternal(Graphics graphics, float startX, float startY, float endX, float endY, + int width, Color color, ButtonBorderStyle style, Border3DSide side) + { + + Pen pen = null; + + switch (style) + { + case ButtonBorderStyle.Solid: + case ButtonBorderStyle.Inset: + case ButtonBorderStyle.Outset: + pen = ThemeEngine.Current.ResPool.GetDashPen(color, DashStyle.Solid); + break; + case ButtonBorderStyle.Dashed: + pen = ThemeEngine.Current.ResPool.GetDashPen(color, DashStyle.Dash); + break; + case ButtonBorderStyle.Dotted: + pen = ThemeEngine.Current.ResPool.GetDashPen(color, DashStyle.Dot); + break; + default: + case ButtonBorderStyle.None: + return; + } + + switch (style) + { + case ButtonBorderStyle.Outset: + { + Color colorGrade; + int hue, brightness, saturation; + int brightnessSteps; + int brightnessDownSteps; + + WidgetPaint.Color2HBS(color, out hue, out brightness, out saturation); + + brightnessDownSteps = brightness / width; + if (brightness > 127) + { + brightnessSteps = Math.Max(6, (160 - brightness) / width); + } + else + { + brightnessSteps = (127 - brightness) / width; + } + + for (int i = 0; i < width; i++) + { + switch (side) + { + case Border3DSide.Left: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Min(255, brightness + brightnessSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY + i, endX + i, endY - i); + break; + } + + case Border3DSide.Right: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Max(0, brightness - brightnessDownSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX - i, startY + i, endX - i, endY - i); + break; + } + + case Border3DSide.Top: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Min(255, brightness + brightnessSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY + i, endX - i, endY + i); + break; + } + + case Border3DSide.Bottom: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Max(0, brightness - brightnessDownSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY - i, endX - i, endY - i); + break; + } + } + } + break; + } + + case ButtonBorderStyle.Inset: + { + Color colorGrade; + int hue, brightness, saturation; + int brightnessSteps; + int brightnessDownSteps; + + WidgetPaint.Color2HBS(color, out hue, out brightness, out saturation); + + brightnessDownSteps = brightness / width; + if (brightness > 127) + { + brightnessSteps = Math.Max(6, (160 - brightness) / width); + } + else + { + brightnessSteps = (127 - brightness) / width; + } + + for (int i = 0; i < width; i++) + { + switch (side) + { + case Border3DSide.Left: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Max(0, brightness - brightnessDownSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY + i, endX + i, endY - i); + break; + } + + case Border3DSide.Right: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Min(255, brightness + brightnessSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX - i, startY + i, endX - i, endY - i); + break; + } + + case Border3DSide.Top: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Max(0, brightness - brightnessDownSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY + i, endX - i, endY + i); + break; + } + + case Border3DSide.Bottom: + { + colorGrade = WidgetPaint.HBS2Color(hue, Math.Min(255, brightness + brightnessSteps * (width - i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen(colorGrade); + graphics.DrawLine(pen, startX + i, startY - i, endX - i, endY - i); + break; + } + } + } + break; + } + + /* + I decided to have the for-loop duplicated for speed reasons; + that way we only have to switch once (as opposed to have the + for-loop around the switch) + */ + default: + { + switch (side) + { + case Border3DSide.Left: + { + for (int i = 0; i < width; i++) + { + graphics.DrawLine(pen, startX + i, startY + i, endX + i, endY - i); + } + break; + } + + case Border3DSide.Right: + { + for (int i = 0; i < width; i++) + { + graphics.DrawLine(pen, startX - i, startY + i, endX - i, endY - i); + } + break; + } + + case Border3DSide.Top: + { + for (int i = 0; i < width; i++) + { + graphics.DrawLine(pen, startX + i, startY + i, endX - i, endY + i); + } + break; + } + + case Border3DSide.Bottom: + { + for (int i = 0; i < width; i++) + { + graphics.DrawLine(pen, startX + i, startY - i, endX - i, endY - i); + } + break; + } + } + break; + } + } + } + + /* + This function actually draws the various caption elements. + This way we can scale them nicely, no matter what size, and they + still look like MS's scaled caption buttons. (as opposed to scaling a bitmap) + */ + + private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) + { + switch (button) + { + case CaptionButton.Close: + { + if (lineWidth < 2) + { + 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); + 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); + } + + graphics.DrawLine(pen, captionRect.Left + 2 * lineWidth + shift, captionRect.Top + 2 * lineWidth + shift, captionRect.Right - 2 * lineWidth + shift, captionRect.Bottom - 2 * lineWidth + shift); + graphics.DrawLine(pen, captionRect.Right - 2 * lineWidth + shift, captionRect.Top + 2 * lineWidth + shift, captionRect.Left + 2 * lineWidth + shift, captionRect.Bottom - 2 * lineWidth + shift); + return; + } + + case CaptionButton.Help: + { + StringFormat sf = new StringFormat(); + Font font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel); + + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + + graphics.DrawString("?", font, ResPool.GetSolidBrush(color), captionRect.X + captionRect.Width / 2 + shift, captionRect.Y + captionRect.Height / 2 + shift + lineWidth / 2, sf); + + sf.Dispose(); + font.Dispose(); + + return; + } + + case CaptionButton.Maximize: + { + /* Top 'caption bar' line */ + for (int i = 0; i < Math.Max(2, lineWidth); i++) + { + 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); + } + + /* Left side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + graphics.DrawLine(pen, captionRect.Left + lineWidth + shift + i, captionRect.Top + 2 * lineWidth + shift, captionRect.Left + lineWidth + shift + i, captionRect.Bottom - lineWidth + shift); + } + + /* Right side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + 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); + } + + /* Bottom line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + graphics.DrawLine(pen, captionRect.Left + lineWidth + shift, captionRect.Bottom - lineWidth + shift - i, captionRect.Right - lineWidth - lineWidth / 2 + shift, captionRect.Bottom - lineWidth + shift - i); + } + return; + } + + case CaptionButton.Minimize: + { + /* Bottom line */ + for (int i = 0; i < Math.Max(2, lineWidth); i++) + { + graphics.DrawLine(pen, captionRect.Left + lineWidth + shift, captionRect.Bottom - lineWidth + shift - i, captionRect.Right - 3 * lineWidth + shift, captionRect.Bottom - lineWidth + shift - i); + } + return; + } + + case CaptionButton.Restore: + { + /** First 'window' **/ + /* Top 'caption bar' line */ + for (int i = 0; i < Math.Max(2, lineWidth); i++) + { + 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); + } + + /* Left side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + 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); + } + + /* Right side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + 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); + } + + /* Bottom line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + 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); + } + + /** Second 'window' **/ + /* Top 'caption bar' line */ + for (int i = 0; i < Math.Max(2, lineWidth); i++) + { + 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); + } + + /* Left side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + graphics.DrawLine(pen, captionRect.Left + lineWidth + shift + i, captionRect.Top + 4 * lineWidth + shift + 1, captionRect.Left + lineWidth + shift + i, captionRect.Bottom - lineWidth + shift); + } + + /* Right side line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + 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); + } + + /* Bottom line */ + for (int i = 0; i < Math.Max(1, lineWidth / 2); i++) + { + graphics.DrawLine(pen, captionRect.Left + lineWidth + shift, captionRect.Bottom - lineWidth + shift - i, captionRect.Right - 3 * lineWidth - lineWidth / 2 + shift, captionRect.Bottom - lineWidth + shift - i); + } + + return; + } + + } + } + + /* Generic scroll button */ + public void DrawScrollButtonPrimitive(Graphics dc, Rectangle area, ButtonState state) + { + if ((state & ButtonState.Pushed) == ButtonState.Pushed) + { + dc.FillRectangle(SystemBrushes.Control, area.X + 1, + area.Y + 1, area.Width - 2, area.Height - 2); + + dc.DrawRectangle(SystemPens.ControlDark, area.X, + area.Y, area.Width, area.Height); + + return; + } + + Brush sb_control = SystemBrushes.Control; + Brush sb_lightlight = SystemBrushes.ControlLightLight; + Brush sb_dark = SystemBrushes.ControlDark; + Brush sb_darkdark = SystemBrushes.ControlDarkDark; + + dc.FillRectangle(sb_control, area.X, area.Y, area.Width, 1); + dc.FillRectangle(sb_control, area.X, area.Y, 1, area.Height); + + dc.FillRectangle(sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1); + dc.FillRectangle(sb_lightlight, area.X + 1, area.Y + 2, 1, + area.Height - 4); + + dc.FillRectangle(sb_dark, area.X + 1, area.Y + area.Height - 2, + area.Width - 2, 1); + + dc.FillRectangle(sb_darkdark, area.X, area.Y + area.Height - 1, + area.Width, 1); + + dc.FillRectangle(sb_dark, area.X + area.Width - 2, + area.Y + 1, 1, area.Height - 3); + + dc.FillRectangle(sb_darkdark, area.X + area.Width - 1, + area.Y, 1, area.Height - 1); + + dc.FillRectangle(sb_control, area.X + 2, + area.Y + 2, area.Width - 4, area.Height - 4); + + } + + public override void CPDrawBorderStyle(Graphics dc, Rectangle area, BorderStyle border_style) + { + switch (border_style) + { + case BorderStyle.Fixed3D: + dc.DrawLine(ResPool.GetPen(ColorControlDark), area.X, area.Y, area.X + area.Width, area.Y); + dc.DrawLine(ResPool.GetPen(ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height); + dc.DrawLine(ResPool.GetPen(ColorControlLight), area.X, area.Y + area.Height - 1, area.X + area.Width, + area.Y + area.Height - 1); + dc.DrawLine(ResPool.GetPen(ColorControlLight), area.X + area.Width - 1, area.Y, area.X + area.Width - 1, + area.Y + area.Height); + + dc.DrawLine(ResPool.GetPen(ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2); + dc.DrawLine(ResPool.GetPen(ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2); + dc.DrawLine(ResPool.GetPen(ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3); + dc.DrawLine(ResPool.GetPen(ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1); + break; + case BorderStyle.FixedSingle: + dc.DrawRectangle(ResPool.GetPen(ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1); + break; + case BorderStyle.None: + default: + break; + } + + } + #endregion // WidgetPaint + + + } //class +} diff --git a/source/ShiftUI/Theming/ThemeVisualStyles.cs b/source/ShiftUI/Theming/ThemeVisualStyles.cs new file mode 100644 index 0000000..d0bd4ea --- /dev/null +++ b/source/ShiftUI/Theming/ThemeVisualStyles.cs @@ -0,0 +1,2162 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// Copyright (c) 2004-2006 Novell, Inc. +// +// Authors: +// George Giolfan, [email protected] +// Ernesto Carrea, [email protected] + +using System.Drawing; +using System.Drawing.Drawing2D; +using ShiftUI.VisualStyles; +using System; + +namespace ShiftUI +{ + /// <summary> + /// VisualStyles theme. + /// </summary> + /// <remarks> + /// This theme uses only the managed VisualStyles API. + /// To select it, set MONO_THEME to VisualStyles and call <see cref="Application.EnableVisualStyles"/>. + /// </remarks> + class ThemeVisualStyles : ThemeWin32Classic + { + static bool render_client_areas; + static bool render_non_client_areas; + + public ThemeVisualStyles () + { + Update (); + } + + public override void ResetDefaults () + { + base.ResetDefaults (); + Update (); + } + + static void Update () + { + bool visual_styles_is_enabled_by_user = VisualStyleInformation.IsEnabledByUser; + render_client_areas = + visual_styles_is_enabled_by_user && + (Application.VisualStyleState == VisualStyleState.ClientAndNonClientAreasEnabled || + Application.VisualStyleState == VisualStyleState.ClientAreaEnabled); + render_non_client_areas = + visual_styles_is_enabled_by_user && + (Application.VisualStyleState == VisualStyleState.ClientAndNonClientAreasEnabled/* || + Application.VisualStyleState == VisualStyleState.NonClientAreaEnabled*/); + } + + public static bool RenderClientAreas { + get { return render_client_areas; } + } + + #region Widgets + #region ButtonBase + public override void DrawButtonBase (Graphics dc, Rectangle clip_area, ButtonBase button) + { + if (button.FlatStyle == FlatStyle.System) { + ButtonRenderer.DrawButton ( + dc, + new Rectangle (Point.Empty, button.Size), + button.Text, + button.Font, + button.TextFormatFlags, + null, + Rectangle.Empty, + ShouldPaintFocusRectagle (button), + GetPushButtonState (button) + ); + return; + } + base.DrawButtonBase (dc, clip_area, button); + } + static PushButtonState GetPushButtonState (ButtonBase button) + { + if (!button.Enabled) + return PushButtonState.Disabled; + if (button.Pressed) + return PushButtonState.Pressed; + if (button.Entered) + return PushButtonState.Hot; + if (button.IsDefault || button.Focused || button.paint_as_acceptbutton) + return PushButtonState.Default; + return PushButtonState.Normal; + } + #endregion + + #region Button 2.0 + public override void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea) + { + if (!RenderClientAreas || + !button.UseVisualStyleBackColor) { + base.DrawButtonBackground (g, button, clipArea); + return; + } + ButtonRenderer.GetPushButtonRenderer (GetPushButtonState (button)).DrawBackground (g, new Rectangle (Point.Empty, button.Size)); + } + #endregion + + #region CheckBox + protected override void CheckBox_DrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle) + { + if (checkbox.Appearance == Appearance.Normal && checkbox.FlatStyle == FlatStyle.System) { + CheckBoxRenderer.DrawCheckBox ( + dc, + new Point (checkbox_rectangle.Left, checkbox_rectangle.Top), + GetCheckBoxState (checkbox) + ); + return; + } + base.CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle); + } + static CheckBoxState GetCheckBoxState (CheckBox checkBox) + { + switch (checkBox.CheckState) { + case CheckState.Checked: + if (!checkBox.Enabled) + return CheckBoxState.CheckedDisabled; + else if (checkBox.Pressed) + return CheckBoxState.CheckedPressed; + else if (checkBox.Entered) + return CheckBoxState.CheckedHot; + return CheckBoxState.CheckedNormal; + case CheckState.Indeterminate: + if (!checkBox.Enabled) + return CheckBoxState.MixedDisabled; + else if (checkBox.Pressed) + return CheckBoxState.MixedPressed; + else if (checkBox.Entered) + return CheckBoxState.MixedHot; + return CheckBoxState.MixedNormal; + default: + if (!checkBox.Enabled) + return CheckBoxState.UncheckedDisabled; + else if (checkBox.Pressed) + return CheckBoxState.UncheckedPressed; + else if (checkBox.Entered) + return CheckBoxState.UncheckedHot; + return CheckBoxState.UncheckedNormal; + } + } + #endregion + #region ComboBox + static VisualStyleElement ComboBoxGetVisualStyleElement (ComboBox comboBox, ButtonState state) + { + if (state == ButtonState.Inactive) + return VisualStyleElement.ComboBox.DropDownButton.Disabled; + if (state == ButtonState.Pushed) + return VisualStyleElement.ComboBox.DropDownButton.Pressed; + if (comboBox.DropDownButtonEntered) + return VisualStyleElement.ComboBox.DropDownButton.Hot; + return VisualStyleElement.ComboBox.DropDownButton.Normal; + } + public override void ComboBoxDrawNormalDropDownButton (ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state) + { + if (!RenderClientAreas) { + base.ComboBoxDrawNormalDropDownButton (comboBox, g, clippingArea, area, state); + return; + } + VisualStyleElement element = ComboBoxGetVisualStyleElement (comboBox, state); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ComboBoxDrawNormalDropDownButton (comboBox, g, clippingArea, area, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, area, clippingArea); + } + public override bool ComboBoxNormalDropDownButtonHasTransparentBackground (ComboBox comboBox, ButtonState state) + { + if (!RenderClientAreas) + return base.ComboBoxNormalDropDownButtonHasTransparentBackground (comboBox, state); + VisualStyleElement element = ComboBoxGetVisualStyleElement (comboBox, state); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.ComboBoxNormalDropDownButtonHasTransparentBackground (comboBox, state); + return new VisualStyleRenderer (element).IsBackgroundPartiallyTransparent (); + } + public override bool ComboBoxDropDownButtonHasHotElementStyle (ComboBox comboBox) + { + if (!RenderClientAreas) + return base.ComboBoxDropDownButtonHasHotElementStyle (comboBox); + switch (comboBox.FlatStyle) { + case FlatStyle.Flat: + case FlatStyle.Popup: + return base.ComboBoxDropDownButtonHasHotElementStyle (comboBox); + } + return true; + } + static bool ComboBoxShouldPaintBackground (ComboBox comboBox) + { + if (comboBox.DropDownStyle == ComboBoxStyle.Simple) + return false; + switch (comboBox.FlatStyle) { + case FlatStyle.Flat: + case FlatStyle.Popup: + return false; + } + return true; + } + public override void ComboBoxDrawBackground (ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style) + { + if (!RenderClientAreas || !ComboBoxShouldPaintBackground (comboBox)) { + base.ComboBoxDrawBackground (comboBox, g, clippingArea, style); + return; + } + VisualStyleElement element; + if (!comboBox.Enabled) + element = VisualStyleElement.ComboBox.Border.Disabled; + else if (comboBox.Entered) + element = VisualStyleElement.ComboBox.Border.Hot; + else if (comboBox.Focused) + element = VisualStyleElement.ComboBox.Border.Focused; + else + element = VisualStyleElement.ComboBox.Border.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ComboBoxDrawBackground (comboBox, g, clippingArea, style); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, new Rectangle (Point.Empty, comboBox.Size), clippingArea); + } + public override bool CombBoxBackgroundHasHotElementStyle (ComboBox comboBox) + { + if (RenderClientAreas && + ComboBoxShouldPaintBackground (comboBox) && + comboBox.Enabled && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ComboBox.Border.Hot)) + return true; + return base.CombBoxBackgroundHasHotElementStyle (comboBox); + } + #endregion + #region WidgetPaint + #region DrawButton + public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat || + (state & ButtonState.Checked) == ButtonState.Checked) { + base.CPDrawButton (dc, rectangle, state); + return; + } + VisualStyleElement element; + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.PushButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.PushButton.Pressed; + else + element = VisualStyleElement.Button.PushButton.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawButton (dc, rectangle, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, rectangle); + } + #endregion + #region DrawCaptionButton + public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat || + (state & ButtonState.Checked) == ButtonState.Checked) { + base.CPDrawCaptionButton (graphics, rectangle, button, state); + return; + } + VisualStyleElement element = GetCaptionButtonVisualStyleElement (button, state); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawCaptionButton (graphics, rectangle, button, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (graphics, rectangle); + } + static VisualStyleElement GetCaptionButtonVisualStyleElement (CaptionButton button, ButtonState state) + { + switch (button) { + case CaptionButton.Minimize: + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + return VisualStyleElement.Window.MinButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + return VisualStyleElement.Window.MinButton.Pressed; + else + return VisualStyleElement.Window.MinButton.Normal; + case CaptionButton.Maximize: + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + return VisualStyleElement.Window.MaxButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + return VisualStyleElement.Window.MaxButton.Pressed; + else + return VisualStyleElement.Window.MaxButton.Normal; + case CaptionButton.Close: + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + return VisualStyleElement.Window.CloseButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + return VisualStyleElement.Window.CloseButton.Pressed; + else + return VisualStyleElement.Window.CloseButton.Normal; + case CaptionButton.Restore: + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + return VisualStyleElement.Window.RestoreButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + return VisualStyleElement.Window.RestoreButton.Pressed; + else + return VisualStyleElement.Window.RestoreButton.Normal; + default: + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + return VisualStyleElement.Window.HelpButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + return VisualStyleElement.Window.HelpButton.Pressed; + else + return VisualStyleElement.Window.HelpButton.Normal; + } + } + #endregion + #region DrawCheckBox + public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat) { + base.CPDrawCheckBox (dc, rectangle, state); + return; + } + VisualStyleElement element; + if ((state & ButtonState.Checked) == ButtonState.Checked) + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.CheckBox.CheckedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.CheckBox.CheckedPressed; + else + element = VisualStyleElement.Button.CheckBox.CheckedNormal; + else + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.CheckBox.UncheckedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.CheckBox.UncheckedPressed; + else + element = VisualStyleElement.Button.CheckBox.UncheckedNormal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawCheckBox (dc, rectangle, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, rectangle); + } + #endregion + #region DrawComboButton + public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat || + (state & ButtonState.Checked) == ButtonState.Checked) { + base.CPDrawComboButton (graphics, rectangle, state); + return; + } + VisualStyleElement element; + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.ComboBox.DropDownButton.Disabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.ComboBox.DropDownButton.Pressed; + else + element = VisualStyleElement.ComboBox.DropDownButton.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawComboButton (graphics, rectangle, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (graphics, rectangle); + } + #endregion + #region DrawMixedCheckBox + public override void CPDrawMixedCheckBox (Graphics dc, Rectangle rectangle, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat) { + base.CPDrawMixedCheckBox (dc, rectangle, state); + return; + } + VisualStyleElement element; + if ((state & ButtonState.Checked) == ButtonState.Checked) + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.CheckBox.MixedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.CheckBox.MixedPressed; + else + element = VisualStyleElement.Button.CheckBox.MixedNormal; + else + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.CheckBox.UncheckedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.CheckBox.UncheckedPressed; + else + element = VisualStyleElement.Button.CheckBox.UncheckedNormal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawMixedCheckBox (dc, rectangle, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, rectangle); + } + #endregion + #region DrawRadioButton + public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat) { + base.CPDrawRadioButton (dc, rectangle, state); + return; + } + VisualStyleElement element; + if ((state & ButtonState.Checked) == ButtonState.Checked) + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.RadioButton.CheckedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.RadioButton.CheckedPressed; + else + element = VisualStyleElement.Button.RadioButton.CheckedNormal; + else + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + element = VisualStyleElement.Button.RadioButton.UncheckedDisabled; + else if ((state & ButtonState.Pushed) == ButtonState.Pushed) + element = VisualStyleElement.Button.RadioButton.UncheckedPressed; + else + element = VisualStyleElement.Button.RadioButton.UncheckedNormal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawRadioButton (dc, rectangle, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, rectangle); + } + #endregion + #region DrawScrollButton + public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state) + { + if (!RenderClientAreas || + (state & ButtonState.Flat) == ButtonState.Flat || + (state & ButtonState.Checked) == ButtonState.Checked) { + base.CPDrawScrollButton (dc, area, type, state); + return; + } + VisualStyleElement element = GetScrollButtonVisualStyleElement (type, state); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.CPDrawScrollButton (dc, area, type, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, area); + } + static VisualStyleElement GetScrollButtonVisualStyleElement (ScrollButton type, ButtonState state) + { + switch (type) { + case ScrollButton.Left: + if (IsDisabled (state)) + return VisualStyleElement.ScrollBar.ArrowButton.LeftDisabled; + else if (IsPressed (state)) + return VisualStyleElement.ScrollBar.ArrowButton.LeftPressed; + else + return VisualStyleElement.ScrollBar.ArrowButton.LeftNormal; + case ScrollButton.Right: + if (IsDisabled (state)) + return VisualStyleElement.ScrollBar.ArrowButton.RightDisabled; + else if (IsPressed (state)) + return VisualStyleElement.ScrollBar.ArrowButton.RightPressed; + else + return VisualStyleElement.ScrollBar.ArrowButton.RightNormal; + case ScrollButton.Up: + if (IsDisabled (state)) + return VisualStyleElement.ScrollBar.ArrowButton.UpDisabled; + else if (IsPressed (state)) + return VisualStyleElement.ScrollBar.ArrowButton.UpPressed; + else + return VisualStyleElement.ScrollBar.ArrowButton.UpNormal; + default: + if (IsDisabled (state)) + return VisualStyleElement.ScrollBar.ArrowButton.DownDisabled; + else if (IsPressed (state)) + return VisualStyleElement.ScrollBar.ArrowButton.DownPressed; + else + return VisualStyleElement.ScrollBar.ArrowButton.DownNormal; + } + } + static bool IsDisabled (ButtonState state) + { + return (state & ButtonState.Inactive) == ButtonState.Inactive; + } + static bool IsPressed (ButtonState state) + { + return (state & ButtonState.Pushed) == ButtonState.Pushed; + } + #endregion + #endregion + /* FIXME: I SAID NO. + #region DataGridView + #region DataGridViewHeaderCell + #region DataGridViewRowHeaderCell + public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + if (!RenderClientAreas || + !cell.DataGridView.EnableHeadersVisualStyles) + return base.DataGridViewRowHeaderCellDrawBackground (cell, g, bounds); + VisualStyleElement element = DataGridViewRowHeaderCellGetVisualStyleElement (cell); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.DataGridViewRowHeaderCellDrawBackground (cell, g, bounds); + bounds.Width--; + Bitmap bitmap = new Bitmap (bounds.Height, bounds.Width); + Graphics bitmap_g = Graphics.FromImage (bitmap); + Rectangle bitmap_rectangle = new Rectangle (Point.Empty, bitmap.Size); + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + if (!AreEqual (element, VisualStyleElement.Header.Item.Normal) && renderer.IsBackgroundPartiallyTransparent ()) + new VisualStyleRenderer (VisualStyleElement.Header.Item.Normal).DrawBackground (bitmap_g, bitmap_rectangle); + renderer.DrawBackground (bitmap_g, bitmap_rectangle); + bitmap_g.Dispose (); + g.Transform = new Matrix(0, 1, 1, 0, 0, 0); + g.DrawImage (bitmap, bounds.Y, bounds.X); + bitmap.Dispose (); + g.ResetTransform (); + return true; + } + public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell) + { + if (!RenderClientAreas || + !cell.DataGridView.EnableHeadersVisualStyles || !VisualStyleRenderer.IsElementDefined (DataGridViewRowHeaderCellGetVisualStyleElement (cell))) + return base.DataGridViewRowHeaderCellDrawSelectionBackground (cell); + return true; + } + public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + if (!RenderClientAreas || + !cell.DataGridView.EnableHeadersVisualStyles || !VisualStyleRenderer.IsElementDefined (DataGridViewRowHeaderCellGetVisualStyleElement (cell))) + return base.DataGridViewRowHeaderCellDrawBorder (cell, g, bounds); + g.DrawLine (cell.GetBorderPen (), bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom - 1); + return true; + } + static VisualStyleElement DataGridViewRowHeaderCellGetVisualStyleElement (DataGridViewRowHeaderCell cell) + { + if (cell.DataGridView.PressedHeaderCell == cell) + return VisualStyleElement.Header.Item.Pressed; + if (cell.DataGridView.EnteredHeaderCell == cell) + return VisualStyleElement.Header.Item.Hot; + if (cell.OwningRow.SelectedInternal) + return VisualStyleElement.Header.Item.Pressed; + return VisualStyleElement.Header.Item.Normal; + } + #endregion + #region DataGridViewColumnHeaderCell + public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + if (!RenderClientAreas || + !cell.DataGridView.EnableHeadersVisualStyles || cell is DataGridViewTopLeftHeaderCell) + return base.DataGridViewColumnHeaderCellDrawBackground (cell, g, bounds); + VisualStyleElement element = DataGridViewColumnHeaderCellGetVisualStyleElement (cell); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.DataGridViewColumnHeaderCellDrawBackground (cell, g, bounds); + bounds.Height--; + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + if (!AreEqual (element, VisualStyleElement.Header.Item.Normal) && renderer.IsBackgroundPartiallyTransparent ()) + new VisualStyleRenderer (VisualStyleElement.Header.Item.Normal).DrawBackground (g, bounds); + renderer.DrawBackground (g, bounds); + return true; + } + public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + if (!RenderClientAreas || + !cell.DataGridView.EnableHeadersVisualStyles || + cell is DataGridViewTopLeftHeaderCell || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.Header.Item.Normal)) + return base.DataGridViewColumnHeaderCellDrawBorder (cell, g, bounds); + g.DrawLine (cell.GetBorderPen (), bounds.Left, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1); + return true; + } + static VisualStyleElement DataGridViewColumnHeaderCellGetVisualStyleElement (DataGridViewColumnHeaderCell cell) + { + if (cell.DataGridView.PressedHeaderCell == cell) + return VisualStyleElement.Header.Item.Pressed; + if (cell.DataGridView.EnteredHeaderCell == cell) + return VisualStyleElement.Header.Item.Hot; + return VisualStyleElement.Header.Item.Normal; + } + #endregion + public override bool DataGridViewHeaderCellHasPressedStyle (DataGridView dataGridView) + { + if (!RenderClientAreas || + !dataGridView.EnableHeadersVisualStyles || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.Header.Item.Pressed)) + return base.DataGridViewHeaderCellHasPressedStyle (dataGridView); + return true; + } + public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView) + { + if (!RenderClientAreas || + !dataGridView.EnableHeadersVisualStyles || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.Header.Item.Hot)) + return base.DataGridViewHeaderCellHasHotStyle (dataGridView); + return true; + } + #endregion + #endregion*/ + + #region DateTimePicker + #region Border + protected override void DateTimePickerDrawBorder (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.DateTimePickerDrawBorder (dateTimePicker, g, clippingArea); + return; + } + VisualStyleElement element; + if (!dateTimePicker.Enabled) + element = VisualStyleElement.DatePicker.DateBorder.Disabled; + else if (dateTimePicker.Entered) + element = VisualStyleElement.DatePicker.DateBorder.Hot; + else if (dateTimePicker.Focused) + element = VisualStyleElement.DatePicker.DateBorder.Focused; + else + element = VisualStyleElement.DatePicker.DateBorder.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DateTimePickerDrawBorder (dateTimePicker, g, clippingArea); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, new Rectangle (Point.Empty, dateTimePicker.Size), clippingArea); + } + public override bool DateTimePickerBorderHasHotElementStyle { + get { + if (RenderClientAreas && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.DatePicker.DateBorder.Hot)) + return true; + return base.DateTimePickerBorderHasHotElementStyle; + } + } + #endregion + #region Drop down button + protected override void DateTimePickerDrawDropDownButton (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.DateTimePickerDrawDropDownButton (dateTimePicker, g, clippingArea); + return; + } + VisualStyleElement element; + if (!dateTimePicker.Enabled) + element = VisualStyleElement.DatePicker.ShowCalendarButtonRight.Disabled; + else if (dateTimePicker.is_drop_down_visible) + element = VisualStyleElement.DatePicker.ShowCalendarButtonRight.Pressed; + else if (dateTimePicker.DropDownButtonEntered) + element = VisualStyleElement.DatePicker.ShowCalendarButtonRight.Hot; + else + element = VisualStyleElement.DatePicker.ShowCalendarButtonRight.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DateTimePickerDrawDropDownButton (dateTimePicker, g, clippingArea); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, dateTimePicker.drop_down_arrow_rect, clippingArea); + } + //TODO: Until somebody figures out how to obtain the proper width this will need to be updated when new Windows versions/themes are released. + const int DateTimePickerDropDownWidthOnWindowsVista = 34; + const int DateTimePickerDropDownHeightOnWindowsVista = 20; + public override Rectangle DateTimePickerGetDropDownButtonArea (DateTimePicker dateTimePicker) + { + if (!RenderClientAreas) + return base.DateTimePickerGetDropDownButtonArea (dateTimePicker); + VisualStyleElement element = VisualStyleElement.DatePicker.ShowCalendarButtonRight.Pressed; + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.DateTimePickerGetDropDownButtonArea (dateTimePicker); + Size size = new Size (DateTimePickerDropDownWidthOnWindowsVista, DateTimePickerDropDownHeightOnWindowsVista); + return new Rectangle (dateTimePicker.Width - size.Width, 0, size.Width, size.Height); + } + public override Rectangle DateTimePickerGetDateArea (DateTimePicker dateTimePicker) + { + if (!RenderClientAreas || + dateTimePicker.ShowUpDown) + return base.DateTimePickerGetDateArea (dateTimePicker); + VisualStyleElement element = VisualStyleElement.DatePicker.DateBorder.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.DateTimePickerGetDateArea (dateTimePicker); + Graphics g = dateTimePicker.CreateGraphics (); + Rectangle result = new VisualStyleRenderer (element).GetBackgroundContentRectangle (g, dateTimePicker.ClientRectangle); + g.Dispose (); + result.Width -= DateTimePickerDropDownWidthOnWindowsVista; + return result; + } + public override bool DateTimePickerDropDownButtonHasHotElementStyle { + get { + if (RenderClientAreas && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.DatePicker.ShowCalendarButtonRight.Hot)) + return true; + return base.DateTimePickerDropDownButtonHasHotElementStyle; + } + } + #endregion + #endregion + #region ListView + protected override void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.ListViewDrawColumnHeaderBackground (listView, columnHeader, g, area, clippingArea); + return; + } + VisualStyleElement element; + if (listView.HeaderStyle == ColumnHeaderStyle.Clickable) + if (columnHeader.Pressed) + element = VisualStyleElement.Header.Item.Pressed; + else if (columnHeader == listView.EnteredColumnHeader) + element = VisualStyleElement.Header.Item.Hot; + else + element = VisualStyleElement.Header.Item.Normal; + else + element = VisualStyleElement.Header.Item.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ListViewDrawColumnHeaderBackground (listView, columnHeader, g, area, clippingArea); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, area, clippingArea); + } + protected override void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.ListViewDrawUnusedHeaderBackground (listView, g, area, clippingArea); + return; + } + VisualStyleElement element = VisualStyleElement.Header.Item.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ListViewDrawUnusedHeaderBackground (listView, g, area, clippingArea); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, area, clippingArea); + } + public override bool ListViewHasHotHeaderStyle { + get { + if (!RenderClientAreas || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.Header.Item.Hot)) + return base.ListViewHasHotHeaderStyle; + return true; + } + } + public override int ListViewGetHeaderHeight (ListView listView, Font font) + { + if (!RenderClientAreas) + return base.ListViewGetHeaderHeight (listView, font); + VisualStyleElement element = VisualStyleElement.Header.Item.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.ListViewGetHeaderHeight (listView, font); + Widget control = null; + Graphics g; + if (listView == null) { + control = new Widget (); + g = control.CreateGraphics (); + } else + g = listView.CreateGraphics (); + int result = new VisualStyleRenderer (element).GetPartSize (g, ThemeSizeType.True).Height; + g.Dispose (); + if (listView == null) + control.Dispose (); + return result; + } + #endregion + #region GroupBox + public override void DrawGroupBox (Graphics dc, Rectangle area, GroupBox box) + { + GroupBoxRenderer.DrawGroupBox ( + dc, + new Rectangle (Point.Empty, box.Size), + box.Text, + box.Font, + box.ForeColor == GroupBox.DefaultForeColor ? Color.Empty : box.ForeColor, + box.Enabled ? GroupBoxState.Normal : GroupBoxState.Disabled); + } + #endregion + #region Managed window + Rectangle ManagedWindowGetTitleBarRectangle (InternalWindowManager wm) + { + return new Rectangle (0, 0, wm.Form.Width, ManagedWindowTitleBarHeight (wm) + ManagedWindowBorderWidth (wm) * (wm.IsMinimized ? 2 : 1)); + } + Region ManagedWindowGetWindowRegion (Form form) + { + if (form.WindowManager is MdiWindowManager && form.WindowManager.IsMaximized) + return null; + VisualStyleElement title_bar_element = ManagedWindowGetTitleBarVisualStyleElement (form.WindowManager); + if (!VisualStyleRenderer.IsElementDefined (title_bar_element)) + return null; + VisualStyleRenderer renderer = new VisualStyleRenderer (title_bar_element); + if (!renderer.IsBackgroundPartiallyTransparent ()) + return null; + IDeviceContext dc = GetMeasurementDeviceContext (); + Rectangle title_bar_rectangle = ManagedWindowGetTitleBarRectangle (form.WindowManager); + Region region = renderer.GetBackgroundRegion (dc, title_bar_rectangle); + ReleaseMeasurementDeviceContext (dc); + region.Union (new Rectangle (0, title_bar_rectangle.Bottom, form.Width, form.Height)); + return region; + } + public override void ManagedWindowOnSizeInitializedOrChanged (Form form) + { + base.ManagedWindowOnSizeInitializedOrChanged (form); + if (!render_non_client_areas) + return; + form.Region = ManagedWindowGetWindowRegion (form); + } + protected override Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm) + { + if (!render_non_client_areas) + return base.ManagedWindowDrawTitleBarAndBorders (dc, clip, wm); + VisualStyleElement title_bar_element = ManagedWindowGetTitleBarVisualStyleElement (wm); + VisualStyleElement left_border_element; + VisualStyleElement right_border_element; + VisualStyleElement bottom_border_element; + ManagedWindowGetBorderVisualStyleElements (wm, out left_border_element, out right_border_element, out bottom_border_element); + if (!VisualStyleRenderer.IsElementDefined (title_bar_element) || + (!wm.IsMinimized && ( + !VisualStyleRenderer.IsElementDefined (left_border_element) || + !VisualStyleRenderer.IsElementDefined (right_border_element) || + !VisualStyleRenderer.IsElementDefined (bottom_border_element)))) + return base.ManagedWindowDrawTitleBarAndBorders (dc, clip, wm); + VisualStyleRenderer renderer = new VisualStyleRenderer (title_bar_element); + Rectangle title_bar_rectangle = ManagedWindowGetTitleBarRectangle (wm); + renderer.DrawBackground (dc, title_bar_rectangle, clip); + if (!wm.IsMinimized) { + int border_width = ManagedWindowBorderWidth (wm); + renderer.SetParameters (left_border_element); + renderer.DrawBackground (dc, new Rectangle ( + 0, + title_bar_rectangle.Bottom, + border_width, + wm.Form.Height - title_bar_rectangle.Bottom + ), clip); + renderer.SetParameters (right_border_element); + renderer.DrawBackground (dc, new Rectangle ( + wm.Form.Width - border_width, + title_bar_rectangle.Bottom, + border_width, + wm.Form.Height - title_bar_rectangle.Bottom + ), clip); + renderer.SetParameters (bottom_border_element); + renderer.DrawBackground (dc, new Rectangle ( + 0, + wm.Form.Height - border_width, + wm.Form.Width, + border_width + ), clip); + } + return title_bar_rectangle; + } + static FormWindowState ManagedWindowGetWindowState (InternalWindowManager wm) + { + return wm.GetWindowState (); + } + static bool ManagedWindowIsDisabled (InternalWindowManager wm) + { + return !wm.Form.Enabled; + } + static bool ManagedWindowIsActive (InternalWindowManager wm) + { + return wm.IsActive; + } + static VisualStyleElement ManagedWindowGetTitleBarVisualStyleElement (InternalWindowManager wm) + { + if (wm.IsToolWindow) + #region Small window + switch (ManagedWindowGetWindowState (wm)) { + case FormWindowState.Minimized: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.SmallMinCaption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.SmallMinCaption.Active; + return VisualStyleElement.Window.SmallMinCaption.Inactive; + case FormWindowState.Maximized: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.SmallMaxCaption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.SmallMaxCaption.Active; + return VisualStyleElement.Window.SmallMaxCaption.Inactive; + default: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.SmallCaption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.SmallCaption.Active; + return VisualStyleElement.Window.SmallCaption.Inactive; + } + #endregion + else + #region Normal window + switch (ManagedWindowGetWindowState (wm)) { + case FormWindowState.Minimized: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.MinCaption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.MinCaption.Active; + return VisualStyleElement.Window.MinCaption.Inactive; + case FormWindowState.Maximized: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.MaxCaption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.MaxCaption.Active; + return VisualStyleElement.Window.MaxCaption.Inactive; + default: + if (ManagedWindowIsDisabled (wm)) + return VisualStyleElement.Window.Caption.Disabled; + else if (ManagedWindowIsActive (wm)) + return VisualStyleElement.Window.Caption.Active; + return VisualStyleElement.Window.Caption.Inactive; + } + #endregion + } + static void ManagedWindowGetBorderVisualStyleElements (InternalWindowManager wm, out VisualStyleElement left, out VisualStyleElement right, out VisualStyleElement bottom) + { + bool active = !ManagedWindowIsDisabled (wm) && ManagedWindowIsActive (wm); + if (wm.IsToolWindow) { + if (active) { + left = VisualStyleElement.Window.SmallFrameLeft.Active; + right = VisualStyleElement.Window.SmallFrameRight.Active; + bottom = VisualStyleElement.Window.SmallFrameBottom.Active; + } else { + left = VisualStyleElement.Window.SmallFrameLeft.Inactive; + right = VisualStyleElement.Window.SmallFrameRight.Inactive; + bottom = VisualStyleElement.Window.SmallFrameBottom.Inactive; + } + } else { + if (active) { + left = VisualStyleElement.Window.FrameLeft.Active; + right = VisualStyleElement.Window.FrameRight.Active; + bottom = VisualStyleElement.Window.FrameBottom.Active; + } else { + left = VisualStyleElement.Window.FrameLeft.Inactive; + right = VisualStyleElement.Window.FrameRight.Inactive; + bottom = VisualStyleElement.Window.FrameBottom.Inactive; + } + } + } + public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form) + { + if (render_non_client_areas && (button.State & ButtonState.Inactive) != ButtonState.Inactive) { + VisualStyleElement element; + if (ManagedWindowIsMaximizedMdiChild (form)) + switch (button.Caption) { + case CaptionButton.Close: + element = VisualStyleElement.Window.MdiCloseButton.Hot; + break; + case CaptionButton.Help: + element = VisualStyleElement.Window.MdiHelpButton.Hot; + break; + case CaptionButton.Minimize: + element = VisualStyleElement.Window.MdiMinButton.Hot; + break; + default: + element = VisualStyleElement.Window.MdiRestoreButton.Hot; + break; + } + else if (form.WindowManager.IsToolWindow) + element = VisualStyleElement.Window.SmallCloseButton.Hot; + else + switch (button.Caption) { + case CaptionButton.Close: + element = VisualStyleElement.Window.CloseButton.Hot; + break; + case CaptionButton.Help: + element = VisualStyleElement.Window.HelpButton.Hot; + break; + case CaptionButton.Maximize: + element = VisualStyleElement.Window.MaxButton.Hot; + break; + case CaptionButton.Minimize: + element = VisualStyleElement.Window.MinButton.Hot; + break; + default: + element = VisualStyleElement.Window.RestoreButton.Hot; + break; + } + if (VisualStyleRenderer.IsElementDefined (element)) + return true; + } + return base.ManagedWindowTitleButtonHasHotElementStyle (button, form); + } + static bool ManagedWindowIsMaximizedMdiChild (Form form) + { + return form.WindowManager is MdiWindowManager && + ManagedWindowGetWindowState (form.WindowManager) == FormWindowState.Maximized; + } + static bool ManagedWindowTitleButtonIsDisabled (TitleButton button, InternalWindowManager wm) + { + return (button.State & ButtonState.Inactive) == ButtonState.Inactive; + } + static bool ManagedWindowTitleButtonIsPressed (TitleButton button) + { + return (button.State & ButtonState.Pushed) == ButtonState.Pushed; + } + static VisualStyleElement ManagedWindowGetTitleButtonVisualStyleElement (TitleButton button, Form form) + { + if (form.WindowManager.IsToolWindow) { + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.SmallCloseButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.SmallCloseButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.SmallCloseButton.Hot; + return VisualStyleElement.Window.SmallCloseButton.Normal; + } + switch (button.Caption) { + case CaptionButton.Close: + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.CloseButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.CloseButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.CloseButton.Hot; + return VisualStyleElement.Window.CloseButton.Normal; + case CaptionButton.Help: + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.HelpButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.HelpButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.HelpButton.Hot; + return VisualStyleElement.Window.HelpButton.Normal; + case CaptionButton.Maximize: + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.MaxButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MaxButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MaxButton.Hot; + return VisualStyleElement.Window.MaxButton.Normal; + case CaptionButton.Minimize: + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.MinButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MinButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MinButton.Hot; + return VisualStyleElement.Window.MinButton.Normal; + default: + if (ManagedWindowTitleButtonIsDisabled (button, form.WindowManager)) + return VisualStyleElement.Window.RestoreButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.RestoreButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.RestoreButton.Hot; + return VisualStyleElement.Window.RestoreButton.Normal; + } + } + protected override void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form) + { + if (!render_non_client_areas) { + base.ManagedWindowDrawTitleButton (dc, button, clip, form); + return; + } + VisualStyleElement element = ManagedWindowGetTitleButtonVisualStyleElement (button, form); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ManagedWindowDrawTitleButton (dc, button, clip, form); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, button.Rectangle, clip); + } + public override Size ManagedWindowButtonSize (InternalWindowManager wm) + { + if (!render_non_client_areas) + return base.ManagedWindowButtonSize (wm); + VisualStyleElement element = wm.IsToolWindow && !wm.IsMinimized ? + VisualStyleElement.Window.SmallCloseButton.Normal : + VisualStyleElement.Window.CloseButton.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.ManagedWindowButtonSize (wm); + IDeviceContext dc = GetMeasurementDeviceContext (); + Size result = new VisualStyleRenderer (element).GetPartSize (dc, ThemeSizeType.True); + ReleaseMeasurementDeviceContext (dc); + return result; + } + public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm) + { + if (!render_non_client_areas) { + base.ManagedWindowDrawMenuButton (dc, button, clip, wm); + return; + } + VisualStyleElement element = ManagedWindowGetMenuButtonVisualStyleElement (button, wm); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ManagedWindowDrawMenuButton (dc, button, clip, wm); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, button.Rectangle, clip); + } + static VisualStyleElement ManagedWindowGetMenuButtonVisualStyleElement (TitleButton button, InternalWindowManager wm) + { + switch (button.Caption) { + case CaptionButton.Close: + if (ManagedWindowTitleButtonIsDisabled (button, wm)) + return VisualStyleElement.Window.MdiCloseButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MdiCloseButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MdiCloseButton.Hot; + return VisualStyleElement.Window.MdiCloseButton.Normal; + case CaptionButton.Help: + if (ManagedWindowTitleButtonIsDisabled (button, wm)) + return VisualStyleElement.Window.MdiHelpButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MdiHelpButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MdiHelpButton.Hot; + return VisualStyleElement.Window.MdiHelpButton.Normal; + case CaptionButton.Minimize: + if (ManagedWindowTitleButtonIsDisabled (button, wm)) + return VisualStyleElement.Window.MdiMinButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MdiMinButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MdiMinButton.Hot; + return VisualStyleElement.Window.MdiMinButton.Normal; + default: + if (ManagedWindowTitleButtonIsDisabled (button, wm)) + return VisualStyleElement.Window.MdiRestoreButton.Disabled; + if (ManagedWindowTitleButtonIsPressed (button)) + return VisualStyleElement.Window.MdiRestoreButton.Pressed; + if (button.Entered) + return VisualStyleElement.Window.MdiRestoreButton.Hot; + return VisualStyleElement.Window.MdiRestoreButton.Normal; + } + } + #endregion + #region ProgressBar + public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) + { + if (!RenderClientAreas || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Bar.Normal) || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Chunk.Normal)) { + base.DrawProgressBar (dc, clip_rect, ctrl); + return; + } + VisualStyleRenderer renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Bar.Normal); + renderer.DrawBackground (dc, ctrl.ClientRectangle, clip_rect); + Rectangle client_area = renderer.GetBackgroundContentRectangle (dc, new Rectangle (Point.Empty, ctrl.Size)); + renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Chunk.Normal); + /* Draw Blocks */ + int draw_mode = 0; + int max_blocks = int.MaxValue; + int start_pixel = client_area.X; + draw_mode = (int)ctrl.Style; + switch (draw_mode) { + case 1: // Continuous + client_area.Width = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max (ctrl.Maximum - ctrl.Minimum, 1)))); + renderer.DrawBackground (dc, client_area, clip_rect); + break; + case 2: // Marquee + int ms_diff = (int)(DateTime.Now - ctrl.start).TotalMilliseconds; + double percent_done = (double) ms_diff / ProgressBarMarqueeSpeedScaling + % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed; + max_blocks = 5; + start_pixel = client_area.X + (int)(client_area.Width * percent_done); + goto default; + default: // Blocks + int block_width = renderer.GetInteger (IntegerProperty.ProgressChunkSize); + block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0! + int first_pixel_outside_filled_area = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1))) + client_area.X; + int block_count = 0; + int increment = block_width + renderer.GetInteger (IntegerProperty.ProgressSpaceSize); + Rectangle block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height); + while (true) { + if (max_blocks != int.MaxValue) { + if (block_count == max_blocks) + break; + if (block_rect.Right >= client_area.Width) + block_rect.X -= client_area.Width; + } else { + if (block_rect.X >= first_pixel_outside_filled_area) + break; + if (block_rect.Right >= first_pixel_outside_filled_area) + if (first_pixel_outside_filled_area == client_area.Right) + block_rect.Width = first_pixel_outside_filled_area - block_rect.X; + else + break; + } + if (clip_rect.IntersectsWith (block_rect)) + renderer.DrawBackground (dc, block_rect, clip_rect); + block_rect.X += increment; + block_count++; + } + break; + } + } + #endregion + #region RadioButton + protected override void RadioButton_DrawButton (RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) { + if (radio_button.Appearance == Appearance.Normal && radio_button.FlatStyle == FlatStyle.System) { + RadioButtonRenderer.DrawRadioButton ( + dc, + new Point (radiobutton_rectangle.Left, radiobutton_rectangle.Top), + GetRadioButtonState (radio_button) + ); + return; + } + base.RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle); + } + static RadioButtonState GetRadioButtonState (RadioButton checkBox) + { + if (checkBox.Checked) { + if (!checkBox.Enabled) + return RadioButtonState.CheckedDisabled; + else if (checkBox.Pressed) + return RadioButtonState.CheckedPressed; + else if (checkBox.Entered) + return RadioButtonState.CheckedHot; + return RadioButtonState.CheckedNormal; + } else { + if (!checkBox.Enabled) + return RadioButtonState.UncheckedDisabled; + else if (checkBox.Pressed) + return RadioButtonState.UncheckedPressed; + else if (checkBox.Entered) + return RadioButtonState.UncheckedHot; + return RadioButtonState.UncheckedNormal; + } + } + #endregion + #region ScrollBar + public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar) + { + if (!RenderClientAreas || + !ScrollBarAreElementsDefined) { + base.DrawScrollBar (dc, clip, bar); + return; + } + VisualStyleElement element; + VisualStyleRenderer renderer; + int scroll_button_width = bar.scrollbutton_width; + int scroll_button_height = bar.scrollbutton_height; + if (bar.vert) { + bar.FirstArrowArea = new Rectangle (0, 0, bar.Width, scroll_button_height); + bar.SecondArrowArea = new Rectangle ( + 0, + bar.ClientRectangle.Height - scroll_button_height, + bar.Width, + scroll_button_height); + Rectangle thumb_pos = bar.ThumbPos; + thumb_pos.Width = bar.Width; + bar.ThumbPos = thumb_pos; + #region Background, upper track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + element = VisualStyleElement.ScrollBar.LowerTrackVertical.Pressed; + else + element = bar.Enabled ? + VisualStyleElement.ScrollBar.LowerTrackVertical.Normal : + VisualStyleElement.ScrollBar.LowerTrackVertical.Disabled; + renderer = new VisualStyleRenderer (element); + Rectangle upper_track_rect = new Rectangle ( + 0, + 0, + bar.ClientRectangle.Width, + bar.ThumbPos.Top); + if (clip.IntersectsWith (upper_track_rect)) + renderer.DrawBackground (dc, upper_track_rect, clip); + #endregion + #region Background, lower track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + element = VisualStyles.VisualStyleElement.ScrollBar.LowerTrackVertical.Pressed; + else + element = bar.Enabled ? + VisualStyleElement.ScrollBar.LowerTrackVertical.Normal : + VisualStyleElement.ScrollBar.LowerTrackVertical.Disabled; + renderer = new VisualStyleRenderer (element); + Rectangle lower_track_rect = new Rectangle ( + 0, + bar.ThumbPos.Bottom, + bar.ClientRectangle.Width, + bar.ClientRectangle.Height - bar.ThumbPos.Bottom); + if (clip.IntersectsWith (lower_track_rect)) + renderer.DrawBackground (dc, lower_track_rect, clip); + #endregion + #region Buttons + if (clip.IntersectsWith (bar.FirstArrowArea)) { + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.ArrowButton.UpDisabled; + else if (bar.firstbutton_state == ButtonState.Pushed) + element = VisualStyleElement.ScrollBar.ArrowButton.UpPressed; + else if (bar.FirstButtonEntered) + element = VisualStyleElement.ScrollBar.ArrowButton.UpHot; + else if (ScrollBarHasHoverArrowButtonStyleVisualStyles && bar.Entered) + element = VisualStyleElement.ScrollBar.ArrowButton.UpHover; + else + element = VisualStyleElement.ScrollBar.ArrowButton.UpNormal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.FirstArrowArea); + } + if (clip.IntersectsWith (bar.SecondArrowArea)) { + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.ArrowButton.DownDisabled; + else if (bar.secondbutton_state == ButtonState.Pushed) + element = VisualStyleElement.ScrollBar.ArrowButton.DownPressed; + else if (bar.SecondButtonEntered) + element = VisualStyleElement.ScrollBar.ArrowButton.DownHot; + else if (ScrollBarHasHoverArrowButtonStyleVisualStyles && bar.Entered) + element = VisualStyleElement.ScrollBar.ArrowButton.DownHover; + else + element = VisualStyleElement.ScrollBar.ArrowButton.DownNormal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.SecondArrowArea); + } + #endregion + #region Thumb and grip + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.LowerTrackVertical.Disabled; + else if (bar.ThumbPressed) + element = VisualStyleElement.ScrollBar.ThumbButtonVertical.Pressed; + else if (bar.ThumbEntered) + element = VisualStyleElement.ScrollBar.ThumbButtonVertical.Hot; + else + element = VisualStyleElement.ScrollBar.ThumbButtonVertical.Normal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.ThumbPos, clip); + + if (bar.Enabled && bar.ThumbPos.Height >= 20) { + element = VisualStyleElement.ScrollBar.GripperVertical.Normal; + if (VisualStyleRenderer.IsElementDefined (element)) { + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.ThumbPos, clip); + } + } + #endregion + } else { + bar.FirstArrowArea = new Rectangle (0, 0, scroll_button_width, bar.Height); + bar.SecondArrowArea = new Rectangle ( + bar.ClientRectangle.Width - scroll_button_width, + 0, + scroll_button_width, + bar.Height); + Rectangle thumb_pos = bar.ThumbPos; + thumb_pos.Height = bar.Height; + bar.ThumbPos = thumb_pos; + #region Background, left track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + element = VisualStyleElement.ScrollBar.LeftTrackHorizontal.Pressed; + else + element = bar.Enabled ? + VisualStyleElement.ScrollBar.LeftTrackHorizontal.Normal : + VisualStyleElement.ScrollBar.LeftTrackHorizontal.Disabled; + renderer = new VisualStyleRenderer (element); + Rectangle left_track_rect = new Rectangle ( + 0, + 0, + bar.ThumbPos.Left, + bar.ClientRectangle.Height); + if (clip.IntersectsWith (left_track_rect)) + renderer.DrawBackground (dc, left_track_rect, clip); + #endregion + #region Background, right track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + element = VisualStyleElement.ScrollBar.RightTrackHorizontal.Pressed; + else + element = bar.Enabled ? + VisualStyleElement.ScrollBar.RightTrackHorizontal.Normal : + VisualStyleElement.ScrollBar.RightTrackHorizontal.Disabled; + renderer = new VisualStyleRenderer (element); + Rectangle right_track_rect = new Rectangle ( + bar.ThumbPos.Right, + 0, + bar.ClientRectangle.Width - bar.ThumbPos.Right, + bar.ClientRectangle.Height); + if (clip.IntersectsWith (right_track_rect)) + renderer.DrawBackground (dc, right_track_rect, clip); + #endregion + #region Buttons + if (clip.IntersectsWith (bar.FirstArrowArea)) { + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.ArrowButton.LeftDisabled; + else if (bar.firstbutton_state == ButtonState.Pushed) + element = VisualStyleElement.ScrollBar.ArrowButton.LeftPressed; + else if (bar.FirstButtonEntered) + element = VisualStyleElement.ScrollBar.ArrowButton.LeftHot; + else if (ScrollBarHasHoverArrowButtonStyleVisualStyles && bar.Entered) + element = VisualStyleElement.ScrollBar.ArrowButton.LeftHover; + else + element = VisualStyleElement.ScrollBar.ArrowButton.LeftNormal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.FirstArrowArea); + } + if (clip.IntersectsWith (bar.SecondArrowArea)) { + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.ArrowButton.RightDisabled; + else if (bar.secondbutton_state == ButtonState.Pushed) + element = VisualStyleElement.ScrollBar.ArrowButton.RightPressed; + else if (bar.SecondButtonEntered) + element = VisualStyleElement.ScrollBar.ArrowButton.RightHot; + else if (ScrollBarHasHoverArrowButtonStyleVisualStyles && bar.Entered) + element = VisualStyleElement.ScrollBar.ArrowButton.RightHover; + else + element = VisualStyleElement.ScrollBar.ArrowButton.RightNormal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.SecondArrowArea); + } + #endregion + #region Thumb and grip + if (!bar.Enabled) + element = VisualStyleElement.ScrollBar.RightTrackHorizontal.Disabled; + else if (bar.ThumbPressed) + element = VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Pressed; + else if (bar.ThumbEntered) + element = VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Hot; + else + element = VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Normal; + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.ThumbPos, clip); + + if (bar.Enabled && bar.ThumbPos.Height >= 20) { + element = VisualStyleElement.ScrollBar.GripperHorizontal.Normal; + if (VisualStyleRenderer.IsElementDefined (element)) { + renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, bar.ThumbPos, clip); + } + } + #endregion + } + } + public override bool ScrollBarHasHotElementStyles { + get { + if (!RenderClientAreas) + return base.ScrollBarHasHotElementStyles; + return ScrollBarAreElementsDefined; + } + } + public override bool ScrollBarHasPressedThumbStyle { + get { + if (!RenderClientAreas) + return base.ScrollBarHasPressedThumbStyle; + return ScrollBarAreElementsDefined; + } + } + const int WindowsVistaMajorVersion = 6; + static bool ScrollBarHasHoverArrowButtonStyleVisualStyles = + Environment.OSVersion.Version.Major >= WindowsVistaMajorVersion; + public override bool ScrollBarHasHoverArrowButtonStyle { + get { + if (RenderClientAreas && + ScrollBarHasHoverArrowButtonStyleVisualStyles) + return ScrollBarAreElementsDefined; + return base.ScrollBarHasHoverArrowButtonStyle; + } + } + static bool ScrollBarAreElementsDefined { + get { + return + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.ArrowButton.DownDisabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.LeftTrackHorizontal.Disabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.LowerTrackVertical.Disabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.RightTrackHorizontal.Disabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.ThumbButtonHorizontal.Disabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.ThumbButtonVertical.Disabled) && + VisualStyleRenderer.IsElementDefined (VisualStyleElement.ScrollBar.UpperTrackVertical.Disabled); + } + } + #endregion + #region StatusBar + protected override void DrawStatusBarBackground(Graphics dc, Rectangle clip, StatusBar sb) { + if (!RenderClientAreas) { + base.DrawStatusBarBackground (dc, clip, sb); + return; + } + VisualStyleElement element = VisualStyleElement.Status.Bar.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawStatusBarBackground (dc, clip, sb); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, sb.ClientRectangle, clip); + } + protected override void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area) + { + if (!RenderClientAreas) { + base.DrawStatusBarSizingGrip (dc, clip, sb, area); + return; + } + VisualStyleElement element = VisualStyleElement.Status.Gripper.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawStatusBarSizingGrip (dc, clip, sb, area); + return; + } + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + Rectangle sizing_grip_rectangle = new Rectangle (Point.Empty, renderer.GetPartSize (dc, ThemeSizeType.True)); + sizing_grip_rectangle.X = sb.Width - sizing_grip_rectangle.Width; + sizing_grip_rectangle.Y = sb.Height - sizing_grip_rectangle.Height; + renderer.DrawBackground (dc, sizing_grip_rectangle, clip); + } + protected override void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel) + { + if (!RenderClientAreas) { + base.DrawStatusBarPanelBackground (dc, area, panel); + return; + } + VisualStyleElement element = VisualStyleElement.Status.Pane.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawStatusBarPanelBackground (dc, area, panel); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, area); + } + #endregion + #region TextBoxBase + static bool TextBoxBaseShouldPaint (TextBoxBase textBoxBase) + { + return textBoxBase.BorderStyle == BorderStyle.Fixed3D; + } + static VisualStyleElement TextBoxBaseGetVisualStyleElement (TextBoxBase textBoxBase) + { + if (!textBoxBase.Enabled) + return VisualStyleElement.TextBox.TextEdit.Disabled; + if (textBoxBase.ReadOnly) + return VisualStyleElement.TextBox.TextEdit.ReadOnly; + if (textBoxBase.Entered) + return VisualStyleElement.TextBox.TextEdit.Hot; + if (textBoxBase.Focused) + return VisualStyleElement.TextBox.TextEdit.Focused; + return VisualStyleElement.TextBox.TextEdit.Normal; + } + public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea) + { + if (!RenderClientAreas || + !TextBoxBaseShouldPaint (textBoxBase)) { + base.TextBoxBaseFillBackground (textBoxBase, g, clippingArea); + return; + } + VisualStyleElement element = TextBoxBaseGetVisualStyleElement (textBoxBase); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TextBoxBaseFillBackground (textBoxBase, g, clippingArea); + return; + } + Rectangle bounds = new Rectangle(Point.Empty, textBoxBase.Size); + bounds.X -= (bounds.Width - textBoxBase.ClientSize.Width) / 2; + bounds.Y -= (bounds.Height - textBoxBase.ClientSize.Height) / 2; + new VisualStyleRenderer (element).DrawBackground (g, bounds, clippingArea); + } + public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m) + { + if (!RenderClientAreas || + !TextBoxBaseShouldPaint (textBoxBase)) + return base.TextBoxBaseHandleWmNcPaint (textBoxBase, ref m); + VisualStyleElement element = TextBoxBaseGetVisualStyleElement (textBoxBase); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.TextBoxBaseHandleWmNcPaint (textBoxBase, ref m); + PaintEventArgs e = XplatUI.PaintEventStart (ref m, textBoxBase.Handle, false); + new VisualStyleRenderer (element).DrawBackgroundExcludingArea ( + e.Graphics, + new Rectangle (Point.Empty, textBoxBase.Size), + new Rectangle (new Point ((textBoxBase.Width - textBoxBase.ClientSize.Width) / 2, + (textBoxBase.Height - textBoxBase.ClientSize.Height) / 2), + textBoxBase.ClientSize)); + XplatUI.PaintEventEnd (ref m, textBoxBase.Handle, false); + return true; + } + public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase) + { + if (!RenderClientAreas || + !TextBoxBaseShouldPaint (textBoxBase)) + return base.TextBoxBaseShouldPaintBackground (textBoxBase); + VisualStyleElement element = TextBoxBaseGetVisualStyleElement (textBoxBase); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.TextBoxBaseShouldPaintBackground (textBoxBase); + return new VisualStyleRenderer (element).IsBackgroundPartiallyTransparent (); + } + #endregion + /* FIXME: I SAID NO. + #region ToolBar + static bool ToolBarIsDisabled (ToolBarItem item) + { + return !item.Button.Enabled; + } + static bool ToolBarIsPressed (ToolBarItem item) + { + return item.Pressed; + } + static bool ToolBarIsChecked (ToolBarItem item) + { + return item.Button.Pushed; + } + static bool ToolBarIsHot (ToolBarItem item) + { + return item.Hilight; + } + #region Border + protected override void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat) + { + if (!RenderClientAreas) { + base.DrawToolBarButtonBorder (dc, item, is_flat); + return; + } + if (item.Button.Style == ToolBarButtonStyle.Separator) + return; + VisualStyleElement element; + if (item.Button.Style == ToolBarButtonStyle.DropDownButton) + element = ToolBarGetDropDownButtonVisualStyleElement (item); + else + element = ToolBarGetButtonVisualStyleElement (item); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawToolBarButtonBorder (dc, item, is_flat); + return; + } + Rectangle rectangle = item.Rectangle; + if (item.Button.Style == ToolBarButtonStyle.DropDownButton && item.Button.Parent.DropDownArrows) + rectangle.Width -= ToolBarDropDownWidth; + new VisualStyleRenderer (element).DrawBackground (dc, rectangle); + } + private static VisualStyleElement ToolBarGetDropDownButtonVisualStyleElement (ToolBarItem item) + { + if (item.Button.Parent.DropDownArrows) { + if (ToolBarIsDisabled (item)) + return VisualStyleElement.ToolBar.SplitButton.Disabled; + if (ToolBarIsPressed (item)) + return VisualStyleElement.ToolBar.SplitButton.Pressed; + if (ToolBarIsChecked (item)) + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.SplitButton.HotChecked; + else + return VisualStyleElement.ToolBar.SplitButton.Checked; + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.SplitButton.Hot; + return VisualStyleElement.ToolBar.SplitButton.Normal; + } else { + if (ToolBarIsDisabled (item)) + return VisualStyleElement.ToolBar.DropDownButton.Disabled; + if (ToolBarIsPressed (item)) + return VisualStyleElement.ToolBar.DropDownButton.Pressed; + if (ToolBarIsChecked (item)) + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.DropDownButton.HotChecked; + else + return VisualStyleElement.ToolBar.DropDownButton.Checked; + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.DropDownButton.Hot; + return VisualStyleElement.ToolBar.DropDownButton.Normal; + } + } + private static VisualStyleElement ToolBarGetButtonVisualStyleElement (ToolBarItem item) + { + if (ToolBarIsDisabled (item)) + return VisualStyleElement.ToolBar.Button.Disabled; + if (ToolBarIsPressed (item)) + return VisualStyleElement.ToolBar.Button.Pressed; + if (ToolBarIsChecked (item)) + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.Button.HotChecked; + else + return VisualStyleElement.ToolBar.Button.Checked; + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.Button.Hot; + return VisualStyleElement.ToolBar.Button.Normal; + } + #endregion + #region Separator + protected override void DrawToolBarSeparator (Graphics dc, ToolBarItem item) + { + if (!RenderClientAreas) { + base.DrawToolBarSeparator (dc, item); + return; + } + VisualStyleElement element = ToolBarGetSeparatorVisualStyleElement (item); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawToolBarSeparator (dc, item); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, item.Rectangle); + } + static VisualStyleElement ToolBarGetSeparatorVisualStyleElement (ToolBarItem toolBarItem) + { + return toolBarItem.Button.Parent.Vertical ? + VisualStyleElement.ToolBar.SeparatorVertical.Normal : + VisualStyleElement.ToolBar.SeparatorHorizontal.Normal; + } + #endregion + #region Toggle button background + protected override void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item) + { + if (!RenderClientAreas || + !VisualStyleRenderer.IsElementDefined (ToolBarGetButtonVisualStyleElement (item))) + base.DrawToolBarToggleButtonBackground (dc, item); + } + #endregion + #region Drop down arrow + protected override void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat) + { + if (!RenderClientAreas) { + base.DrawToolBarDropDownArrow (dc, item, is_flat); + return; + } + VisualStyleElement element = ToolBarGetDropDownArrowVisualStyleElement (item); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawToolBarDropDownArrow (dc, item, is_flat); + return; + } + Rectangle rect = item.Rectangle; + rect.X = item.Rectangle.Right - ToolBarDropDownWidth; + rect.Width = ToolBarDropDownWidth; + new VisualStyleRenderer (element).DrawBackground (dc, rect); + } + private static VisualStyleElement ToolBarGetDropDownArrowVisualStyleElement (ToolBarItem item) + { + if (ToolBarIsDisabled (item)) + return VisualStyleElement.ToolBar.SplitButtonDropDown.Disabled; + if (ToolBarIsPressed (item)) + return VisualStyleElement.ToolBar.SplitButtonDropDown.Pressed; + if (ToolBarIsChecked (item)) + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.SplitButtonDropDown.HotChecked; + else + return VisualStyleElement.ToolBar.SplitButtonDropDown.Checked; + if (ToolBarIsHot (item)) + return VisualStyleElement.ToolBar.SplitButtonDropDown.Hot; + return VisualStyleElement.ToolBar.SplitButtonDropDown.Normal; + } + #endregion + public override bool ToolBarHasHotElementStyles (ToolBar toolBar) + { + if (!RenderClientAreas) + return base.ToolBarHasHotElementStyles (toolBar); + return true; + } + public override bool ToolBarHasHotCheckedElementStyles { + get { + if (!RenderClientAreas) + return base.ToolBarHasHotCheckedElementStyles; + return true; + } + } + #endregion*/ + #region ToolTip + protected override void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) + { + if (!RenderClientAreas) { + base.ToolTipDrawBackground (dc, clip_rectangle, control); + return; + } + VisualStyleElement element = VisualStyleElement.ToolTip.Standard.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.ToolTipDrawBackground (dc, clip_rectangle, control); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, control.ClientRectangle); + } + public override bool ToolTipTransparentBackground { + get { + if (!RenderClientAreas) + return base.ToolTipTransparentBackground; + VisualStyleElement element = VisualStyleElement.ToolTip.Standard.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.ToolTipTransparentBackground; + return new VisualStyleRenderer (element).IsBackgroundPartiallyTransparent (); + } + } + #endregion + #region TrackBar + protected override Size TrackBarGetThumbSize (TrackBar trackBar) + { + if (!RenderClientAreas) + return base.TrackBarGetThumbSize (trackBar); + VisualStyleElement element = TrackBarGetThumbVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.TrackBarGetThumbSize (trackBar); + Graphics g = trackBar.CreateGraphics (); + Size result = new VisualStyleRenderer (element).GetPartSize (g, ThemeSizeType.True); + g.Dispose (); + return trackBar.Orientation == Orientation.Horizontal ? result : TrackBarRotateVerticalThumbSize (result); + } + static VisualStyleElement TrackBarGetThumbVisualStyleElement (TrackBar trackBar) + { + if (trackBar.Orientation == Orientation.Horizontal) + switch (trackBar.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + return TrackBarGetHorizontalThumbBottomVisualStyleElement (trackBar); + case TickStyle.TopLeft: + return TrackBarGetHorizontalThumbTopVisualStyleElement (trackBar); + default: + return TrackBarGetHorizontalThumbVisualStyleElement (trackBar); + } + else + switch (trackBar.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + return TrackBarGetVerticalThumbRightVisualStyleElement (trackBar); + case TickStyle.TopLeft: + return TrackBarGetVerticalThumbLeftVisualStyleElement (trackBar); + default: + return TrackBarGetVerticalThumbVisualStyleElement (trackBar); + } + } + static Size TrackBarRotateVerticalThumbSize (Size value) + { + int temporary = value.Width; + value.Width = value.Height; + value.Height = temporary; + return value; + } + #region Track + protected override void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clippingArea); + return; + } + VisualStyleElement element = VisualStyleElement.TrackBar.Track.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clippingArea); + return; + } + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, new Rectangle (channel_startpoint, new Size (thumb_area.Width, renderer.GetPartSize (dc, ThemeSizeType.True).Height)), clippingArea); + } + protected override void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + if (!RenderClientAreas) { + base.TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clippingArea); + return; + } + VisualStyleElement element = VisualStyleElement.TrackBar.TrackVertical.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clippingArea); + return; + } + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (dc, new Rectangle (channel_startpoint, new Size (renderer.GetPartSize (dc, ThemeSizeType.True).Width, thumb_area.Height)), clippingArea); + } + #endregion + #region Thumb + static bool TrackBarIsDisabled (TrackBar trackBar) + { + return !trackBar.Enabled; + } + static bool TrackBarIsHot (TrackBar trackBar) + { + return trackBar.ThumbEntered; + } + static bool TrackBarIsPressed (TrackBar trackBar) + { + return trackBar.thumb_pressed; + } + static bool TrackBarIsFocused (TrackBar trackBar) + { + return trackBar.Focused; + } + #region Horizontal + protected override void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetHorizontalThumbBottomVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, thumb_pos, clippingArea); + } + static VisualStyleElement TrackBarGetHorizontalThumbBottomVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.ThumbBottom.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.ThumbBottom.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.ThumbBottom.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.ThumbBottom.Focused; + return VisualStyleElement.TrackBar.ThumbBottom.Normal; + } + protected override void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetHorizontalThumbTopVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, thumb_pos, clippingArea); + } + static VisualStyleElement TrackBarGetHorizontalThumbTopVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.ThumbTop.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.ThumbTop.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.ThumbTop.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.ThumbTop.Focused; + return VisualStyleElement.TrackBar.ThumbTop.Normal; + } + protected override void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetHorizontalThumbVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, thumb_pos, clippingArea); + } + static VisualStyleElement TrackBarGetHorizontalThumbVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.Thumb.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.Thumb.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.Thumb.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.Thumb.Focused; + return VisualStyleElement.TrackBar.Thumb.Normal; + } + #endregion + #region Vertical + static Rectangle TrackBarRotateVerticalThumbSize (Rectangle value) + { + int temporary = value.Width; + value.Width = value.Height; + value.Height = temporary; + return value; + } + protected override void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetVerticalThumbRightVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, TrackBarRotateVerticalThumbSize (thumb_pos), clippingArea); + } + static VisualStyleElement TrackBarGetVerticalThumbRightVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.ThumbRight.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.ThumbRight.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.ThumbRight.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.ThumbRight.Focused; + return VisualStyleElement.TrackBar.ThumbRight.Normal; + } + protected override void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetVerticalThumbLeftVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, TrackBarRotateVerticalThumbSize (thumb_pos), clippingArea); + } + static VisualStyleElement TrackBarGetVerticalThumbLeftVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.ThumbLeft.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.ThumbLeft.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.ThumbLeft.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.ThumbLeft.Focused; + return VisualStyleElement.TrackBar.ThumbLeft.Normal; + } + protected override void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + if (!RenderClientAreas) { + base.TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + VisualStyleElement element = TrackBarGetVerticalThumbVisualStyleElement (trackBar); + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clippingArea, trackBar); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, TrackBarRotateVerticalThumbSize (thumb_pos), clippingArea); + } + static VisualStyleElement TrackBarGetVerticalThumbVisualStyleElement (TrackBar trackBar) + { + if (TrackBarIsDisabled (trackBar)) + return VisualStyleElement.TrackBar.ThumbVertical.Disabled; + else if (TrackBarIsPressed (trackBar)) + return VisualStyleElement.TrackBar.ThumbVertical.Pressed; + else if (TrackBarIsHot (trackBar)) + return VisualStyleElement.TrackBar.ThumbVertical.Hot; + else if (TrackBarIsFocused (trackBar)) + return VisualStyleElement.TrackBar.ThumbVertical.Focused; + return VisualStyleElement.TrackBar.ThumbVertical.Normal; + } + #endregion + #endregion + #region Ticks + const EdgeStyle TrackBarTickEdgeStyle = EdgeStyle.Bump; + const EdgeEffects TrackBarTickEdgeEffects = EdgeEffects.None; + #region Horizontal + protected override ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g) + { + if (!RenderClientAreas || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.TrackBar.Ticks.Normal)) + return base.TrackBarGetHorizontalTickPainter (g); + return new TrackBarHorizontalTickPainter (g); + } + class TrackBarHorizontalTickPainter : ITrackBarTickPainter + { + readonly Graphics g; + readonly VisualStyleRenderer renderer; + public TrackBarHorizontalTickPainter (Graphics g) + { + this.g = g; + renderer = new VisualStyleRenderer (VisualStyleElement.TrackBar.Ticks.Normal); + } + public void Paint (float x1, float y1, float x2, float y2) + { + renderer.DrawEdge (g, new Rectangle ( + (int)Math.Round (x1), + (int)Math.Round (y1), + 1, + (int)Math.Round (y2 - y1) + 1), Edges.Left, TrackBarTickEdgeStyle, TrackBarTickEdgeEffects); + } + } + #endregion + #region Vertical + protected override ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g) + { + if (!RenderClientAreas || + !VisualStyleRenderer.IsElementDefined (VisualStyleElement.TrackBar.TicksVertical.Normal)) + return base.TrackBarGetVerticalTickPainter (g); + return new TrackBarVerticalTickPainter (g); + } + class TrackBarVerticalTickPainter : ITrackBarTickPainter + { + readonly Graphics g; + readonly VisualStyleRenderer renderer; + public TrackBarVerticalTickPainter (Graphics g) + { + this.g = g; + renderer = new VisualStyleRenderer (VisualStyleElement.TrackBar.TicksVertical.Normal); + } + public void Paint (float x1, float y1, float x2, float y2) + { + renderer.DrawEdge (g, new Rectangle ( + (int)Math.Round (x1), + (int)Math.Round (y1), + (int)Math.Round (x2 - x1) + 1, + 1), Edges.Top, TrackBarTickEdgeStyle, TrackBarTickEdgeEffects); + } + } + #endregion + #endregion + public override bool TrackBarHasHotThumbStyle { + get { + if (!RenderClientAreas) + return base.TrackBarHasHotThumbStyle; + return true; + } + } + #endregion + #region TreeView + [MonoInternalNote ("Use the sizing information provided by the VisualStyles API.")] + public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle) + { + if (!RenderClientAreas) { + base.TreeViewDrawNodePlusMinus (treeView, node, dc, x, middle); + return; + } + VisualStyleElement element = node.IsExpanded ? + VisualStyleElement.TreeView.Glyph.Opened : + VisualStyleElement.TreeView.Glyph.Closed; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.TreeViewDrawNodePlusMinus (treeView, node, dc, x, middle); + return; + } + new VisualStyleRenderer (element).DrawBackground (dc, new Rectangle (x, middle - 4, 9, 9)); + } + #endregion + #region UpDownBase + public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, PushButtonState state) + { + if (!RenderClientAreas) { + base.UpDownBaseDrawButton (g, bounds, top, state); + return; + } + VisualStyleElement element; + if (top) + switch (state) { + case PushButtonState.Disabled: + element = VisualStyleElement.Spin.Up.Disabled; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.Spin.Up.Pressed; + break; + case PushButtonState.Hot: + element = VisualStyleElement.Spin.Up.Hot; + break; + default: + element = VisualStyleElement.Spin.Up.Normal; + break; + } + else + switch (state) { + case PushButtonState.Disabled: + element = VisualStyleElement.Spin.Down.Disabled; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.Spin.Down.Pressed; + break; + case PushButtonState.Hot: + element = VisualStyleElement.Spin.Down.Hot; + break; + default: + element = VisualStyleElement.Spin.Down.Normal; + break; + } + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.UpDownBaseDrawButton (g, bounds, top, state); + return; + } + new VisualStyleRenderer (element).DrawBackground (g, bounds); + } + public override bool UpDownBaseHasHotButtonStyle { + get { + if (!RenderClientAreas) + return base.UpDownBaseHasHotButtonStyle; + return true; + } + } + #endregion + #endregion + + static bool AreEqual (VisualStyleElement value1, VisualStyleElement value2) + { + return + value1.ClassName == value1.ClassName && + value1.Part == value2.Part && + value1.State == value2.State; + } + + #region Measurement device context + static Widget control; + static IDeviceContext GetMeasurementDeviceContext () + { + if (control == null) + control = new Widget (); + return control.CreateGraphics (); + } + static void ReleaseMeasurementDeviceContext (IDeviceContext dc) + { + dc.Dispose (); + } + #endregion + } +} diff --git a/source/ShiftUI/Theming/ThemeWin32Classic.cs b/source/ShiftUI/Theming/ThemeWin32Classic.cs new file mode 100644 index 0000000..8c89066 --- /dev/null +++ b/source/ShiftUI/Theming/ThemeWin32Classic.cs @@ -0,0 +1,7815 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004-2006 Novell, Inc. +// +// Authors: +// Jordi Mas i Hernandez, [email protected] +// Peter Bartok, [email protected] +// John BouAntoun, [email protected] +// Marek Safar, [email protected] +// Alexander Olk, [email protected] +// + +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.Drawing.Text; +using System.Text; +using ShiftUI.Theming; +using System; + +namespace ShiftUI +{ + + internal class ThemeWin32Classic : Theme + { + public override Version Version { + get { + return new Version(0, 1, 0, 0); + } + } + + /* Hardcoded colour values not exposed in the API constants in all configurations */ + protected static readonly Color arrow_color = Color.Black; + protected static readonly Color pen_ticks_color = Color.Black; + protected static StringFormat string_format_menu_text; + protected static StringFormat string_format_menu_shortcut; + protected static StringFormat string_format_menu_menubar_text; + static ImageAttributes imagedisabled_attributes; + Font window_border_font; + const int SEPARATOR_HEIGHT = 6; + const int SEPARATOR_MIN_WIDTH = 20; + const int SM_CXBORDER = 1; + const int SM_CYBORDER = 1; + const int MENU_TAB_SPACE = 8; // Pixels added to the width of an item because of a tabd + const int MENU_BAR_ITEMS_SPACE = 8; // Space between menu bar items + const int CheckSize = 13; + + #region Principal Theme Methods + public ThemeWin32Classic () + { + ResetDefaults (); + } + + public override void ResetDefaults() { + defaultWindowBackColor = this.ColorWindow; + defaultWindowForeColor = this.ColorControlText; + window_border_font = null; + + /* Menu string formats */ + string_format_menu_text = new StringFormat (); + string_format_menu_text.LineAlignment = StringAlignment.Center; + string_format_menu_text.Alignment = StringAlignment.Near; + string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show; + string_format_menu_text.SetTabStops (0f, new float [] { 50f }); + string_format_menu_text.FormatFlags |= StringFormatFlags.NoWrap; + + string_format_menu_shortcut = new StringFormat (); + string_format_menu_shortcut.LineAlignment = StringAlignment.Center; + string_format_menu_shortcut.Alignment = StringAlignment.Far; + + string_format_menu_menubar_text = new StringFormat (); + string_format_menu_menubar_text.LineAlignment = StringAlignment.Center; + string_format_menu_menubar_text.Alignment = StringAlignment.Center; + string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show; + } + + public override bool DoubleBufferingSupported { + get {return true; } + } + + public override int HorizontalScrollBarHeight { + get { + return XplatUI.HorizontalScrollBarHeight; + } + } + + public override int VerticalScrollBarWidth { + get { + return XplatUI.VerticalScrollBarWidth; + } + } + + public override Font WindowBorderFont { + get { + return window_border_font ?? (window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold)); + } + } + + #endregion // Principal Theme Methods + + #region Internal Methods + protected Brush GetControlBackBrush (Color c) { + if (c.ToArgb () == DefaultControlBackColor.ToArgb ()) + return SystemBrushes.Control; + return ResPool.GetSolidBrush (c); + } + + protected Brush GetControlForeBrush (Color c) { + if (c.ToArgb () == DefaultControlForeColor.ToArgb ()) + return SystemBrushes.ControlText; + return ResPool.GetSolidBrush (c); + } + #endregion // Internal Methods + + #region Widget + public override Font GetLinkFont (Widget control) + { + return new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Underline, control.Font.Unit); + } + #endregion // Widget + + #region OwnerDraw Support + public override void DrawOwnerDrawBackground (DrawItemEventArgs e) + { + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { + e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds); + return; + } + + e.Graphics.FillRectangle (ResPool.GetSolidBrush(e.BackColor), e.Bounds); + } + + public override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e) + { + if (e.State == DrawItemState.Focus) + CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor); + } + #endregion // OwnerDraw Support + + #region Button + #region Standard Button Style + public override void DrawButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + DrawButtonBackground (g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawButtonImage (g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawButtonFocus (g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawButtonText (g, b, textBounds); + } + + public virtual void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea) + { + if (button.Pressed) + ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor); + else if (button.InternalSelected) + ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor); + else if (button.Entered) + ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor); + else if (!button.Enabled) + ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor); + else + ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor); + } + + public virtual void DrawButtonFocus (Graphics g, Button button) + { + WidgetPaint.DrawFocusRectangle (g, Rectangle.Inflate (button.ClientRectangle, -4, -4)); + } + + public virtual void DrawButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds) + { + if (button.Enabled) + g.DrawImage (button.Image, imageBounds); + else + CPDrawImageDisabled (g, button.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawButtonText (Graphics g, ButtonBase button, Rectangle textBounds) + { + // Ensure that at least one line is going to get displayed. + // Line limit does not ensure that despite its description. + if (button.Font != null && button.Font.Height > 0) + textBounds.Height = Math.Max (textBounds.Height, button.Font.Height); + + if (button.Enabled) + TextRenderer.DrawTextInternal (g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering); + else + DrawStringDisabled20 (g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering); + } + #endregion + + #region FlatStyle Button Style + public override void DrawFlatButton (Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (b.BackgroundImage == null) + DrawFlatButtonBackground (g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawFlatButtonImage (g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawFlatButtonFocus (g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawFlatButtonText (g, b, textBounds); + } + + public virtual void DrawFlatButtonBackground (Graphics g, ButtonBase button, Rectangle clipArea) + { + if (button.Pressed) + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance); + else if (button.InternalSelected) { + if (button.Entered) + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance); + else + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance); + } + else if (button.Entered) + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance); + else if (!button.Enabled) + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance); + else + ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance); + } + + public virtual void DrawFlatButtonFocus (Graphics g, ButtonBase button) + { + if (!button.Pressed) { + Color focus_color = WidgetPaint.Dark (button.BackColor); + g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9)); + } + } + + public virtual void DrawFlatButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds) + { + // No changes from Standard for image for this theme + DrawButtonImage (g, button, imageBounds); + } + + public virtual void DrawFlatButtonText (Graphics g, ButtonBase button, Rectangle textBounds) + { + // No changes from Standard for text for this theme + DrawButtonText (g, button, textBounds); + } + #endregion + + #region Popup Button Style + public override void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + DrawPopupButtonBackground (g, b, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawPopupButtonImage (g, b, imageBounds); + + // If we're focused, draw a focus rectangle + if (b.Focused && b.Enabled && b.ShowFocusCues) + DrawPopupButtonFocus (g, b); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawPopupButtonText (g, b, textBounds); + } + + public virtual void DrawPopupButtonBackground (Graphics g, Button button, Rectangle clipArea) + { + if (button.Pressed) + ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor); + else if (button.Entered) + ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor); + else if (button.InternalSelected) + ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor); + else if (!button.Enabled) + ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor); + else + ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor); + } + + public virtual void DrawPopupButtonFocus (Graphics g, Button button) + { + // No changes from Standard for image for this theme + DrawButtonFocus (g, button); + } + + public virtual void DrawPopupButtonImage (Graphics g, Button button, Rectangle imageBounds) + { + // No changes from Standard for image for this theme + DrawButtonImage (g, button, imageBounds); + } + + public virtual void DrawPopupButtonText (Graphics g, Button button, Rectangle textBounds) + { + // No changes from Standard for image for this theme + DrawButtonText (g, button, textBounds); + } + #endregion + + #region Button Layout Calculations + public override Size CalculateButtonAutoSize (Button button) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal (button.Text, button.Font, button.UseCompatibleTextRendering); + Size image_size = button.Image == null ? Size.Empty : button.Image.Size; + + // Pad the text size + if (button.Text.Length != 0) { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (button.TextImageRelation) { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max (button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max (text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (button.Padding.Vertical + 6); + ret_size.Width += (button.Padding.Horizontal + 6); + + return ret_size; + } + + public override void CalculateButtonTextAndImageLayout (Graphics g, ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle) + { + Image image = button.Image; + string text = button.Text; + Rectangle content_rect = button.PaddingClientRectangle; + Size text_size = TextRenderer.MeasureTextInternal (g, text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering); + Size image_size = image == null ? Size.Empty : image.Size; + + textRectangle = Rectangle.Inflate (content_rect, -4, -4); + imageRectangle = Rectangle.Empty; + + bool displayEllipsis = (button.TextFormatFlags & (TextFormatFlags.EndEllipsis | TextFormatFlags.PathEllipsis | TextFormatFlags.WordEllipsis)) != 0; + + switch (button.TextImageRelation) { + case TextImageRelation.Overlay: + // Overlay is easy, text always goes here + + // Image is dependent on ImageAlign + if (image == null) { + if (button.Pressed) + textRectangle.Offset (1, 1); + return; + } + + int image_x = 0; + int image_y = 0; + int image_height = image.Height; + int image_width = image.Width; + + switch (button.ImageAlign) { + case System.Drawing.ContentAlignment.TopLeft: + image_x = 5; + image_y = 5; + break; + case System.Drawing.ContentAlignment.TopCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = 5; + break; + case System.Drawing.ContentAlignment.TopRight: + image_x = content_rect.Width - image_width - 5; + image_y = 5; + break; + case System.Drawing.ContentAlignment.MiddleLeft: + image_x = 5; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleRight: + image_x = content_rect.Width - image_width - 4; + image_y = (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.BottomLeft: + image_x = 5; + image_y = content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomCenter: + image_x = (content_rect.Width - image_width) / 2; + image_y = content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomRight: + image_x = content_rect.Width - image_width - 4; + image_y = content_rect.Height - image_height - 4; + break; + default: + image_x = 5; + image_y = 5; + break; + } + + imageRectangle = new Rectangle (image_x, image_y, image_width, image_height); + break; + case TextImageRelation.ImageAboveText: + LayoutTextAboveOrBelowImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextAboveImage: + LayoutTextAboveOrBelowImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, displayEllipsis, out textRectangle, out imageRectangle); + break; + case TextImageRelation.ImageBeforeText: + LayoutTextBeforeOrAfterImage (textRectangle, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextBeforeImage: + LayoutTextBeforeOrAfterImage (textRectangle, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + } + if (button.Pressed) + textRectangle.Offset (1, 1); + } + + 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) + { + int element_spacing = 0; // Spacing between the Text and the Image + int total_width = textSize.Width + element_spacing + imageSize.Width; + + if (!textFirst) + element_spacing += 2; + + // If the text is too big, chop it down to the size we have available to it + if (total_width > totalArea.Width) { + textSize.Width = totalArea.Width - element_spacing - imageSize.Width; + total_width = totalArea.Width; + } + + int excess_width = totalArea.Width - total_width; + int offset = 0; + + Rectangle final_text_rect; + Rectangle final_image_rect; + + HorizontalAlignment h_text = GetHorizontalAlignment (textAlign); + HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign); + + if (h_image == HorizontalAlignment.Left) + offset = 0; + else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right) + offset = excess_width; + else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center)) + offset += (int)(excess_width / 3); + else + offset += (int)(2 * (excess_width / 3)); + + if (textFirst) { + final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + } + else { + final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height); + final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height); + } + + textRect = final_text_rect; + imageRect = final_image_rect; + } + + 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) + { + int element_spacing = 0; // Spacing between the Text and the Image + int total_height = textSize.Height + element_spacing + imageSize.Height; + + if (textFirst) + element_spacing += 2; + + if (textSize.Width > totalArea.Width) + textSize.Width = totalArea.Width; + + // If the there isn't enough room and we're text first, cut out the image + if (total_height > totalArea.Height && textFirst) { + imageSize = Size.Empty; + total_height = totalArea.Height; + } + + int excess_height = totalArea.Height - total_height; + int offset = 0; + + Rectangle final_text_rect; + Rectangle final_image_rect; + + VerticalAlignment v_text = GetVerticalAlignment (textAlign); + VerticalAlignment v_image = GetVerticalAlignment (imageAlign); + + if (v_image == VerticalAlignment.Top) + offset = 0; + else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom) + offset = excess_height; + else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center)) + offset += (int)(excess_height / 3); + else + offset += (int)(2 * (excess_height / 3)); + + if (textFirst) { + var textHeight = excess_height >= 0 ? totalArea.Height - imageSize.Height - element_spacing: textSize.Height; + final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textHeight); + final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height); + } + else { + final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height); + var textHeight = excess_height >= 0 ? totalArea.Height - final_image_rect.Height : textSize.Height; + final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textHeight); + + if (final_text_rect.Bottom > totalArea.Bottom) { + final_text_rect.Y -= (final_text_rect.Bottom - totalArea.Bottom); + if (final_text_rect.Y < totalArea.Top) + final_text_rect.Y = totalArea.Top; + } + } + + if (displayEllipsis) { + // Don't use more space than is available otherwise ellipsis won't show + if (final_text_rect.Height > totalArea.Bottom) + final_text_rect.Height = totalArea.Bottom - final_text_rect.Top; + } + + textRect = final_text_rect; + imageRect = final_image_rect; + } + + private HorizontalAlignment GetHorizontalAlignment (System.Drawing.ContentAlignment align) + { + switch (align) { + case System.Drawing.ContentAlignment.BottomLeft: + case System.Drawing.ContentAlignment.MiddleLeft: + case System.Drawing.ContentAlignment.TopLeft: + return HorizontalAlignment.Left; + case System.Drawing.ContentAlignment.BottomCenter: + case System.Drawing.ContentAlignment.MiddleCenter: + case System.Drawing.ContentAlignment.TopCenter: + return HorizontalAlignment.Center; + case System.Drawing.ContentAlignment.BottomRight: + case System.Drawing.ContentAlignment.MiddleRight: + case System.Drawing.ContentAlignment.TopRight: + return HorizontalAlignment.Right; + } + + return HorizontalAlignment.Left; + } + + private enum VerticalAlignment + { + Top = 0, + Center = 1, + Bottom = 2 + } + + private VerticalAlignment GetVerticalAlignment (System.Drawing.ContentAlignment align) + { + switch (align) { + case System.Drawing.ContentAlignment.TopLeft: + case System.Drawing.ContentAlignment.TopCenter: + case System.Drawing.ContentAlignment.TopRight: + return VerticalAlignment.Top; + case System.Drawing.ContentAlignment.MiddleLeft: + case System.Drawing.ContentAlignment.MiddleCenter: + case System.Drawing.ContentAlignment.MiddleRight: + return VerticalAlignment.Center; + case System.Drawing.ContentAlignment.BottomLeft: + case System.Drawing.ContentAlignment.BottomCenter: + case System.Drawing.ContentAlignment.BottomRight: + return VerticalAlignment.Bottom; + } + + return VerticalAlignment.Top; + } + + internal Rectangle AlignInRectangle (Rectangle outer, Size inner, System.Drawing.ContentAlignment align) + { + int x = 0; + int y = 0; + + if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft) + x = outer.X; + else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter) + x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left); + else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight) + x = outer.Right - inner.Width; + if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight) + y = outer.Y; + else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight) + y = outer.Y + (outer.Height - inner.Height) / 2; + else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft) + y = outer.Bottom - inner.Height; + + return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height)); + } + #endregion + #endregion + + #region ButtonBase + public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) + { + // Draw the button: Draw border, etc. + ButtonBase_DrawButton(button, dc); + + // Draw the image + if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null))) + ButtonBase_DrawImage(button, dc); + + // Draw the focus rectangle + if (ShouldPaintFocusRectagle (button)) + ButtonBase_DrawFocus(button, dc); + + // Now the text + if (button.Text != null && button.Text != String.Empty) + ButtonBase_DrawText(button, dc); + } + + protected static bool ShouldPaintFocusRectagle (ButtonBase button) + { + return (button.Focused || button.paint_as_acceptbutton) && button.Enabled && button.ShowFocusCues; + } + + protected virtual void ButtonBase_DrawButton (ButtonBase button, Graphics dc) + { + Rectangle borderRectangle; + bool check_or_radio = false; + bool check_or_radio_checked = false; + + bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false; + + CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor); + + if (button is CheckBox) { + check_or_radio = true; + check_or_radio_checked = ((CheckBox)button).Checked; + } else if (button is RadioButton) { + check_or_radio = true; + check_or_radio_checked = ((RadioButton)button).Checked; + } + + if (button.Focused && button.Enabled && !check_or_radio) { + // shrink the rectangle for the normal button drawing inside the focus rectangle + borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1); + } else { + borderRectangle = button.ClientRectangle; + } + + if (button.FlatStyle == FlatStyle.Popup) { + if (!button.is_pressed && !button.is_entered && !check_or_radio_checked) + Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + else if (!button.is_pressed && button.is_entered &&!check_or_radio_checked) + Internal_DrawButton (dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor); + else if (button.is_pressed || check_or_radio_checked) + Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + } else if (button.FlatStyle == FlatStyle.Flat) { + if (button.is_entered && !button.is_pressed && !check_or_radio_checked) { + if ((button.image == null) && (button.image_list == null)) { + Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush (cpcolor.Dark); + dc.FillRectangle (brush, borderRectangle); + } + } else if (button.is_pressed || check_or_radio_checked) { + if ((button.image == null) && (button.image_list == null)) { + Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush (cpcolor.LightLight); + dc.FillRectangle (brush, borderRectangle); + } + + Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + dc.DrawRectangle (pen, borderRectangle.X + 4, borderRectangle.Y + 4, + borderRectangle.Width - 9, borderRectangle.Height - 9); + } + + Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor); + } else { + if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked) + Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor); + else + Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor); + } + } + + private void Internal_DrawButton (Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor) + { + switch (state) { + case 0: // normal or normal disabled button + Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen (backcolor); + dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3); + dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1); + + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + dc.DrawLine (pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + dc.DrawLine (pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3); + + pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2); + break; + case 1: // popup button normal (or pressed normal or popup button) + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1); + break; + case 2: // popup button poped up + pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2); + dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y); + + pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2); + break; + case 3: // flat button not entered + pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1); + break; + default: + break; + } + } + + protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc) + { + // Need to draw a picture + Image i; + int image_x; + int image_y; + int image_width; + int image_height; + + int width = button.ClientSize.Width; + int height = button.ClientSize.Height; + + if (button.ImageIndex != -1) { // We use ImageIndex instead of image_index since it will return -1 if image_list is null + i = button.image_list.Images[button.ImageIndex]; + } else { + i = button.image; + } + + image_width = i.Width; + image_height = i.Height; + + switch (button.ImageAlign) { + case ContentAlignment.TopLeft: { + image_x = 5; + image_y = 5; + break; + } + + case ContentAlignment.TopCenter: { + image_x = (width - image_width) / 2; + image_y = 5; + break; + } + + case ContentAlignment.TopRight: { + image_x = width - image_width - 5; + image_y = 5; + break; + } + + case ContentAlignment.MiddleLeft: { + image_x = 5; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.MiddleCenter: { + image_x = (width - image_width) / 2; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.MiddleRight: { + image_x = width - image_width - 4; + image_y = (height - image_height) / 2; + break; + } + + case ContentAlignment.BottomLeft: { + image_x = 5; + image_y = height - image_height - 4; + break; + } + + case ContentAlignment.BottomCenter: { + image_x = (width - image_width) / 2; + image_y = height - image_height - 4; + break; + } + + case ContentAlignment.BottomRight: { + image_x = width - image_width - 4; + image_y = height - image_height - 4; + break; + } + + default: { + image_x = 5; + image_y = 5; + break; + } + } + + dc.SetClip (new Rectangle(3, 3, width - 5, height - 5)); + + if (button.Enabled) + dc.DrawImage (i, image_x, image_y, image_width, image_height); + else + CPDrawImageDisabled (dc, i, image_x, image_y, ColorControl); + + dc.ResetClip (); + } + + protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc) + { + Color focus_color = button.ForeColor; + + int inflate_value = -3; + + if (!(button is CheckBox) && !(button is RadioButton)) { + inflate_value = -4; + + if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) + focus_color = WidgetPaint.Dark(button.BackColor); + + dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, + button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1); + } + + if (button.Focused) { + Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value); + WidgetPaint.DrawFocusRectangle (dc, rect); + } + } + + protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc) + { + Rectangle buttonRectangle = button.ClientRectangle; + Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4); + + if (button.is_pressed) { + text_rect.X++; + text_rect.Y++; + } + + // Ensure that at least one line is going to get displayed. + // Line limit does not ensure that despite its description. + text_rect.Height = Math.Max (button.Font.Height, text_rect.Height); + + if (button.Enabled) { + dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format); + } else { + if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) { + dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (ColorGrayText), text_rect, button.text_format); + } else { + CPDrawStringDisabled (dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format); + } + } + } + + public override Size ButtonBaseDefaultSize { + get { + return new Size (75, 23); + } + } + #endregion // ButtonBase + + #region CheckBox + public override void DrawCheckBox (Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (cb.Appearance == Appearance.Button && cb.FlatStyle != FlatStyle.Flat) + ButtonBase_DrawButton (cb, g); + else if (cb.Appearance != Appearance.Button) + DrawCheckBoxGlyph (g, cb, glyphArea); + + // Draw the borders and such for a Flat CheckBox Button + if (cb.Appearance == Appearance.Button && cb.FlatStyle == FlatStyle.Flat) + DrawFlatButton (g, cb, textBounds, imageBounds, clipRectangle); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawCheckBoxImage (g, cb, imageBounds); + + if (cb.Focused && cb.Enabled && cb.ShowFocusCues && textBounds != Rectangle.Empty) + DrawCheckBoxFocus (g, cb, textBounds); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawCheckBoxText (g, cb, textBounds); + } + + public virtual void DrawCheckBoxGlyph (Graphics g, CheckBox cb, Rectangle glyphArea) + { + if (cb.Pressed) + ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState); + else if (cb.InternalSelected) + ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState); + else if (cb.Entered) + ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState); + else if (!cb.Enabled) + ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState); + else + ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState); + } + + public virtual void DrawCheckBoxFocus (Graphics g, CheckBox cb, Rectangle focusArea) + { + WidgetPaint.DrawFocusRectangle (g, focusArea); + } + + public virtual void DrawCheckBoxImage (Graphics g, CheckBox cb, Rectangle imageBounds) + { + if (cb.Enabled) + g.DrawImage (cb.Image, imageBounds); + else + CPDrawImageDisabled (g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawCheckBoxText (Graphics g, CheckBox cb, Rectangle textBounds) + { + if (cb.Enabled) + TextRenderer.DrawTextInternal (g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering); + else + DrawStringDisabled20 (g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering); + } + + public override void CalculateCheckBoxTextAndImageLayout (ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle) + { + int check_size = CheckSize; + + if (button is CheckBox) + check_size = (button as CheckBox).Appearance == Appearance.Normal ? check_size : 0; + + glyphArea = new Rectangle (button.Padding.Left, button.Padding.Top, check_size, check_size); + + Rectangle content_rect = button.PaddingClientRectangle; + ContentAlignment align = ContentAlignment.TopLeft; + + if (button is CheckBox) + align = (button as CheckBox).CheckAlign; + else if (button is RadioButton) + align = (button as RadioButton).CheckAlign; + + switch (align) { + case ContentAlignment.BottomCenter: + glyphArea.Y += content_rect.Height - check_size - 2; + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.BottomLeft: + glyphArea.Y += content_rect.Height - check_size - 2; + content_rect.Width -= check_size; + content_rect.Offset (check_size, 0); + break; + case ContentAlignment.BottomRight: + glyphArea.Y += content_rect.Height - check_size - 2; + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + case ContentAlignment.MiddleCenter: + glyphArea.Y += (content_rect.Height - check_size) / 2; + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.MiddleLeft: + glyphArea.Y += (content_rect.Height - check_size) / 2; + content_rect.Width -= check_size; + content_rect.Offset (check_size, 0); + break; + case ContentAlignment.MiddleRight: + glyphArea.Y += (content_rect.Height - check_size) / 2; + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + case ContentAlignment.TopCenter: + glyphArea.X += (content_rect.Width - check_size) / 2; + break; + case ContentAlignment.TopLeft: + content_rect.Width -= check_size; + content_rect.Offset (check_size, 0); + break; + case ContentAlignment.TopRight: + glyphArea.X += content_rect.Width - check_size; + content_rect.Width -= check_size; + break; + } + + Image image = button.Image; + string text = button.Text; + + Size proposed = Size.Empty; + + // Force wrapping if we aren't AutoSize and our text is too long + if (!button.AutoSize) + proposed.Width = button.PaddingClientRectangle.Width - glyphArea.Width - 2; + + Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, proposed, button.TextFormatFlags, button.UseCompatibleTextRendering); + + // Text can't be bigger than the content rectangle + text_size.Height = Math.Min (text_size.Height, content_rect.Height); + text_size.Width = Math.Min (text_size.Width, content_rect.Width); + + Size image_size = image == null ? Size.Empty : image.Size; + + textRectangle = Rectangle.Empty; + imageRectangle = Rectangle.Empty; + + switch (button.TextImageRelation) { + case TextImageRelation.Overlay: + // Text is centered vertically, and 2 pixels to the right + textRectangle.X = content_rect.Left + 2; + textRectangle.Y = button.PaddingClientRectangle.Top + ((content_rect.Height - text_size.Height) / 2) - 1; + textRectangle.Size = text_size; + + // Image is dependent on ImageAlign + if (image == null) + return; + + int image_x = button.PaddingClientRectangle.Left; + int image_y = button.PaddingClientRectangle.Top; + int image_height = image.Height; + int image_width = image.Width; + + switch (button.ImageAlign) { + case System.Drawing.ContentAlignment.TopLeft: + image_x += 5; + image_y += 5; + break; + case System.Drawing.ContentAlignment.TopCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += 5; + break; + case System.Drawing.ContentAlignment.TopRight: + image_x += content_rect.Width - image_width - 5; + image_y += 5; + break; + case System.Drawing.ContentAlignment.MiddleLeft: + image_x += 5; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.MiddleRight: + image_x += content_rect.Width - image_width - 4; + image_y += (content_rect.Height - image_height) / 2; + break; + case System.Drawing.ContentAlignment.BottomLeft: + image_x += 5; + image_y += content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomCenter: + image_x += (content_rect.Width - image_width) / 2; + image_y += content_rect.Height - image_height - 4; + break; + case System.Drawing.ContentAlignment.BottomRight: + image_x += content_rect.Width - image_width - 4; + image_y += content_rect.Height - image_height - 4; + break; + default: + image_x += 5; + image_y += 5; + break; + } + + imageRectangle = new Rectangle (image_x + check_size, image_y, image_width, image_height); + break; + case TextImageRelation.ImageAboveText: + content_rect.Inflate (-4, -4); + LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextAboveImage: + content_rect.Inflate (-4, -4); + LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, false, out textRectangle, out imageRectangle); + break; + case TextImageRelation.ImageBeforeText: + content_rect.Inflate (-4, -4); + LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + case TextImageRelation.TextBeforeImage: + content_rect.Inflate (-4, -4); + LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle); + break; + } + } + + public override Size CalculateCheckBoxAutoSize (CheckBox checkBox) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal (checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering); + Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size; + + // Pad the text size + if (checkBox.Text.Length != 0) { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (checkBox.TextImageRelation) { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max (checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max (text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (checkBox.Padding.Vertical); + ret_size.Width += (checkBox.Padding.Horizontal) + 15; + + // There seems to be a minimum height + if (ret_size.Height == checkBox.Padding.Vertical) + ret_size.Height += 14; + + return ret_size; + } + + public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) { + StringFormat text_format; + Rectangle client_rectangle; + Rectangle text_rectangle; + Rectangle checkbox_rectangle; + int checkmark_size = CheckSize; + int checkmark_space = 4; + + client_rectangle = checkbox.ClientRectangle; + text_rectangle = client_rectangle; + checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size); + + text_format = new StringFormat(); + text_format.Alignment = StringAlignment.Near; + text_format.LineAlignment = StringAlignment.Center; + if (checkbox.ShowKeyboardCuesInternal) + text_format.HotkeyPrefix = HotkeyPrefix.Show; + else + text_format.HotkeyPrefix = HotkeyPrefix.Hide; + + /* Calculate the position of text and checkbox rectangle */ + if (checkbox.appearance!=Appearance.Button) { + switch(checkbox.check_alignment) { + case ContentAlignment.BottomCenter: { + checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2; + checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + text_rectangle.Height=client_rectangle.Height-checkbox_rectangle.Y-checkmark_space; + break; + } + + case ContentAlignment.BottomLeft: { + checkbox_rectangle.X=client_rectangle.Left; + checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size; + text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.BottomRight: { + checkbox_rectangle.X=client_rectangle.Right-checkmark_size; + checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.MiddleCenter: { + checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2; + checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + break; + } + + default: + case ContentAlignment.MiddleLeft: { + checkbox_rectangle.X=client_rectangle.Left; + checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2; + text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.MiddleRight: { + checkbox_rectangle.X=client_rectangle.Right-checkmark_size; + checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.TopCenter: { + checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2; + checkbox_rectangle.Y=client_rectangle.Top; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + text_rectangle.Y=checkmark_size+checkmark_space; + text_rectangle.Height=client_rectangle.Height-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.TopLeft: { + checkbox_rectangle.X=client_rectangle.Left; + text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + + case ContentAlignment.TopRight: { + checkbox_rectangle.X=client_rectangle.Right-checkmark_size; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space; + break; + } + } + } else { + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + } + + /* Set the horizontal alignment of our text */ + switch(checkbox.text_alignment) { + case ContentAlignment.BottomLeft: + case ContentAlignment.MiddleLeft: + case ContentAlignment.TopLeft: { + text_format.Alignment=StringAlignment.Near; + break; + } + + case ContentAlignment.BottomCenter: + case ContentAlignment.MiddleCenter: + case ContentAlignment.TopCenter: { + text_format.Alignment=StringAlignment.Center; + break; + } + + case ContentAlignment.BottomRight: + case ContentAlignment.MiddleRight: + case ContentAlignment.TopRight: { + text_format.Alignment=StringAlignment.Far; + break; + } + } + + /* Set the vertical alignment of our text */ + switch(checkbox.text_alignment) { + case ContentAlignment.TopLeft: + case ContentAlignment.TopCenter: + case ContentAlignment.TopRight: { + text_format.LineAlignment=StringAlignment.Near; + break; + } + + case ContentAlignment.BottomLeft: + case ContentAlignment.BottomCenter: + case ContentAlignment.BottomRight: { + text_format.LineAlignment=StringAlignment.Far; + break; + } + + case ContentAlignment.MiddleLeft: + case ContentAlignment.MiddleCenter: + case ContentAlignment.MiddleRight: { + text_format.LineAlignment=StringAlignment.Center; + break; + } + } + + ButtonState state = ButtonState.Normal; + if (checkbox.FlatStyle == FlatStyle.Flat) { + state |= ButtonState.Flat; + } + + if (checkbox.Checked) { + state |= ButtonState.Checked; + } + + if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) { + state |= ButtonState.Checked; + state |= ButtonState.Pushed; + } + + // finally make sure the pushed and inavtive states are rendered + if (!checkbox.Enabled) { + state |= ButtonState.Inactive; + } + else if (checkbox.is_pressed) { + state |= ButtonState.Pushed; + } + + // Start drawing + + CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle); + + if ((checkbox.image != null) || (checkbox.image_list != null)) + ButtonBase_DrawImage(checkbox, dc); + + CheckBox_DrawText(checkbox, text_rectangle, dc, text_format); + + if (checkbox.Focused && checkbox.Enabled && checkbox.appearance != Appearance.Button && checkbox.Text != String.Empty && checkbox.ShowFocusCues) { + SizeF text_size = dc.MeasureString (checkbox.Text, checkbox.Font); + + Rectangle focus_rect = Rectangle.Empty; + focus_rect.X = text_rectangle.X; + focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2); + focus_rect.Size = text_size.ToSize (); + CheckBox_DrawFocus (checkbox, dc, focus_rect); + } + + text_format.Dispose (); + } + + protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle ) + { + Brush brush = checkbox.BackColor.ToArgb () == ColorControl.ToArgb () ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor); + dc.FillRectangle (brush, checkbox.ClientRectangle); + // render as per normal button + if (checkbox.appearance==Appearance.Button) { + ButtonBase_DrawButton (checkbox, dc); + + if ((checkbox.Focused) && checkbox.Enabled) + ButtonBase_DrawFocus(checkbox, dc); + } else { + // establish if we are rendering a flat style of some sort + if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) { + DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox); + } else { + CPDrawCheckBox (dc, checkbox_rectangle, state); + } + } + } + + protected virtual void CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format ) + { + DrawCheckBox_and_RadioButtonText (checkbox, text_rectangle, dc, + text_format, checkbox.Appearance, checkbox.Checked); + } + + protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle ) + { + DrawInnerFocusRectangle (dc, text_rectangle, checkbox.BackColor); + } + + // renders a checkBox with the Flat and Popup FlatStyle + protected virtual void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox) + { + Pen pen; + Rectangle rect; + Rectangle checkbox_rectangle; + Rectangle fill_rectangle; + int lineWidth; + int Scale; + + // set up our rectangles first + if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) { + // clip one pixel from bottom right for non popup rendered checkboxes + checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0)); + 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)); + } else { + // clip two pixels from bottom right for non popup rendered checkboxes + checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0)); + 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)); + } + + + // if disabled render in disabled state + if (checkbox.Enabled) { + // process the state of the checkbox + if (checkbox.is_entered || checkbox.Capture) { + // decide on which background color to use + if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) { + graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle); + } else if (checkbox.FlatStyle == FlatStyle.Flat) { + if (!checkbox.is_pressed) { + graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle); + } else + graphics.FillRectangle(ResPool.GetSolidBrush (WidgetPaint.LightLight (checkbox.BackColor)), fill_rectangle); + } else { + // use regular window background color + graphics.FillRectangle(ResPool.GetSolidBrush (WidgetPaint.LightLight (checkbox.BackColor)), fill_rectangle); + } + + // render the outer border + if (checkbox.FlatStyle == FlatStyle.Flat) { + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid); + } else { + // draw sunken effect + CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, checkbox.BackColor); + } + } else { + graphics.FillRectangle(ResPool.GetSolidBrush (WidgetPaint.LightLight (checkbox.BackColor)), fill_rectangle); + + if (checkbox.FlatStyle == FlatStyle.Flat) { + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid); + } else { + // draw the outer border + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, WidgetPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid); + } + } + } else { + if (checkbox.FlatStyle == FlatStyle.Popup) { + graphics.FillRectangle(SystemBrushes.Control, fill_rectangle); + } + + // draw disabled state, + WidgetPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid); + } + + if (checkbox.Checked) { + /* Need to draw a check-mark */ + + /* Make sure we've got at least a line width of 1 */ + lineWidth = Math.Max(3, fill_rectangle.Width/3); + Scale=Math.Max(1, fill_rectangle.Width/9); + + // flat style check box is rendered inside a rectangle shifted down by one + rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height); + if (checkbox.Enabled) { + pen=ResPool.GetPen(checkbox.ForeColor); + } else { + pen=SystemPens.ControlDark; + } + + for (int i=0; i<lineWidth; i++) { + graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i); + 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); + } + } + } + + private void DrawCheckBox_and_RadioButtonText (ButtonBase button_base, Rectangle text_rectangle, Graphics dc, + StringFormat text_format, Appearance appearance, bool ischecked) + { + // offset the text if it's pressed and a button + if (appearance == Appearance.Button) { + if (ischecked || (button_base.Capture && button_base.FlatStyle != FlatStyle.Flat)) { + text_rectangle.X ++; + text_rectangle.Y ++; + } + + text_rectangle.Inflate (-4, -4); + } + + /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */ + + // Windows seems to not wrap text in certain situations, this matches as close as I could get it + if ((float)(button_base.Font.Height * 1.5f) > text_rectangle.Height) { + text_format.FormatFlags |= StringFormatFlags.NoWrap; + } + if (button_base.Enabled) { + dc.DrawString (button_base.Text, button_base.Font, ResPool.GetSolidBrush (button_base.ForeColor), text_rectangle, text_format); + } else if (button_base.FlatStyle == FlatStyle.Flat || button_base.FlatStyle == FlatStyle.Popup) { + dc.DrawString (button_base.Text, button_base.Font, SystemBrushes.ControlDarkDark, text_rectangle, text_format); + } else { + CPDrawStringDisabled (dc, button_base.Text, button_base.Font, button_base.BackColor, text_rectangle, text_format); + } + } + #endregion // CheckBox + + #region CheckedListBox + + public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + Rectangle item_rect = e.Bounds; + ButtonState state; + + /* Draw checkbox */ + + if ((e.State & DrawItemState.Checked) == DrawItemState.Checked) { + state = ButtonState.Checked; + if ((e.State & DrawItemState.Inactive) == DrawItemState.Inactive) + state |= ButtonState.Inactive; + } else + state = ButtonState.Normal; + + if (ctrl.ThreeDCheckBoxes == false) + state |= ButtonState.Flat; + + Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, CheckSize, CheckSize); + WidgetPaint.DrawCheckBox (e.Graphics, + item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y, + checkbox_rect.Width, checkbox_rect.Height, + state); + + item_rect.X += checkbox_rect.Right; + item_rect.Width -= checkbox_rect.Right; + + /* Draw text*/ + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } + else { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + e.Graphics.FillRectangle (ResPool.GetSolidBrush + (back_color), item_rect); + + e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush (fore_color), + item_rect, ctrl.StringFormat); + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) { + CPDrawFocusRectangle (e.Graphics, item_rect, + fore_color, back_color); + } + } + + #endregion // CheckedListBox + + #region ComboBox + public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + Rectangle text_draw = e.Bounds; + StringFormat string_format = new StringFormat (); + string_format.FormatFlags = StringFormatFlags.LineLimit; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } + else { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + if (!ctrl.Enabled) + fore_color = ColorInactiveCaptionText; + + e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds); + + if (e.Index != -1) { + e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush (fore_color), + text_draw, string_format); + } + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) { + CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color); + } + + string_format.Dispose (); + } + + public override void DrawFlatStyleComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) + { + Point[] arrow = new Point[3]; + Point P1; + Point P2; + Point P3; + int centerX; + int centerY; + int shiftX; + int shiftY; + Rectangle rect; + + rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2); + centerX=rect.Left+rect.Width/2; + centerY=rect.Top+rect.Height/2; + shiftX=Math.Max(1, rect.Width/8); + shiftY=Math.Max(1, rect.Height/8); + + if ((state & ButtonState.Pushed)!=0) { + shiftX++; + shiftY++; + } + + rect.Y-=shiftY; + centerY-=shiftY; + P1=new Point(rect.Left + 1, centerY); + P2=new Point(rect.Right - 1, centerY); + P3=new Point(centerX, rect.Bottom - 1); + + arrow[0]=P1; + arrow[1]=P2; + arrow[2]=P3; + + /* Draw the arrow */ + if ((state & ButtonState.Inactive)!=0) { + /* Move away from the shadow */ + arrow[0].X += 1; arrow[0].Y += 1; + arrow[1].X += 1; arrow[1].Y += 1; + arrow[2].X += 1; arrow[2].Y += 1; + + graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding); + + arrow[0]=P1; + arrow[1]=P2; + arrow[2]=P3; + + graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding); + } else { + graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding); + } + } + public override void ComboBoxDrawNormalDropDownButton (ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state) + { + CPDrawComboButton (g, area, state); + } + public override bool ComboBoxNormalDropDownButtonHasTransparentBackground (ComboBox comboBox, ButtonState state) + { + return true; + } + public override bool ComboBoxDropDownButtonHasHotElementStyle (ComboBox comboBox) + { + return false; + } + public override void ComboBoxDrawBackground (ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style) + { + if (!comboBox.Enabled) + g.FillRectangle (ResPool.GetSolidBrush (ColorControl), comboBox.ClientRectangle); + + if (comboBox.DropDownStyle == ComboBoxStyle.Simple) + g.FillRectangle (ResPool.GetSolidBrush (comboBox.Parent.BackColor), comboBox.ClientRectangle); + + if (style == FlatStyle.Popup && (comboBox.Entered || comboBox.Focused)) { + Rectangle area = comboBox.TextArea; + area.Height -= 1; + area.Width -= 1; + g.DrawRectangle (ResPool.GetPen (SystemColors.ControlDark), area); + g.DrawLine (ResPool.GetPen (SystemColors.ControlDark), comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Top, comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Bottom); + } + bool is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup; + if (!is_flat && clippingArea.IntersectsWith (comboBox.TextArea)) + WidgetPaint.DrawBorder3D (g, comboBox.TextArea, Border3DStyle.Sunken); + } + public override bool CombBoxBackgroundHasHotElementStyle (ComboBox comboBox) + { + return false; + } + #endregion ComboBox + + /* FIXME: NEIN. I will NOT port DataGrids over. + #region Datagrid + public override int DataGridPreferredColumnWidth { get { return 75;} } + public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} } + public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} } + public override Color DataGridAlternatingBackColor { get { return ColorWindow;} } + public override Color DataGridBackColor { get { return ColorWindow;} } + public override Color DataGridBackgroundColor { get { return ColorAppWorkspace;} } + public override Color DataGridCaptionBackColor { get { return ColorActiveCaption;} } + public override Color DataGridCaptionForeColor { get { return ColorActiveCaptionText;} } + public override Color DataGridGridLineColor { get { return ColorControl;} } + public override Color DataGridHeaderBackColor { get { return ColorControl;} } + public override Color DataGridHeaderForeColor { get { return ColorControlText;} } + public override Color DataGridLinkColor { get { return ColorHotTrack;} } + public override Color DataGridLinkHoverColor { get { return ColorHotTrack;} } + public override Color DataGridParentRowsBackColor { get { return ColorControl;} } + public override Color DataGridParentRowsForeColor { get { return ColorWindowText;} } + public override Color DataGridSelectionBackColor { get { return ColorActiveCaption;} } + public override Color DataGridSelectionForeColor { get { return ColorActiveCaptionText;} } + + public override void DataGridPaint (PaintEventArgs pe, DataGrid grid) + { + DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid); + DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid); + + // Paint scrollBar corner + if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) { + + Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.VScrollBar.Width, + grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.HScrollBar.Height, + grid.VScrollBar.Width, grid.HScrollBar.Height); + + if (pe.ClipRectangle.IntersectsWith (corner)) { + pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), + corner); + } + } + } + + public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid) + { + Rectangle bounds = clip; + bounds.Intersect (grid.caption_area); + + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor), bounds); + + // Bottom line + g.DrawLine (ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds.X, bounds.Y + bounds.Height -1, + bounds.X + bounds.Width, bounds.Y + bounds.Height -1); + + // Caption text + if (grid.CaptionText != String.Empty) { + Rectangle text_rect = grid.caption_area; + text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2; + text_rect.Height = grid.CaptionFont.Height; + + g.DrawString (grid.CaptionText, grid.CaptionFont, + ResPool.GetSolidBrush (grid.CaptionForeColor), + text_rect); + } + + // Back button + if (bounds.IntersectsWith (grid.back_button_rect)) { + g.DrawImage (grid.back_button_image, grid.back_button_rect); + if (grid.back_button_mouseover) { + CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides); + } + } + + // Rows button + if (bounds.IntersectsWith (grid.parent_rows_button_rect)) { + g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect); + if (grid.parent_rows_button_mouseover) { + CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides); + } + } + } + + public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid) + { + if (!grid.CurrentTableStyle.ColumnHeadersVisible) + return; + + Rectangle columns_area = grid.column_headers_area; + + // Paint corner shared between row and column header + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + Rectangle rect_bloc = grid.column_headers_area; + rect_bloc.Width = grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_bloc)) { + if (grid.FlatMode) + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc); + else + CPDrawBorder3D (g, rect_bloc, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Middle, + grid.CurrentTableStyle.CurrentHeaderBackColor); + } + + columns_area.X += grid.RowHeaderWidth; + columns_area.Width -= grid.RowHeaderWidth; + } + + // Set column painting + Rectangle rect_columnhdr = new Rectangle (); + int col_pixel; + Region current_clip; + Region prev_clip = g.Clip; + rect_columnhdr.Y = columns_area.Y; + rect_columnhdr.Height = columns_area.Height; + + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + + col_pixel = grid.GetColumnStartingPixel (column); + rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset; + rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width; + + if (clip.IntersectsWith (rect_columnhdr) == false) + continue; + + current_clip = new Region (rect_columnhdr); + current_clip.Intersect (columns_area); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + DataGridPaintColumnHeader (g, rect_columnhdr, grid, column); + + current_clip.Dispose (); + } + + g.Clip = prev_clip; + + Rectangle not_usedarea = grid.column_headers_area; + not_usedarea.X = (column_cnt == 0) ? grid.RowHeaderWidth : rect_columnhdr.X + rect_columnhdr.Width; + not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - not_usedarea.X; + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea); + } + + public override void DataGridPaintColumnHeader (Graphics g, Rectangle bounds, DataGrid grid, int col) + { + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.HeaderBackColor), bounds); + + // Paint Borders + if (!grid.FlatMode) { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y); + + if (col == 0) { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height); + } else { + g.DrawLine (ResPool.GetPen (ColorControlLightLight), + bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 3); + } + + if (col == (grid.VisibleColumnCount -1)) { + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X + bounds.Width - 1, bounds.Y, + bounds.X + bounds.Width - 1, bounds.Y + bounds.Height); + } else { + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X + bounds.Width - 1, bounds.Y + 2, + bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 3); + } + + g.DrawLine (ResPool.GetPen (ColorControlDark), + bounds.X, bounds.Y + bounds.Height - 1, + bounds.X + bounds.Width, bounds.Y + bounds.Height - 1); + } + + bounds.X += 2; + bounds.Width -= 2; + + DataGridColumnStyle style = grid.CurrentTableStyle.GridColumnStyles[col]; + + if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) + bounds.Width -= 16; + + // Caption + StringFormat format = new StringFormat (); + format.FormatFlags |= StringFormatFlags.NoWrap; + format.LineAlignment = StringAlignment.Center; + format.Trimming = StringTrimming.Character; + + g.DrawString (style.HeaderText, grid.CurrentTableStyle.HeaderFont, + ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds, format); + + // Arrow (6 x 6) + if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) { + Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2)); + + if (style.ArrowDrawingMode == DataGridColumnStyle.ArrowDrawing.Ascending) { + g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y); + } else { + g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y); + g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6); + } + } + } + + public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid) + { + Rectangle rect_row = new Rectangle (); + + rect_row.X = grid.ParentRowsArea.X; + rect_row.Width = grid.ParentRowsArea.Width; + rect_row.Height = (grid.CaptionFont.Height + 3); + + object[] parentRows = grid.data_source_stack.ToArray(); + + Region current_clip; + Region prev_clip = g.Clip; + for (int row = 0; row < parentRows.Length; row++) { + rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height; + + if (clip.IntersectsWith (rect_row) == false) + continue; + + current_clip = new Region (rect_row); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid); + + current_clip.Dispose (); + } + + g.Clip = prev_clip; + } + + public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid) + { + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), + bounds); + + Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold); + // set up some standard string formating variables + StringFormat text_format = new StringFormat(); + text_format.LineAlignment = StringAlignment.Center; + text_format.Alignment = StringAlignment.Near; + + string table_name = ""; + if (row.view is DataRowView) + table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": "; + // XXX else? + + Rectangle text_rect; + Size text_size; + + text_size = g.MeasureString (table_name, bold_font).ToSize(); + text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size); + + g.DrawString (table_name, + bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format); + + foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) { + if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType)) + continue; + + text_rect.X += text_rect.Size.Width + 5; + + string text = String.Format ("{0}: {1}", + pd.Name, + pd.GetValue (row.view)); + + text_rect.Size = g.MeasureString (text, grid.Font).ToSize(); + text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX + + g.DrawString (text, + grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format); + } + + // Paint Borders + if (!grid.FlatMode) { + CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom); + } + } + + public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) + { + Point[] arrow = new Point[3]; + Point P1, P2, P3; + int centerX, centerY, shiftX; + Rectangle rect; + + rect = new Rectangle (bounds.X + bounds.Width /4, + bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2); + + centerX = rect.Left + rect.Width / 2; + centerY = rect.Top + rect.Height / 2; + shiftX = Math.Max (1, rect.Width / 8); + rect.X -= shiftX; + centerX -= shiftX; + P1 = new Point (centerX, rect.Top - 1); + P2 = new Point (centerX, rect.Bottom); + P3 = new Point (rect.Right, centerY); + arrow[0] = P1; + arrow[1] = P2; + arrow[2] = P3; + + g.FillPolygon (ResPool.GetSolidBrush + (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding); + } + + public override void DataGridPaintRowHeaderStar (Graphics g, Rectangle bounds, DataGrid grid) + { + int x = bounds.X + 4; + int y = bounds.Y + 3; + Pen pen = ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor); + + g.DrawLine (pen, x + 4, y, x + 4, y + 8); + g.DrawLine (pen, x, y + 4, x + 8, y + 4); + g.DrawLine (pen, x + 1, y + 1, x + 7, y + 7); + g.DrawLine (pen, x + 7, y + 1, x + 1, y + 7); + } + + public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid) + { + bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1; + bool is_current_row = row == grid.CurrentCell.RowNumber; + + // Background + g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), bounds); + + // Draw arrow + if (is_current_row) { + if (grid.IsChanging) { + g.DrawString ("...", grid.Font, + ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor), + bounds); + } else { + Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18); + DataGridPaintRowHeaderArrow (g, rect, grid); + } + } + else if (is_add_row) { + DataGridPaintRowHeaderStar (g, bounds, grid); + } + + if (!grid.FlatMode && !is_add_row) { + CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, + Border3DSide.Left | Border3DSide.Right | + Border3DSide.Top | Border3DSide.Bottom); + } + } + + public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid) + { + Rectangle rect_row = new Rectangle (); + Rectangle not_usedarea = new Rectangle (); + + int rowcnt = grid.VisibleRowCount; + + bool showing_add_row = false; + + if (grid.RowsCount < grid.DataGridRows.Length) { + /* the table has an add row + + if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) { + showing_add_row = true; + } + } + + rect_row.Width = cells.Width + grid.RowHeadersArea.Width; + for (int r = 0; r < rowcnt; r++) { + int row = grid.FirstVisibleRow + r; + if (row == grid.DataGridRows.Length - 1) + rect_row.Height = grid.DataGridRows[row].Height; + else + rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset; + rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset; + if (clip.IntersectsWith (rect_row)) { + if (grid.CurrentTableStyle.HasRelations + && !(showing_add_row && row == grid.DataGridRows.Length - 1)) + DataGridPaintRelationRow (g, row, rect_row, false, clip, grid); + else + DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid); + } + } + + not_usedarea.X = 0; + // the rowcnt == 0 check is needed because + // otherwise we'd draw over the caption on + // empty datasources (since rect_row would be + // Empty) + if (rowcnt == 0) + not_usedarea.Y = cells.Y; + else + not_usedarea.Y = rect_row.Y + rect_row.Height; + not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height; + not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width; + + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea); + } + + public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + Rectangle rect_header; + Rectangle icon_bounds = new Rectangle (); + Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor); + + /* paint the header if it's visible and intersects the clip + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + rect_header = row_rect; + rect_header.Width = grid.RowHeaderWidth; + row_rect.X += grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_header)) { + DataGridPaintRowHeader (g, rect_header, row, grid); + } + + icon_bounds = rect_header; + icon_bounds.X += icon_bounds.Width / 2; + icon_bounds.Y += 3; + icon_bounds.Width = 8; + icon_bounds.Height = 8; + + g.DrawRectangle (pen, icon_bounds); + + /* the - part of the icon + g.DrawLine (pen, + icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2, + icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2); + + if (!grid.IsExpanded (row)) { + /* the | part of the icon + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2); + } + } + + Rectangle nested_rect = row_rect; + + if (grid.DataGridRows[row].IsExpanded) + nested_rect.Height -= grid.DataGridRows[row].RelationHeight; + + DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid); + + if (grid.DataGridRows[row].IsExpanded) { + // XXX we should create this in the + // datagrid and cache it for use by + // the theme instead of doing it each + // time through here + string[] relations = grid.CurrentTableStyle.Relations; + StringBuilder relation_builder = new StringBuilder (""); + + for (int i = 0; i < relations.Length; i ++) { + if (i > 0) + relation_builder.Append ("\n"); + + relation_builder.Append (relations[i]); + } + string relation_text = relation_builder.ToString (); + + StringFormat string_format = new StringFormat (); + string_format.FormatFlags |= StringFormatFlags.NoWrap; + + + //Region prev_clip = g.Clip; + //Region current_clip; + Rectangle rect_cell = row_rect; + + rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset; + rect_cell.Y += nested_rect.Height; + rect_cell.Height = grid.DataGridRows[row].RelationHeight; + + rect_cell.Width = 0; + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width; + } + rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width); + + g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor), + rect_cell); + + + /* draw the line leading from the +/- to the relation area + Rectangle outline = grid.DataGridRows[row].relation_area; + outline.Y = rect_cell.Y; + outline.Height --; + + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height, + icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2); + + g.DrawLine (pen, + icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2, + outline.X, outline.Y + outline.Height / 2); + + g.DrawRectangle (pen, outline); + + g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor), + outline, string_format); + + if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) { + Rectangle not_usedarea = new Rectangle (); + not_usedarea.X = rect_cell.X + rect_cell.Width; + not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width; + not_usedarea.Y = row_rect.Y; + not_usedarea.Height = row_rect.Height; + if (clip.IntersectsWith (not_usedarea)) + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), + not_usedarea); + } + } + } + + public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + Rectangle rect_cell = new Rectangle (); + int col_pixel; + Color backcolor, forecolor; + Brush backBrush, foreBrush; + Rectangle not_usedarea = Rectangle.Empty; + + rect_cell.Y = row_rect.Y; + rect_cell.Height = row_rect.Height; + + if (grid.IsSelected (row)) { + backcolor = grid.SelectionBackColor; + forecolor = grid.SelectionForeColor; + } else { + if (row % 2 == 0) { + backcolor = grid.BackColor; + } else { + backcolor = grid.AlternatingBackColor; + } + + forecolor = grid.ForeColor; + } + + + backBrush = ResPool.GetSolidBrush (backcolor); + foreBrush = ResPool.GetSolidBrush (forecolor); + + // PaintCells at row, column + int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount; + DataGridCell current_cell = grid.CurrentCell; + + if (column_cnt > 0) { + Region prev_clip = g.Clip; + Region current_clip; + + for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) { + if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false) + continue; + + col_pixel = grid.GetColumnStartingPixel (column); + + rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset; + rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width; + + if (clip.IntersectsWith (rect_cell)) { + current_clip = new Region (rect_cell); + current_clip.Intersect (row_rect); + current_clip.Intersect (prev_clip); + g.Clip = current_clip; + + Brush colBackBrush = backBrush; + Brush colForeBrush = foreBrush; + + // If we are in the precise cell we are editing, then use the normal colors + // even if we are selected. + if (grid.is_editing && column == current_cell.ColumnNumber && row == current_cell.RowNumber) { + colBackBrush = ResPool.GetSolidBrush (grid.BackColor); + colForeBrush = ResPool.GetSolidBrush (grid.ForeColor); + } + + if (is_newrow) { + grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, + colBackBrush, + colForeBrush); + } else { + grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row, + colBackBrush, + colForeBrush, + grid.RightToLeft == RightToLeft.Yes); + } + + current_clip.Dispose (); + } + } + + g.Clip = prev_clip; + + if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) { + not_usedarea.X = rect_cell.X + rect_cell.Width; + not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width; + not_usedarea.Y = row_rect.Y; + not_usedarea.Height = row_rect.Height; + } + } + else { + not_usedarea = row_rect; + } + + if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea)) + g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), + not_usedarea); + } + + public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, + Rectangle clip, DataGrid grid) + { + /* paint the header if it's visible and intersects the clip + if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { + Rectangle rect_header = row_rect; + rect_header.Width = grid.RowHeaderWidth; + row_rect.X += grid.RowHeaderWidth; + if (clip.IntersectsWith (rect_header)) { + DataGridPaintRowHeader (g, rect_header, row, grid); + } + } + + DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid); + } + + #endregion // Datagrid + + #region DataGridView + #region DataGridViewHeaderCell + #region DataGridViewRowHeaderCell + public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + + public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell) + { + return false; + } + + public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + #endregion + + #region DataGridViewColumnHeaderCell + public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + + public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds) + { + return false; + } + #endregion + + public override bool DataGridViewHeaderCellHasPressedStyle (DataGridView dataGridView) + { + return false; + } + + public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView) + { + return false; + } + #endregion + #endregion +*/ + + #region DateTimePicker + protected virtual void DateTimePickerDrawBorder (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + this.CPDrawBorder3D (g, dateTimePicker.ClientRectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dateTimePicker.BackColor); + } + + protected virtual void DateTimePickerDrawDropDownButton (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea) + { + ButtonState state = dateTimePicker.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal; + g.FillRectangle (ResPool.GetSolidBrush (ColorControl), dateTimePicker.drop_down_arrow_rect); + this.CPDrawComboButton ( + g, + dateTimePicker.drop_down_arrow_rect, + state); + } + + public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp) + { + + if (!clip_rectangle.IntersectsWith (dtp.ClientRectangle)) + return; + + // draw the outer border + Rectangle button_bounds = dtp.ClientRectangle; + DateTimePickerDrawBorder (dtp, dc, clip_rectangle); + + // deflate by the border width + if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) { + button_bounds.Inflate (-2,-2); + if (!dtp.ShowUpDown) { + DateTimePickerDrawDropDownButton (dtp, dc, clip_rectangle); + } else { + ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal; + ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal; + Rectangle up_bounds = dtp.drop_down_arrow_rect; + Rectangle down_bounds = dtp.drop_down_arrow_rect; + + up_bounds.Height = up_bounds.Height / 2; + down_bounds.Y = up_bounds.Height; + down_bounds.Height = dtp.Height - up_bounds.Height; + if (down_bounds.Height > up_bounds.Height) + { + down_bounds.Y += 1; + down_bounds.Height -= 1; + } + + up_bounds.Inflate (-1, -1); + down_bounds.Inflate (-1, -1); + + WidgetPaint.DrawScrollButton (dc, up_bounds, ScrollButton.Up, up_state); + WidgetPaint.DrawScrollButton (dc, down_bounds, ScrollButton.Down, down_state); + } + } + + // render the date part + if (!clip_rectangle.IntersectsWith (dtp.date_area_rect)) + return; + + // fill the background + dc.FillRectangle (SystemBrushes.Window, dtp.date_area_rect); + + // Update date_area_rect if we are drawing the checkbox + Rectangle date_area_rect = dtp.date_area_rect; + if (dtp.ShowCheckBox) { + Rectangle check_box_rect = dtp.CheckBoxRect; + date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2; + date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2; + + ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal; + CPDrawCheckBox(dc, check_box_rect, bs); + + if (dtp.is_checkbox_selected) + CPDrawFocusRectangle (dc, check_box_rect, dtp.foreground_color, dtp.background_color); + } + + // render each text part + using (StringFormat text_format = StringFormat.GenericTypographic) + { + text_format.LineAlignment = StringAlignment.Near; + text_format.Alignment = StringAlignment.Near; + text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; + text_format.FormatFlags &= ~StringFormatFlags.NoClip; + + // Calculate the rectangles for each part + if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty) + { + Graphics gr = dc; + for (int i = 0; i < dtp.part_data.Length; i++) + { + DateTimePicker.PartData fd = dtp.part_data[i]; + RectangleF text_rect = new RectangleF(); + string text = fd.GetText(dtp.Value); + text_rect.Size = gr.MeasureString (text, dtp.Font, 250, text_format); + if (!fd.is_literal) + text_rect.Width = Math.Max (dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width); + + if (i > 0) { + text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right; + } else { + text_rect.X = date_area_rect.X; + } + text_rect.Y = 2; + text_rect.Inflate (1, 0); + fd.drawing_rectangle = text_rect; + } + } + + // draw the text part + Brush text_brush = ResPool.GetSolidBrush (dtp.ShowCheckBox && dtp.Checked == false ? + SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false + RectangleF clip_rectangleF = clip_rectangle; + + for (int i = 0; i < dtp.part_data.Length; i++) + { + DateTimePicker.PartData fd = dtp.part_data [i]; + string text; + + if (!clip_rectangleF.IntersectsWith (fd.drawing_rectangle)) + continue; + + text = dtp.editing_part_index == i ? dtp.editing_text : fd.GetText (dtp.Value); + + PointF text_position = new PointF (); + SizeF text_size; + RectangleF text_rect; + + text_size = dc.MeasureString (text, dtp.Font, 250, text_format); + text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2; + text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2; + text_rect = new RectangleF (text_position, text_size); + text_rect = RectangleF.Intersect (text_rect, date_area_rect); + + if (text_rect.IsEmpty) + break; + + if (text_rect.Right >= date_area_rect.Right) + text_format.FormatFlags &= ~StringFormatFlags.NoClip; + else + text_format.FormatFlags |= StringFormatFlags.NoClip; + + if (fd.Selected) { + dc.FillRectangle (SystemBrushes.Highlight, text_rect); + dc.DrawString (text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format); + + } else { + dc.DrawString (text, dtp.Font, text_brush, text_rect, text_format); + } + + if (fd.drawing_rectangle.Right > date_area_rect.Right) + break; // the next part would be not be visible, so don't draw anything more. + } + } + } + + public override bool DateTimePickerBorderHasHotElementStyle { + get { + return false; + } + } + + public override Rectangle DateTimePickerGetDropDownButtonArea (DateTimePicker dateTimePicker) + { + Rectangle rect = dateTimePicker.ClientRectangle; + rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2; + if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) { + rect.Width = SystemInformation.VerticalScrollBarWidth; + } else { + rect.Width = Math.Max (rect.Width - 2, 0); + } + + rect.Inflate (0, -2); + return rect; + } + + public override Rectangle DateTimePickerGetDateArea (DateTimePicker dateTimePicker) + { + Rectangle rect = dateTimePicker.ClientRectangle; + if (dateTimePicker.ShowUpDown) { + // set the space to the left of the up/down button + if (rect.Width > (DateTimePicker.up_down_width + 4)) { + rect.Width -= (DateTimePicker.up_down_width + 4); + } else { + rect.Width = 0; + } + } else { + // set the space to the left of the up/down button + // TODO make this use up down button + if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) { + rect.Width -= SystemInformation.VerticalScrollBarWidth; + } else { + rect.Width = 0; + } + } + + rect.Inflate (-2, -2); + return rect; + } + public override bool DateTimePickerDropDownButtonHasHotElementStyle { + get { + return false; + } + } + #endregion // DateTimePicker + + #region GroupBox + public override void DrawGroupBox (Graphics dc, Rectangle area, GroupBox box) { + StringFormat text_format; + SizeF size; + int width; + int y; + + dc.FillRectangle (GetControlBackBrush (box.BackColor), box.ClientRectangle); + + text_format = new StringFormat(); + text_format.HotkeyPrefix = HotkeyPrefix.Show; + + size = dc.MeasureString (box.Text, box.Font); + width = 0; + + if (size.Width > 0) { + width = ((int) size.Width) + 7; + + if (width > box.Width - 16) + width = box.Width - 16; + } + + y = box.Font.Height / 2; + + // Clip the are that the text will be in + Region prev_clip = dc.Clip; + dc.SetClip (new Rectangle (10, 0, width, box.Font.Height), CombineMode.Exclude); + /* Draw group box*/ + CPDrawBorder3D (dc, new Rectangle (0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor); + dc.Clip = prev_clip; + + /* Text */ + if (box.Text.Length != 0) { + if (box.Enabled) { + dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format); + } else { + CPDrawStringDisabled (dc, box.Text, box.Font, box.BackColor, + new RectangleF (10, 0, width, box.Font.Height), text_format); + } + } + + text_format.Dispose (); + } + + public override Size GroupBoxDefaultSize { + get { + return new Size (200,100); + } + } + #endregion + + #region HScrollBar + public override Size HScrollBarDefaultSize { + get { + return new Size (80, this.ScrollBarButtonSize); + } + } + + #endregion // HScrollBar + + #region ListBox + + public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e) + { + Color back_color, fore_color; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { + back_color = ColorHighlight; + fore_color = ColorHighlightText; + } else { + back_color = e.BackColor; + fore_color = e.ForeColor; + } + + e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds); + + e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font, + ResPool.GetSolidBrush (fore_color), + e.Bounds, ctrl.StringFormat); + + if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) + CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color); + } + + #endregion ListBox + + #region ListView + // Drawing + public override void DrawListViewItems (Graphics dc, Rectangle clip, ListView control) + { + bool details = control.View == View.Details; + int first = control.FirstVisibleIndex; + int lastvisibleindex = control.LastVisibleIndex; + + if (control.VirtualMode) + control.OnCacheVirtualItems (new CacheVirtualItemsEventArgs (first, lastvisibleindex)); + + for (int i = first; i <= lastvisibleindex; i++) { + ListViewItem item = control.GetItemAtDisplayIndex (i); + if (clip.IntersectsWith (item.Bounds)) { + bool owner_draw = false; + if (control.OwnerDraw) + owner_draw = DrawListViewItemOwnerDraw (dc, item, i); + if (!owner_draw) + { + DrawListViewItem (dc, control, item); + if (control.View == View.Details) + DrawListViewSubItems (dc, control, item); + } + } + } + + if (control.UsingGroups) { + // Use InternalCount instead of Count to take into account Default Group as needed + for (int i = 0; i < control.Groups.InternalCount; i++) { + ListViewGroup group = control.Groups.GetInternalGroup (i); + if (group.ItemCount > 0 && clip.IntersectsWith (group.HeaderBounds)) + DrawListViewGroupHeader (dc, control, group); + } + } + + ListViewInsertionMark insertion_mark = control.InsertionMark; + int insertion_mark_index = insertion_mark.Index; + if (Application.VisualStylesEnabled && insertion_mark.Bounds != Rectangle.Empty && + (control.View != View.Details && control.View != View.List) && + insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) { + + Brush brush = ResPool.GetSolidBrush (insertion_mark.Color); + dc.FillRectangle (brush, insertion_mark.Line); + dc.FillPolygon (brush, insertion_mark.TopTriangle); + dc.FillPolygon (brush, insertion_mark.BottomTriangle); + } + + // draw the gridlines + if (details && control.GridLines && !control.UsingGroups) { + Size control_size = control.ClientSize; + int top = (control.HeaderStyle == ColumnHeaderStyle.None) ? + 0 : control.header_control.Height; + + // draw vertical gridlines + foreach (ColumnHeader col in control.Columns) { + int column_right = col.Rect.Right - control.h_marker; + dc.DrawLine (SystemPens.Control, + column_right, top, + column_right, control_size.Height); + } + + // draw horizontal gridlines + int item_height = control.ItemSize.Height; + if (item_height == 0) + item_height = control.Font.Height + 2; + + int y = top + item_height - (control.v_marker % item_height); // scroll bar offset + while (y < control_size.Height) { + dc.DrawLine (SystemPens.Control, 0, y, control_size.Width, y); + y += item_height; + } + } + + // Draw corner between the two scrollbars + if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) { + Rectangle rect = new Rectangle (); + rect.X = control.h_scroll.Location.X + control.h_scroll.Width; + rect.Width = control.v_scroll.Width; + rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height; + rect.Height = control.h_scroll.Height; + dc.FillRectangle (SystemBrushes.Control, rect); + } + + Rectangle box_select_rect = control.item_control.BoxSelectRectangle; + if (!box_select_rect.Size.IsEmpty) + dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect); + + } + + public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control) + { + bool details = (control.View == View.Details); + + // border is drawn directly in the Paint method + if (details && control.HeaderStyle != ColumnHeaderStyle.None) { + dc.FillRectangle (SystemBrushes.Control, + 0, 0, control.TotalWidth, control.Font.Height + 5); + if (control.Columns.Count > 0) { + foreach (ColumnHeader col in control.Columns) { + Rectangle rect = col.Rect; + rect.X -= control.h_marker; + + bool owner_draw = false; + if (control.OwnerDraw) + owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect); + if (owner_draw) + continue; + + ListViewDrawColumnHeaderBackground (control, col, dc, rect, clip); + rect.X += 5; + rect.Width -= 10; + if (rect.Width <= 0) + continue; + + int image_index; + if (control.SmallImageList == null) + image_index = -1; + else + image_index = col.ImageKey == String.Empty ? col.ImageIndex : control.SmallImageList.Images.IndexOfKey (col.ImageKey); + + if (image_index > -1 && image_index < control.SmallImageList.Images.Count) { + int image_width = control.SmallImageList.ImageSize.Width + 5; + int text_width = (int)dc.MeasureString (col.Text, control.Font).Width; + int x_origin = rect.X; + int y_origin = rect.Y + ((rect.Height - control.SmallImageList.ImageSize.Height) / 2); + + switch (col.TextAlign) { + case HorizontalAlignment.Left: + break; + case HorizontalAlignment.Right: + x_origin = rect.Right - (text_width + image_width); + break; + case HorizontalAlignment.Center: + x_origin = (rect.Width - (text_width + image_width)) / 2 + rect.X; + break; + } + + if (x_origin < rect.X) + x_origin = rect.X; + + control.SmallImageList.Draw (dc, new Point (x_origin, y_origin), image_index); + rect.X += image_width; + rect.Width -= image_width; + } + + dc.DrawString (col.Text, control.Font, SystemBrushes.ControlText, rect, col.Format); + } + int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker; + if (right < control.Right) { + Rectangle rect = control.Columns [0].Rect; + rect.X = right; + rect.Width = control.Right - right; + ListViewDrawUnusedHeaderBackground (control, dc, rect, clip); + } + } + } + } + + protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea) + { + ButtonState state; + if (listView.HeaderStyle == ColumnHeaderStyle.Clickable) + state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal; + else + state = ButtonState.Flat; + CPDrawButton (g, area, state); + } + + protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea) + { + ButtonState state; + if (listView.HeaderStyle == ColumnHeaderStyle.Clickable) + state = ButtonState.Normal; + else + state = ButtonState.Flat; + CPDrawButton (g, area, state); + } + + public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x) + { + Rectangle rect = col.Rect; + rect.X -= view.h_marker; + Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B); + dc.FillRectangle (ResPool.GetSolidBrush (color), rect); + rect.X += 3; + rect.Width -= 8; + if (rect.Width <= 0) + return; + color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B); + dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format); + dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height); + } + + protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds) + { + ListViewItemStates state = ListViewItemStates.ShowKeyboardCues; + if (column.Pressed) + state |= ListViewItemStates.Selected; + + DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc, + bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont); + control.OnDrawColumnHeader (args); + + return !args.DrawDefault; + } + + protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index) + { + ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues; + if (item.Selected) + item_state |= ListViewItemStates.Selected; + if (item.Focused) + item_state |= ListViewItemStates.Focused; + + DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc, + item, item.Bounds, index, item_state); + item.ListView.OnDrawItem (args); + + if (args.DrawDefault) + return false; + + if (item.ListView.View == View.Details) { + int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count); + + // Do system drawing for subitems if no owner draw is done + for (int j = 0; j < count; j++) { + if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j)) { + if (j == 0) // The first sub item contains the main item semantics + DrawListViewItem (dc, item.ListView, item); + else + DrawListViewSubItem (dc, item.ListView, item, j); + } + } + } + + return true; + } + + protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item) + { + Rectangle rect_checkrect = item.CheckRectReal; + Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon); + Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire); + Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label); + + // Tile view doesn't support CheckBoxes + if (control.CheckBoxes && control.View != View.Tile) { + if (control.StateImageList == null) { + // Make sure we've got at least a line width of 1 + int check_wd = Math.Max (3, rect_checkrect.Width / 6); + int scale = Math.Max (1, rect_checkrect.Width / 12); + + // set the checkbox background + dc.FillRectangle (SystemBrushes.Window, + rect_checkrect); + // define a rectangle inside the border area + Rectangle rect = new Rectangle (rect_checkrect.X + 2, + rect_checkrect.Y + 2, + rect_checkrect.Width - 4, + rect_checkrect.Height - 4); + Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2); + dc.DrawRectangle (pen, rect); + + // Need to draw a check-mark + if (item.Checked) { + Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1); + // adjustments to get the check-mark at the right place + rect.X ++; rect.Y ++; + // following logic is taken from DrawFrameControl method + int x_offset = rect.Width / 5; + int y_offset = rect.Height / 3; + for (int i = 0; i < check_wd; i++) { + dc.DrawLine (check_pen, rect.Left + x_offset, + rect.Top + y_offset + i, + rect.Left + x_offset + 2 * scale, + rect.Top + y_offset + 2 * scale + i); + dc.DrawLine (check_pen, + rect.Left + x_offset + 2 * scale, + rect.Top + y_offset + 2 * scale + i, + rect.Left + x_offset + 6 * scale, + rect.Top + y_offset - 2 * scale + i); + } + } + } + else { + int simage_idx; + if (item.Checked) + simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1; + else + simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1; + + if (simage_idx > -1) + control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx); + } + } + + ImageList image_list = control.View == View.LargeIcon || control.View == View.Tile ? control.LargeImageList : control.SmallImageList; + if (image_list != null) { + int idx; + + if (item.ImageKey != String.Empty) + idx = image_list.Images.IndexOfKey (item.ImageKey); + else + idx = item.ImageIndex; + + if (idx > -1 && idx < image_list.Images.Count) { + // Draw a thumbnail image if it exists for a FileViewListViewItem, otherwise draw + // the standard icon. See https://bugzilla.xamarin.com/show_bug.cgi?id=28025. + image_list.Draw(dc, icon_rect.Location, idx); + } + } + + // draw the item text + // format for the item text + StringFormat format = new StringFormat (); + if (control.View == View.SmallIcon || control.View == View.LargeIcon) + format.LineAlignment = StringAlignment.Near; + else + format.LineAlignment = StringAlignment.Center; + if (control.View == View.LargeIcon) + format.Alignment = StringAlignment.Center; + else + format.Alignment = StringAlignment.Near; + + if (control.LabelWrap && control.View != View.Details && control.View != View.Tile) + format.FormatFlags = StringFormatFlags.LineLimit; + else + format.FormatFlags = StringFormatFlags.NoWrap; + + if ((control.View == View.LargeIcon && !item.Focused) || control.View == View.Details || control.View == View.Tile) + format.Trimming = StringTrimming.EllipsisCharacter; + + Rectangle highlight_rect = text_rect; + if (control.View == View.Details) { // Adjustments for Details view + Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font)); + + if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds + highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width); + } + + if (item.Selected && control.Focused) + dc.FillRectangle (SystemBrushes.Highlight, highlight_rect); + else if (item.Selected && !control.HideSelection) + dc.FillRectangle (SystemBrushes.Control, highlight_rect); + else + dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect); + + Brush textBrush = + !control.Enabled ? SystemBrushes.ControlLight : + (item.Selected && control.Focused) ? SystemBrushes.HighlightText : + this.ResPool.GetSolidBrush (item.ForeColor); + + // Tile view renders its Text in a different fashion + if (control.View == View.Tile && Application.VisualStylesEnabled) { + // Item.Text is drawn using its first subitem's bounds + dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format); + + int count = Math.Min (control.Columns.Count, item.SubItems.Count); + for (int i = 1; i < count; i++) { + ListViewItem.ListViewSubItem sub_item = item.SubItems [i]; + if (sub_item.Text == null || sub_item.Text.Length == 0) + continue; + + Brush itemBrush = item.Selected && control.Focused ? + SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor); + dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format); + } + } else + + if (item.Text != null && item.Text.Length > 0) { + Font font = item.Font; + + if (control.HotTracking && item.Hot) + font = item.HotFont; + + if (item.Selected && control.Focused) + dc.DrawString (item.Text, font, textBrush, highlight_rect, format); + else + dc.DrawString (item.Text, font, textBrush, text_rect, format); + } + + if (item.Focused && control.Focused) { + Rectangle focus_rect = highlight_rect; + if (control.FullRowSelect && control.View == View.Details) { + int width = 0; + foreach (ColumnHeader col in control.Columns) + width += col.Width; + focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height); + } + if (control.ShowFocusCues) { + if (item.Selected) + CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight); + else + CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor); + } + } + + format.Dispose (); + } + + protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item) + { + int columns_count = control.Columns.Count; + int count = Math.Min (item.SubItems.Count, columns_count); + // 0th item already done (in this case) + for (int i = 1; i < count; i++) + DrawListViewSubItem (dc, control, item, i); + + // Fill in selection for remaining columns if Column.Count > SubItems.Count + Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label); + if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) { + for (int index = count; index < columns_count; index++) { + ColumnHeader col = control.Columns [index]; + sub_item_rect.X = col.Rect.X - control.h_marker; + sub_item_rect.Width = col.Wd; + dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control, + sub_item_rect); + } + } + } + + protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index) + { + ListViewItem.ListViewSubItem subItem = item.SubItems [index]; + ColumnHeader col = control.Columns [index]; + StringFormat format = new StringFormat (); + format.Alignment = col.Format.Alignment; + format.LineAlignment = StringAlignment.Center; + format.FormatFlags = StringFormatFlags.NoWrap; + format.Trimming = StringTrimming.EllipsisCharacter; + + Rectangle sub_item_rect = subItem.Bounds; + Rectangle sub_item_text_rect = sub_item_rect; + sub_item_text_rect.X += 3; + sub_item_text_rect.Width -= ListViewItemPaddingWidth; + + SolidBrush sub_item_back_br = null; + SolidBrush sub_item_fore_br = null; + Font sub_item_font = null; + + if (item.UseItemStyleForSubItems) { + sub_item_back_br = ResPool.GetSolidBrush (item.BackColor); + sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor); + + // Hot tracking for subitems only applies when UseStyle is true + if (control.HotTracking && item.Hot) + sub_item_font = item.HotFont; + else + sub_item_font = item.Font; + } else { + sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor); + sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor); + sub_item_font = subItem.Font; + } + + if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) { + Brush bg, text; + if (control.Focused) { + bg = SystemBrushes.Highlight; + text = SystemBrushes.HighlightText; + } else { + bg = SystemBrushes.Control; + text = sub_item_fore_br; + + } + + dc.FillRectangle (bg, sub_item_rect); + if (subItem.Text != null && subItem.Text.Length > 0) + dc.DrawString (subItem.Text, sub_item_font, + text, sub_item_text_rect, format); + } else { + dc.FillRectangle (sub_item_back_br, sub_item_rect); + if (subItem.Text != null && subItem.Text.Length > 0) + dc.DrawString (subItem.Text, sub_item_font, + sub_item_fore_br, + sub_item_text_rect, format); + } + + format.Dispose (); + } + + protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index) + { + ListView control = item.ListView; + ListViewItem.ListViewSubItem subitem = item.SubItems [index]; + + DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, + subitem, item.Index, index, control.Columns [index], state); + control.OnDrawSubItem (args); + + return !args.DrawDefault; + } + + protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group) + { + Rectangle text_bounds = group.HeaderBounds; + Rectangle header_bounds = group.HeaderBounds; + text_bounds.Offset (8, 0); + text_bounds.Inflate (-8, 0); + int text_height = control.Font.Height + 2; // add a tiny padding between the text and the group line + + Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold); + Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), + SystemColors.Desktop, Color.White); + Pen pen = new Pen (brush); + + StringFormat sformat = new StringFormat (); + switch (group.HeaderAlignment) { + case HorizontalAlignment.Left: + sformat.Alignment = StringAlignment.Near; + break; + case HorizontalAlignment.Center: + sformat.Alignment = StringAlignment.Center; + break; + case HorizontalAlignment.Right: + sformat.Alignment = StringAlignment.Far; + break; + } + + sformat.LineAlignment = StringAlignment.Near; + dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat); + dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_height, header_bounds.Left + ListViewGroupLineWidth, + header_bounds.Top + text_height); + + sformat.Dispose (); + font.Dispose (); + pen.Dispose (); + brush.Dispose (); + } + + public override bool ListViewHasHotHeaderStyle { + get { + return false; + } + } + + // Sizing + public override int ListViewGetHeaderHeight (ListView listView, Font font) + { + return ListViewGetHeaderHeight (font); + } + + static int ListViewGetHeaderHeight (Font font) + { + return font.Height + 5; + } + + public static int ListViewGetHeaderHeight () + { + return ListViewGetHeaderHeight (ThemeEngine.Current.DefaultFont); + } + + public override Size ListViewCheckBoxSize { + get { return new Size (16, 16); } + } + + public override int ListViewColumnHeaderHeight { + get { return 16; } + } + + public override int ListViewDefaultColumnWidth { + get { return 60; } + } + + public override int ListViewVerticalSpacing { + get { return 22; } + } + + public override int ListViewEmptyColumnWidth { + get { return 10; } + } + + public override int ListViewHorizontalSpacing { + get { return 4; } + } + + public override int ListViewItemPaddingWidth { + get { return 6; } + } + + public override Size ListViewDefaultSize { + get { return new Size (121, 97); } + } + + public override int ListViewGroupHeight { + get { return 20; } + } + + public int ListViewGroupLineWidth { + get { return 200; } + } + + public override int ListViewTileWidthFactor { + get { return 22; } + } + + public override int ListViewTileHeightFactor { + get { return 3; } + } + #endregion // ListView + + #region Menus + + public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar) + { + item.X = x; + item.Y = y; + + if (item.Visible == false) { + item.Width = 0; + item.Height = 0; + return; + } + + if (item.Separator == true) { + item.Height = SEPARATOR_HEIGHT; + item.Width = SEPARATOR_MIN_WIDTH; + return; + } + + if (item.MeasureEventDefined) { + MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index); + item.PerformMeasureItem (mi); + item.Height = mi.ItemHeight; + item.Width = mi.ItemWidth; + return; + } else { + SizeF size; + size = dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text); + item.Width = (int) size.Width; + item.Height = (int) size.Height; + + if (!menuBar) { + if (item.Shortcut != Shortcut.None && item.ShowShortcut) { + item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width; + size = dc.MeasureString (" " + item.GetShortCutText (), MenuFont); + item.Width += MENU_TAB_SPACE + (int) size.Width; + } + + item.Width += 4 + (MenuCheckSize.Width * 2); + } else { + item.Width += MENU_BAR_ITEMS_SPACE; + x += item.Width; + } + + if (item.Height < MenuHeight) + item.Height = MenuHeight; + } + } + + // Updates the menu rect and returns the height + public override int CalcMenuBarSize (Graphics dc, Menu menu, int width) + { + int x = 0; + int y = 0; + menu.Height = 0; + + foreach (MenuItem item in menu.MenuItems) { + + CalcItemSize (dc, item, y, x, true); + + if (x + item.Width > width) { + item.X = 0; + y += item.Height; + item.Y = y; + x = 0; + } + + x += item.Width; + item.MenuBar = true; + + if (y + item.Height > menu.Height) + menu.Height = item.Height + y; + } + + menu.Width = width; + return menu.Height; + } + + public override void CalcPopupMenuSize (Graphics dc, Menu menu) + { + int x = 3; + int start = 0; + int i, n, y, max; + + menu.Height = 0; + + while (start < menu.MenuItems.Count) { + y = 3; + max = 0; + for (i = start; i < menu.MenuItems.Count; i++) { + MenuItem item = menu.MenuItems [i]; + + if ((i != start) && (item.Break || item.BarBreak)) + break; + + CalcItemSize (dc, item, y, x, false); + y += item.Height; + + if (item.Width > max) + max = item.Width; + } + + // Replace the -1 by the menu width (separators) + for (n = start; n < i; n++, start++) + menu.MenuItems [n].Width = max; + + if (y > menu.Height) + menu.Height = y; + + x+= max; + } + + menu.Width = x; + + //space for border + menu.Width += 2; + menu.Height += 2; + + menu.Width += SM_CXBORDER; + menu.Height += SM_CYBORDER; + } + + // Draws a menu bar in a window + public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect) + { + if (menu.Height == 0) + CalcMenuBarSize (dc, menu, rect.Width); + + bool keynav = (menu as MainMenu).tracker.hotkey_active; + HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide; + string_format_menu_menubar_text.HotkeyPrefix = hp; + string_format_menu_text.HotkeyPrefix = hp; + + rect.Height = menu.Height; + dc.FillRectangle (SystemBrushes.Menu, rect); + + for (int i = 0; i < menu.MenuItems.Count; i++) { + MenuItem item = menu.MenuItems [i]; + Rectangle item_rect = item.bounds; + item_rect.X += rect.X; + item_rect.Y += rect.Y; + item.MenuHeight = menu.Height; + item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); + } + } + + protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color) + { + Color bg_color; + if (color.R == 0 && color.G == 0 && color.B == 0) + bg_color = Color.White; + else + bg_color = Color.Black; + + Bitmap bmp = new Bitmap (size.Width, size.Height); + Graphics gr = Graphics.FromImage (bmp); + Rectangle rect = new Rectangle (Point.Empty, size); + gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect); + CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty); + bmp.MakeTransparent (bg_color); + gr.Dispose (); + + return bmp; + } + + public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e) + { + StringFormat string_format; + Rectangle rect_text = e.Bounds; + + if (item.Visible == false) + return; + + if (item.MenuBar) + string_format = string_format_menu_menubar_text; + else + string_format = string_format_menu_text; + + if (item.Separator == true) { + int liney = e.Bounds.Y + (e.Bounds.Height / 2); + + e.Graphics.DrawLine (SystemPens.ControlDark, + e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney); + + e.Graphics.DrawLine (SystemPens.ControlLight, + e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1); + + return; + } + + if (!item.MenuBar) + rect_text.X += MenuCheckSize.Width; + + if (item.BarBreak) { /* Draw vertical break bar*/ + Rectangle rect = e.Bounds; + rect.Y++; + rect.Width = 3; + rect.Height = item.MenuHeight - 6; + + e.Graphics.DrawLine (SystemPens.ControlDark, + rect.X, rect.Y , rect.X, rect.Y + rect.Height); + + e.Graphics.DrawLine (SystemPens.ControlLight, + rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height); + } + + Color color_text; + Color color_back; + Brush brush_text = null; + Brush brush_back = null; + + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) { + color_text = ColorHighlightText; + color_back = ColorHighlight; + brush_text = SystemBrushes.HighlightText; + brush_back = SystemBrushes.Highlight; + } else { + color_text = ColorMenuText; + color_back = ColorMenu; + brush_text = ResPool.GetSolidBrush (ColorMenuText); + brush_back = SystemBrushes.Menu; + } + + /* Draw background */ + if (!item.MenuBar) + e.Graphics.FillRectangle (brush_back, e.Bounds); + + if (item.Enabled) { + e.Graphics.DrawString (item.Text, e.Font, + brush_text, + rect_text, string_format); + + if (item.MenuBar) { + Border3DStyle border_style = Border3DStyle.Adjust; + if ((item.Status & DrawItemState.HotLight) != 0) + border_style = Border3DStyle.RaisedInner; + else if ((item.Status & DrawItemState.Selected) != 0) + border_style = Border3DStyle.SunkenOuter; + + if (border_style != Border3DStyle.Adjust) + CPDrawBorder3D(e.Graphics, e.Bounds, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu); + } + } else { + if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) { + e.Graphics.DrawString (item.Text, e.Font, Brushes.White, + new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height), + string_format); + + } + + e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format); + } + + if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) { + string str = item.GetShortCutText (); + Rectangle rect = rect_text; + rect.X = item.XTab; + rect.Width -= item.XTab; + + if (item.Enabled) { + e.Graphics.DrawString (str, e.Font, brush_text, rect, string_format_menu_shortcut); + } else { + if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) { + e.Graphics.DrawString (str, e.Font, Brushes.White, + new RectangleF(rect.X + 1, rect.Y + 1, rect.Width, rect_text.Height), + string_format_menu_shortcut); + + } + e.Graphics.DrawString (str, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect, string_format_menu_shortcut); + } + } + + /* Draw arrow */ + if (item.MenuBar == false && (item.IsPopup || item.MdiList)) { + + int cx = MenuCheckSize.Width; + int cy = MenuCheckSize.Height; + Bitmap bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text); + + if (item.Enabled) { + e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx, + e.Bounds.Y + ((e.Bounds.Height - cy) /2)); + } else { + WidgetPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx, + e.Bounds.Y + ((e.Bounds.Height - cy) /2), color_back); + } + + bmp.Dispose (); + } + + /* Draw checked or radio */ + if (item.MenuBar == false && item.Checked) { + + Rectangle area = e.Bounds; + int cx = MenuCheckSize.Width; + int cy = MenuCheckSize.Height; + Bitmap bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text); + + e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2)); + + bmp.Dispose (); + } + } + + public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect) + { + // Fill rectangle area + dc.FillRectangle (SystemBrushes.Menu, cliparea); + + + // Draw menu items + for (int i = 0; i < menu.MenuItems.Count; i++) { + if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) { + MenuItem item = menu.MenuItems [i]; + item.MenuHeight = menu.Height; + item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status)); + } + } + } + + #endregion // Menus + + #region MonthCalendar + + // draw the month calendar + public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) + { + Rectangle client_rectangle = mc.ClientRectangle; + Size month_size = mc.SingleMonthSize; + // cache local copies of Marshal-by-ref internal members (gets around error CS0197) + Size calendar_spacing = (Size)((object)mc.calendar_spacing); + Size date_cell_size = (Size)((object)mc.date_cell_size); + + // draw the singlecalendars + int x_offset = 1; + int y_offset = 1; + // adjust for the position of the specific month + for (int i=0; i < mc.CalendarDimensions.Height; i++) + { + if (i > 0) + { + y_offset += month_size.Height + calendar_spacing.Height; + } + // now adjust for x position + for (int j=0; j < mc.CalendarDimensions.Width; j++) + { + if (j > 0) + { + x_offset += month_size.Width + calendar_spacing.Width; + } + else + { + x_offset = 1; + } + + Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height); + if (month_rect.IntersectsWith (clip_rectangle)) { + DrawSingleMonth ( + dc, + clip_rectangle, + month_rect, + mc, + i, + j); + } + } + } + + Rectangle bottom_rect = new Rectangle ( + client_rectangle.X, + Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0), + client_rectangle.Width, + date_cell_size.Height + 2); + // draw the today date if it's set + if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) + { + dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect); + if (mc.ShowToday) { + int today_offset = 5; + if (mc.ShowTodayCircle) + { + Rectangle today_circle_rect = new Rectangle ( + client_rectangle.X + 5, + Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0), + date_cell_size.Width, + date_cell_size.Height); + DrawTodayCircle (dc, today_circle_rect); + today_offset += date_cell_size.Width + 5; + } + // draw today's date + StringFormat text_format = new StringFormat(); + text_format.LineAlignment = StringAlignment.Center; + text_format.Alignment = StringAlignment.Near; + Rectangle today_rect = new Rectangle ( + today_offset + client_rectangle.X, + Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0), + Math.Max(client_rectangle.Width - today_offset, 0), + date_cell_size.Height); + dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format); + text_format.Dispose (); + } + } + + Brush border_brush; + + if (mc.owner == null) + border_brush = GetControlBackBrush (mc.BackColor); + else + border_brush = SystemBrushes.ControlDarkDark; + + // finally paint the borders of the calendars as required + for (int i = 0; i <= mc.CalendarDimensions.Width; i++) { + if (i == 0 && clip_rectangle.X == client_rectangle.X) { + dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height); + } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) { + dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height); + } else { + Rectangle rect = new Rectangle ( + client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1, + client_rectangle.Y, + calendar_spacing.Width, + client_rectangle.Height); + if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) { + dc.FillRectangle (border_brush, rect); + } + } + } + for (int i = 0; i <= mc.CalendarDimensions.Height; i++) { + if (i == 0 && clip_rectangle.Y == client_rectangle.Y) { + dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1); + } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) { + dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1); + } else { + Rectangle rect = new Rectangle ( + client_rectangle.X, + client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1, + client_rectangle.Width, + calendar_spacing.Height); + if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) { + dc.FillRectangle (border_brush, rect); + } + } + } + + // draw the drop down border if need + if (mc.owner != null) { + Rectangle bounds = mc.ClientRectangle; + if (clip_rectangle.Contains (mc.Location)) { + // find out if top or left line to draw + if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) { + + dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1); + } + if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) { + dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y); + } + } + if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) { + // find out if bottom or right line to draw + if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) { + dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1); + } + if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) { + dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1); + } + } + } + } + + // darws a single part of the month calendar (with one month) + private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) + { + // cache local copies of Marshal-by-ref internal members (gets around error CS0197) + Size title_size = (Size)((object)mc.title_size); + Size date_cell_size = (Size)((object)mc.date_cell_size); + DateTime current_month = (DateTime)((object)mc.current_month); + DateTime sunday = new DateTime(2006, 10, 1); + + // draw the title back ground + DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col); + Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height); + if (title_rect.IntersectsWith (clip_rectangle)) { + dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect); + // draw the title + string title_text = this_month.ToString ("MMMM yyyy"); + dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format); + + if (mc.ShowYearUpDown) { + Rectangle year_rect; + Rectangle upRect, downRect; + ButtonState upState, downState; + + mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect); + dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect); + dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format); + + upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal; + downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal; + + WidgetPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState); + WidgetPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState); + } + + // draw previous and next buttons if it's time + if (row == 0 && col == 0) + { + // draw previous button + DrawMonthCalendarButton ( + dc, + rectangle, + mc, + title_size, + mc.button_x_offset, + (System.Drawing.Size)((object)mc.button_size), + true); + } + if (row == 0 && col == mc.CalendarDimensions.Width-1) + { + // draw next button + DrawMonthCalendarButton ( + dc, + rectangle, + mc, + title_size, + mc.button_x_offset, + (System.Drawing.Size)((object)mc.button_size), + false); + } + } + + // set the week offset and draw week nums if needed + int col_offset = (mc.ShowWeekNumbers) ? 1 : 0; + Rectangle day_name_rect = new Rectangle( + rectangle.X, + rectangle.Y + title_size.Height, + (7 + col_offset) * date_cell_size.Width, + date_cell_size.Height); + if (day_name_rect.IntersectsWith (clip_rectangle)) { + dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect); + // draw the day names + DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek); + for (int i=0; i < 7; i++) + { + int position = i - (int) first_day_of_week; + if (position < 0) + { + position = 7 + position; + } + // draw it + Rectangle day_rect = new Rectangle( + day_name_rect.X + ((i + col_offset)* date_cell_size.Width), + day_name_rect.Y, + date_cell_size.Width, + date_cell_size.Height); + dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format); + } + + // draw the vertical divider + int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0); + dc.DrawLine ( + ResPool.GetPen (mc.ForeColor), + rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset, + rectangle.Y + vert_divider_y, + rectangle.Right - mc.divider_line_offset, + rectangle.Y + vert_divider_y); + } + + + // draw the actual date items in the grid (including the week numbers) + Rectangle date_rect = new Rectangle ( + rectangle.X, + rectangle.Y + title_size.Height + date_cell_size.Height, + date_cell_size.Width, + date_cell_size.Height); + int month_row_count = 0; + bool draw_week_num_divider = false; + DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1)); + for (int i=0; i < 6; i++) + { + // establish if this row is in our clip_area + Rectangle row_rect = new Rectangle ( + rectangle.X, + rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)), + date_cell_size.Width * 7, + date_cell_size.Height); + if (mc.ShowWeekNumbers) { + row_rect.Width += date_cell_size.Width; + } + + bool draw_row = row_rect.IntersectsWith (clip_rectangle); + if (draw_row) { + dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect); + } + // establish if this is a valid week to draw + if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) { + month_row_count = i; + } + + // draw the week number if required + if (mc.ShowWeekNumbers && month_row_count == i) { + if (!draw_week_num_divider) { + draw_week_num_divider = draw_row; + } + // get the week for this row + int week = mc.GetWeekOfYear (current_date); + + if (draw_row) { + dc.DrawString ( + week.ToString(), + mc.Font, + ResPool.GetSolidBrush (mc.TitleBackColor), + date_rect, + mc.centered_format); + } + date_rect.Offset(date_cell_size.Width, 0); + } + + // only draw the days if we have to + if(month_row_count == i) { + for (int j=0; j < 7; j++) + { + if (draw_row) { + DrawMonthCalendarDate ( + dc, + date_rect, + mc, + current_date, + this_month, + row, + col); + } + + // move the day on + current_date = current_date.AddDays(1); + date_rect.Offset(date_cell_size.Width, 0); + } + + // shift the rectangle down one row + int offset = (mc.ShowWeekNumbers) ? -8 : -7; + date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height); + } + } + + // month_row_count is zero based, so add one + month_row_count++; + + // draw week numbers if required + if (draw_week_num_divider) { + col_offset = 1; + dc.DrawLine ( + ResPool.GetPen (mc.ForeColor), + rectangle.X + date_cell_size.Width - 1, + rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset, + rectangle.X + date_cell_size.Width - 1, + rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset); + } + } + + // draws the pervious or next button + private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) + { + const int arrow_width = 4; + const int arrow_height = 7; + + bool is_clicked = false; + Rectangle button_rect; + PointF arrow_center; + PointF [] arrow_path = new PointF [3]; + + // prepare the button + if (is_previous) + { + is_clicked = mc.is_previous_clicked; + + button_rect = new Rectangle ( + rectangle.X + 1 + x_offset, + rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2), + Math.Max(button_size.Width - 1, 0), + Math.Max(button_size.Height - 1, 0)); + + arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), + rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1); + if (is_clicked) { + arrow_center.X += 1; + arrow_center.Y += 1; + } + + arrow_path [0].X = arrow_center.X; + arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f; + arrow_path [1].X = arrow_center.X; + arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f; + arrow_path [2].X = arrow_center.X - arrow_width; + arrow_path [2].Y = arrow_center.Y + 0.5f; + } + else + { + is_clicked = mc.is_next_clicked; + + button_rect = new Rectangle ( + rectangle.Right - 1 - x_offset - button_size.Width, + rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2), + Math.Max(button_size.Width - 1, 0), + Math.Max(button_size.Height - 1, 0)); + + arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), + rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1); + if (is_clicked) { + arrow_center.X += 1; + arrow_center.Y += 1; + } + + arrow_path [0].X = arrow_center.X - arrow_width; + arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f; + arrow_path [1].X = arrow_center.X - arrow_width; + arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f; + arrow_path [2].X = arrow_center.X; + arrow_path [2].Y = arrow_center.Y + 0.5f; + } + + // fill the background + dc.FillRectangle (SystemBrushes.Control, button_rect); + // draw the border + if (is_clicked) { + dc.DrawRectangle (SystemPens.ControlDark, button_rect); + } + else { + CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom); + } + // draw the arrow + dc.FillPolygon (SystemBrushes.ControlText, arrow_path); + //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding); + } + + + // draws one day in the calendar grid + private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) { + Color date_color = mc.ForeColor; + Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0)); + + // find out if we are the lead of the first calendar or the trail of the last calendar + if (date.Year != month.Year || date.Month != month.Month) { + DateTime check_date = month.AddMonths (-1); + // check if it's the month before + if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) { + date_color = mc.TrailingForeColor; + } else { + // check if it's the month after + check_date = month.AddMonths (1); + if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) { + date_color = mc.TrailingForeColor; + } else { + return; + } + } + } else { + date_color = mc.ForeColor; + } + + const int inflate = -1; + + if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) { + // see if the date is in the start of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate); + dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360); + } else if (date == mc.SelectionStart.Date) { + // see if the date is in the start of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate); + dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180); + // fill the other side as a straight rect + if (date < mc.SelectionEnd.Date) + { + // use rectangle instead of rectangle to go all the way to edge of rect + selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2)); + selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0); + dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect); + } + } else if (date == mc.SelectionEnd.Date) { + // see if it is the end of selection + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate); + dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180); + // fill the other side as a straight rect + if (date > mc.SelectionStart.Date) { + selection_rect.X = rectangle.X; + selection_rect.Width = rectangle.Width - (rectangle.Width / 2); + dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect); + } + } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) { + // now see if it's in the middle + date_color = mc.BackColor; + // draw the left hand of the back ground + Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate); + dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect); + } + + // establish if it's a bolded font + Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font; + + // just draw the date now + dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format); + + // today circle if needed + if (mc.ShowTodayCircle && date == DateTime.Now.Date) { + DrawTodayCircle (dc, interior); + } + + // draw the selection grid + if (mc.is_date_clicked && mc.clicked_date == date) { + Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot); + dc.DrawRectangle (pen, interior); + } + } + + private void DrawTodayCircle (Graphics dc, Rectangle rectangle) { + Color circle_color = Color.FromArgb (248, 0, 0); + // draw the left hand of the circle + Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0)); + Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0)); + Point [] curve_points = new Point [3]; + curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12); + curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y); + curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y); + + Pen pen = ResPool.GetSizedPen(circle_color, 2); + dc.DrawArc (pen, lhs_circle_rect, 90, 180); + dc.DrawArc (pen, rhs_circle_rect, 270, 180); + dc.DrawCurve (pen, curve_points); + dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y)); + } + + #endregion // MonthCalendar + + #region Panel + public override Size PanelDefaultSize { + get { + return new Size (200, 100); + } + } + #endregion // Panel + + #region PictureBox + public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) { + Rectangle client = pb.ClientRectangle; + + client = new Rectangle (client.Left + pb.Padding.Left, client.Top + pb.Padding.Top, client.Width - pb.Padding.Horizontal, client.Height - pb.Padding.Vertical); + + // FIXME - instead of drawing the whole picturebox every time + // intersect the clip rectangle with the drawn picture and only draw what's needed, + // Also, we only need a background fill where no image goes + if (pb.Image != null) { + switch (pb.SizeMode) { + case PictureBoxSizeMode.StretchImage: + dc.DrawImage (pb.Image, client.Left, client.Top, client.Width, client.Height); + break; + + case PictureBoxSizeMode.CenterImage: + dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2)); + break; + + case PictureBoxSizeMode.Zoom: + Size image_size; + + if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height)) + image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width); + else + image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height); + + dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height); + break; + + default: + // Normal, AutoSize + dc.DrawImage (pb.Image, client.Left, client.Top, pb.Image.Width, pb.Image.Height); + break; + } + + return; + } + } + + public override Size PictureBoxDefaultSize { + get { + return new Size (100, 50); + } + } + #endregion // PictureBox + + /* + #region PrintPreviewControl + public override int PrintPreviewControlPadding { + get { return 8; } + } + + public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview) + { + int page_width, page_height; + int padding = PrintPreviewControlPadding; + PreviewPageInfo[] pis = preview.page_infos; + + if (preview.AutoZoom) { + int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding; + int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding; + + float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height; + + /* try to lay things out using the width to determine the size + page_width = width_available / preview.Columns; + page_height = (int)(page_width / image_ratio); + + /* does the height fit? + if (page_height * (preview.Rows + 1) > height_available) { + /* no, lay things out via the height + page_height = height_available / (preview.Rows + 1); + page_width = (int)(page_height * image_ratio); + } + } + else { + page_width = (int)(pis[0].Image.Width * preview.Zoom); + page_height = (int)(pis[0].Image.Height * preview.Zoom); + } + + return new Size (page_width, page_height); + } + + public override void PrintPreviewWidgetPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size) + { + int padding = 8; + PreviewPageInfo[] pis = preview.page_infos; + if (pis == null) + return; + + int page_x, page_y; + + int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding; + int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding; + + Rectangle viewport = preview.ViewPort; + + pe.Graphics.Clip = new Region (viewport); + + /* center things if we can + int off_x = viewport.Width / 2 - width / 2; + if (off_x < 0) off_x = 0; + int off_y = viewport.Height / 2 - height / 2; + if (off_y < 0) off_y = 0; + + page_y = off_y + padding - preview.vbar_value; + + if (preview.StartPage > 0) { + int p = preview.StartPage - 1; + for (int py = 0; py < preview.Rows + 1; py ++) { + page_x = off_x + padding - preview.hbar_value; + for (int px = 0; px < preview.Columns; px ++) { + if (p >= pis.Length) + continue; + Image image = preview.image_cache[p]; + if (image == null) + image = pis[p].Image; + Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size); + + pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); + + page_x += padding + page_size.Width; + p++; + } + page_y += padding + page_size.Height; + } + } + } + #endregion // PrintPreviewControl*/ + + #region ProgressBar + public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) + { + Rectangle client_area = ctrl.client_area; + + /* Draw border */ + CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl); + + /* Draw Blocks */ + int draw_mode = 0; + int max_blocks = int.MaxValue; + int start_pixel = client_area.X; + draw_mode = (int) ctrl.Style; + + switch (draw_mode) { + case 1: { // Continuous + int pixels_to_draw; + pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1)))); + dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height)); + break; + } + case 2: // Marquee + if (XplatUI.ThemesEnabled) { + int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds; + double percent_done = (double) ms_diff / ProgressBarMarqueeSpeedScaling + % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed; + max_blocks = 5; + start_pixel = client_area.X + (int) (client_area.Width * percent_done); + } + + goto case 0; + case 0: + default: // Blocks + Rectangle block_rect; + int space_betweenblocks = ProgressBarChunkSpacing; + int block_width; + int increment; + int barpos_pixels; + int block_count = 0; + + block_width = ProgressBarGetChunkSize (client_area.Height); + block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0! + barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1))); + increment = block_width + space_betweenblocks; + + block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height); + while (true) { + if (max_blocks != int.MaxValue) { + if (block_count >= max_blocks) + break; + if (block_rect.X > client_area.Width) + block_rect.X -= client_area.Width; + } else { + if ((block_rect.X - client_area.X) >= barpos_pixels) + break; + } + + if (clip_rect.IntersectsWith (block_rect) == true) { + dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), block_rect); + } + + block_rect.X += increment; + block_count++; + } + break; + + } + } + + public const int ProgressBarChunkSpacing = 2; + + public static int ProgressBarGetChunkSize () + { + return ProgressBarGetChunkSize (ProgressBarDefaultHeight); + } + + static int ProgressBarGetChunkSize (int progressBarClientAreaHeight) + { + int size = (progressBarClientAreaHeight * 2) / 3; + return size; + } + + const int ProgressBarDefaultHeight = 23; + + public override Size ProgressBarDefaultSize { + get { + return new Size (100, ProgressBarDefaultHeight); + } + } + + public const double ProgressBarMarqueeSpeedScaling = 15; + + #endregion // ProgressBar + + #region RadioButton + public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) { + StringFormat text_format; + Rectangle client_rectangle; + Rectangle text_rectangle; + Rectangle radiobutton_rectangle; + int radiobutton_size = 13; + int radiobutton_space = 4; + + client_rectangle = radio_button.ClientRectangle; + text_rectangle = client_rectangle; + radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size); + + text_format = new StringFormat(); + text_format.Alignment = StringAlignment.Near; + text_format.LineAlignment = StringAlignment.Center; + text_format.HotkeyPrefix = HotkeyPrefix.Show; + + /* Calculate the position of text and checkbox rectangle */ + if (radio_button.appearance!=Appearance.Button) { + switch(radio_button.radiobutton_alignment) { + case ContentAlignment.BottomCenter: { + radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2; + radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.BottomLeft: { + radiobutton_rectangle.X=client_rectangle.Left; + radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size; + text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.BottomRight: { + radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size; + radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.MiddleCenter: { + radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2; + radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + break; + } + + default: + case ContentAlignment.MiddleLeft: { + radiobutton_rectangle.X=client_rectangle.Left; + radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2; + text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.MiddleRight: { + radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size; + radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.TopCenter: { + radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2; + radiobutton_rectangle.Y=client_rectangle.Top; + text_rectangle.X=client_rectangle.X; + text_rectangle.Y=radiobutton_size+radiobutton_space; + text_rectangle.Width=client_rectangle.Width; + text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.TopLeft: { + radiobutton_rectangle.X=client_rectangle.Left; + radiobutton_rectangle.Y=client_rectangle.Top; + text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + + case ContentAlignment.TopRight: { + radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size; + radiobutton_rectangle.Y=client_rectangle.Top; + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space; + break; + } + } + } else { + text_rectangle.X=client_rectangle.X; + text_rectangle.Width=client_rectangle.Width; + } + + /* Set the horizontal alignment of our text */ + switch(radio_button.text_alignment) { + case ContentAlignment.BottomLeft: + case ContentAlignment.MiddleLeft: + case ContentAlignment.TopLeft: { + text_format.Alignment=StringAlignment.Near; + break; + } + + case ContentAlignment.BottomCenter: + case ContentAlignment.MiddleCenter: + case ContentAlignment.TopCenter: { + text_format.Alignment=StringAlignment.Center; + break; + } + + case ContentAlignment.BottomRight: + case ContentAlignment.MiddleRight: + case ContentAlignment.TopRight: { + text_format.Alignment=StringAlignment.Far; + break; + } + } + + /* Set the vertical alignment of our text */ + switch(radio_button.text_alignment) { + case ContentAlignment.TopLeft: + case ContentAlignment.TopCenter: + case ContentAlignment.TopRight: { + text_format.LineAlignment=StringAlignment.Near; + break; + } + + case ContentAlignment.BottomLeft: + case ContentAlignment.BottomCenter: + case ContentAlignment.BottomRight: { + text_format.LineAlignment=StringAlignment.Far; + break; + } + + case ContentAlignment.MiddleLeft: + case ContentAlignment.MiddleCenter: + case ContentAlignment.MiddleRight: { + text_format.LineAlignment=StringAlignment.Center; + break; + } + } + + ButtonState state = ButtonState.Normal; + if (radio_button.FlatStyle == FlatStyle.Flat) { + state |= ButtonState.Flat; + } + + if (radio_button.Checked) { + state |= ButtonState.Checked; + } + + if (!radio_button.Enabled) { + state |= ButtonState.Inactive; + } + + // Start drawing + RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle); + + if ((radio_button.image != null) || (radio_button.image_list != null)) + ButtonBase_DrawImage(radio_button, dc); + + RadioButton_DrawText(radio_button, text_rectangle, dc, text_format); + + if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) { + SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font); + + Rectangle focus_rect = Rectangle.Empty; + focus_rect.X = text_rectangle.X; + focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2); + focus_rect.Size = text_size.ToSize (); + + RadioButton_DrawFocus (radio_button, dc, focus_rect); + } + + text_format.Dispose (); + } + + protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) + { + dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle); + + if (radio_button.appearance==Appearance.Button) { + ButtonBase_DrawButton (radio_button, dc); + + if ((radio_button.Focused) && radio_button.Enabled) + ButtonBase_DrawFocus(radio_button, dc); + } else { + // establish if we are rendering a flat style of some sort + if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) { + DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button); + } else { + CPDrawRadioButton(dc, radiobutton_rectangle, state); + } + } + } + + protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format) + { + DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, + text_format, radio_button.Appearance, radio_button.Checked); + } + + protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle) + { + DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor); + } + + + // renders a radio button with the Flat and Popup FlatStyle + protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button) + { + int lineWidth; + + if (radio_button.Enabled) { + + // draw the outer flatstyle arcs + if (radio_button.FlatStyle == FlatStyle.Flat) { + graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359); + + // fill in the area depending on whether or not the mouse is hovering + if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) { + graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + } else { + graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + } + } else { + // must be a popup radio button + // fill the control + graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359); + + if (radio_button.is_entered || radio_button.Capture) { + // draw the popup 3d button knob + graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359); + + graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180); + graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180); + + } else { + // just draw lighter flatstyle outer circle + graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359); + } + } + } else { + // disabled + // fill control background color regardless of actual backcolor + graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359); + // draw the ark as control dark + graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359); + } + + // draw the check + if (radio_button.Checked) { + lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3); + + Pen dot_pen = SystemPens.ControlDarkDark; + Brush dot_brush = SystemBrushes.ControlDarkDark; + + if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) { + dot_pen = SystemPens.ControlDark; + dot_brush = SystemBrushes.ControlDark; + } + + if (rectangle.Height > 13) { + graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359); + } else { + int x_half_pos = (rectangle.Width / 2) + rectangle.X; + int y_half_pos = (rectangle.Height / 2) + rectangle.Y; + + graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos); + graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1); + + graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2); + graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2); + } + } + } + + public override Size RadioButtonDefaultSize { + get { + return new Size (104,24); + } + } + + public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle) + { + // Draw Button Background + if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) { + glyphArea.Height -= 2; + glyphArea.Width -= 2; + } + + DrawRadioButtonGlyph (g, rb, glyphArea); + + // If we have an image, draw it + if (imageBounds.Size != Size.Empty) + DrawRadioButtonImage (g, rb, imageBounds); + + if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty) + DrawRadioButtonFocus (g, rb, textBounds); + + // If we have text, draw it + if (textBounds != Rectangle.Empty) + DrawRadioButtonText (g, rb, textBounds); + } + + public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea) + { + if (rb.Pressed) + ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked); + else if (rb.InternalSelected) + ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked); + else if (rb.Entered) + ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked); + else if (!rb.Enabled) + ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked); + else + ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked); + } + + public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea) + { + WidgetPaint.DrawFocusRectangle (g, focusArea); + } + + public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds) + { + if (rb.Enabled) + g.DrawImage (rb.Image, imageBounds); + else + CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl); + } + + public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds) + { + if (rb.Enabled) + TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering); + else + DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering); + } + + public override Size CalculateRadioButtonAutoSize (RadioButton rb) + { + Size ret_size = Size.Empty; + Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering); + Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size; + + // Pad the text size + if (rb.Text.Length != 0) { + text_size.Height += 4; + text_size.Width += 4; + } + + switch (rb.TextImageRelation) { + case TextImageRelation.Overlay: + ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height); + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageAboveText: + case TextImageRelation.TextAboveImage: + ret_size.Height = text_size.Height + image_size.Height; + ret_size.Width = Math.Max (text_size.Width, image_size.Width); + break; + case TextImageRelation.ImageBeforeText: + case TextImageRelation.TextBeforeImage: + ret_size.Height = Math.Max (text_size.Height, image_size.Height); + ret_size.Width = text_size.Width + image_size.Width; + break; + } + + // Pad the result + ret_size.Height += (rb.Padding.Vertical); + ret_size.Width += (rb.Padding.Horizontal) + 15; + + // There seems to be a minimum height + if (ret_size.Height == rb.Padding.Vertical) + ret_size.Height += 14; + + return ret_size; + } + + public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle) + { + CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle); + } + #endregion // RadioButton + + #region ScrollBar + public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar) + { + int scrollbutton_width = bar.scrollbutton_width; + int scrollbutton_height = bar.scrollbutton_height; + Rectangle first_arrow_area; + Rectangle second_arrow_area; + Rectangle thumb_pos; + + thumb_pos = bar.ThumbPos; + + if (bar.vert) { + first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Width = bar.Width; + bar.ThumbPos = thumb_pos; + + Brush VerticalBrush; + /* Background, upper track */ + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black); + else + VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom); + if (clip.IntersectsWith (UpperTrack)) + dc.FillRectangle (VerticalBrush, UpperTrack); + + /* Background, lower track */ + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black); + else + VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom); + if (clip.IntersectsWith (LowerTrack)) + dc.FillRectangle (VerticalBrush, LowerTrack); + + /* Buttons */ + if (clip.IntersectsWith (first_arrow_area)) + CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state); + if (clip.IntersectsWith (second_arrow_area)) + CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state); + } else { + first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height); + bar.FirstArrowArea = first_arrow_area; + + second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height); + bar.SecondArrowArea = second_arrow_area; + + thumb_pos.Height = bar.Height; + bar.ThumbPos = thumb_pos; + + Brush HorizontalBrush; + //Background, left track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards) + HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black); + else + HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height); + if (clip.IntersectsWith (LeftTrack)) + dc.FillRectangle (HorizontalBrush, LeftTrack); + + //Background, right track + if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward) + HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black); + else + HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White); + Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height); + if (clip.IntersectsWith (RightTrack)) + dc.FillRectangle (HorizontalBrush, RightTrack); + + /* Buttons */ + if (clip.IntersectsWith (first_arrow_area)) + CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state); + if (clip.IntersectsWith (second_arrow_area)) + CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state); + } + + /* Thumb */ + ScrollBar_DrawThumb(bar, thumb_pos, clip, dc); + } + + protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc) + { + if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos)) + DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal); + } + + public override int ScrollBarButtonSize { + get { return 16; } + } + + public override bool ScrollBarHasHotElementStyles { + get { + return false; + } + } + + public override bool ScrollBarHasPressedThumbStyle { + get { + return false; + } + } + + public override bool ScrollBarHasHoverArrowButtonStyle { + get { + return false; + } + } + #endregion // ScrollBar + + #region StatusBar + public override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) { + Rectangle area = sb.ClientRectangle; + int horz_border = 2; + int vert_border = 2; + + Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc); + Graphics dc = Graphics.FromImage (backbuffer); + + DrawStatusBarBackground (dc, clip, sb); + + if (!sb.ShowPanels && sb.Text != String.Empty) { + string text = sb.Text; + StringFormat string_format = new StringFormat (); + string_format.Trimming = StringTrimming.Character; + string_format.FormatFlags = StringFormatFlags.NoWrap; + + if (text.Length > 127) + text = text.Substring (0, 127); + + if (text [0] == '\t') { + string_format.Alignment = StringAlignment.Center; + text = text.Substring (1); + if (text [0] == '\t') { + string_format.Alignment = StringAlignment.Far; + text = text.Substring (1); + } + } + + dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor), + new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format); + string_format.Dispose (); + } else if (sb.ShowPanels) { + Brush br_forecolor = GetControlForeBrush (sb.ForeColor); + int prev_x = area.X + horz_border; + int y = area.Y + vert_border; + for (int i = 0; i < sb.Panels.Count; i++) { + Rectangle pr = new Rectangle (prev_x, y, + sb.Panels [i].Width, area.Height); + prev_x += pr.Width + StatusBarHorzGapWidth; + if (pr.IntersectsWith (clip)) + DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]); + } + } + + if (sb.SizingGrip) + DrawStatusBarSizingGrip (dc, clip, sb, area); + + real_dc.DrawImage (backbuffer, 0, 0); + dc.Dispose (); + backbuffer.Dispose (); + + } + + protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb) + { + bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb (); + + Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor); + dc.FillRectangle (brush, clip); + } + + protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area) + { + area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16); + CPDrawSizeGrip (dc, ColorControl, area); + } + + protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index, + Brush br_forecolor, StatusBarPanel panel) { + int border_size = 3; // this is actually const, even if the border style is none + int icon_width = 16; + + area.Height -= border_size; + + DrawStatusBarPanelBackground (dc, area, panel); + + if (panel.Style == StatusBarPanelStyle.OwnerDraw) { + StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs ( + dc, panel.Parent.Font, area, index, DrawItemState.Default, + panel, panel.Parent.ForeColor, panel.Parent.BackColor); + panel.Parent.OnDrawItemInternal (e); + return; + } + + string text = panel.Text; + StringFormat string_format = new StringFormat (); + string_format.Trimming = StringTrimming.Character; + string_format.FormatFlags = StringFormatFlags.NoWrap; + + + if (text != null && text.Length > 0 && text [0] == '\t') { + string_format.Alignment = StringAlignment.Center; + text = text.Substring (1); + if (text [0] == '\t') { + string_format.Alignment = StringAlignment.Far; + text = text.Substring (1); + } + } + + Rectangle string_rect = Rectangle.Empty; + int x; + int len; + int icon_x = 0; + int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1; + + switch (panel.Alignment) { + case HorizontalAlignment.Right: + len = (int) dc.MeasureString (text, panel.Parent.Font).Width; + x = area.Right - len - 4; + string_rect = new Rectangle (x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + if (panel.Icon != null) { + icon_x = x - icon_width - 2; + } + break; + case HorizontalAlignment.Center: + len = (int) dc.MeasureString (text, panel.Parent.Font).Width; + x = area.Left + ((panel.Width - len) / 2); + + string_rect = new Rectangle (x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + + if (panel.Icon != null) { + icon_x = x - icon_width - 2; + } + break; + + + default: + int left = area.Left + border_size;; + if (panel.Icon != null) { + icon_x = area.Left + 2; + left = icon_x + icon_width + 2; + } + + x = left; + string_rect = new Rectangle (x, y, + area.Right - x - border_size, + area.Bottom - y - border_size); + break; + } + + RectangleF clip_bounds = dc.ClipBounds; + dc.SetClip (area); + dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format); + dc.SetClip (clip_bounds); + + if (panel.Icon != null) { + dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width)); + } + } + + protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel) + { + if (panel.BorderStyle != StatusBarPanelBorderStyle.None) { + Border3DStyle border_style = Border3DStyle.SunkenOuter; + if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised) + border_style = Border3DStyle.RaisedInner; + + CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor); + } + } + + public override int StatusBarSizeGripWidth { + get { return 15; } + } + + public override int StatusBarHorzGapWidth { + get { return 3; } + } + + public override Size StatusBarDefaultSize { + get { + return new Size (100, 22); + } + } + #endregion // StatusBar + + #region TabControl + + #region TabControl settings + + public override Size TabControlDefaultItemSize { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.DefaultItemSize; } + } + + public override Point TabControlDefaultPadding { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.DefaultPadding; } + } + + public override int TabControlMinimumTabWidth { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.MinimumTabWidth; } + } + + public override Rectangle TabWidgetselectedDelta { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.SelectedTabDelta; } + } + + public override int TabWidgetselectedSpacing { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.SelectedSpacing; } + } + + public override int TabPanelOffsetX { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.TabPanelOffset.X; } + } + + public override int TabPanelOffsetY { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.TabPanelOffset.Y; } + } + + public override int TabControlColSpacing { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.ColSpacing; } + } + + public override Point TabControlImagePadding { + get { return ThemeElements.CurrentTheme.TabWidgetPainter.ImagePadding; } + } + + public override int TabWidgetscrollerWidth { + get {return ThemeElements.CurrentTheme.TabWidgetPainter.ScrollerWidth; } + } + + + public override Size TabControlGetSpacing (TabWidget tab) + { + try { + return ThemeElements.CurrentTheme.TabWidgetPainter.RowSpacing (tab); + } catch { + throw new Exception ("Invalid Appearance value: " + tab.Appearance); + } + } + #endregion + + public override void DrawTabControl (Graphics dc, Rectangle area, TabWidget tab) + { + ThemeElements.CurrentTheme.TabWidgetPainter.Draw (dc, area, tab); + } + + public override Rectangle TabControlGetDisplayRectangle (TabWidget tab) + { + return ThemeElements.CurrentTheme.TabWidgetPainter.GetDisplayRectangle (tab); + } + + public override Rectangle TabControlGetPanelRect (TabWidget tab) + { + return ThemeElements.CurrentTheme.TabWidgetPainter.GetTabPanelRect (tab); + } + + #endregion + + #region TextBox + public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea) + { + if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) { + g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea); + } else { + g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea); + } + } + + public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m) + { + return false; + } + + public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase) + { + return true; + } + #endregion + + /* FIXME: I don't ever remember porting over this. + #region ToolBar + public override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) + { + StringFormat format = new StringFormat (); + format.Trimming = StringTrimming.EllipsisCharacter; + format.LineAlignment = StringAlignment.Center; + if (control.ShowKeyboardCuesInternal) + format.HotkeyPrefix = HotkeyPrefix.Show; + else + format.HotkeyPrefix = HotkeyPrefix.Hide; + + if (control.TextAlign == ToolBarTextAlign.Underneath) + format.Alignment = StringAlignment.Center; + else + format.Alignment = StringAlignment.Near; + + if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) { + dc.FillRectangle (SystemBrushes.Control, clip_rectangle); + } + + if (control.Divider && clip_rectangle.Y < 2) { + if (clip_rectangle.Y < 1) { + dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0); + } + dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1); + } + + foreach (ToolBarItem item in control.items) + if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle)) + DrawToolBarButton (dc, control, item, format); + + format.Dispose (); + } + + protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format) + { + bool is_flat = (control.Appearance == ToolBarAppearance.Flat); + + DrawToolBarButtonBorder (dc, item, is_flat); + + switch (item.Button.Style) { + case ToolBarButtonStyle.DropDownButton: + if (control.DropDownArrows) + DrawToolBarDropDownArrow (dc, item, is_flat); + DrawToolBarButtonContents (dc, control, item, format); + break; + + case ToolBarButtonStyle.Separator: + if (is_flat) + DrawToolBarSeparator (dc, item); + break; + + case ToolBarButtonStyle.ToggleButton: + DrawToolBarToggleButtonBackground (dc, item); + DrawToolBarButtonContents (dc, control, item, format); + break; + + default: + DrawToolBarButtonContents (dc, control, item, format); + break; + } + } + + const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom; + + protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat) + { + if (item.Button.Style == ToolBarButtonStyle.Separator) + return; + + Border3DStyle style; + + if (is_flat) { + if (item.Button.Pushed || item.Pressed) + style = Border3DStyle.SunkenOuter; + else if (item.Hilight) + style = Border3DStyle.RaisedInner; + else + return; + + } else { + if (item.Button.Pushed || item.Pressed) + style = Border3DStyle.Sunken; + else + style = Border3DStyle.Raised; + } + + Rectangle rect = item.Rectangle; + if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat) + rect.Width -= ToolBarDropDownWidth; + + CPDrawBorder3D (dc, rect, style, all_sides); + } + + protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item) + { + Rectangle area = item.Rectangle; + int offset = (int) SystemPens.Widget.Width + 1; + dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom); + dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom); + } + + protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item) + { + Brush brush; + Rectangle area = item.Rectangle; + area.X += ToolBarImageGripWidth; + area.Y += ToolBarImageGripWidth; + area.Width -= 2 * ToolBarImageGripWidth; + area.Height -= 2 * ToolBarImageGripWidth; + + if (item.Button.Pushed) + brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight); + else if (item.Button.PartialPush) + brush = SystemBrushes.ControlLight; + else + brush = SystemBrushes.Control; + + dc.FillRectangle (brush, area); + } + + protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat) + { + Rectangle rect = item.Rectangle; + rect.X = item.Rectangle.Right - ToolBarDropDownWidth; + rect.Width = ToolBarDropDownWidth; + + if (is_flat) { + if (item.DDPressed) + CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides); + else if (item.Button.Pushed || item.Pressed) + CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides); + else if (item.Hilight) + CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides); + } else { + if (item.DDPressed) + CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides); + else if (item.Button.Pushed || item.Pressed) + CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides); + else + CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides); + } + + PointF [] vertices = new PointF [3]; + PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2)); + + // Increase vertical and horizontal position by 1 when button is pressed + if (item.Pressed || item.Button.Pushed || item.DDPressed) { + ddCenter.X += 1; + ddCenter.Y += 1; + } + + vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f; + vertices [0].Y = ddCenter.Y; + vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f; + vertices [1].Y = ddCenter.Y; + vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment + vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight; + dc.FillPolygon (SystemBrushes.ControlText, vertices); + } + + protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format) + { + if (item.Button.Image != null) { + int x = item.ImageRectangle.X + ToolBarImageGripWidth; + int y = item.ImageRectangle.Y + ToolBarImageGripWidth; + + // Increase vertical and horizontal position by 1 when button is pressed + if (item.Pressed || item.Button.Pushed) { + x += 1; + y += 1; + } + + if (item.Button.Enabled) + dc.DrawImage (item.Button.Image, x, y); + else + CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl); + } + + Rectangle text_rect = item.TextRectangle; + if (text_rect.Width <= 0 || text_rect.Height <= 0) + return; + + if (item.Pressed || item.Button.Pushed) { + text_rect.X += 1; + text_rect.Y += 1; + } + + if (item.Button.Enabled) + dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format); + else + CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format); + } + + // Grip width for the ToolBar + public override int ToolBarGripWidth { + get { return 2;} + } + + // Grip width for the Image on the ToolBarButton + public override int ToolBarImageGripWidth { + get { return 2;} + } + + // width of the separator + public override int ToolBarSeparatorWidth { + get { return 4; } + } + + // width of the dropdown arrow rect + public override int ToolBarDropDownWidth { + get { return 13; } + } + + // width for the dropdown arrow on the ToolBarButton + public override int ToolBarDropDownArrowWidth { + get { return 5;} + } + + // height for the dropdown arrow on the ToolBarButton + public override int ToolBarDropDownArrowHeight { + get { return 3;} + } + + public override Size ToolBarDefaultSize { + get { + return new Size (100, 42); + } + } + + public override bool ToolBarHasHotElementStyles (ToolBar toolBar) + { + return toolBar.Appearance == ToolBarAppearance.Flat; + } + + public override bool ToolBarHasHotCheckedElementStyles { + get { + return false; + } + } + #endregion // ToolBar*/ + + #region ToolTip + public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) + { + ToolTipDrawBackground (dc, clip_rectangle, control); + + TextFormatFlags flags = TextFormatFlags.HidePrefix; + + Color foreground = control.ForeColor; + if (control.title.Length > 0) { + Font bold_font = new Font (control.Font, control.Font.Style | FontStyle.Bold); + TextRenderer.DrawTextInternal (dc, control.title, bold_font, control.title_rect, + foreground, flags, false); + bold_font.Dispose (); + } + + if (control.icon != null) + dc.DrawIcon (control.icon, control.icon_rect); + + TextRenderer.DrawTextInternal (dc, control.Text, control.Font, control.text_rect, foreground, flags, false); + } + + protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) + { + Brush back_brush = ResPool.GetSolidBrush (control.BackColor); + dc.FillRectangle (back_brush, control.ClientRectangle); + dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1); + } + + public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) + { + Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false); + size.Width += 4; + size.Height += 3; + Rectangle text_rect = new Rectangle (Point.Empty, size); + text_rect.Inflate (-2, -1); + tt.text_rect = text_rect; + tt.icon_rect = tt.title_rect = Rectangle.Empty; + + Size title_size = Size.Empty; + if (tt.title.Length > 0) { + Font bold_font = new Font (tt.Font, tt.Font.Style | FontStyle.Bold); + title_size = TextRenderer.MeasureTextInternal (tt.title, bold_font, false); + bold_font.Dispose (); + } + + Size icon_size = Size.Empty; + if (tt.icon != null) + icon_size = new Size (size.Height, size.Height); + + if (icon_size != Size.Empty || title_size != Size.Empty) { + int padding = 8; + int top_area_width = 0; + int top_area_height = icon_size.Height > title_size.Height ? icon_size.Height : title_size.Height; + Size text_size = size; + Point location = new Point (padding, padding); + + if (icon_size != Size.Empty) { + tt.icon_rect = new Rectangle (location, icon_size); + top_area_width = icon_size.Width + padding; + } + + if (title_size != Size.Empty) { + Rectangle title_rect = new Rectangle (location, new Size (title_size.Width, top_area_height)); + if (icon_size != Size.Empty) + title_rect.X += icon_size.Width + padding; + + tt.title_rect = title_rect; + top_area_width += title_size.Width; + } + + tt.text_rect = new Rectangle (new Point (location.X, location.Y + top_area_height + padding), + text_size); + + size.Height += padding + top_area_height; + if (top_area_width > size.Width) + size.Width = top_area_width; + + // margins + size.Width += padding * 2; + size.Height += padding * 2; + } + + return size; + } + + public override bool ToolTipTransparentBackground { + get { + return false; + } + } + #endregion // ToolTip + + #region BalloonWindow + NotifyIcon.BalloonWindow balloon_window; + + public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon) + { + Widget control = Widget.FromHandle(handle); + + if (control == null) + return; + + if (balloon_window != null) { + balloon_window.Close (); + balloon_window.Dispose (); + } + + balloon_window = new NotifyIcon.BalloonWindow (handle); + balloon_window.Title = title; + balloon_window.Text = text; + balloon_window.Icon = icon; + balloon_window.Timeout = timeout; + balloon_window.Show (); + } + + public override void HideBalloonWindow (IntPtr handle) + { + if (balloon_window == null || balloon_window.OwnerHandle != handle) + return; + + balloon_window.Close (); + balloon_window.Dispose (); + balloon_window = null; + } + + private const int balloon_iconsize = 16; + private const int balloon_bordersize = 8; + + public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) + { + Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText); + Rectangle rect = control.ClientRectangle; + int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize; + + // Rectangle borders and background. + dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect); + dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1); + + // Icon + Image image; + switch (control.Icon) { + case ToolTipIcon.Info: { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize); + break; + } + + case ToolTipIcon.Warning: { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize); + break; + } + + case ToolTipIcon.Error: { + image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize); + break; + } + + default: { + image = null; + break; + } + } + + if (control.Icon != ToolTipIcon.None) + dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize)); + + // Title + Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), + rect.Y + balloon_bordersize, + rect.Width - ((3 * balloon_bordersize) + iconsize), + rect.Height - (2 * balloon_bordersize)); + + Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit); + dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format); + + // Text + Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, + rect.Y + balloon_bordersize, + rect.Width - (2 * balloon_bordersize), + rect.Height - (2 * balloon_bordersize)); + + StringFormat textformat = control.Format; + textformat.LineAlignment = StringAlignment.Far; + dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat); + } + + public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control) + { + Rectangle deskrect = Screen.GetWorkingArea (control); + SizeF maxsize = new SizeF (250, 200); + + SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format); + SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format); + + if (titlesize.Height < balloon_iconsize) + titlesize.Height = balloon_iconsize; + + Rectangle rect = new Rectangle (); + rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize)); + rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize); + rect.X = deskrect.Width - rect.Width - 2; + rect.Y = deskrect.Height - rect.Height - 2; + + return rect; + } + #endregion // BalloonWindow + + #region TrackBar + public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb) + { + int result = tb.Value; + int value_pos = tb.Value; + float pixels_betweenticks; + Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty; + Point channel_startpoint = Point.Empty, na_point = Point.Empty; + + GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point); + + /* Convert thumb position from mouse position to value*/ + if (tb.Orientation == Orientation.Vertical) { + value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0); + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + else if (value_pos + tb.Minimum < tb.Minimum) + value_pos = 0; + + result = value_pos + tb.Minimum; + } else { + value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0); + + if (value_pos + tb.Minimum > tb.Maximum) + value_pos = tb.Maximum - tb.Minimum; + else if (value_pos + tb.Minimum < tb.Minimum) + value_pos = 0; + + result = value_pos + tb.Minimum; + } + + return result; + } + + 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) + { + thumb_area = Rectangle.Empty; + thumb_pos = Rectangle.Empty; + + if (tb.Orientation == Orientation.Vertical) { + toptick_startpoint = new Point (); + bottomtick_startpoint = new Point (); + channel_startpoint = new Point (); + float pixel_len; + const int space_from_right = 8; + const int space_from_left = 8; + const int space_from_bottom = 11; + Rectangle area = tb.ClientRectangle; + + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.Y = 8; + channel_startpoint.X = 9; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.Y = 8; + channel_startpoint.X = 19; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + case TickStyle.Both: + channel_startpoint.Y = 8; + channel_startpoint.X = 18; + bottomtick_startpoint.Y = 13; + bottomtick_startpoint.X = 32; + toptick_startpoint.Y = 13; + toptick_startpoint.X = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Height = area.Height - space_from_right - space_from_left; + thumb_area.Width = TrackBarVerticalTrackWidth; + + pixel_len = thumb_area.Height - 11; + if (tb.Maximum == tb.Minimum) { + pixels_betweenticks = 0; + } else { + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + } + + thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum)); + } else { + toptick_startpoint = new Point (); + bottomtick_startpoint = new Point (); + channel_startpoint = new Point (); + float pixel_len; + const int space_from_right = 8; + const int space_from_left = 8; + Rectangle area = tb.ClientRectangle; + + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + channel_startpoint.X = 8; + channel_startpoint.Y = 9; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 24; + break; + case TickStyle.TopLeft: + channel_startpoint.X = 8; + channel_startpoint.Y = 19; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + case TickStyle.Both: + channel_startpoint.X = 8; + channel_startpoint.Y = 18; + bottomtick_startpoint.X = 13; + bottomtick_startpoint.Y = 32; + toptick_startpoint.X = 13; + toptick_startpoint.Y = 8; + break; + default: + break; + } + + thumb_area.X = area.X + channel_startpoint.X; + thumb_area.Y = area.Y + channel_startpoint.Y; + thumb_area.Width = area.Width - space_from_right - space_from_left; + thumb_area.Height = TrackBarHorizontalTrackHeight; + + pixel_len = thumb_area.Width - 11; + if (tb.Maximum == tb.Minimum) { + pixels_betweenticks = 0; + } else { + pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum); + } + + thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum)); + } + + thumb_pos.Size = TrackBarGetThumbSize (tb); + } + + protected virtual Size TrackBarGetThumbSize (TrackBar trackBar) + { + return TrackBarGetThumbSize (); + } + + public static Size TrackBarGetThumbSize () + { + /* Draw thumb fixed 10x22 size */ + return new Size (10, 22); + } + + public const int TrackBarVerticalTrackWidth = 4; + + public const int TrackBarHorizontalTrackHeight = 4; + + #region Ticks + protected interface ITrackBarTickPainter + { + void Paint (float x1, float y1, float x2, float y2); + } + + class TrackBarTickPainter : ITrackBarTickPainter + { + readonly Graphics g; + readonly Pen pen; + public TrackBarTickPainter (Graphics g, Pen pen) + { + this.g = g; + this.pen = pen; + } + public void Paint (float x1, float y1, float x2, float y2) + { + g.DrawLine (pen, x1, y1, x2, y2); + } + } + protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g) + { + return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color)); + } + #endregion + + #region DrawTrackBar_Vertical + private void 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) { + + Point toptick_startpoint = new Point (); + Point bottomtick_startpoint = new Point (); + Point channel_startpoint = new Point (); + float pixel_len; + float pixels_betweenticks; + Rectangle area = tb.ClientRectangle; + + GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint); + + #region Track + TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle); + #endregion + + #region Thumb + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + thumb_pos.X = channel_startpoint.X - 8; + TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + case TickStyle.TopLeft: + thumb_pos.X = channel_startpoint.X - 10; + TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + default: + thumb_pos.X = area.X + 10; + TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + } + #endregion + + pixel_len = thumb_area.Height - 11; + pixels_betweenticks = pixel_len / ticks; + + thumb_area.X = thumb_pos.X; + thumb_area.Y = channel_startpoint.Y; + thumb_area.Width = thumb_pos.Height; + + #region Ticks + if (pixels_betweenticks <= 0) + return; + if (tb.TickStyle == TickStyle.None) + return; + Region outside = new Region (area); + outside.Exclude (thumb_area); + + if (outside.IsVisible (clip_rectangle)) { + ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc); + + if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) { + float x = area.X + bottomtick_startpoint.X; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) { + float y = area.Y + bottomtick_startpoint.Y + inc; + tick_painter.Paint ( + x, y, + x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y); + } + } + + if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) { + float x = area.X + toptick_startpoint.X; + for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) { + float y = area.Y + toptick_startpoint.Y + inc; + tick_painter.Paint ( + x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y, + x, y); + } + } + } + + outside.Dispose (); + #endregion + } + + #region Track + protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y, + 1, thumb_area.Height); + + dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y, + 1, thumb_area.Height); + + dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y, + 1, thumb_area.Height); + } + #endregion + + #region Thumb + protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y); + dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9); + dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10); + dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5); + + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8); + dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6); + dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4); + dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2); + } + + protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y); + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9); + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5); + dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10); + dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5); + dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10); + + dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8); + dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6); + dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4); + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2); + } + + protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9); + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10); + dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9); + + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8); + } + #endregion + + #region Ticks + protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g) + { + return GetTrackBarTickPainter (g); + } + #endregion + #endregion + + #region DrawTrackBar_Horizontal + /* + Horizontal trackbar + + Does not matter the size of the control, Win32 always draws: + - Ticks starting from pixel 13, 8 + - Channel starting at pos 8, 19 and ends at Width - 8 + - Autosize makes always the control 45 pixels high + - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum) + + */ + private void 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) { + Point toptick_startpoint = new Point (); + Point bottomtick_startpoint = new Point (); + Point channel_startpoint = new Point (); + float pixel_len; + float pixels_betweenticks; + Rectangle area = tb.ClientRectangle; + + GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint); + + #region Track + TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle); + #endregion + + #region Thumb + switch (tb.TickStyle) { + case TickStyle.BottomRight: + case TickStyle.None: + thumb_pos.Y = channel_startpoint.Y - 8; + TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + case TickStyle.TopLeft: + thumb_pos.Y = channel_startpoint.Y - 10; + TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + default: + thumb_pos.Y = area.Y + 10; + TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb); + break; + } + #endregion + + pixel_len = thumb_area.Width - 11; + pixels_betweenticks = pixel_len / ticks; + + thumb_area.Y = thumb_pos.Y; + thumb_area.X = channel_startpoint.X; + thumb_area.Height = thumb_pos.Height; + #region Ticks + if (pixels_betweenticks <= 0) + return; + if (tb.TickStyle == TickStyle.None) + return; + Region outside = new Region (area); + outside.Exclude (thumb_area); + + if (outside.IsVisible (clip_rectangle)) { + ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc); + + if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) { + float y = area.Y + bottomtick_startpoint.Y; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) { + float x = area.X + bottomtick_startpoint.X + inc; + tick_painter.Paint ( + x, y, + x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2)); + } + } + + if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) { + float y = area.Y + toptick_startpoint.Y; + for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) { + float x = area.X + toptick_startpoint.X + inc; + tick_painter.Paint ( + x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), + x, y); + } + } + } + + outside.Dispose (); + #endregion + } + + #region Track + protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea) + { + dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y, + thumb_area.Width, 1); + + dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1, + thumb_area.Width, 1); + + dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3, + thumb_area.Width, 1); + } + #endregion + + #region Thumb + protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15); + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16); + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5); + + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16); + dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1); + dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1); + dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1); + } + + protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16); + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y); + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16); + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20); + + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15); + dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1); + dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1); + dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1); + } + + protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar) + { + Pen pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19); + + pen = SystemPens.ControlDark; + dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19); + dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20); + dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20); + + dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18); + } + #endregion + + #region Ticks + protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g) + { + return GetTrackBarTickPainter (g); + } + #endregion + #endregion + + public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) + { + Brush br_thumb; + int value_pos; + bool mouse_value; + float ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/ + Rectangle area; + Rectangle thumb_pos = tb.ThumbPos; + Rectangle thumb_area = tb.ThumbArea; + + if (tb.thumb_pressed) { + value_pos = tb.thumb_mouseclick; + mouse_value = true; + } else { + value_pos = tb.Value - tb.Minimum; + mouse_value = false; + } + + area = tb.ClientRectangle; + + if (!tb.Enabled) { + br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight); + } else if (tb.thumb_pressed == true) { + br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl); + } else { + br_thumb = SystemBrushes.Control; + } + + + /* Widget Background */ + if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) { + dc.FillRectangle (SystemBrushes.Control, clip_rectangle); + } else { + dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle); + } + + if (tb.Focused) { + CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor); + } + + if (tb.Orientation == Orientation.Vertical) { + DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + br_thumb, ticks, value_pos, mouse_value); + + } else { + DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area, + br_thumb, ticks, value_pos, mouse_value); + } + + tb.ThumbPos = thumb_pos; + tb.ThumbArea = thumb_area; + } + + public override Size TrackBarDefaultSize { + get { + return new Size (104, 42); + } + } + + public override bool TrackBarHasHotThumbStyle { + get { + return false; + } + } + #endregion // TrackBar + + #region UpDownBase + public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state) + { + WidgetPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal); + } + + public override bool UpDownBaseHasHotButtonStyle { + get { + return false; + } + } + #endregion + + #region VScrollBar + public override Size VScrollBarDefaultSize { + get { + return new Size (this.ScrollBarButtonSize, 80); + } + } + #endregion // VScrollBar + + #region TreeView + public override Size TreeViewDefaultSize { + get { + return new Size (121, 97); + } + } + + public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle) + { + int height = treeView.ActualItemHeight - 2; + dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height); + + dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8); + + if (node.IsExpanded) { + dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); + } else { + dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); + dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2); + } + } + #endregion + + #region Managed window + public override int ManagedWindowTitleBarHeight (InternalWindowManager wm) + { + if (wm.IsToolWindow && !wm.IsMinimized) + return SystemInformation.ToolWindowCaptionHeight; + if (wm.Form.FormBorderStyle == FormBorderStyle.None) + return 0; + return SystemInformation.CaptionHeight; + } + + public override int ManagedWindowBorderWidth (InternalWindowManager wm) + { + if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) || + wm.IsMinimized) + return 3; + else + return 4; + } + + public override int ManagedWindowIconWidth (InternalWindowManager wm) + { + return ManagedWindowTitleBarHeight (wm) - 5; + } + + public override void ManagedWindowSetButtonLocations (InternalWindowManager wm) + { + TitleButtons buttons = wm.TitleButtons; + Form form = wm.form; + + buttons.HelpButton.Visible = form.HelpButton; + + foreach (TitleButton button in buttons) { + button.Visible = false; + } + + switch (form.FormBorderStyle) { + case FormBorderStyle.None: + if (form.WindowState != FormWindowState.Normal) + goto case FormBorderStyle.Sizable; + break; + case FormBorderStyle.FixedToolWindow: + case FormBorderStyle.SizableToolWindow: + buttons.CloseButton.Visible = true; + if (form.WindowState != FormWindowState.Normal) + goto case FormBorderStyle.Sizable; + break; + case FormBorderStyle.FixedSingle: + case FormBorderStyle.Fixed3D: + case FormBorderStyle.FixedDialog: + case FormBorderStyle.Sizable: + switch (form.WindowState) { + case FormWindowState.Normal: + buttons.MinimizeButton.Visible = true; + buttons.MaximizeButton.Visible = true; + buttons.RestoreButton.Visible = false; + break; + case FormWindowState.Maximized: + buttons.MinimizeButton.Visible = true; + buttons.MaximizeButton.Visible = false; + buttons.RestoreButton.Visible = true; + break; + case FormWindowState.Minimized: + buttons.MinimizeButton.Visible = false; + buttons.MaximizeButton.Visible = true; + buttons.RestoreButton.Visible = true; + break; + } + buttons.CloseButton.Visible = true; + break; + } + + // Respect MinimizeBox/MaximizeBox + if (form.MinimizeBox == false && form.MaximizeBox == false) { + buttons.MinimizeButton.Visible = false; + buttons.MaximizeButton.Visible = false; + } else if (form.MinimizeBox == false) + buttons.MinimizeButton.State = ButtonState.Inactive; + else if (form.MaximizeBox == false) + buttons.MaximizeButton.State = ButtonState.Inactive; + + int bw = ManagedWindowBorderWidth (wm); + Size btsize = ManagedWindowButtonSize (wm); + int btw = btsize.Width; + int bth = btsize.Height; + int top = bw + 2; + int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton; + + if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) { + buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth); + left -= 2 + btw; + + if (buttons.MaximizeButton.Visible) { + buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth); + left -= 2 + btw; + } + if (buttons.RestoreButton.Visible) { + buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth); + left -= 2 + btw; + } + + buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth); + left -= 2 + btw; + } else if (wm.IsToolWindow) { + buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth); + left -= 2 + btw; + } + } + + protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm) + { + Form form = wm.Form; + int tbheight = ManagedWindowTitleBarHeight (wm); + int bdwidth = ManagedWindowBorderWidth (wm); + Color titlebar_color = Color.FromArgb (255, 10, 36, 106); + Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240); + Color color = ThemeEngine.Current.ColorControlDark; + Color color2 = Color.FromArgb (255, 192, 192, 192); + + Pen pen = ResPool.GetPen (ColorControl); + Rectangle borders = new Rectangle (0, 0, form.Width, form.Height); + WidgetPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised); + // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves + borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5); + for (int i = 2; i < bdwidth; i++) { + dc.DrawRectangle (pen, borders); + borders.Inflate (-1, -1); + } + + + bool draw_titlebar_enabled = false; + if (wm.Form.Parent != null && wm.Form.Parent is Form) { + draw_titlebar_enabled = false; + } else if (wm.IsActive && !wm.IsMaximized) { + draw_titlebar_enabled = true; + } + if (draw_titlebar_enabled) { + color = titlebar_color; + color2 = titlebar_color2; + } + + Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1); + + // HACK: For now always draw the titlebar until we get updates better + if (tb.Width > 0 && tb.Height > 0) { + using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal)) + { + dc.FillRectangle (gradient, tb); + } + } + + if (!wm.IsMinimized) + // Draw the line just beneath the title bar + dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth, + tbheight + bdwidth - 1, form.Width - bdwidth - 1, + tbheight + bdwidth - 1); + return tb; + } + + public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm) + { +#if debug + Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations"); + dc.FillRectangle (Brushes.Black, clip); +#endif + Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm); + + Form form = wm.Form; + if (wm.ShowIcon) { + Rectangle icon = ManagedWindowGetTitleBarIconArea (wm); + if (icon.IntersectsWith (clip)) + dc.DrawIcon (form.Icon, icon); + const int SpacingBetweenIconAndCaption = 2; + tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ; + tb.X = icon.Right + SpacingBetweenIconAndCaption; + } + + foreach (TitleButton button in wm.TitleButtons.AllButtons) { + tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form)); + } + const int SpacingBetweenCaptionAndLeftMostButton = 3; + tb.Width -= SpacingBetweenCaptionAndLeftMostButton; + + string window_caption = form.Text; + window_caption = window_caption.Replace (Environment.NewLine, string.Empty); + + if (window_caption != null && window_caption != string.Empty) { + StringFormat format = new StringFormat (); + format.FormatFlags = StringFormatFlags.NoWrap; + format.Trimming = StringTrimming.EllipsisCharacter; + format.LineAlignment = StringAlignment.Center; + + if (tb.IntersectsWith (clip)) + dc.DrawString (window_caption, WindowBorderFont, + ThemeEngine.Current.ResPool.GetSolidBrush (Color.White), + tb, format); + } + } + + public override Size ManagedWindowButtonSize (InternalWindowManager wm) + { + int height = ManagedWindowTitleBarHeight (wm); + if (!wm.IsMaximized && !wm.IsMinimized) { + if (wm.IsToolWindow) + return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2, + height - 5); + if (wm.Form.FormBorderStyle == FormBorderStyle.None) + return Size.Empty; + } else + height = SystemInformation.CaptionHeight; + + return new Size (SystemInformation.CaptionButtonSize.Width - 2, + height - 5); + } + + private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form) + { + if (!button.Visible) { + return int.MaxValue; + } + + if (button.Rectangle.IntersectsWith (clip)) { + ManagedWindowDrawTitleButton (dc, button, clip, form); + } + return button.Rectangle.Left; + } + + protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form) + { + dc.FillRectangle (SystemBrushes.Control, button.Rectangle); + + WidgetPaint.DrawCaptionButton (dc, button.Rectangle, + button.Caption, button.State); + } + + public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm) + { + int bw = ManagedWindowBorderWidth (wm); + return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth); + } + + public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm) + { + Size result = SystemInformation.MenuButtonSize; + result.Width -= 2; + result.Height -= 4; + return result; + } + + public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form) + { + return false; + } + + public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm) + { + dc.FillRectangle (SystemBrushes.Control, button.Rectangle); + WidgetPaint.DrawCaptionButton (dc, button.Rectangle, + button.Caption, button.State); + } + + public override void ManagedWindowOnSizeInitializedOrChanged (Form form) + { + } + #endregion + + #region WidgetPaint + public override void 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) { + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left); + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top); + DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right); + DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom); + } + + public override void 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) { + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left); + DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top); + DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right); + DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom); + } + + public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) { + CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl); + } + + public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color) + { + Pen penTopLeft; + Pen penTopLeftInner; + Pen penBottomRight; + Pen penBottomRightInner; + Rectangle rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); + bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false; + + if ((style & Border3DStyle.Adjust) != 0) { + rect.Y -= 2; + rect.X -= 2; + rect.Width += 4; + rect.Height += 4; + } + + penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color); + + CPColor cpcolor = CPColor.Empty; + + if (!is_ColorControl) + cpcolor = ResPool.GetCPColor (control_color); + + switch (style) { + case Border3DStyle.Raised: + penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + break; + case Border3DStyle.Sunken: + penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + break; + case Border3DStyle.Etched: + penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + break; + case Border3DStyle.RaisedOuter: + penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + break; + case Border3DStyle.SunkenOuter: + penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + break; + case Border3DStyle.RaisedInner: + penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight); + penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + break; + case Border3DStyle.SunkenInner: + penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + break; + case Border3DStyle.Flat: + penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark); + break; + case Border3DStyle.Bump: + penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark); + break; + default: + break; + } + + bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter)); + + if ((sides & Border3DSide.Middle) != 0) { + Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color); + graphics.FillRectangle (brush, rect); + } + + if ((sides & Border3DSide.Left) != 0) { + graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top); + if ((rect.Width > 2) && inner) + graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top); + } + + if ((sides & Border3DSide.Top) != 0) { + graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top); + if ((rect.Height > 2) && inner) + graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1); + } + + if ((sides & Border3DSide.Right) != 0) { + graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1); + if ((rect.Width > 3) && inner) + graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2); + } + + if ((sides & Border3DSide.Bottom) != 0) { + graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + if ((rect.Height > 3) && inner) + graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2); + } + } + + public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state) + { + CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight); + } + + private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen) + { + // sadly enough, the rectangle gets always filled with a hatchbrush + dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, + Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), + ColorControl), + rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2); + + if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) { + dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); + + dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); + } else + if ((state & ButtonState.Flat) == ButtonState.Flat) { + dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1); + } else + if ((state & ButtonState.Checked) == ButtonState.Checked) { + dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4); + + Pen pen = DarkPen; + dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); + + pen = NormalPen; + dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); + dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); + + pen = LightPen; + dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); + dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); + } else + if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) { + Pen pen = DarkPen; + dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y); + + pen = NormalPen; + dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3); + dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1); + + pen = LightPen; + dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1); + dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1); + } else + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) { + Pen pen = LightPen; + dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y); + dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2); + + pen = NormalPen; + dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2); + dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3); + + pen = DarkPen; + dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1); + dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2); + } + } + + + public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) { + Rectangle captionRect; + int lineWidth; + + CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight); + + if (rectangle.Width<rectangle.Height) { + captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4); + } else { + captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4); + } + + if ((state & ButtonState.Pushed)!=0) { + captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3); + } + + /* Make sure we've got at least a line width of 1 */ + lineWidth=Math.Max(1, captionRect.Width/7); + + switch(button) { + case CaptionButton.Close: { + Pen pen; + + if ((state & ButtonState.Inactive)!=0) { + pen = ResPool.GetSizedPen (ColorControlLight, lineWidth); + DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button); + + pen = ResPool.GetSizedPen (ColorControlDark, lineWidth); + DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button); + return; + } else { + pen = ResPool.GetSizedPen (ColorControlText, lineWidth); + DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button); + return; + } + } + + case CaptionButton.Help: + case CaptionButton.Maximize: + case CaptionButton.Minimize: + case CaptionButton.Restore: { + if ((state & ButtonState.Inactive)!=0) { + DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button); + + DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button); + return; + } else { + DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button); + return; + } + } + } + } + + public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state) + { + CPDrawCheckBoxInternal (dc, rectangle, state, false /* mixed */); + } + + private void CPDrawCheckBoxInternal (Graphics dc, Rectangle rectangle, ButtonState state, bool mixed) + { + Pen check_pen = (mixed) ? Pens.Gray : Pens.Black; + + Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); + + if ((state & ButtonState.All) == ButtonState.All) { + cb_rect.Width -= 2; + cb_rect.Height -= 2; + + dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + + check_pen = SystemPens.ControlDark; + } else + if ((state & ButtonState.Flat) == ButtonState.Flat) { + cb_rect.Width -= 2; + cb_rect.Height -= 2; + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + else + dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1); + } else { + cb_rect.Width -= 1; + cb_rect.Height -= 1; + + int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height; + + int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2); + int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2); + + Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size); + + if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) { + dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, + Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), + ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + } else + dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3); + + Pen pen = SystemPens.ControlDark; + dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1); + dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y); + + pen = SystemPens.ControlDarkDark; + dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2); + dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1); + + pen = SystemPens.ControlLightLight; + dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom); + dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom); + + // oh boy, matching ms is like fighting against windmills + using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50, + Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), ColorControl))) { + dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1); + dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1); + } + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + check_pen = SystemPens.ControlDark; + } + + if ((state & ButtonState.Checked) == ButtonState.Checked) { + int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2; + + if (check_size < 7) { + int lineWidth = Math.Max (3, check_size / 3); + int Scale = Math.Max (1, check_size / 9); + + 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, + check_size, check_size); + + for (int i = 0; i < lineWidth; i++) { + dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i); + 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); + } + } else { + int lineWidth = Math.Max (3, check_size / 3) + 1; + + int x_half = cb_rect.Width / 2; + int y_half = cb_rect.Height / 2; + + Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), + check_size, check_size); + + int gradient_left = check_size / 3; + int gradient_right = check_size - gradient_left - 1; + + + for (int i = 0; i < lineWidth; i++) { + dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i); + dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i - 1 - gradient_right); + } + } + } + } + + public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) { + Point[] arrow = new Point[3]; + Point P1; + Point P2; + Point P3; + int centerX; + int centerY; + int shiftX; + int shiftY; + Rectangle rect; + + if ((state & ButtonState.Checked)!=0) { + graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle); + } + + if ((state & ButtonState.Flat)!=0) { + WidgetPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid); + } else { + if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) { + // this needs to render like a pushed button - jba + // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl); + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0)); + graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle); + } else { + CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl); + } + } + + rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2); + centerX=rect.Left+rect.Width/2; + centerY=rect.Top+rect.Height/2; + shiftX=Math.Max(1, rect.Width/8); + shiftY=Math.Max(1, rect.Height/8); + + if ((state & ButtonState.Pushed)!=0) { + shiftX++; + shiftY++; + } + + rect.Y-=shiftY; + centerY-=shiftY; + P1=new Point(rect.Left, centerY); + P2=new Point(rect.Right, centerY); + P3=new Point(centerX, rect.Bottom); + + arrow[0]=P1; + arrow[1]=P2; + arrow[2]=P3; + + /* Draw the arrow */ + if ((state & ButtonState.Inactive)!=0) { + /* Move away from the shadow */ + arrow[0].X += 1; arrow[0].Y += 1; + arrow[1].X += 1; arrow[1].Y += 1; + arrow[2].X += 1; arrow[2].Y += 1; + + graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding); + + arrow[0]=P1; + arrow[1]=P2; + arrow[2]=P3; + + graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding); + } else { + graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding); + } + } + + public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds) + { + Pen pen = Pens.Black; + Rectangle rect = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1); // Dunno why, but MS does it that way, too + int X; + int Y; + + graphics.FillRectangle (SystemBrushes.ControlLightLight, rect); + graphics.DrawRectangle (pen, rect); + + X = rect.X + rect.Width / 2; + Y = rect.Y + rect.Height / 2; + + /* Draw the cross */ + graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2); + graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y); + + /* Draw 'arrows' for vertical lines */ + graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3); + graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3); + + /* Draw 'arrows' for horizontal lines */ + graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1); + graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1); + } + + public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) { + // make a rectange to trace around border of the button + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0)); + + Color outerColor = foreColor; + // adjust focus color according to the flatstyle + if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) { + outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? WidgetPaint.Dark(ColorControl) : ColorControlText; + } + + // draw the outer rectangle + graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle); + + // draw the inner rectangle + if (button.FlatStyle == FlatStyle.Popup) { + DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor); + } else { + // draw a flat inner rectangle + Pen pen = ResPool.GetPen (WidgetPaint.LightLight (backColor)); + graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4)); + } + } + + public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor) + { + // make a rectange to trace around border of the button + Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0)); + +#if NotUntilCairoIsFixed + Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255)); + DashStyle oldStyle; // used for caching old penstyle + Pen pen = ResPool.GetPen (colorBackInverted); + + oldStyle = pen.DashStyle; + pen.DashStyle = DashStyle.Dot; + + graphics.DrawRectangle (pen, trace_rectangle); + pen.DashStyle = oldStyle; +#else + CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor); +#endif + } + + + public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) + { + Rectangle rect = rectangle; + Pen pen; + HatchBrush brush; + + if (backColor.GetBrightness () >= 0.5) { + foreColor = Color.Transparent; + backColor = Color.Black; + + } else { + backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255)); + foreColor = Color.Black; + } + + brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor); + pen = new Pen (brush, 1); + + rect.Width--; + rect.Height--; + + graphics.DrawRectangle (pen, rect); + pen.Dispose (); + } + + public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled) + { + Brush sb; + Pen pen; + + if (primary == true) { + pen = Pens.Black; + if (enabled == true) { + sb = Brushes.White; + } else { + sb = SystemBrushes.Control; + } + } else { + pen = Pens.White; + if (enabled == true) { + sb = Brushes.Black; + } else { + sb = SystemBrushes.Control; + } + } + graphics.FillRectangle (sb, rectangle); + graphics.DrawRectangle (pen, rectangle); + } + + + public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) { + Color foreColor; + int h; + int b; + int s; + + WidgetPaint.Color2HBS(backColor, out h, out b, out s); + + if (b>127) { + foreColor=Color.Black; + } else { + foreColor=Color.White; + } + + // still not perfect. it seems that ms calculates the position of the first dot or line + + using (Pen pen = new Pen (foreColor)) { + pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1}; + + for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height) + graphics.DrawLine (pen, area.X, y, area.Right - 1, y); + } + } + + public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) { + /* + Microsoft seems to ignore the background and simply make + the image grayscale. At least when having > 256 colors on + the display. + */ + + if (imagedisabled_attributes == null) { + imagedisabled_attributes = new ImageAttributes (); + ColorMatrix colorMatrix=new ColorMatrix(new float[][] { + // This table would create a perfect grayscale image, based on luminance + // new float[]{0.3f,0.3f,0.3f,0,0}, + // new float[]{0.59f,0.59f,0.59f,0,0}, + // new float[]{0.11f,0.11f,0.11f,0,0}, + // new float[]{0,0,0,1,0,0}, + // new float[]{0,0,0,0,1,0}, + // new float[]{0,0,0,0,0,1} + + // This table generates a image that is grayscaled and then + // brightened up. Seems to match MS close enough. + new float[]{0.2f,0.2f,0.2f,0,0}, + new float[]{0.41f,0.41f,0.41f,0,0}, + new float[]{0.11f,0.11f,0.11f,0,0}, + new float[]{0.15f,0.15f,0.15f,1,0,0}, + new float[]{0.15f,0.15f,0.15f,0,1,0}, + new float[]{0.15f,0.15f,0.15f,0,0,1} + }); + + imagedisabled_attributes.SetColorMatrix (colorMatrix); + } + + graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes); + + } + + + public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) { + Pen penBorder; + Pen penInside; + + if (primary) { + penBorder = ResPool.GetSizedPen (Color.White, 2); + penInside = ResPool.GetPen (Color.Black); + } else { + penBorder = ResPool.GetSizedPen (Color.Black, 2); + penInside = ResPool.GetPen (Color.White); + } + penBorder.Alignment=PenAlignment.Inset; + penInside.Alignment=PenAlignment.Inset; + + graphics.DrawRectangle(penBorder, rectangle); + graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5); + } + + + public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) { + Rectangle rect; + int lineWidth; + + if (backColor != Color.Empty) + graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle); + + Brush brush = ResPool.GetSolidBrush (color); + + switch(glyph) { + case MenuGlyph.Arrow: { + float height = rectangle.Height * 0.7f; + float width = height / 2.0f; + + PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f)); + + PointF [] vertices = new PointF [3]; + vertices [0].X = ddCenter.X; + vertices [0].Y = ddCenter.Y - (height / 2.0f); + vertices [1].X = ddCenter.X; + vertices [1].Y = ddCenter.Y + (height / 2.0f); + vertices [2].X = ddCenter.X + width + 0.1f; + vertices [2].Y = ddCenter.Y; + + graphics.FillPolygon (brush, vertices); + + return; + } + + case MenuGlyph.Bullet: { + + lineWidth=Math.Max(2, rectangle.Width/3); + rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2); + + graphics.FillEllipse(brush, rect); + + return; + } + + case MenuGlyph.Checkmark: { + + Pen pen = ResPool.GetPen (color); + lineWidth = Math.Max (2, rectangle.Width / 6); + rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2); + + int Scale = Math.Max (1, rectangle.Width / 12); + int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2)); + + for (int i=0; i<lineWidth; i++) { + graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i); + graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i); + } + return; + } + } + + } + + public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state) + { + CPDrawCheckBoxInternal (graphics, rectangle, state, true /* mixed */); + } + + public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state) + { + CPColor cpcolor = ResPool.GetCPColor (ColorControl); + + Color dot_color = Color.Black; + + Color top_left_outer = Color.Black; + Color top_left_inner = Color.Black; + Color bottom_right_outer = Color.Black; + Color bottom_right_inner = Color.Black; + + int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height * 0.9f) : (int)(rectangle.Width * 0.9f); + int radius = ellipse_diameter / 2; + + Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter); + + Brush brush = null; + + if ((state & ButtonState.All) == ButtonState.All) { + brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), + ColorControl.G, ColorControl.B), ColorControl); + dot_color = cpcolor.Dark; + } else + if ((state & ButtonState.Flat) == ButtonState.Flat) { + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed)) + brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl); + else + brush = SystemBrushes.ControlLightLight; + } else { + if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed)) + brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl); + else + brush = SystemBrushes.ControlLightLight; + + top_left_outer = cpcolor.Dark; + top_left_inner = cpcolor.DarkDark; + bottom_right_outer = cpcolor.Light; + bottom_right_inner = Color.Transparent; + + if ((state & ButtonState.Inactive) == ButtonState.Inactive) + dot_color = cpcolor.Dark; + } + + dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1); + + int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f)); + + dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f); + dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f); + dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f); + + if (bottom_right_inner != Color.Transparent) + dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f); + else + 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)) { + dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f); + } + + if ((state & ButtonState.Checked) == ButtonState.Checked) { + int inflate = line_width * 4; + Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate); + if (rectangle.Height > 13) { + tmp.X += 1; + tmp.Y += 1; + tmp.Height -= 1; + dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp); + } else { + Pen pen = ResPool.GetPen (dot_color); + dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2)); + dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1); + + dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom); + dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom); + } + } + } + + public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) { + + } + + + public override void CPDrawReversibleLine (Point start, Point end, Color backColor) { + + } + + + /* Scroll button: regular button + direction arrow */ + public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state) + { + DrawScrollButtonPrimitive (dc, area, state); + + bool fill_rect = true; + int offset = 0; + + if ((state & ButtonState.Pushed) != 0) + offset = 1; + + // skip the border + Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4); + + Point [] arrow = new Point [3]; + for (int i = 0; i < 3; i++) + arrow [i] = new Point (); + + Pen pen = SystemPens.ControlText; + + if ((state & ButtonState.Inactive) != 0) { + pen = SystemPens.ControlDark; + } + + switch (type) { + default: + case ScrollButton.Down: + int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1; + int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1; + if (x_middle == 1) + x_middle = 2; + + int triangle_height; + + if (rect.Height < 8) { + triangle_height = 2; + fill_rect = false; + } else if (rect.Height == 11) { + triangle_height = 3; + } else { + triangle_height = (int)Math.Round (rect.Height / 3.0f); + } + + arrow [0].X = rect.X + x_middle; + arrow [0].Y = rect.Y + y_middle + triangle_height / 2; + + arrow [1].X = arrow [0].X + triangle_height - 1; + arrow [1].Y = arrow [0].Y - triangle_height + 1; + arrow [2].X = arrow [0].X - triangle_height + 1; + arrow [2].Y = arrow [1].Y; + + dc.DrawPolygon (pen, arrow); + + if ((state & ButtonState.Inactive) != 0) { + dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1); + dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y); + } + + if (fill_rect) { + for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) { + dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i); + arrow [1].X -= 1; + arrow [2].X += 1; + } + } + break; + + case ScrollButton.Up: + x_middle = (int)Math.Round (rect.Width / 2.0f) - 1; + y_middle = (int)Math.Round (rect.Height / 2.0f); + if (x_middle == 1) + x_middle = 2; + + if (y_middle == 1) + y_middle = 2; + + if (rect.Height < 8) { + triangle_height = 2; + fill_rect = false; + } else if (rect.Height == 11) { + triangle_height = 3; + } else { + triangle_height = (int)Math.Round (rect.Height / 3.0f); + } + + arrow [0].X = rect.X + x_middle; + arrow [0].Y = rect.Y + y_middle - triangle_height / 2; + + arrow [1].X = arrow [0].X + triangle_height - 1; + arrow [1].Y = arrow [0].Y + triangle_height - 1; + arrow [2].X = arrow [0].X - triangle_height + 1; + arrow [2].Y = arrow [1].Y; + + dc.DrawPolygon (pen, arrow); + + if ((state & ButtonState.Inactive) != 0) { + dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1); + } + + if (fill_rect) { + for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) { + dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i); + arrow [1].X -= 1; + arrow [2].X += 1; + } + } + break; + + case ScrollButton.Left: + y_middle = (int)Math.Round (rect.Height / 2.0f) - 1; + if (y_middle == 1) + y_middle = 2; + + int triangle_width; + + if (rect.Width < 8) { + triangle_width = 2; + fill_rect = false; + } else if (rect.Width == 11) { + triangle_width = 3; + } else { + triangle_width = (int)Math.Round (rect.Width / 3.0f); + } + + arrow [0].X = rect.Left + triangle_width - 1; + arrow [0].Y = rect.Y + y_middle; + + if (arrow [0].X - 1 == rect.X) + arrow [0].X += 1; + + arrow [1].X = arrow [0].X + triangle_width - 1; + arrow [1].Y = arrow [0].Y - triangle_width + 1; + arrow [2].X = arrow [1].X; + arrow [2].Y = arrow [0].Y + triangle_width - 1; + + dc.DrawPolygon (pen, arrow); + + if ((state & ButtonState.Inactive) != 0) { + dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1); + } + + if (fill_rect) { + for (int i = 0; i < arrow [2].X - arrow [0].X; i++) { + dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y); + arrow [1].Y += 1; + arrow [2].Y -= 1; + } + } + break; + + case ScrollButton.Right: + y_middle = (int)Math.Round (rect.Height / 2.0f) - 1; + if (y_middle == 1) + y_middle = 2; + + if (rect.Width < 8) { + triangle_width = 2; + fill_rect = false; + } else if (rect.Width == 11) { + triangle_width = 3; + } else { + triangle_width = (int)Math.Round (rect.Width / 3.0f); + } + + arrow [0].X = rect.Right - triangle_width - 1; + arrow [0].Y = rect.Y + y_middle; + + if (arrow [0].X - 1 == rect.X) + arrow [0].X += 1; + + arrow [1].X = arrow [0].X - triangle_width + 1; + arrow [1].Y = arrow [0].Y - triangle_width + 1; + arrow [2].X = arrow [1].X; + arrow [2].Y = arrow [0].Y + triangle_width - 1; + + dc.DrawPolygon (pen, arrow); + + if ((state & ButtonState.Inactive) != 0) { + dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1); + dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y); + } + + if (fill_rect) { + for (int i = 0; i < arrow [0].X - arrow [1].X; i++) { + dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y); + arrow [1].Y += 1; + arrow [2].Y -= 1; + } + } + break; + } + } + + public override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect, + Color backColor) { + + } + + + public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds) + { + Pen pen_dark = ResPool.GetPen(WidgetPaint.Dark(backColor)); + Pen pen_light_light = ResPool.GetPen(WidgetPaint.LightLight(backColor)); + + for (int i = 2; i < bounds.Width - 2; i += 4) { + dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1); + dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i); + dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1); + } + } + + private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString) + { + CPColor cpcolor = ResPool.GetCPColor (color); + + layoutRectangle.Offset (1, 1); + TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString); + + layoutRectangle.Offset (-1, -1); + TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString); + } + + public override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format) + { + CPColor cpcolor = ResPool.GetCPColor (color); + + dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), + new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height), + format); + dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format); + } + + public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format) + { + CPColor cpcolor = ResPool.GetCPColor (color); + + layoutRectangle.Offset (1, 1); + TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format); + + layoutRectangle.Offset (-1, -1); + TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format); + } + + public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds) + { + graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds); + } + + private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY, + int width, Color color, ButtonBorderStyle style, Border3DSide side) + { + DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, + width, color, style, side); + } + + private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY, + int width, Color color, ButtonBorderStyle style, Border3DSide side) { + + Pen pen = null; + + switch (style) { + case ButtonBorderStyle.Solid: + case ButtonBorderStyle.Inset: + case ButtonBorderStyle.Outset: + pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid); + break; + case ButtonBorderStyle.Dashed: + pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash); + break; + case ButtonBorderStyle.Dotted: + pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot); + break; + default: + case ButtonBorderStyle.None: + return; + } + + switch(style) { + case ButtonBorderStyle.Outset: { + Color colorGrade; + int hue, brightness, saturation; + int brightnessSteps; + int brightnessDownSteps; + + WidgetPaint.Color2HBS(color, out hue, out brightness, out saturation); + + brightnessDownSteps=brightness/width; + if (brightness>127) { + brightnessSteps=Math.Max(6, (160-brightness)/width); + } else { + brightnessSteps=(127-brightness)/width; + } + + for (int i=0; i<width; i++) { + switch(side) { + case Border3DSide.Left: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i); + break; + } + + case Border3DSide.Right: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i); + break; + } + + case Border3DSide.Top: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i); + break; + } + + case Border3DSide.Bottom: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i); + break; + } + } + } + break; + } + + case ButtonBorderStyle.Inset: { + Color colorGrade; + int hue, brightness, saturation; + int brightnessSteps; + int brightnessDownSteps; + + WidgetPaint.Color2HBS(color, out hue, out brightness, out saturation); + + brightnessDownSteps=brightness/width; + if (brightness>127) { + brightnessSteps=Math.Max(6, (160-brightness)/width); + } else { + brightnessSteps=(127-brightness)/width; + } + + for (int i=0; i<width; i++) { + switch(side) { + case Border3DSide.Left: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i); + break; + } + + case Border3DSide.Right: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i); + break; + } + + case Border3DSide.Top: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i); + break; + } + + case Border3DSide.Bottom: { + colorGrade=WidgetPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation); + pen = ThemeEngine.Current.ResPool.GetPen (colorGrade); + graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i); + break; + } + } + } + break; + } + + /* + I decided to have the for-loop duplicated for speed reasons; + that way we only have to switch once (as opposed to have the + for-loop around the switch) + */ + default: { + switch(side) { + case Border3DSide.Left: { + for (int i=0; i<width; i++) { + graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i); + } + break; + } + + case Border3DSide.Right: { + for (int i=0; i<width; i++) { + graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i); + } + break; + } + + case Border3DSide.Top: { + for (int i=0; i<width; i++) { + graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i); + } + break; + } + + case Border3DSide.Bottom: { + for (int i=0; i<width; i++) { + graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i); + } + break; + } + } + break; + } + } + } + + /* + This function actually draws the various caption elements. + This way we can scale them nicely, no matter what size, and they + still look like MS's scaled caption buttons. (as opposed to scaling a bitmap) + */ + + private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) { + switch(button) { + case CaptionButton.Close: { + if (lineWidth<2) { + 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); + 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); + } + + graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift); + graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift); + return; + } + + case CaptionButton.Help: { + StringFormat sf = new StringFormat(); + Font font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel); + + sf.Alignment=StringAlignment.Center; + sf.LineAlignment=StringAlignment.Center; + + + graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf); + + sf.Dispose(); + font.Dispose(); + + return; + } + + case CaptionButton.Maximize: { + /* Top 'caption bar' line */ + for (int i=0; i<Math.Max(2, lineWidth); i++) { + 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); + } + + /* Left side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift); + } + + /* Right side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + 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); + } + + /* Bottom line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i); + } + return; + } + + case CaptionButton.Minimize: { + /* Bottom line */ + for (int i=0; i<Math.Max(2, lineWidth); i++) { + graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i); + } + return; + } + + case CaptionButton.Restore: { + /** First 'window' **/ + /* Top 'caption bar' line */ + for (int i=0; i<Math.Max(2, lineWidth); i++) { + 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); + } + + /* Left side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + 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); + } + + /* Right side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + 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); + } + + /* Bottom line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + 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); + } + + /** Second 'window' **/ + /* Top 'caption bar' line */ + for (int i=0; i<Math.Max(2, lineWidth); i++) { + 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); + } + + /* Left side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift); + } + + /* Right side line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + 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); + } + + /* Bottom line */ + for (int i=0; i<Math.Max(1, lineWidth/2); i++) { + graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i); + } + + return; + } + + } + } + + /* Generic scroll button */ + public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) { + if ((state & ButtonState.Pushed) == ButtonState.Pushed) { + dc.FillRectangle (SystemBrushes.Control, area.X + 1, + area.Y + 1, area.Width - 2 , area.Height - 2); + + dc.DrawRectangle (SystemPens.ControlDark, area.X, + area.Y, area.Width, area.Height); + + return; + } + + Brush sb_control = SystemBrushes.Control; + Brush sb_lightlight = SystemBrushes.ControlLightLight; + Brush sb_dark = SystemBrushes.ControlDark; + Brush sb_darkdark = SystemBrushes.ControlDarkDark; + + dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1); + dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height); + + dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1); + dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1, + area.Height - 4); + + dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2, + area.Width - 2, 1); + + dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1, + area.Width , 1); + + dc.FillRectangle (sb_dark, area.X + area.Width - 2, + area.Y + 1, 1, area.Height -3); + + dc.FillRectangle (sb_darkdark, area.X + area.Width -1, + area.Y, 1, area.Height - 1); + + dc.FillRectangle (sb_control, area.X + 2, + area.Y + 2, area.Width - 4, area.Height - 4); + + } + + public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) { + switch (border_style){ + case BorderStyle.Fixed3D: + dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y); + dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height); + dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , + area.Y + area.Height - 1); + dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, + area.Y + area.Height); + + dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2); + dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2); + dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3); + dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1); + break; + case BorderStyle.FixedSingle: + dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1); + break; + case BorderStyle.None: + default: + break; + } + + } + #endregion // WidgetPaint + + + } //class +} diff --git a/source/ShiftUI/Theming/VisualStyles/CheckBoxPainter.cs b/source/ShiftUI/Theming/VisualStyles/CheckBoxPainter.cs new file mode 100644 index 0000000..0f20ca0 --- /dev/null +++ b/source/ShiftUI/Theming/VisualStyles/CheckBoxPainter.cs @@ -0,0 +1,104 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// +// Authors: +// George Giolfan ([email protected]) + +using System.Drawing; +using ShiftUI.VisualStyles; +namespace ShiftUI.Theming.VisualStyles +{ + class CheckBoxPainter : Default.CheckBoxPainter + { + public override void DrawNormalCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + CheckBoxState check_box_state; + switch (state) { + case CheckState.Checked: + check_box_state = CheckBoxState.CheckedNormal; + break; + case CheckState.Indeterminate: + check_box_state = CheckBoxState.MixedNormal; + break; + default: + check_box_state = CheckBoxState.UncheckedNormal; + break; + } + DrawCheckBox (g, bounds, check_box_state); + } + public override void DrawHotCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + CheckBoxState check_box_state; + switch (state) { + case CheckState.Checked: + check_box_state = CheckBoxState.CheckedHot; + break; + case CheckState.Indeterminate: + check_box_state = CheckBoxState.MixedHot; + break; + default: + check_box_state = CheckBoxState.UncheckedHot; + break; + } + DrawCheckBox (g, bounds, check_box_state); + } + public override void DrawPressedCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + CheckBoxState check_box_state; + switch (state) { + case CheckState.Checked: + check_box_state = CheckBoxState.CheckedPressed; + break; + case CheckState.Indeterminate: + check_box_state = CheckBoxState.MixedPressed; + break; + default: + check_box_state = CheckBoxState.UncheckedPressed; + break; + } + DrawCheckBox (g, bounds, check_box_state); + } + public override void DrawDisabledCheckBox (Graphics g, Rectangle bounds, Color backColor, Color foreColor, CheckState state) + { + CheckBoxState check_box_state; + switch (state) { + case CheckState.Checked: + check_box_state = CheckBoxState.CheckedDisabled; + break; + case CheckState.Indeterminate: + check_box_state = CheckBoxState.MixedDisabled; + break; + default: + check_box_state = CheckBoxState.UncheckedDisabled; + break; + } + DrawCheckBox (g, bounds, check_box_state); + } + static void DrawCheckBox (Graphics g, Rectangle bounds, CheckBoxState state) + { + CheckBoxRenderer.DrawCheckBox ( + g, + bounds.Location, + state + ); + } + } +} diff --git a/source/ShiftUI/Theming/VisualStyles/RadioButtonPainter.cs b/source/ShiftUI/Theming/VisualStyles/RadioButtonPainter.cs new file mode 100644 index 0000000..16283de --- /dev/null +++ b/source/ShiftUI/Theming/VisualStyles/RadioButtonPainter.cs @@ -0,0 +1,56 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// +// Authors: +// George Giolfan ([email protected]) + +using System.Drawing; +using ShiftUI.VisualStyles; +namespace ShiftUI.Theming.VisualStyles +{ + class RadioButtonPainter : Default.RadioButtonPainter + { + public override void DrawNormalRadioButton (Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked) + { + DrawRadioButton (g, bounds, isChecked ? RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal); + } + public override void DrawHotRadioButton(Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked) + { + DrawRadioButton (g, bounds, isChecked ? RadioButtonState.CheckedHot : RadioButtonState.UncheckedHot); + } + public override void DrawPressedRadioButton(Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked) + { + DrawRadioButton (g, bounds, isChecked ? RadioButtonState.CheckedPressed : RadioButtonState.UncheckedPressed); + } + public override void DrawDisabledRadioButton(Graphics g, Rectangle bounds, Color backColor, Color foreColor, bool isChecked) + { + DrawRadioButton (g, bounds, isChecked ? RadioButtonState.CheckedDisabled : RadioButtonState.UncheckedDisabled); + } + static void DrawRadioButton (Graphics g, Rectangle bounds, RadioButtonState state) + { + RadioButtonRenderer.DrawRadioButton ( + g, + bounds.Location, + state + ); + } + } +} diff --git a/source/ShiftUI/Theming/VisualStyles/TabControlPainter.cs b/source/ShiftUI/Theming/VisualStyles/TabControlPainter.cs new file mode 100644 index 0000000..0574f33 --- /dev/null +++ b/source/ShiftUI/Theming/VisualStyles/TabControlPainter.cs @@ -0,0 +1,267 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// +// Authors: +// George Giolfan ([email protected]) + +using System.Drawing; +using ShiftUI; +using ShiftUI.Theming.Default; +using ShiftUI.VisualStyles; +namespace ShiftUI.Theming.VisualStyles +{ + class TabWidgetPainter : Default.TabWidgetPainter + { + static bool ShouldPaint (TabWidget tabControl) { + return ThemeVisualStyles.RenderClientAreas && + tabControl.Alignment == TabAlignment.Top && + tabControl.DrawMode == TabDrawMode.Normal; + } + protected override void DrawBackground (Graphics dc, Rectangle area, TabWidget tab) + { + if (!ShouldPaint (tab)) { + base.DrawBackground (dc, area, tab); + return; + } + + VisualStyleElement element = VisualStyleElement.Tab.Pane.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawBackground (dc, area, tab); + return; + } + Rectangle panel_rectangle = GetTabPanelRect (tab); + if (panel_rectangle.IntersectsWith (area)) + new VisualStyleRenderer (element).DrawBackground (dc, panel_rectangle, area); + } + protected override int DrawTab (Graphics dc, TabPage page, TabWidget tab, Rectangle bounds, bool is_selected) + { + if (!ShouldPaint (tab)) + return base.DrawTab (dc, page, tab, bounds, is_selected); + VisualStyleElement element = GetVisualStyleElement (tab, page, is_selected); + if (!VisualStyleRenderer.IsElementDefined (element)) + return base.DrawTab (dc, page, tab, bounds, is_selected); + new VisualStyleRenderer (element).DrawBackground (dc, bounds); + bounds.Inflate ( + -(tab.Padding.X), + -(tab.Padding.Y)); + Rectangle text_area = bounds; + if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) { + int image_y = bounds.Y + (bounds.Height - tab.ImageList.ImageSize.Height) / 2; + tab.ImageList.Draw (dc, new Point (bounds.X, image_y), page.ImageIndex); + int image_occupied_space = tab.ImageList.ImageSize.Width + 2; + text_area.X += image_occupied_space; + text_area.Width -= image_occupied_space; + } + if (page.Text != null) + dc.DrawString (page.Text, tab.Font, SystemBrushes.ControlText, text_area, DefaultFormatting); + if (tab.Focused && is_selected && tab.ShowFocusCues) + WidgetPaint.DrawFocusRectangle (dc, bounds); + return 0; + } + static VisualStyleElement GetVisualStyleElement (TabWidget tabControl, TabPage tabPage, bool selected) + { + bool top_edge = tabPage.Row == tabControl.RowCount; + int tab_page_index = tabControl.TabPages.IndexOf (tabPage); + bool left_edge = true; + int index; + for (index = tabControl.SliderPos; index < tab_page_index; index++) + if (tabControl.TabPages [index].Row == tabPage.Row) { + left_edge = false; + break; + } + bool right_edge = true; + for (index = tab_page_index; index < tabControl.TabCount; index++) + if (tabControl.TabPages [index].Row == tabPage.Row) { + right_edge = false; + break; + } + if (!tabPage.Enabled) + #region Disabled + if (top_edge) + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TopTabItem.Disabled; + else + return VisualStyleElement.Tab.TopTabItemLeftEdge.Disabled; + else + if (right_edge) + return VisualStyleElement.Tab.TopTabItemRightEdge.Disabled; + else + return VisualStyleElement.Tab.TopTabItem.Disabled; + else + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TabItem.Disabled; + else + return VisualStyleElement.Tab.TabItemLeftEdge.Disabled; + else + if (right_edge) + return VisualStyleElement.Tab.TabItemRightEdge.Disabled; + else + return VisualStyleElement.Tab.TabItem.Disabled; + #endregion + else if (selected) + #region Pressed + if (top_edge) + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TopTabItem.Pressed; + else + return VisualStyleElement.Tab.TopTabItemLeftEdge.Pressed; + else + if (right_edge) + return VisualStyleElement.Tab.TopTabItemRightEdge.Pressed; + else + return VisualStyleElement.Tab.TopTabItem.Pressed; + else + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TabItem.Pressed; + else + return VisualStyleElement.Tab.TabItemLeftEdge.Pressed; + else + if (right_edge) + return VisualStyleElement.Tab.TabItemRightEdge.Pressed; + else + return VisualStyleElement.Tab.TabItem.Pressed; + #endregion + else if (tabControl.EnteredTabPage == tabPage) + #region Hot + if (top_edge) + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TopTabItem.Hot; + else + return VisualStyleElement.Tab.TopTabItemLeftEdge.Hot; + else + if (right_edge) + return VisualStyleElement.Tab.TopTabItemRightEdge.Hot; + else + return VisualStyleElement.Tab.TopTabItem.Hot; + else + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TabItem.Hot; + else + return VisualStyleElement.Tab.TabItemLeftEdge.Hot; + else + if (right_edge) + return VisualStyleElement.Tab.TabItemRightEdge.Hot; + else + return VisualStyleElement.Tab.TabItem.Hot; + #endregion + else + #region Normal + if (top_edge) + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TopTabItemBothEdges.Normal; + else + return VisualStyleElement.Tab.TopTabItemLeftEdge.Normal; + else + if (right_edge) + return VisualStyleElement.Tab.TopTabItemRightEdge.Normal; + else + return VisualStyleElement.Tab.TopTabItem.Normal; + else + if (left_edge) + if (right_edge) + return VisualStyleElement.Tab.TabItemBothEdges.Normal; + else + return VisualStyleElement.Tab.TabItemLeftEdge.Normal; + else + if (right_edge) + return VisualStyleElement.Tab.TabItemRightEdge.Normal; + else + return VisualStyleElement.Tab.TabItem.Normal; + #endregion + } + public override bool HasHotElementStyles (TabWidget tabControl) + { + if (!ShouldPaint (tabControl)) + return base.HasHotElementStyles (tabControl); + return true; + } + protected override void DrawScrollButton (Graphics dc, Rectangle bounds, Rectangle clippingArea, ScrollButton button, PushButtonState state) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.DrawScrollButton (dc, bounds, clippingArea, button, state); + return; + } + VisualStyleElement element; + if (button == ScrollButton.Left) + switch (state) { + case PushButtonState.Hot: + element = VisualStyleElement.Spin.DownHorizontal.Hot; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.Spin.DownHorizontal.Pressed; + break; + default: + element = VisualStyleElement.Spin.DownHorizontal.Normal; + break; + } + else + switch (state) { + case PushButtonState.Hot: + element = VisualStyleElement.Spin.UpHorizontal.Hot; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.Spin.UpHorizontal.Pressed; + break; + default: + element = VisualStyleElement.Spin.UpHorizontal.Normal; + break; + } + if (!VisualStyleRenderer.IsElementDefined (element)) { + if (button == ScrollButton.Left) + switch (state) { + case PushButtonState.Hot: + element = VisualStyleElement.ScrollBar.ArrowButton.LeftHot; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.ScrollBar.ArrowButton.LeftPressed; + break; + default: + element = VisualStyleElement.ScrollBar.ArrowButton.LeftNormal; + break; + } + else + switch (state) { + case PushButtonState.Hot: + element = VisualStyleElement.ScrollBar.ArrowButton.RightHot; + break; + case PushButtonState.Pressed: + element = VisualStyleElement.ScrollBar.ArrowButton.RightPressed; + break; + default: + element = VisualStyleElement.ScrollBar.ArrowButton.RightNormal; + break; + } + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.DrawScrollButton (dc, bounds, clippingArea, button, state); + return; + } + } + new VisualStyleRenderer (element).DrawBackground (dc, bounds, clippingArea); + } + } +} diff --git a/source/ShiftUI/Theming/VisualStyles/ToolStripPainter.cs b/source/ShiftUI/Theming/VisualStyles/ToolStripPainter.cs new file mode 100644 index 0000000..3ee1c1a --- /dev/null +++ b/source/ShiftUI/Theming/VisualStyles/ToolStripPainter.cs @@ -0,0 +1,213 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2008 George Giolfan +// +// Authors: +// George Giolfan ([email protected]) + +using System.Drawing; +using ShiftUI.VisualStyles; +namespace ShiftUI.Theming.VisualStyles +{ + class ToolStripPainter : Default.ToolStripPainter + { + static bool IsDisabled (ToolStripItem toolStripItem) + { + return !toolStripItem.Enabled; + } + static bool IsPressed (ToolStripItem toolStripItem) + { + return toolStripItem.Pressed; + } + static bool IsChecked (ToolStripItem toolStripItem) + { + ToolStripButton tool_strip_button = toolStripItem as ToolStripButton; + if (tool_strip_button == null) + return false; + return tool_strip_button.Checked; + } + static bool IsHot (ToolStripItem toolStripItem) + { + return toolStripItem.Selected; + } + public override void OnRenderButtonBackground (ToolStripItemRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderButtonBackground (e); + return; + } + VisualStyleElement element; + if (IsDisabled (e.Item)) + element = VisualStyleElement.ToolBar.Button.Disabled; + else if (IsPressed (e.Item)) + element = VisualStyleElement.ToolBar.Button.Pressed; + else if (IsChecked (e.Item)) + if (IsHot (e.Item)) + element = VisualStyleElement.ToolBar.Button.HotChecked; + else + element = VisualStyleElement.ToolBar.Button.Checked; + else if (IsHot (e.Item)) + element = VisualStyleElement.ToolBar.Button.Hot; + else + element = VisualStyleElement.ToolBar.Button.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderButtonBackground (e); + return; + } + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.Item.Bounds); + } + public override void OnRenderDropDownButtonBackground (ToolStripItemRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderDropDownButtonBackground (e); + return; + } + VisualStyleElement element; + if (IsDisabled (e.Item)) + element = VisualStyleElement.ToolBar.DropDownButton.Disabled; + else if (IsPressed (e.Item)) + element = VisualStyleElement.ToolBar.DropDownButton.Pressed; + else if (IsChecked (e.Item)) + if (IsHot (e.Item)) + element = VisualStyleElement.ToolBar.DropDownButton.HotChecked; + else + element = VisualStyleElement.ToolBar.DropDownButton.Checked; + else if (IsHot (e.Item)) + element = VisualStyleElement.ToolBar.DropDownButton.Hot; + else + element = VisualStyleElement.ToolBar.DropDownButton.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderDropDownButtonBackground (e); + return; + } + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.Item.Bounds); + } + public override void OnRenderGrip (ToolStripGripRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderGrip (e); + return; + } + if (e.GripStyle == ToolStripGripStyle.Hidden) + return; + VisualStyleElement element = e.GripDisplayStyle == ToolStripGripDisplayStyle.Vertical ? + VisualStyleElement.Rebar.Gripper.Normal : + VisualStyleElement.Rebar.GripperVertical.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderGrip (e); + return; + } + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.GripDisplayStyle == ToolStripGripDisplayStyle.Vertical ? + // GetPartSize seems to return useless values. + new Rectangle (2, 0, 5, 20) : + new Rectangle (0, 2, 20, 5)); + } + public override void OnRenderOverflowButtonBackground (ToolStripItemRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderOverflowButtonBackground (e); + return; + } + VisualStyleElement element = e.ToolStrip.Orientation == Orientation.Horizontal ? + VisualStyleElement.Rebar.Chevron.Normal : + VisualStyleElement.Rebar.ChevronVertical.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderOverflowButtonBackground (e); + return; + } + OnRenderButtonBackground (e); + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.Item.Bounds); + } + public override void OnRenderSeparator (ToolStripSeparatorRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderSeparator (e); + return; + } + VisualStyleElement element = e.ToolStrip.Orientation == Orientation.Horizontal ? + VisualStyleElement.ToolBar.SeparatorHorizontal.Normal : + VisualStyleElement.ToolBar.SeparatorVertical.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderSeparator (e); + return; + } + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.Item.Bounds); + } + public override void OnRenderSplitButtonBackground (ToolStripItemRenderEventArgs e) + { + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderSplitButtonBackground (e); + return; + } + VisualStyleElement element, drop_down_element; + if (IsDisabled (e.Item)) { + element = VisualStyleElement.ToolBar.SplitButton.Disabled; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.Disabled;; + } else if (IsPressed (e.Item)) { + element = VisualStyleElement.ToolBar.SplitButton.Pressed; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.Pressed; + } else if (IsChecked (e.Item)) + if (IsHot (e.Item)) { + element = VisualStyleElement.ToolBar.SplitButton.HotChecked; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.HotChecked; + } else { + element = VisualStyleElement.ToolBar.Button.Checked; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.Checked; + } + else if (IsHot (e.Item)) { + element = VisualStyleElement.ToolBar.SplitButton.Hot; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.Hot; + } else { + element = VisualStyleElement.ToolBar.SplitButton.Normal; + drop_down_element = VisualStyleElement.ToolBar.SplitButtonDropDown.Normal; + } + if (!VisualStyleRenderer.IsElementDefined (element) || + !VisualStyleRenderer.IsElementDefined (drop_down_element)) { + base.OnRenderSplitButtonBackground (e); + return; + } + ToolStripSplitButton tool_strip_split_button = (ToolStripSplitButton)e.Item; + VisualStyleRenderer renderer = new VisualStyleRenderer (element); + renderer.DrawBackground (e.Graphics, tool_strip_split_button.ButtonBounds); + renderer.SetParameters (drop_down_element); + renderer.DrawBackground (e.Graphics, tool_strip_split_button.DropDownButtonBounds); + } + public override void OnRenderToolStripBackground (ToolStripRenderEventArgs e) + { + if (e.ToolStrip.BackgroundImage != null) + return; + + if (!ThemeVisualStyles.RenderClientAreas) { + base.OnRenderToolStripBackground (e); + return; + } + VisualStyleElement element; + if (e.ToolStrip is StatusStrip) + element = VisualStyleElement.Status.Bar.Normal; + else + element = VisualStyleElement.Rebar.Band.Normal; + if (!VisualStyleRenderer.IsElementDefined (element)) { + base.OnRenderToolStripBackground (e); + return; + } + new VisualStyleRenderer (element).DrawBackground (e.Graphics, e.ToolStrip.Bounds, e.AffectedBounds); + } + } +} |
