RaUI/Source/ryControls/Gdu.WinFormUI/WLControls/WLButton.cs
如果当时 34a3ef3ed9 ### 2021-02-22更新
------
#### ryControls    V2.1.2102.2201
*.[新增]新加入Gdu.WinformUI控件。
2021-02-22 21:42:59 +08:00

515 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 本代码受中华人民共和国著作权法保护,作者仅授权下载代码之人在学习和交流范围内
* 自由使用与修改代码;欲将代码用于商业用途的,请与作者联系。
* 使用本代码请保留此处信息。作者联系方式ping3108@163.com, 欢迎进行技术交流
*/
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using MGdu.WinFormUI.MyGraphics;
namespace MGdu.WinFormUI
{
//忽略没有注释警告
#pragma warning disable 1591
/// <summary>
///
/// </summary>
public class WLButton
{
#region private var
private Control _owner;
private GMButtonState _state;
private EventHandler _click;
private PaintEventHandler _paint;
private bool _capture;
private Rectangle _bounds;
#endregion
#region properties
/// <summary>
/// 是否在这个按钮上按下了鼠标未释放
/// </summary>
public bool Capture
{ get { return _capture; } }
public Size BtnSize
{
get { return Bounds.Size; }
}
public Point Location
{
get { return Bounds.Location; }
}
public ButtonForePathGetter ForePathGetter { get; set; }
public event EventHandler Click
{
add { _click = value; }
remove { _click = null; }
}
public event PaintEventHandler Paint
{
add { _paint = value; }
remove { _paint = null; }
}
public GMButtonState State
{
get { return _state; }
set
{
if (value != _state)
{
_state = value;
_owner.Invalidate(Bounds);
}
}
}
/// <summary>
/// 是否可见
/// </summary>
public bool Visible { get; set; }
/// <summary>
///
/// </summary>
public Rectangle Bounds
{
get { return _bounds; }
set
{
if (_bounds != value)
{
_bounds = value;
}
}
}
public Font ForeFont { get; set; }
public string Text { get; set; }
public Size ForePathSize { get; set; }
public ButtonColorTable ColorTable { get; set; }
public ButtonBorderType BorderType { get; set; }
public bool DrawLightGlass { get; set; }
/// <summary>
/// 画两次可以加深颜色
/// </summary>
public bool DrawForePathTwice { get; set; }
/// <summary>
/// 用于在click事件中传回数据
/// </summary>
public object ClickSendBackOject { get; set; }
public Image BackImageNormal { get; set; }
public Image BackImageHover { get; set; }
public Image BackImagePressed { get; set; }
public Image BackImageDisabled { get; set; }
public bool Enabled { get; set; }
public ForePathRatoteDirection RotateDirection { get; set; }
public ForePathRenderMode HowForePathRender { get; set; }
/// <summary>
/// 获取或设置是否将绘制完全限制在指定的区域内
/// </summary>
public bool RestrictedBounds { get; set; }
public int Radius { get; set; }
public RoundStyle RoundedType { get; set; }
#endregion
#region private render method
private void RenderNormal(Graphics g)
{
RenderInternal(g, BackImageNormal, ColorTable.BorderColorNormal,
ColorTable.BackColorNormal, ColorTable.ForeColorNormal);
}
private void RenderHover(Graphics g)
{
RenderInternal(g, BackImageHover, ColorTable.BorderColorHover,
ColorTable.BackColorHover, ColorTable.ForeColorHover);
}
private void RenderPressed(Graphics g)
{
RenderInternal(g, BackImagePressed, ColorTable.BorderColorPressed,
ColorTable.BackColorPressed, ColorTable.ForeColorPressed);
}
private void RenderDisabled(Graphics g)
{
RenderInternal(g, BackImageDisabled, ColorTable.BorderColorDisabled,
ColorTable.BackColorDisabled, ColorTable.ForeColorDisabled);
}
private void RenderInternal(Graphics g, Image backImage, Color borderColor,
Color backColor, Color foreColor)
{
Region oldClip = g.Clip;
Region newClip = null;
if (RestrictedBounds)
{
newClip = new Region(Bounds);
g.Clip = newClip;
}
if (backImage != null)
{
g.DrawImage(backImage, Bounds);
}
else
{
FillInBackground(g, backColor);
RenderForePathAndText(g, foreColor);
DrawBorder(g, borderColor);
}
if (RestrictedBounds)
{
g.Clip = oldClip;
newClip.Dispose();
}
}
private void FillInBackground(Graphics g, Color backColor)
{
BasicBlockPainter.RenderFlatBackground(
g,
Bounds,
backColor,
BorderType,
Radius,
RoundedType);
if (BorderType == ButtonBorderType.Ellipse && DrawLightGlass)
{
using (GraphicsPath gp = new GraphicsPath())
{
Rectangle rect = Bounds;
rect.Height--;
rect.Width--;
gp.AddEllipse(rect);
using (PathGradientBrush pb = new PathGradientBrush(gp))
{
pb.CenterPoint = new PointF(rect.X + rect.Width / 2.0f, rect.Y + rect.Height / 4.0f);
pb.CenterColor = Color.FromArgb(180, Color.White);
pb.SurroundColors = new Color[] { Color.FromArgb(40, Color.White) };
g.FillPath(pb, gp);
}
}
}
}
private void DrawBorder(Graphics g, Color borderColor)
{
BasicBlockPainter.RenderBorder(
g,
Bounds,
borderColor,
BorderType,
Radius,
RoundedType);
}
private void RenderForePathAndText(Graphics g, Color foreColor)
{
if (ForePathGetter != null)
{
if(string.IsNullOrEmpty(Text))
PathOnly(g,foreColor);
else
PathAndText(g,foreColor);
}
else if(!string.IsNullOrEmpty(Text))
TextOnly(g,foreColor);
}
private void PathOnly(Graphics g, Color foreColor)
{
using (GraphicsPath path = ForePathGetter(Bounds))
{
PathWithRotate(g, path, foreColor, Bounds);
if (DrawForePathTwice)
PathWithRotate(g, path, foreColor, Bounds);
}
}
private void TextOnly(Graphics g, Color foreColor)
{
Size size = TextRenderer.MeasureText(Text, ForeFont);
int x = Bounds.Left + (Bounds.Width - size.Width) / 2;
int y = Bounds.Top + (Bounds.Height - size.Height) / 2;
Rectangle textRect = new Rectangle(new Point(x, y), size);
TextRenderer.DrawText(
g,
Text,
ForeFont,
textRect,
foreColor,
TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter);
}
private void PathAndText(Graphics g, Color foreColor)
{
Size size = TextRenderer.MeasureText(Text, ForeFont);
Rectangle rect = Bounds;
rect.Offset(-size.Width / 2 + 2, 0);
using (GraphicsPath path = ForePathGetter(rect))
{
PathWithRotate(g, path, foreColor, rect);
int x = rect.Left + rect.Width / 2 + ForePathSize.Width / 2 + 1;
int y = rect.Top + (rect.Height - size.Height) / 2;
Rectangle textRect = new Rectangle(new Point(x, y), size);
TextRenderer.DrawText(
g,
Text,
ForeFont,
textRect,
foreColor,
TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter);
}
}
private void PathWithRotate(Graphics g, GraphicsPath path, Color foreColor, Rectangle pathRect)
{
Pen p = new Pen(foreColor);
SolidBrush sb = new SolidBrush(foreColor);
if (RotateDirection == ForePathRatoteDirection.Down)
{
if (HowForePathRender == ForePathRenderMode.Draw)
g.DrawPath(p, path);
else
g.FillPath(sb, path);
}
else
{
int dx = 0, dy = 0, angle = 0;
switch (RotateDirection)
{
case ForePathRatoteDirection.Left:
dx = ForePathSize.Width - 1;
dy = 0;
angle = 90;
break;
case ForePathRatoteDirection.Up:
dx = ForePathSize.Width - 1;
dy = ForePathSize.Height - 1;
angle = 180;
break;
case ForePathRatoteDirection.Right:
dx = 0;
dy = ForePathSize.Height - 1;
angle = 270;
break;
}
int pathX = pathRect.Left + (pathRect.Width - ForePathSize.Width) / 2;
int pathY = pathRect.Top + (pathRect.Height - ForePathSize.Height) / 2;
g.TranslateTransform(pathX, pathY);
g.TranslateTransform(dx, dy);
g.RotateTransform(angle);
using (GraphicsPath newPath = ForePathGetter(new Rectangle(Point.Empty, ForePathSize)))
{
if (HowForePathRender == ForePathRenderMode.Draw)
g.DrawPath(p, newPath);
else
g.FillPath(sb, newPath);
}
g.ResetTransform();
}
p.Dispose();
sb.Dispose();
}
#region mouse operation
private void MouseDown(Point location)
{
if (Bounds.Contains(location))
{
State = GMButtonState.Pressed;
_capture = true;
}
else
{
_capture = false;
}
}
private void MouseMove(Point location)
{
if (Bounds.Contains(location))
{
if (State == GMButtonState.Normal)
{
// 没有在窗体其他地方按下按钮
if (!_owner.Capture)
{
State = GMButtonState.Hover;
}
}
else if (State == GMButtonState.PressLeave)
{
State = GMButtonState.Pressed;
}
}
else
{
if (_capture)
{
State = GMButtonState.PressLeave;
}
else
{
State = GMButtonState.Normal;
}
}
}
private void MouseLeave(Point location)
{
State = GMButtonState.Normal;
_capture = false;
}
private void MouseUp(Point location)
{
if (Bounds.Contains(location))
{
State = GMButtonState.Hover;
if (_capture)
OnClick(EventArgs.Empty);
}
else
{
State = GMButtonState.Normal;
}
_capture = false;
}
#endregion
#endregion
#region event
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected virtual void OnClick(EventArgs e)
{
if (_click != null)
{
object obj = (ClickSendBackOject != null) ? ClickSendBackOject : this;
_click(obj, e);
}
}
protected virtual void OnPaint(PaintEventArgs e)
{
if (_paint != null)
{
_paint(this, e);
}
}
#endregion
#region public method
/// <summary>
///
/// </summary>
/// <param name="owner"></param>
public WLButton(Control owner)
{
_owner = owner;
_state = GMButtonState.Normal;
Visible = true;
Enabled = true;
BorderType = ButtonBorderType.Rectangle;
DrawLightGlass = false;
RotateDirection = ForePathRatoteDirection.Down;
HowForePathRender = ForePathRenderMode.Draw;
RestrictedBounds = true;
Radius = 0;
RoundedType = RoundStyle.None;
}
public void DrawButton(Graphics g)
{
if (!Visible)
return;
if (Enabled)
{
switch (State)
{
case GMButtonState.Hover:
RenderHover(g);
break;
case GMButtonState.Pressed:
RenderPressed(g);
break;
default:
RenderNormal(g);
break;
}
}
else
{
RenderDisabled(g);
}
OnPaint(new PaintEventArgs(g, Bounds));
}
public void MouseOperation(Point location, MouseOperationType type)
{
if (!Visible)
return;
switch (type)
{
case MouseOperationType.Move:
MouseMove(location);
break;
case MouseOperationType.Down:
MouseDown(location);
break;
case MouseOperationType.Up:
MouseUp(location);
break;
case MouseOperationType.Leave:
MouseLeave(location);
break;
default:
break;
}
}
#endregion
}
}