1114 lines
39 KiB
C#
1114 lines
39 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.ComponentModel;
|
|
using System.QQ;
|
|
|
|
namespace System.QQ
|
|
{
|
|
/// <summary>
|
|
/// 鼠标的当前位置
|
|
/// </summary>
|
|
public enum ButtonMousePosition
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
None,
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
Button,
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
Splitebutton,
|
|
}
|
|
|
|
/// <summary>
|
|
/// 控件的状态。
|
|
/// </summary>
|
|
public enum ControlState
|
|
{
|
|
/// <summary>
|
|
/// 正常
|
|
/// </summary>
|
|
Normal,
|
|
/// <summary>
|
|
/// 鼠标经过
|
|
/// </summary>
|
|
Hover,
|
|
/// <summary>
|
|
/// 鼠标按下
|
|
/// </summary>
|
|
Pressed,
|
|
}
|
|
|
|
/// <summary>
|
|
/// 建立圆角路径的样式。
|
|
/// </summary>
|
|
public enum RoundStyle
|
|
{
|
|
/// <summary>
|
|
/// 四个角都不是圆角。
|
|
/// </summary>
|
|
None = 0,
|
|
/// <summary>
|
|
/// 四个角都为圆角。
|
|
/// </summary>
|
|
All = 1,
|
|
/// <summary>
|
|
/// 左边两个角为圆角。
|
|
/// </summary>
|
|
Left = 2,
|
|
/// <summary>
|
|
/// 右边两个角为圆角。
|
|
/// </summary>
|
|
Right = 3,
|
|
/// <summary>
|
|
/// 上边两个角为圆角。
|
|
/// </summary>
|
|
Top = 4,
|
|
/// <summary>
|
|
/// 下边两个角为圆角。
|
|
/// </summary>
|
|
Bottom = 5,
|
|
/// <summary>
|
|
/// 左下角为圆角。
|
|
/// </summary>
|
|
BottomLeft = 6,
|
|
/// <summary>
|
|
/// 右下角为圆角。
|
|
/// </summary>
|
|
BottomRight = 7,
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class QQButton : System.Windows.Forms.Button
|
|
{
|
|
private Color _borderColor = Color.FromArgb(161, 162, 160);
|
|
private Color _innerBorderColor = Color.FromArgb(200, 255, 255, 255);
|
|
private Color _baseColor = Color.FromArgb(10, 66, 204, 255);
|
|
private Color _baseColorEnd = Color.FromArgb(200, 66, 204, 255);
|
|
private Color _arrowColor = Color.FromArgb(64, 64, 64);
|
|
private int _imageWidth = 24;
|
|
private int _imageHeight = 24;
|
|
private RoundStyle _roundStyle = RoundStyle.All;
|
|
private int _radius = 2;
|
|
private int _imageTextSpace = 2;
|
|
private bool _pressOffset = true;
|
|
private bool _alwaysShowBorder = false;
|
|
private bool _showSpliteButton = false;
|
|
private int _spliteButtonWidth = 18;
|
|
private ControlState _controlState;
|
|
private ButtonMousePosition _mousePosition;
|
|
|
|
private bool _contextHandle;
|
|
private bool _contextOpened;
|
|
private int _contextOffset = 5;
|
|
|
|
/// <summary>
|
|
/// 普通按钮按下事件
|
|
/// </summary>
|
|
public event EventHandler OnButtonClick;
|
|
/// <summary>
|
|
/// 分割按钮按下事件
|
|
/// </summary>
|
|
public event EventHandler OnSpliteButtonClick;
|
|
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public QQButton()
|
|
: base()
|
|
{
|
|
SetStyle(
|
|
ControlStyles.SupportsTransparentBackColor |
|
|
ControlStyles.UserPaint |
|
|
ControlStyles.AllPaintingInWmPaint |
|
|
ControlStyles.OptimizedDoubleBuffer |
|
|
ControlStyles.ResizeRedraw |
|
|
ControlStyles.SupportsTransparentBackColor, true);
|
|
SetStyle(ControlStyles.Opaque, false);
|
|
|
|
this.BackColor = Color.Transparent;
|
|
}
|
|
/// <summary>
|
|
/// 下拉菜单与按钮的距离
|
|
/// </summary>
|
|
[DefaultValue(5)]
|
|
[Description("下拉菜单与按钮的距离")]
|
|
public int ContextOffset
|
|
{
|
|
get { return _contextOffset; }
|
|
set
|
|
{
|
|
_contextOffset = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 图片高度
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
[Description("是否启用分割按钮")]
|
|
public bool ShowSpliteButton
|
|
{
|
|
get { return _showSpliteButton; }
|
|
set
|
|
{
|
|
if (_showSpliteButton != value)
|
|
{
|
|
_showSpliteButton = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 分割按钮的宽度
|
|
/// </summary>
|
|
[DefaultValue(18)]
|
|
[Description("分割按钮的宽度")]
|
|
public int SpliteButtonWidth
|
|
{
|
|
get { return _spliteButtonWidth; }
|
|
set
|
|
{
|
|
if (_spliteButtonWidth != value)
|
|
{
|
|
_spliteButtonWidth = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 当鼠标按下时图片和文字是否产生偏移
|
|
/// </summary>
|
|
[DefaultValue(true)]
|
|
[Description("当鼠标按下时图片和文字是否产生偏移")]
|
|
public bool PressOffset
|
|
{
|
|
get { return _pressOffset; }
|
|
set
|
|
{
|
|
_pressOffset = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框
|
|
/// </summary>
|
|
[DefaultValue(false)]
|
|
[Description("是否一直显示按钮边框,设置为false则只在鼠标经过和按下时显示边框")]
|
|
public bool AlwaysShowBorder
|
|
{
|
|
get { return _alwaysShowBorder; }
|
|
set
|
|
{
|
|
if (_alwaysShowBorder != value)
|
|
{
|
|
_alwaysShowBorder = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 当显示分割按钮时,分割按钮的箭头颜色
|
|
/// </summary>
|
|
[DefaultValue(typeof(Color), "64,64,64")]
|
|
[Description("当显示分割按钮时,分割按钮的箭头颜色")]
|
|
public Color ArrowColor
|
|
{
|
|
get { return _arrowColor; }
|
|
set
|
|
{
|
|
if (_arrowColor != value)
|
|
{
|
|
_arrowColor = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 按钮的边框颜色
|
|
/// </summary>
|
|
[DefaultValue(typeof(Color), "161, 162, 160")]
|
|
[Description("按钮的边框颜色")]
|
|
public Color BorderColor
|
|
{
|
|
get { return _borderColor; }
|
|
set
|
|
{
|
|
if (_borderColor != value)
|
|
{
|
|
_borderColor = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 按钮内边框颜色
|
|
/// </summary>
|
|
[DefaultValue(typeof(Color), "200, 255, 255, 255")]
|
|
[Description("按钮内边框颜色")]
|
|
public Color InnerBorderColor
|
|
{
|
|
get { return _innerBorderColor; }
|
|
set
|
|
{
|
|
if (_innerBorderColor != value)
|
|
{
|
|
_innerBorderColor = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 鼠标经过和按下时按钮的渐变背景颜色
|
|
/// </summary>
|
|
[DefaultValue(typeof(Color), "10 ,66, 204, 160")]
|
|
[Description("鼠标经过和按下时按钮的渐变背景颜色")]
|
|
public Color BaseColor
|
|
{
|
|
get { return _baseColor; }
|
|
set
|
|
{
|
|
if (_baseColor != value)
|
|
{
|
|
_baseColor = value;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 鼠标经过和按下时按钮的渐变背景颜色
|
|
/// </summary>
|
|
[DefaultValue(typeof(Color), "200 ,66, 204, 160")]
|
|
[Description("鼠标经过和按下时按钮的渐变背景颜色")]
|
|
public Color BaseColorEnd
|
|
{
|
|
get { return _baseColorEnd; }
|
|
set
|
|
{
|
|
if (_baseColorEnd != value)
|
|
{
|
|
_baseColorEnd = value;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 图片宽度
|
|
/// </summary>
|
|
[DefaultValue(24)]
|
|
[Description("图片宽度")]
|
|
public int ImageWidth
|
|
{
|
|
get { return _imageWidth; }
|
|
set
|
|
{
|
|
if (value != _imageWidth)
|
|
{
|
|
|
|
_imageWidth = value < 12 ? 12 : value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 图片高度
|
|
/// </summary>
|
|
[DefaultValue(24)]
|
|
[Description("图片高度")]
|
|
public int ImageHeight
|
|
{
|
|
get { return _imageHeight; }
|
|
set
|
|
{
|
|
if (value != _imageHeight)
|
|
{
|
|
|
|
_imageHeight = value < 12 ? 12 : value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 按钮圆角样式
|
|
/// </summary>
|
|
[DefaultValue(typeof(RoundStyle), "1")]
|
|
[Description("按钮圆角样式")]
|
|
public RoundStyle RoundStyle
|
|
{
|
|
get { return _roundStyle; }
|
|
set
|
|
{
|
|
if (_roundStyle != value)
|
|
{
|
|
_roundStyle = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 按钮圆角弧度
|
|
/// </summary>
|
|
[DefaultValue(2)]
|
|
[Description("按钮圆角弧度")]
|
|
public int Radius
|
|
{
|
|
get { return _radius; }
|
|
set
|
|
{
|
|
if (_radius != value)
|
|
{
|
|
_radius = value < 2 ? 2 : value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 图片与文字之间的间距
|
|
/// </summary>
|
|
[DefaultValue(2)]
|
|
[Description("图片与文字之间的间距")]
|
|
public int ImageTextSpace
|
|
{
|
|
get { return _imageTextSpace; }
|
|
set
|
|
{
|
|
if (_imageTextSpace != value)
|
|
{
|
|
_imageTextSpace = value < 0 ? 0 : value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 按钮当前状态
|
|
/// </summary>
|
|
internal ControlState ControlState
|
|
{
|
|
get { return _controlState; }
|
|
set
|
|
{
|
|
if (_controlState != value)
|
|
{
|
|
_controlState = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 鼠标当前所在位置
|
|
/// </summary>
|
|
internal ButtonMousePosition CurrentMousePosition
|
|
{
|
|
get { return _mousePosition; }
|
|
set
|
|
{
|
|
if (_mousePosition != value)
|
|
{
|
|
_mousePosition = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 普通按钮矩形位置
|
|
/// </summary>
|
|
internal Rectangle ButtonRect
|
|
{
|
|
get
|
|
{
|
|
if (ShowSpliteButton)
|
|
{
|
|
return new Rectangle(0, 0, ClientRectangle.Width - SpliteButtonWidth, ClientRectangle.Height);
|
|
}
|
|
else
|
|
{
|
|
return ClientRectangle;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分割按钮矩形位置
|
|
/// </summary>
|
|
internal Rectangle SpliteButtonRect
|
|
{
|
|
get
|
|
{
|
|
if (ShowSpliteButton)
|
|
{
|
|
return new Rectangle(ClientRectangle.Width - SpliteButtonWidth, 0, SpliteButtonWidth, ClientRectangle.Height);
|
|
}
|
|
else
|
|
{
|
|
return Rectangle.Empty;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseLeave(EventArgs e)
|
|
{
|
|
base.OnMouseLeave(e);
|
|
if (!_contextOpened)
|
|
{
|
|
ControlState = ControlState.Normal;
|
|
CurrentMousePosition = ButtonMousePosition.None;
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="mevent"></param>
|
|
protected override void OnMouseMove(MouseEventArgs mevent)
|
|
{
|
|
base.OnMouseMove(mevent);
|
|
if (ClientRectangle.Contains(mevent.Location))
|
|
{
|
|
ControlState = ControlState.Hover;
|
|
if (ShowSpliteButton)
|
|
{
|
|
CurrentMousePosition = ButtonRect.Contains(mevent.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton;
|
|
}
|
|
else
|
|
{
|
|
CurrentMousePosition = ButtonMousePosition.Button;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ControlState = ControlState.Normal;
|
|
CurrentMousePosition = ButtonMousePosition.None;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
base.OnMouseDown(e);
|
|
if (e.Button == MouseButtons.Left && e.Clicks == 1)
|
|
{
|
|
ControlState = ControlState.Pressed;
|
|
if (ShowSpliteButton)
|
|
{
|
|
CurrentMousePosition = ButtonRect.Contains(e.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton;
|
|
}
|
|
else
|
|
{
|
|
CurrentMousePosition = ButtonMousePosition.Button;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
{
|
|
base.OnMouseUp(e);
|
|
if (e.Button == MouseButtons.Left && e.Clicks == 1)
|
|
{
|
|
if (ClientRectangle.Contains(e.Location))
|
|
{
|
|
ControlState = ControlState.Hover;
|
|
if (ShowSpliteButton)
|
|
{
|
|
CurrentMousePosition = ButtonRect.Contains(e.Location) ? ButtonMousePosition.Button : ButtonMousePosition.Splitebutton;
|
|
if (CurrentMousePosition == ButtonMousePosition.Splitebutton)
|
|
{
|
|
OnSpliteButtonClick?.Invoke(this, EventArgs.Empty);
|
|
if (this.ContextMenuStrip != null)
|
|
{
|
|
if (!_contextHandle)
|
|
{
|
|
_contextHandle = true;
|
|
this.ContextMenuStrip.Opening += new CancelEventHandler(ContextMenuStrip_Opening);
|
|
this.ContextMenuStrip.Closed += new ToolStripDropDownClosedEventHandler(ContextMenuStrip_Closed);
|
|
}
|
|
this.ContextMenuStrip.Opacity = 1.0;
|
|
this.ContextMenuStrip.Show(this, 0, this.Height + ContextOffset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OnButtonClick?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CurrentMousePosition = ButtonMousePosition.Button;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ControlState = ControlState.Normal;
|
|
CurrentMousePosition = ButtonMousePosition.None;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ContextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
|
{
|
|
_contextOpened = false;
|
|
ControlState = ControlState.Normal;
|
|
CurrentMousePosition = ButtonMousePosition.None;
|
|
base.Invalidate();
|
|
}
|
|
|
|
|
|
private void ContextMenuStrip_Opening(object sender, CancelEventArgs e)
|
|
{
|
|
_contextOpened = true;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
base.OnPaintBackground(e);
|
|
|
|
Graphics g = e.Graphics;
|
|
//Rectangle imageRect;
|
|
//Rectangle textRect;
|
|
|
|
CalculateRect(out Rectangle imageRect, out Rectangle textRect, g);
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
|
|
//画边框与背景
|
|
RenderBackGroundInternal(
|
|
g,
|
|
ClientRectangle,
|
|
RoundStyle,
|
|
Radius
|
|
);
|
|
//画图像
|
|
if (Image != null)
|
|
{
|
|
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
|
|
g.DrawImage(
|
|
Image,
|
|
imageRect,
|
|
0,
|
|
0,
|
|
Image.Width,
|
|
Image.Height,
|
|
GraphicsUnit.Pixel);
|
|
}
|
|
//画文字
|
|
if (Text != "")
|
|
{
|
|
TextRenderer.DrawText(
|
|
g,
|
|
Text,
|
|
Font,
|
|
textRect,
|
|
ForeColor,
|
|
GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
|
|
}
|
|
//画分割按钮
|
|
if (ShowSpliteButton)
|
|
{
|
|
RenderSpliteButton(g, ClientRectangle);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取图像以及文字的位置
|
|
/// </summary>
|
|
/// <param name="imageRect"></param>
|
|
/// <param name="textRect"></param>
|
|
/// <param name="g"></param>
|
|
private void CalculateRect(
|
|
out Rectangle imageRect, out Rectangle textRect, Graphics g)
|
|
{
|
|
imageRect = Rectangle.Empty;
|
|
textRect = Rectangle.Empty;
|
|
SizeF textSize = g.MeasureString(Text, Font);
|
|
if (Image == null)
|
|
{
|
|
switch (TextAlign)
|
|
{
|
|
case ContentAlignment.BottomCenter:
|
|
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.BottomLeft:
|
|
textRect = new Rectangle(2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.BottomRight:
|
|
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.MiddleCenter:
|
|
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.MiddleLeft:
|
|
textRect = new Rectangle(2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.MiddleRight:
|
|
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.TopCenter:
|
|
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.TopLeft:
|
|
textRect = new Rectangle(2, 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
case ContentAlignment.TopRight:
|
|
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, 2, (int)textSize.Width, (int)textSize.Height);
|
|
break;
|
|
}
|
|
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
|
|
{
|
|
textRect.X += 1;
|
|
textRect.Y += 1;
|
|
}
|
|
if (RightToLeft == RightToLeft.Yes)
|
|
{
|
|
textRect.X = ButtonRect.Width - textRect.Right;
|
|
}
|
|
return;
|
|
}
|
|
if (this.Text == "")
|
|
{
|
|
switch (ImageAlign)
|
|
{
|
|
case ContentAlignment.BottomCenter:
|
|
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, Height - ImageHeight - 3, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.BottomLeft:
|
|
imageRect = new Rectangle(2, Height - ImageHeight - 3, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.BottomRight:
|
|
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, Height - ImageHeight - 3, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.MiddleCenter:
|
|
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.MiddleLeft:
|
|
imageRect = new Rectangle(2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.MiddleRight:
|
|
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.TopCenter:
|
|
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, 2, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.TopLeft:
|
|
imageRect = new Rectangle(2, 2, ImageWidth, ImageHeight);
|
|
break;
|
|
case ContentAlignment.TopRight:
|
|
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, 2, ImageWidth, ImageHeight);
|
|
break;
|
|
}
|
|
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
|
|
{
|
|
imageRect.X += 1;
|
|
imageRect.Y += 1;
|
|
}
|
|
if (RightToLeft == RightToLeft.Yes)
|
|
{
|
|
imageRect.X = ButtonRect.Width - imageRect.Right;
|
|
}
|
|
return;
|
|
}
|
|
switch (TextImageRelation)
|
|
{
|
|
case TextImageRelation.Overlay:
|
|
imageRect = new Rectangle(
|
|
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
|
|
(Height - ImageHeight) / 2,
|
|
ImageWidth,
|
|
ImageHeight);
|
|
textRect = new Rectangle(
|
|
imageRect.Right + ImageTextSpace,
|
|
(Height - (int)textSize.Height) / 2,
|
|
(int)textSize.Width,
|
|
(int)textSize.Height);
|
|
break;
|
|
case TextImageRelation.ImageAboveText:
|
|
imageRect = new Rectangle(
|
|
(ButtonRect.Width - ImageWidth) / 2,
|
|
(Height - ImageHeight - (int)textSize.Height - ImageTextSpace) / 2,
|
|
ImageWidth,
|
|
ImageHeight);
|
|
textRect = new Rectangle(
|
|
(ButtonRect.Width - (int)textSize.Width) / 2,
|
|
imageRect.Bottom + ImageTextSpace,
|
|
(int)textSize.Width,
|
|
(int)textSize.Height);
|
|
break;
|
|
case TextImageRelation.ImageBeforeText:
|
|
imageRect = new Rectangle(
|
|
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
|
|
(Height - ImageHeight) / 2,
|
|
ImageWidth,
|
|
ImageHeight);
|
|
textRect = new Rectangle(
|
|
imageRect.Right + ImageTextSpace,
|
|
(Height - (int)textSize.Height) / 2,
|
|
(int)textSize.Width,
|
|
(int)textSize.Height);
|
|
break;
|
|
case TextImageRelation.TextAboveImage:
|
|
textRect = new Rectangle(
|
|
(ButtonRect.Width - (int)textSize.Width) / 2,
|
|
(Height - (int)textSize.Height - ImageHeight - ImageTextSpace) / 2,
|
|
(int)textSize.Width,
|
|
(int)textSize.Height);
|
|
imageRect = new Rectangle(
|
|
(ButtonRect.Width - ImageWidth) / 2,
|
|
textRect.Bottom + ImageTextSpace,
|
|
ImageWidth,
|
|
ImageHeight);
|
|
break;
|
|
case TextImageRelation.TextBeforeImage:
|
|
textRect = new Rectangle(
|
|
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
|
|
(Height - (int)textSize.Height) / 2,
|
|
(int)textSize.Width,
|
|
(int)textSize.Height);
|
|
imageRect = new Rectangle(
|
|
textRect.Right + ImageTextSpace,
|
|
(Height - ImageHeight) / 2,
|
|
ImageWidth,
|
|
ImageHeight);
|
|
break;
|
|
}
|
|
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
|
|
{
|
|
imageRect.X += 1;
|
|
imageRect.Y += 1;
|
|
textRect.X += 1;
|
|
textRect.Y += 1;
|
|
}
|
|
|
|
if (RightToLeft == RightToLeft.Yes)
|
|
{
|
|
imageRect.X = ButtonRect.Width - imageRect.Right;
|
|
textRect.X = ButtonRect.Width - textRect.Right;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 画边框与背景
|
|
/// </summary>
|
|
internal void RenderBackGroundInternal(
|
|
Graphics g,
|
|
Rectangle rect,
|
|
RoundStyle style,
|
|
int roundWidth
|
|
)
|
|
{
|
|
if (ControlState != ControlState.Normal || AlwaysShowBorder)
|
|
{
|
|
rect.Width--;
|
|
rect.Height--;
|
|
if (style != RoundStyle.None)
|
|
{
|
|
using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
|
|
{
|
|
if (ControlState != ControlState.Normal)
|
|
{
|
|
using (LinearGradientBrush brush = (ControlState == ControlState.Pressed) ? new LinearGradientBrush(rect, BaseColorEnd, BaseColor, LinearGradientMode.ForwardDiagonal) : new LinearGradientBrush(rect, BaseColor, BaseColorEnd, LinearGradientMode.Vertical))
|
|
{
|
|
if (!ShowSpliteButton)
|
|
{
|
|
g.FillPath(brush, path);
|
|
}
|
|
else
|
|
{
|
|
if (CurrentMousePosition == ButtonMousePosition.Button)
|
|
{
|
|
using (GraphicsPath buttonpath = GraphicsPathHelper.CreatePath(ButtonRect, roundWidth, RoundStyle.Left, true))
|
|
{
|
|
g.FillPath(brush, buttonpath);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (GraphicsPath splitepath = GraphicsPathHelper.CreatePath(SpliteButtonRect, roundWidth, RoundStyle.Right, true))
|
|
{
|
|
g.FillPath(brush, splitepath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
using (Pen pen = new Pen(_borderColor))
|
|
{
|
|
g.DrawPath(pen, path);
|
|
}
|
|
}
|
|
rect.Inflate(-1, -1);
|
|
using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
|
|
{
|
|
using (Pen pen = new Pen(InnerBorderColor))
|
|
{
|
|
g.DrawPath(pen, path);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ControlState != ControlState.Normal)
|
|
{
|
|
using (LinearGradientBrush brush = (ControlState == ControlState.Pressed) ? new LinearGradientBrush(rect, BaseColorEnd, BaseColor, LinearGradientMode.ForwardDiagonal) : new LinearGradientBrush(rect, BaseColor, BaseColorEnd, LinearGradientMode.Vertical))
|
|
{
|
|
if (!ShowSpliteButton)
|
|
{
|
|
g.FillRectangle(brush, rect);
|
|
}
|
|
else
|
|
{
|
|
if (CurrentMousePosition == ButtonMousePosition.Button)
|
|
{
|
|
g.FillRectangle(brush, ButtonRect);
|
|
}
|
|
else
|
|
{
|
|
g.FillRectangle(brush, SpliteButtonRect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
using (Pen pen = new Pen(_borderColor))
|
|
{
|
|
g.DrawRectangle(pen, rect);
|
|
}
|
|
rect.Inflate(-1, -1);
|
|
using (Pen pen = new Pen(InnerBorderColor))
|
|
{
|
|
g.DrawRectangle(pen, rect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 画分割按钮
|
|
/// </summary>
|
|
/// <param name="g"></param>
|
|
/// <param name="rect"></param>
|
|
internal void RenderSpliteButton(Graphics g, Rectangle rect)
|
|
{
|
|
Point[] points = new Point[3];
|
|
points[0] = new Point(rect.Width - SpliteButtonWidth + 2, (rect.Height - 4) / 2);
|
|
points[1] = new Point(rect.Width - SpliteButtonWidth + 2 + 8, (rect.Height - 4) / 2);
|
|
points[2] = new Point(rect.Width - SpliteButtonWidth + 2 + 4, (rect.Height - 4) / 2 + 4);
|
|
|
|
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Splitebutton)
|
|
{
|
|
points[0].X += 1;
|
|
points[0].Y += 1;
|
|
points[1].X += 1;
|
|
points[1].Y += 1;
|
|
points[2].X += 1;
|
|
points[2].Y += 1;
|
|
}
|
|
using (SolidBrush brush = new SolidBrush(ArrowColor))
|
|
{
|
|
g.FillPolygon(brush, points);
|
|
}
|
|
}
|
|
|
|
internal static TextFormatFlags GetTextFormatFlags(
|
|
ContentAlignment alignment,
|
|
bool rightToleft)
|
|
{
|
|
TextFormatFlags flags = TextFormatFlags.WordBreak |
|
|
TextFormatFlags.SingleLine;
|
|
if (rightToleft)
|
|
{
|
|
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
|
|
}
|
|
|
|
switch (alignment)
|
|
{
|
|
case ContentAlignment.BottomCenter:
|
|
flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
|
|
break;
|
|
case ContentAlignment.BottomLeft:
|
|
flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
|
|
break;
|
|
case ContentAlignment.BottomRight:
|
|
flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
|
|
break;
|
|
case ContentAlignment.MiddleCenter:
|
|
flags |= TextFormatFlags.HorizontalCenter |
|
|
TextFormatFlags.VerticalCenter;
|
|
break;
|
|
case ContentAlignment.MiddleLeft:
|
|
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
|
|
break;
|
|
case ContentAlignment.MiddleRight:
|
|
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
|
|
break;
|
|
case ContentAlignment.TopCenter:
|
|
flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
|
|
break;
|
|
case ContentAlignment.TopLeft:
|
|
flags |= TextFormatFlags.Top | TextFormatFlags.Left;
|
|
break;
|
|
case ContentAlignment.TopRight:
|
|
flags |= TextFormatFlags.Top | TextFormatFlags.Right;
|
|
break;
|
|
}
|
|
return flags;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class GraphicsPathHelper
|
|
{
|
|
/// <summary>
|
|
/// 建立带有圆角样式的矩形路径
|
|
/// </summary>
|
|
/// <param name="rect">用来建立路径的矩形。</param>
|
|
/// <param name="radius">圆角的大小</param>
|
|
/// <param name="style">圆角的样式</param>
|
|
/// <param name="correction">是否把矩形长宽减 1,以便画出边框</param>
|
|
/// <returns>建立的路径</returns>
|
|
public static GraphicsPath CreatePath(
|
|
Rectangle rect, int radius, RoundStyle style, bool correction)
|
|
{
|
|
GraphicsPath path = new GraphicsPath();
|
|
int radiusCorrection = correction ? 1 : 0;
|
|
switch (style)
|
|
{
|
|
case RoundStyle.None:
|
|
path.AddRectangle(rect);
|
|
break;
|
|
case RoundStyle.All:
|
|
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Y,
|
|
radius,
|
|
radius,
|
|
270,
|
|
90);
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius, 0, 90);
|
|
path.AddArc(
|
|
rect.X,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
90,
|
|
90);
|
|
break;
|
|
case RoundStyle.Left:
|
|
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
|
|
path.AddLine(
|
|
rect.Right - radiusCorrection, rect.Y,
|
|
rect.Right - radiusCorrection, rect.Bottom - radiusCorrection);
|
|
path.AddArc(
|
|
rect.X,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
90,
|
|
90);
|
|
break;
|
|
case RoundStyle.Right:
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Y,
|
|
radius,
|
|
radius,
|
|
270,
|
|
90);
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
0,
|
|
90);
|
|
path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y);
|
|
break;
|
|
case RoundStyle.Top:
|
|
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Y,
|
|
radius,
|
|
radius,
|
|
270,
|
|
90);
|
|
path.AddLine(
|
|
rect.Right - radiusCorrection, rect.Bottom - radiusCorrection,
|
|
rect.X, rect.Bottom - radiusCorrection);
|
|
break;
|
|
case RoundStyle.Bottom:
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
0,
|
|
90);
|
|
path.AddArc(
|
|
rect.X,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
90,
|
|
90);
|
|
path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y);
|
|
break;
|
|
case RoundStyle.BottomLeft:
|
|
path.AddArc(
|
|
rect.X,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
90,
|
|
90);
|
|
path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y);
|
|
path.AddLine(
|
|
rect.Right - radiusCorrection,
|
|
rect.Y,
|
|
rect.Right - radiusCorrection,
|
|
rect.Bottom - radiusCorrection);
|
|
break;
|
|
case RoundStyle.BottomRight:
|
|
path.AddArc(
|
|
rect.Right - radius - radiusCorrection,
|
|
rect.Bottom - radius - radiusCorrection,
|
|
radius,
|
|
radius,
|
|
0,
|
|
90);
|
|
path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y);
|
|
path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y);
|
|
break;
|
|
}
|
|
path.CloseFigure();
|
|
|
|
return path;
|
|
}
|
|
} |