diff --git a/Bin/net40/SunnyUI.Demo.exe b/Bin/net40/SunnyUI.Demo.exe index a988296c..6252d186 100644 Binary files a/Bin/net40/SunnyUI.Demo.exe and b/Bin/net40/SunnyUI.Demo.exe differ diff --git a/Bin/net40/SunnyUI.dll b/Bin/net40/SunnyUI.dll index ecabb8c5..151a827f 100644 Binary files a/Bin/net40/SunnyUI.dll and b/Bin/net40/SunnyUI.dll differ diff --git a/Bin/net45/SunnyUI.dll b/Bin/net45/SunnyUI.dll index 17af4a50..42b3e49d 100644 Binary files a/Bin/net45/SunnyUI.dll and b/Bin/net45/SunnyUI.dll differ diff --git a/Bin/net5.0-windows/SunnyUI.dll b/Bin/net5.0-windows/SunnyUI.dll index bc83f492..9bed1c0e 100644 Binary files a/Bin/net5.0-windows/SunnyUI.dll and b/Bin/net5.0-windows/SunnyUI.dll differ diff --git a/Bin/net5.0-windows/ref/SunnyUI.dll b/Bin/net5.0-windows/ref/SunnyUI.dll index a6e67312..94d24f5c 100644 Binary files a/Bin/net5.0-windows/ref/SunnyUI.dll and b/Bin/net5.0-windows/ref/SunnyUI.dll differ diff --git a/Bin/netcoreapp3.1/SunnyUI.dll b/Bin/netcoreapp3.1/SunnyUI.dll index 2d9c1af3..6f1005e6 100644 Binary files a/Bin/netcoreapp3.1/SunnyUI.dll and b/Bin/netcoreapp3.1/SunnyUI.dll differ diff --git a/SunnyUI.Demo/Controls/FPipe.cs b/SunnyUI.Demo/Controls/FPipe.cs index 0ed7b434..187f491a 100644 --- a/SunnyUI.Demo/Controls/FPipe.cs +++ b/SunnyUI.Demo/Controls/FPipe.cs @@ -38,5 +38,10 @@ namespace Sunny.UI.Demo pipe.Invalidate(); } } + + private void uiValve1_ActiveChanged(object sender, System.EventArgs e) + { + uiPipe8.Active = uiPipe9.Active = uiPipe7.Active = uiPipe10.Active = uiPipe12.Active = uiValve1.Active; + } } } diff --git a/SunnyUI.Demo/Controls/FPipe.designer.cs b/SunnyUI.Demo/Controls/FPipe.designer.cs index 1fc77574..19a2fd38 100644 --- a/SunnyUI.Demo/Controls/FPipe.designer.cs +++ b/SunnyUI.Demo/Controls/FPipe.designer.cs @@ -49,6 +49,8 @@ namespace Sunny.UI.Demo this.uiPipe16 = new Sunny.UI.UIPipe(); this.uiPipe17 = new Sunny.UI.UIPipe(); this.uiPipe18 = new Sunny.UI.UIPipe(); + this.uiValve1 = new Sunny.UI.UIValve(); + this.uiPipe19 = new Sunny.UI.UIPipe(); this.SuspendLayout(); // // timer1 @@ -86,9 +88,9 @@ namespace Sunny.UI.Demo this.uiPipe4.Location = new System.Drawing.Point(34, 63); this.uiPipe4.MinimumSize = new System.Drawing.Size(1, 1); this.uiPipe4.Name = "uiPipe4"; - this.uiPipe4.Radius = 15; + this.uiPipe4.Radius = 16; this.uiPipe4.RadiusSides = Sunny.UI.UICornerRadiusSides.None; - this.uiPipe4.Size = new System.Drawing.Size(15, 365); + this.uiPipe4.Size = new System.Drawing.Size(16, 365); this.uiPipe4.Style = Sunny.UI.UIStyle.Custom; this.uiPipe4.StyleCustomMode = true; this.uiPipe4.TabIndex = 8; @@ -139,12 +141,12 @@ namespace Sunny.UI.Demo this.uiPipe8.FlowColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(128))))); this.uiPipe8.FlowSpeed = 10; this.uiPipe8.Font = new System.Drawing.Font("微软雅黑", 12F); - this.uiPipe8.Location = new System.Drawing.Point(289, 63); + this.uiPipe8.Location = new System.Drawing.Point(289, 175); this.uiPipe8.MinimumSize = new System.Drawing.Size(1, 1); this.uiPipe8.Name = "uiPipe8"; - this.uiPipe8.Radius = 15; + this.uiPipe8.Radius = 16; this.uiPipe8.RadiusSides = Sunny.UI.UICornerRadiusSides.None; - this.uiPipe8.Size = new System.Drawing.Size(15, 365); + this.uiPipe8.Size = new System.Drawing.Size(16, 253); this.uiPipe8.Style = Sunny.UI.UIStyle.Custom; this.uiPipe8.StyleCustomMode = true; this.uiPipe8.TabIndex = 13; @@ -276,10 +278,10 @@ namespace Sunny.UI.Demo this.uiPipe6.Location = new System.Drawing.Point(64, 391); this.uiPipe6.MinimumSize = new System.Drawing.Size(1, 1); this.uiPipe6.Name = "uiPipe6"; - this.uiPipe6.Radius = 15; + this.uiPipe6.Radius = 16; this.uiPipe6.RadiusSides = Sunny.UI.UICornerRadiusSides.LeftBottom; this.uiPipe6.RectColor = System.Drawing.Color.DarkGray; - this.uiPipe6.Size = new System.Drawing.Size(15, 156); + this.uiPipe6.Size = new System.Drawing.Size(16, 156); this.uiPipe6.Style = Sunny.UI.UIStyle.Custom; this.uiPipe6.StyleCustomMode = true; this.uiPipe6.TabIndex = 20; @@ -341,10 +343,10 @@ namespace Sunny.UI.Demo this.uiPipe15.Location = new System.Drawing.Point(375, 391); this.uiPipe15.MinimumSize = new System.Drawing.Size(1, 1); this.uiPipe15.Name = "uiPipe15"; - this.uiPipe15.Radius = 15; + this.uiPipe15.Radius = 16; this.uiPipe15.RadiusSides = Sunny.UI.UICornerRadiusSides.RightBottom; this.uiPipe15.RectColor = System.Drawing.Color.DarkGray; - this.uiPipe15.Size = new System.Drawing.Size(15, 156); + this.uiPipe15.Size = new System.Drawing.Size(16, 156); this.uiPipe15.Style = Sunny.UI.UIStyle.Custom; this.uiPipe15.StyleCustomMode = true; this.uiPipe15.TabIndex = 23; @@ -364,10 +366,10 @@ namespace Sunny.UI.Demo this.uiPipe16.Location = new System.Drawing.Point(538, 391); this.uiPipe16.MinimumSize = new System.Drawing.Size(1, 1); this.uiPipe16.Name = "uiPipe16"; - this.uiPipe16.Radius = 15; + this.uiPipe16.Radius = 16; this.uiPipe16.RadiusSides = Sunny.UI.UICornerRadiusSides.LeftBottom; this.uiPipe16.RectColor = System.Drawing.Color.DarkGray; - this.uiPipe16.Size = new System.Drawing.Size(15, 83); + this.uiPipe16.Size = new System.Drawing.Size(16, 83); this.uiPipe16.Style = Sunny.UI.UIStyle.Custom; this.uiPipe16.StyleCustomMode = true; this.uiPipe16.TabIndex = 24; @@ -418,12 +420,47 @@ namespace Sunny.UI.Demo this.uiPipe18.TabIndex = 26; this.uiPipe18.Text = "uiPipe18"; // + // uiValve1 + // + this.uiValve1.Active = true; + this.uiValve1.Direction = Sunny.UI.UIValve.UIValveDirection.Left; + this.uiValve1.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiValve1.Location = new System.Drawing.Point(255, 122); + this.uiValve1.MinimumSize = new System.Drawing.Size(1, 1); + this.uiValve1.Name = "uiValve1"; + this.uiValve1.PipeSize = 20; + this.uiValve1.Size = new System.Drawing.Size(60, 60); + this.uiValve1.TabIndex = 27; + this.uiValve1.Text = "uiValve1"; + this.uiValve1.ActiveChanged += new System.EventHandler(this.uiValve1_ActiveChanged); + // + // uiPipe19 + // + this.uiPipe19.Active = true; + this.uiPipe19.BackColor = System.Drawing.Color.Transparent; + this.uiPipe19.Direction = Sunny.UI.UILine.LineDirection.Vertical; + this.uiPipe19.FlowColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(128))))); + this.uiPipe19.FlowSpeed = 10; + this.uiPipe19.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiPipe19.Location = new System.Drawing.Point(289, 63); + this.uiPipe19.MinimumSize = new System.Drawing.Size(1, 1); + this.uiPipe19.Name = "uiPipe19"; + this.uiPipe19.Radius = 16; + this.uiPipe19.RadiusSides = Sunny.UI.UICornerRadiusSides.None; + this.uiPipe19.Size = new System.Drawing.Size(16, 74); + this.uiPipe19.Style = Sunny.UI.UIStyle.Custom; + this.uiPipe19.StyleCustomMode = true; + this.uiPipe19.TabIndex = 28; + this.uiPipe19.Text = "uiPipe19"; + // // FPipe // this.AllowShowTitle = true; this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(855, 642); + this.Controls.Add(this.uiValve1); + this.Controls.Add(this.uiPipe19); this.Controls.Add(this.uiPipe18); this.Controls.Add(this.uiPipe16); this.Controls.Add(this.uiPipe15); @@ -471,6 +508,8 @@ namespace Sunny.UI.Demo private UIPipe uiPipe16; private UIPipe uiPipe17; private UIPipe uiPipe18; + private UIValve uiValve1; + private UIPipe uiPipe19; } } diff --git a/SunnyUI/Controls/UIValve.cs b/SunnyUI/Controls/UIValve.cs new file mode 100644 index 00000000..2103e095 --- /dev/null +++ b/SunnyUI/Controls/UIValve.cs @@ -0,0 +1,204 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace Sunny.UI +{ + [ToolboxItem(true)] + [DefaultProperty("Active")] + [DefaultEvent("ActiveChanged")] + public class UIValve : Control + { + public UIValve() + { + SetStyleFlags(); + Width = Height = 60; + rectColor = Color.Silver; + fillColor = Color.White; + valveColor = UIColor.Blue; + } + + protected override void OnClick(EventArgs e) + { + base.OnClick(e); + Active = !Active; + } + + private bool active; + + [DefaultValue(false), Description("是否滚动"), Category("SunnyUI")] + public bool Active + { + get => active; + set + { + if (active != value) + { + active = value; + ActiveChanged?.Invoke(this, EventArgs.Empty); + } + } + } + + public event EventHandler ActiveChanged; + + private void SetStyleFlags(bool supportTransparent = true, bool selectable = true, bool resizeRedraw = false) + { + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.DoubleBuffer, true); + SetStyle(ControlStyles.UserPaint, true); + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + if (supportTransparent) SetStyle(ControlStyles.SupportsTransparentBackColor, true); + if (selectable) SetStyle(ControlStyles.Selectable, true); + if (resizeRedraw) SetStyle(ControlStyles.ResizeRedraw, true); + base.DoubleBuffered = true; + UpdateStyles(); + } + + public enum UIValveDirection + { + Left, + Top, + Right, + Bottom + } + + private UIValveDirection direction = UIValveDirection.Left; + public UIValveDirection Direction + { + get => direction; + set + { + direction = value; + Invalidate(); + } + } + + private Color rectColor; + private Color fillColor; + private Color valveColor; + + /// + /// 阀门颜色 + /// + [Description("阀门颜色"), Category("SunnyUI")] + [DefaultValue(typeof(Color), "80, 160, 255")] + public Color ValveColor + { + get => valveColor; + set => valveColor = value; + } + + /// + /// 边框颜色 + /// + [Description("边框颜色"), Category("SunnyUI")] + [DefaultValue(typeof(Color), "Silver")] + public Color RectColor + { + get => rectColor; + set => rectColor = value; + } + + /// + /// 填充颜色,当值为背景色或透明色或空值则不填充 + /// + [Description("填充颜色"), Category("SunnyUI")] + [DefaultValue(typeof(Color), "White")] + public Color FillColor + { + get => fillColor; + set => fillColor = value; + } + + [Description("管道尺寸"), Category("SunnyUI")] + [DefaultValue(typeof(Color), "White")] + public int PipeSize + { + get => pipeSize; + set => pipeSize = value; + } + + int pipeSize = 24; + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + switch (direction) + { + case UIValveDirection.Left: + int w = pipeSize / 2; + using (Bitmap bmp = new Bitmap(Width, Height)) + using (Graphics g1 = bmp.Graphics()) + using (LinearGradientBrush lgb = new LinearGradientBrush(new Point(0, 0), + new Point(w, 0), + rectColor, + fillColor)) + { + g1.SetHighQuality(); + g1.FillRectangle(lgb, new Rectangle(0, 0, w, Height * 2)); + g1.SetDefaultQuality(); + e.Graphics.DrawImage(bmp, new Rectangle(Width - w * 2 - 8, -5, w, Height + 50), new Rectangle(0, 5, w, Height + 20), GraphicsUnit.Pixel); + } + + using (Bitmap bmp = new Bitmap(Width, Height)) + using (Graphics g1 = bmp.Graphics()) + using (LinearGradientBrush lgb = new LinearGradientBrush(new Point(0, 0), + new Point(w, 0), + fillColor, + rectColor)) + { + g1.SetHighQuality(); + g1.FillRectangle(lgb, new Rectangle(0, 0, w, Height * 2)); + g1.SetDefaultQuality(); + + e.Graphics.DrawImage(bmp, new Rectangle(Width - w - 8, -5, w, Height + 50), new Rectangle(0, 5, w, Height + 20), GraphicsUnit.Pixel); + } + + e.Graphics.DrawRectangle(RectColor, new Rectangle(Width - pipeSize - 8, 0, pipeSize - 1, Height - 1)); + + Rectangle rect = new Rectangle(Width - pipeSize - 8 - 2, 4, pipeSize + 4, 6); + e.Graphics.FillRectangle(rectColor, rect); + + rect = new Rectangle(Width - pipeSize - 8 - 2, Height - 4 - 6, pipeSize + 4, 6); + e.Graphics.FillRectangle(rectColor, rect); + + rect = new Rectangle(Width - pipeSize - 8 - 14, Height / 2 - 2, 14, 4); + e.Graphics.FillRectangle(rectColor, rect); + + rect = new Rectangle(Width - pipeSize - 8 - 14 - 10, Height / 2 - 14, 10, 27); + e.Graphics.FillRectangle(valveColor, rect); + + Color[] colors = GDIEx.GradientColors(Color.White, valveColor, 14); + rect = new Rectangle(Width - pipeSize - 8 - 14 - 10, Height / 2 - 14 + 4, 10, 4); + e.Graphics.FillRectangle(colors[4], rect); + rect = new Rectangle(Width - pipeSize - 8 - 14 - 10, Height / 2 - 14 + 12, 10, 4); + e.Graphics.FillRectangle(colors[4], rect); + rect = new Rectangle(Width - pipeSize - 8 - 14 - 10, Height / 2 - 14 + 20, 10, 4); + e.Graphics.FillRectangle(colors[4], rect); + + rect = new Rectangle(Width - pipeSize - 8 - 14 - 10, Height / 2 - 14, 10, 27); + e.Graphics.DrawRectangle(valveColor, rect); + + Point pt1 = new Point(Width - pipeSize - 8 - 7, Height / 2 - 5); + Point pt2 = new Point(Width - pipeSize - 8 + 2, Height / 2 - 5 - 5); + Point pt3 = new Point(Width - pipeSize - 8 + 2, Height / 2 + 4 + 5); + Point pt4 = new Point(Width - pipeSize - 8 - 7, Height / 2 + 4); + e.Graphics.FillPolygon(rectColor, new PointF[] { pt1, pt2, pt3, pt4, pt1 }); + + break; + case UIValveDirection.Top: + break; + case UIValveDirection.Right: + break; + case UIValveDirection.Bottom: + break; + default: + break; + } + } + } +} diff --git a/SunnyUI/Static/UGDI.cs b/SunnyUI/Static/UGDI.cs index e389616d..52c20c8e 100644 --- a/SunnyUI/Static/UGDI.cs +++ b/SunnyUI/Static/UGDI.cs @@ -453,6 +453,26 @@ namespace Sunny.UI } } + public static void FillPolygon(this Graphics g, Color color, PointF[] points, bool smooth = true) + { + using (SolidBrush sb = new SolidBrush(color)) + { + g.Smooth(smooth); + g.FillPolygon(sb, points); + g.Smooth(false); + } + } + + public static void DrawPolygon(this Graphics g, Color color, PointF[] points, bool smooth = true) + { + using (Pen pn = new Pen(color)) + { + g.Smooth(smooth); + g.DrawPolygon(pn, points); + g.Smooth(false); + } + } + public static void FillEllipse(this Graphics g, Color color, Rectangle rect, bool smooth = true) { using (SolidBrush sb = new SolidBrush(color)) diff --git a/SunnyUI/SunnyUI.csproj b/SunnyUI/SunnyUI.csproj index d42527d0..16711a2d 100644 --- a/SunnyUI/SunnyUI.csproj +++ b/SunnyUI/SunnyUI.csproj @@ -38,6 +38,7 @@ +