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 @@
+