From ed8da00f676976e5a583e25996fe797f68bf4d27 Mon Sep 17 00:00:00 2001 From: yibo <361071264@qq.com> Date: Sat, 9 Jun 2018 08:07:37 +0800 Subject: [PATCH] Add NButton --- WinFormControl/NButton.cs | 350 +++++++++++++++++++++++++++ WinFormControl/WinFormControl.csproj | 3 + 2 files changed, 353 insertions(+) create mode 100644 WinFormControl/NButton.cs diff --git a/WinFormControl/NButton.cs b/WinFormControl/NButton.cs new file mode 100644 index 0000000..dab4825 --- /dev/null +++ b/WinFormControl/NButton.cs @@ -0,0 +1,350 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WinFormControl +{ + public class NButton : Button + { + private bool pulseOnFocus; + + private ImageAttributes imgAttr = new ImageAttributes(); + private float gamma; + private float minGamma; + private float maxGamma; + private float gammaStep; + private Timer pulseTimer = new Timer(); + private Bitmap buttonBitmap; + private Rectangle buttonBitmapRectangle; + + [DefaultValue(false)] + public bool WithStataHode { get; set; } + + [DefaultValue(false)] + public bool SingleSelect { get; set; } + + bool mAsClicked = false; + + bool mDefaultSelected = false; + [DefaultValue(false)] + public bool DefaultSelected + { + get { return mDefaultSelected; } + set + { + if (mDefaultSelected == value) + return; + mDefaultSelected = value; + if (mDefaultSelected) + { + mAsClicked = true; + if (!WithStataHode) + WithStataHode = true; + } + if (mDefaultSelected) + mouseAction = MouseActionType.Hover; + else + mouseAction = MouseActionType.None; + Invalidate(); + } + } + + bool mEnableShadow = false; + [DefaultValue(false)] + public bool EnableShadow { get { return mEnableShadow; } set { mEnableShadow = value; Invalidate(); } } + + bool mEnableCrystal = false; + [DefaultValue(false)] + public bool EnableCrystal { get { return mEnableCrystal; } set { mEnableCrystal = value; Invalidate(); } } + + Color mToColoe = ColorTranslator.FromHtml("#3388FF"); + public Color ToColor { get { return mToColoe; } set { mToColoe = value; Invalidate(); } } + + + Color mClickColor = Color.YellowGreen; + public Color ClickColor { get { return mClickColor; } set { mClickColor = value; } } + + [Category("Sound"), Description("是否播放声音")] + public bool PlaySound { get; set; } + + [Category("Sound"), Description("声音类型")] + public SoundType SoundType { get; set; } + + public NButton() + { + mouseAction = MouseActionType.None; + + this.SetStyle(ControlStyles.AllPaintingInWmPaint | + ControlStyles.DoubleBuffer | + ControlStyles.UserPaint, true); + + this.ForeColor = Color.White; + this.BackColor = ColorTranslator.FromHtml("#3388FF"); + + gamma = 1.0f; + minGamma = 1.0f; + maxGamma = 2.2f; + gammaStep = 0.2f; + pulseTimer.Interval = 120; + pulseTimer.Tick += new EventHandler(pulseTimer_Tick); + } + + [DefaultValue(false)] + public bool PulseOnFocus + { + get { return pulseOnFocus; } + set { pulseOnFocus = value; Invalidate(); } + } + + private enum MouseActionType + { + None, + Hover, + Click + } + + private MouseActionType mouseAction; + + protected override void OnPaint(PaintEventArgs e) + { + Graphics g = e.Graphics; + g.Clear(this.Parent.BackColor); + Color clr = BackColor; + Color ed = ToColor; + int shadowOffset = 8; + int btnOffset = 0; + if (!Enabled) + { + clr = Color.DarkGray; + ed = clr; + } + + switch (mouseAction) + { + case MouseActionType.Click: + shadowOffset = 4; + clr = ClickColor; + ed = clr; + btnOffset = 2; + break; + case MouseActionType.Hover: + clr = ClickColor; + ed = clr; + break; + } + + g.SmoothingMode = SmoothingMode.AntiAlias; + + /// + /// Create main colored shape + /// + + var shadowDeep = EnableShadow ? 8 : 0; + + Rectangle rc = new Rectangle(btnOffset, btnOffset, this.ClientSize.Width - shadowDeep - btnOffset, this.ClientSize.Height - shadowDeep - btnOffset); + GraphicsPath path1 = this.GetPath(rc, 15); + LinearGradientBrush br1 = new LinearGradientBrush(rc, clr, ed, LinearGradientMode.BackwardDiagonal); + /// + /// Create shadow + /// + if (EnableShadow) + { + Rectangle rc2 = rc; + rc2.Offset(shadowOffset, shadowOffset); + GraphicsPath path2 = this.GetPath(rc2, 15); + PathGradientBrush br2 = new PathGradientBrush(path2); + br2.CenterColor = ControlPaint.DarkDark(Color.Silver); + br2.SurroundColors = new Color[] { Color.White }; + g.FillPath(br2, path2); //draw shadow + /// + } + + g.FillPath(br1, path1); //draw main + /// + /// Create top water color to give "aqua " effect + /// + GraphicsPath path3 = null; + LinearGradientBrush br3 = null; + if (EnableCrystal) + { + Rectangle rc3 = rc; + rc3.Inflate(-5, -5); + rc3.Height = 15; + path3 = GetPath(rc3, 15); + br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical); + + /// + ///draw shapes + /// + g.FillPath(br3, path3); //draw top bubble + } + + /// + ///Create a backup of the button image to a bitmap so we can manipulate it 's pulsing action + /// + Graphics g_bmp = null; + if (PulseOnFocus) + { + buttonBitmapRectangle = new Rectangle(rc.Location, rc.Size); + buttonBitmap = new Bitmap(buttonBitmapRectangle.Width, buttonBitmapRectangle.Height); + g_bmp = Graphics.FromImage(buttonBitmap); + g_bmp.SmoothingMode = SmoothingMode.AntiAlias; + g_bmp.FillPath(br1, path1); + if (EnableCrystal) + g_bmp.FillPath(br3, path3); + } + + + + /// + /// Create a Path to draw the text to give the button a nice outline + /// + + var textBrush = new LinearGradientBrush(this.ClientRectangle, this.ForeColor, this.ForeColor, LinearGradientMode.Vertical); + + StringFormat drawFormat = new StringFormat(); + drawFormat.LineAlignment = StringAlignment.Center; + drawFormat.Alignment = System.Drawing.StringAlignment.Center; + + g.DrawString(this.Text, this.Font, textBrush, rc, drawFormat); + if (PulseOnFocus) + g_bmp.DrawString(this.Text, this.Font, textBrush, rc, drawFormat); + } + + private GraphicsPath GetPath(Rectangle rc, int r) + { + int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height; + GraphicsPath path = new GraphicsPath(); + path.AddArc(x, y, r, r, 180, 90); //Upper left corner + path.AddArc(x + w - r, y, r, r, 270, 90); //Upper right corner + path.AddArc(x + w - r, y + h - r, r, r, 0, 90); //Lower right corner + path.AddArc(x, y + h - r, r, r, 90, 90); //Lower left corner + path.CloseFigure(); + return path; + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + this.mouseAction = MouseActionType.Click; + this.Invalidate(); + } + base.OnMouseDown(e); + } + + //protected override void OnMouseUp(MouseEventArgs e) + //{ + // if (this.Bounds.Contains(new Point(e.X + Bounds.X, e.Y + Bounds.Y))) + // { + // //MessageBox.Show(string.Format("x:{0} y:{1}", e.X, e.Y)); + // this.mouseAction = MouseActionType.Hover; + // } + // else + // this.mouseAction = MouseActionType.None; + // this.Invalidate(); + // base.OnMouseUp(e); + //} + + protected override void OnClick(EventArgs e) + { + this.Enabled = false; + if (PlaySound) + SoundPalyUtil.PlaySound(SoundType); + try + { + base.OnClick(e); + } + catch { + Application.DoEvents(); + this.Enabled = true; + mouseAction = MouseActionType.Hover; + this.Invalidate(); + this.Focus(); + throw; + } + + + if (SingleSelect) + { + foreach (var ctl in Parent.Controls) + { + var btn = ctl as NButton; + if (btn == null) + continue; + if (btn.Text == this.Text) + { + if (WithStataHode) + continue; + else + mAsClicked = !mAsClicked; + } + if (btn.mAsClicked) + { + btn.mAsClicked = false; + btn.mouseAction = MouseActionType.None; + btn.Invalidate(); + } + } + } + + if (WithStataHode) + this.mAsClicked = !mAsClicked; + if (mAsClicked) + this.mouseAction = MouseActionType.Hover; + else + this.mouseAction = MouseActionType.None; + Application.DoEvents(); + this.Enabled = true; + // this.Invalidate(); + this.Focus(); + } + + protected override void OnMouseLeave(EventArgs e) + { + if (!mAsClicked) + { + this.mouseAction = MouseActionType.None; + this.Invalidate(); + } + base.OnMouseLeave(e); + } + + protected override void OnGotFocus(EventArgs e) + { + base.OnGotFocus(e); + if (this.pulseOnFocus) + pulseTimer.Start(); + } + + protected override void OnLostFocus(EventArgs e) + { + base.OnLostFocus(e); + pulseTimer.Stop(); + this.Invalidate(); + } + + private void pulseTimer_Tick(object sender, EventArgs e) + { + if (this.Focused && pulseOnFocus && buttonBitmap != null) + { + gamma += gammaStep; + if (gamma > this.maxGamma) + gammaStep = -gammaStep; + if (gamma < this.minGamma) + gammaStep = Math.Abs(gammaStep); + + imgAttr.SetGamma(gamma); + this.CreateGraphics().DrawImage(buttonBitmap, buttonBitmapRectangle, 0, 0, + buttonBitmap.Width, buttonBitmap.Height, GraphicsUnit.Pixel, imgAttr); + } + } + } +} diff --git a/WinFormControl/WinFormControl.csproj b/WinFormControl/WinFormControl.csproj index 20b07d5..2a9c169 100644 --- a/WinFormControl/WinFormControl.csproj +++ b/WinFormControl/WinFormControl.csproj @@ -45,6 +45,9 @@ + + Component + UserControl