UCConduit.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. // ***********************************************************************
  2. // Assembly : HZH_Controls
  3. // Created : 2019-09-04
  4. //
  5. // ***********************************************************************
  6. // <copyright file="UCConduit.cs">
  7. // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
  8. // </copyright>
  9. //
  10. // Blog: https://www.cnblogs.com/bfyx
  11. // GitHub:https://github.com/kwwwvagaa/NetWinformControl
  12. // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
  13. //
  14. // If you use this code, please keep this note.
  15. // ***********************************************************************
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Windows.Forms;
  21. using System.Drawing;
  22. using System.Drawing.Drawing2D;
  23. using System.ComponentModel;
  24. namespace HZH_Controls.Controls
  25. {
  26. /// <summary>
  27. /// Class UCConduit.
  28. /// Implements the <see cref="System.Windows.Forms.UserControl" />
  29. /// </summary>
  30. /// <seealso cref="System.Windows.Forms.UserControl" />
  31. public class UCConduit : UserControl
  32. {
  33. /// <summary>
  34. /// The conduit style
  35. /// </summary>
  36. private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;
  37. /// <summary>
  38. /// Gets or sets the conduit style.
  39. /// </summary>
  40. /// <value>The conduit style.</value>
  41. [Description("样式"), Category("自定义")]
  42. public ConduitStyle ConduitStyle
  43. {
  44. get { return conduitStyle; }
  45. set
  46. {
  47. string strOld = conduitStyle.ToString().Substring(0, 1);
  48. string strNew = value.ToString().Substring(0, 1);
  49. conduitStyle = value;
  50. if (strOld != strNew)
  51. {
  52. this.Size = new Size(this.Size.Height, this.Size.Width);
  53. }
  54. Refresh();
  55. }
  56. }
  57. /// <summary>
  58. /// The conduit color
  59. /// </summary>
  60. private Color conduitColor = Color.FromArgb(255, 77, 59);
  61. [Description("颜色"), Category("自定义")]
  62. /// <summary>
  63. /// Gets or sets the color of the conduit.
  64. /// </summary>
  65. /// <value>The color of the conduit.</value>
  66. public Color ConduitColor
  67. {
  68. get { return conduitColor; }
  69. set
  70. {
  71. conduitColor = value;
  72. Refresh();
  73. }
  74. }
  75. /// <summary>
  76. /// The liquid color
  77. /// </summary>
  78. private Color liquidColor = Color.FromArgb(3, 169, 243);
  79. /// <summary>
  80. /// Gets or sets the color of the liquid.
  81. /// </summary>
  82. /// <value>The color of the liquid.</value>
  83. [Description("液体颜色"), Category("自定义")]
  84. public Color LiquidColor
  85. {
  86. get { return liquidColor; }
  87. set
  88. {
  89. liquidColor = value;
  90. if (liquidDirection != LiquidDirection.None)
  91. Refresh();
  92. }
  93. }
  94. /// <summary>
  95. /// The liquid direction
  96. /// </summary>
  97. private LiquidDirection liquidDirection = LiquidDirection.Forward;
  98. /// <summary>
  99. /// Gets or sets the liquid direction.
  100. /// </summary>
  101. /// <value>The liquid direction.</value>
  102. [Description("液体流动方向"), Category("自定义")]
  103. public LiquidDirection LiquidDirection
  104. {
  105. get { return liquidDirection; }
  106. set
  107. {
  108. liquidDirection = value;
  109. if (value == LiquidDirection.None)
  110. m_timer.Enabled = false;
  111. else
  112. m_timer.Enabled = true;
  113. Refresh();
  114. }
  115. }
  116. /// <summary>
  117. /// The liquid speed
  118. /// </summary>
  119. private int liquidSpeed = 100;
  120. /// <summary>
  121. /// 液体流速,越小,速度越快Gets or sets the liquid speed.
  122. /// </summary>
  123. /// <value>The liquid speed.</value>
  124. [Description("液体流速,越小,速度越快"), Category("自定义")]
  125. public int LiquidSpeed
  126. {
  127. get { return liquidSpeed; }
  128. set
  129. {
  130. if (value <= 0)
  131. return;
  132. liquidSpeed = value;
  133. m_timer.Interval = value;
  134. }
  135. }
  136. /// <summary>
  137. /// The conduit width
  138. /// </summary>
  139. int conduitWidth = 50;
  140. /// <summary>
  141. /// Gets or sets the width of the conduit.
  142. /// </summary>
  143. /// <value>The width of the conduit.</value>
  144. [Description("管道宽度,当ConduitStyle的值是Horizontal_Tilt_Up,Horizontal_Tilt_Down,Vertical_Tilt_Left,Vertical_Tilt_Right时有效,其他时候将根据管道大小使用自动宽度"), Category("自定义")]
  145. public int ConduitWidth
  146. {
  147. get { return conduitWidth; }
  148. set
  149. {
  150. conduitWidth = value;
  151. Refresh();
  152. }
  153. }
  154. /// <summary>
  155. /// The int pen width
  156. /// </summary>
  157. int intPenWidth = 0;
  158. /// <summary>
  159. /// The int line left
  160. /// </summary>
  161. int intLineLeft = 0;
  162. /// <summary>
  163. /// The m timer
  164. /// </summary>
  165. Timer m_timer;
  166. /// <summary>
  167. /// Initializes a new instance of the <see cref="UCConduit" /> class.
  168. /// </summary>
  169. public UCConduit()
  170. {
  171. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  172. this.SetStyle(ControlStyles.DoubleBuffer, true);
  173. this.SetStyle(ControlStyles.ResizeRedraw, true);
  174. this.SetStyle(ControlStyles.Selectable, true);
  175. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  176. this.SetStyle(ControlStyles.UserPaint, true);
  177. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  178. this.SizeChanged += UCConduit_SizeChanged;
  179. this.Size = new Size(200, 50);
  180. m_timer = new Timer();
  181. m_timer.Interval = 100;
  182. m_timer.Tick += timer_Tick;
  183. m_timer.Enabled = true;
  184. }
  185. /// <summary>
  186. /// Handles the Tick event of the timer control.
  187. /// </summary>
  188. /// <param name="sender">The source of the event.</param>
  189. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  190. void timer_Tick(object sender, EventArgs e)
  191. {
  192. intLineLeft += 2;
  193. if (intLineLeft > 12)
  194. intLineLeft = 0;
  195. Refresh();
  196. }
  197. /// <summary>
  198. /// Handles the SizeChanged event of the UCConduit control.
  199. /// </summary>
  200. /// <param name="sender">The source of the event.</param>
  201. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  202. void UCConduit_SizeChanged(object sender, EventArgs e)
  203. {
  204. intPenWidth = conduitStyle.ToString().StartsWith("H") ? this.Height : this.Width;
  205. }
  206. /// <summary>
  207. /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  208. /// </summary>
  209. /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  210. protected override void OnPaint(PaintEventArgs e)
  211. {
  212. base.OnPaint(e);
  213. Graphics g = e.Graphics;
  214. List<ArcEntity> lstArcs = new List<ArcEntity>();
  215. GraphicsPath path = new GraphicsPath();
  216. GraphicsPath linePath = new GraphicsPath();
  217. List<Point[]> tileLine = new List<Point[]>();
  218. switch (conduitStyle)
  219. {
  220. #region H English:H
  221. case ConduitStyle.Horizontal_None_None:
  222. path.AddLines(new PointF[]
  223. {
  224. new PointF(0, 0),
  225. new PointF(this.ClientRectangle.Right, 0),
  226. new PointF(this.ClientRectangle.Right, this.Height),
  227. new PointF(0, this.Height)
  228. });
  229. path.CloseAllFigures();
  230. linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
  231. break;
  232. case ConduitStyle.Horizontal_Up_None:
  233. path.AddLines(new PointF[]
  234. {
  235. new PointF(0, 0),
  236. new PointF(this.ClientRectangle.Right, 0),
  237. new PointF(this.ClientRectangle.Right, this.Height),
  238. new PointF(0+intPenWidth, this.Height)
  239. });
  240. path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
  241. path.CloseAllFigures();
  242. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
  243. linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);
  244. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  245. break;
  246. case ConduitStyle.Horizontal_Down_None:
  247. path.AddLines(new PointF[]
  248. {
  249. new PointF(intPenWidth, 0),
  250. new PointF(this.ClientRectangle.Right, 0),
  251. new PointF(this.ClientRectangle.Right, this.Height),
  252. new PointF(0, this.Height)
  253. });
  254. path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
  255. path.CloseAllFigures();
  256. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
  257. linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);
  258. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  259. break;
  260. case ConduitStyle.Horizontal_None_Up:
  261. path.AddLines(new PointF[]
  262. {
  263. new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
  264. new PointF(0, this.Height),
  265. new PointF(0, 0),
  266. new PointF(this.ClientRectangle.Right-intPenWidth, 0)
  267. });
  268. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
  269. path.CloseAllFigures();
  270. linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
  271. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
  272. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  273. break;
  274. case ConduitStyle.Horizontal_None_Down:
  275. path.AddLines(new PointF[]
  276. {
  277. new PointF(this.ClientRectangle.Right, this.Height),
  278. new PointF(0, this.Height),
  279. new PointF(0, 0),
  280. new PointF(this.ClientRectangle.Right-intPenWidth, 0)
  281. });
  282. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
  283. path.CloseAllFigures();
  284. linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
  285. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
  286. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  287. break;
  288. case ConduitStyle.Horizontal_Down_Up:
  289. path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
  290. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
  291. path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
  292. path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
  293. path.CloseAllFigures();
  294. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
  295. //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
  296. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
  297. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  298. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  299. break;
  300. case ConduitStyle.Horizontal_Up_Down:
  301. path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
  302. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
  303. path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
  304. path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
  305. path.CloseAllFigures();
  306. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
  307. linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
  308. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
  309. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  310. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  311. break;
  312. case ConduitStyle.Horizontal_Up_Up:
  313. path.AddLine(new Point(0, 0), new Point(this.Width, 0));
  314. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
  315. path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
  316. path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
  317. path.CloseAllFigures();
  318. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
  319. //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
  320. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
  321. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  322. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  323. break;
  324. case ConduitStyle.Horizontal_Down_Down:
  325. path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
  326. path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
  327. path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
  328. path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
  329. path.CloseAllFigures();
  330. linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
  331. linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
  332. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
  333. lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  334. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  335. break;
  336. case ConduitStyle.Horizontal_Tilt_Up:
  337. double angleUp = Math.Atan((this.ClientRectangle.Height - conduitWidth) / (double)this.ClientRectangle.Width);
  338. angleUp = angleUp / Math.PI * 180f;
  339. path.AddArc(new Rectangle(this.ClientRectangle.Left - conduitWidth, this.ClientRectangle.Bottom - conduitWidth * 2, conduitWidth * 2, conduitWidth * 2), 90, -1 * (float)angleUp);
  340. path.AddLine(new Point(this.ClientRectangle.Right, this.ClientRectangle.Top + conduitWidth), new Point(this.ClientRectangle.Right, this.ClientRectangle.Top));
  341. path.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Top, conduitWidth * 2, conduitWidth * 2), 270, -1 * (float)angleUp);
  342. path.AddLine(new Point(this.ClientRectangle.Left, this.ClientRectangle.Bottom - conduitWidth), new Point(this.ClientRectangle.Left, this.ClientRectangle.Bottom));
  343. path.CloseAllFigures();
  344. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth / 2, this.ClientRectangle.Top + conduitWidth / 2, conduitWidth, conduitWidth), 270, -1 * (float)angleUp);
  345. linePath.AddArc(new Rectangle(this.ClientRectangle.Left - conduitWidth / 2, this.ClientRectangle.Bottom - 1 - conduitWidth - conduitWidth / 2, conduitWidth, conduitWidth), 95 - (float)angleUp, (float)angleUp + 5);
  346. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Left - conduitWidth, this.ClientRectangle.Bottom - conduitWidth * 2, conduitWidth * 2, conduitWidth * 2), startAngle = 90, sweepAngle = -1 * (float)angleUp });
  347. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Top, conduitWidth * 2, conduitWidth * 2), startAngle = 270, sweepAngle = -1 * (float)angleUp });
  348. tileLine.Add(new Point[]
  349. {
  350. new Point((int)(this.ClientRectangle.Right+1 - Math.Sin(Math.PI * (angleUp / 180.00F)) * conduitWidth),(int)( this.ClientRectangle.Top + conduitWidth - Math.Cos(Math.PI * (angleUp / 180.00F)) * conduitWidth)),
  351. new Point(this.ClientRectangle.Left,this.ClientRectangle.Bottom-conduitWidth-1)
  352. });
  353. tileLine.Add(new Point[]
  354. {
  355. new Point((int)(this.ClientRectangle.Left+1 + Math.Sin(Math.PI * (angleUp / 180.00F)) * conduitWidth),(int)( this.ClientRectangle.Bottom - conduitWidth + Math.Cos(Math.PI * (angleUp / 180.00F)) * conduitWidth)),
  356. new Point(this.ClientRectangle.Right,this.ClientRectangle.Top+conduitWidth)
  357. });
  358. break;
  359. case ConduitStyle.Horizontal_Tilt_Down:
  360. double angleDown = Math.Atan((this.ClientRectangle.Height - conduitWidth) / (double)this.ClientRectangle.Width);
  361. angleDown = angleDown / Math.PI * 180f;
  362. path.AddArc(new Rectangle(this.ClientRectangle.Left - conduitWidth, this.ClientRectangle.Top, conduitWidth * 2, conduitWidth * 2), 270, (float)angleDown);
  363. path.AddLine(new Point(this.ClientRectangle.Right, this.ClientRectangle.Bottom - conduitWidth), new Point(this.ClientRectangle.Right, this.ClientRectangle.Bottom));
  364. path.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Bottom - conduitWidth * 2, conduitWidth * 2, conduitWidth * 2), 90, (float)angleDown);
  365. path.AddLine(new Point(this.ClientRectangle.Left, this.ClientRectangle.Top + conduitWidth), new Point(this.ClientRectangle.Left, this.ClientRectangle.Top));
  366. path.CloseAllFigures();
  367. linePath.AddArc(new Rectangle(this.ClientRectangle.Left - conduitWidth / 2, this.ClientRectangle.Top + conduitWidth / 2, conduitWidth, conduitWidth), 265, (float)angleDown + 5);
  368. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth / 2, this.ClientRectangle.Bottom - conduitWidth - conduitWidth / 2 - 1, conduitWidth, conduitWidth), 90 + (float)angleDown, -1 * (float)angleDown - 5);
  369. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Left - conduitWidth, this.ClientRectangle.Top, conduitWidth * 2, conduitWidth * 2), startAngle = 270, sweepAngle = (float)angleDown });
  370. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Bottom - conduitWidth * 2, conduitWidth * 2, conduitWidth * 2), startAngle = 90, sweepAngle = (float)angleDown });
  371. tileLine.Add(new Point[]
  372. {
  373. new Point((int)(this.ClientRectangle.Left + Math.Sin(Math.PI * (angleDown / 180.00F)) * conduitWidth),(int)( this.ClientRectangle.Top + conduitWidth - Math.Cos(Math.PI * (angleDown / 180.00F)) * conduitWidth)),
  374. new Point(this.ClientRectangle.Right-1,this.ClientRectangle.Bottom-conduitWidth-1)
  375. });
  376. tileLine.Add(new Point[]
  377. {
  378. new Point((int)(this.ClientRectangle.Right - Math.Sin(Math.PI * (angleDown / 180.00F)) * conduitWidth),(int)( this.ClientRectangle.Bottom - conduitWidth + Math.Cos(Math.PI * (angleDown / 180.00F)) * conduitWidth)),
  379. new Point(this.ClientRectangle.Left,this.ClientRectangle.Top+conduitWidth)
  380. });
  381. break;
  382. #endregion
  383. #region V English:V
  384. case ConduitStyle.Vertical_None_None:
  385. path.AddLines(new PointF[]
  386. {
  387. new PointF(0, 0),
  388. new PointF(this.ClientRectangle.Right, 0),
  389. new PointF(this.ClientRectangle.Right, this.Height),
  390. new PointF(0, this.Height)
  391. });
  392. path.CloseAllFigures();
  393. linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
  394. break;
  395. case ConduitStyle.Vertical_Left_None:
  396. path.AddLines(new PointF[]
  397. {
  398. new PointF(this.ClientRectangle.Right, intPenWidth),
  399. new PointF(this.ClientRectangle.Right, this.Height),
  400. new PointF(0, this.Height),
  401. new PointF(0, 0)
  402. });
  403. path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
  404. path.CloseAllFigures();
  405. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
  406. linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);
  407. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  408. break;
  409. case ConduitStyle.Vertical_Right_None:
  410. path.AddLines(new PointF[]
  411. {
  412. new PointF(this.ClientRectangle.Right, 0),
  413. new PointF(this.ClientRectangle.Right, this.Height),
  414. new PointF(0, this.Height),
  415. new PointF(0, intPenWidth)
  416. });
  417. path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
  418. path.CloseAllFigures();
  419. linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
  420. linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);
  421. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  422. break;
  423. case ConduitStyle.Vertical_None_Left:
  424. path.AddLines(new PointF[]
  425. {
  426. new PointF(0, this.Height),
  427. new PointF(0, 0),
  428. new PointF(this.ClientRectangle.Right, 0),
  429. new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
  430. });
  431. path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
  432. path.CloseAllFigures();
  433. linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
  434. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
  435. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  436. break;
  437. case ConduitStyle.Vertical_None_Right:
  438. path.AddLines(new PointF[]
  439. {
  440. new PointF(0, this.Height-intPenWidth),
  441. new PointF(0, 0),
  442. new PointF(this.ClientRectangle.Right, 0),
  443. new PointF(this.ClientRectangle.Right, this.Height),
  444. });
  445. path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
  446. path.CloseAllFigures();
  447. linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
  448. linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
  449. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  450. break;
  451. case ConduitStyle.Vertical_Left_Right:
  452. path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
  453. path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
  454. path.AddLine(0, this.Height - intPenWidth, 0, 0);
  455. path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
  456. path.CloseAllFigures();
  457. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
  458. //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
  459. linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
  460. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  461. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  462. break;
  463. case ConduitStyle.Vertical_Right_Left:
  464. path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
  465. path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
  466. path.AddLine(0, this.Height, 0, intPenWidth);
  467. path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
  468. path.CloseAllFigures();
  469. linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
  470. //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
  471. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
  472. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  473. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  474. break;
  475. case ConduitStyle.Vertical_Left_Left:
  476. path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
  477. path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
  478. path.AddLine(0, this.Height, 0, 0);
  479. path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
  480. path.CloseAllFigures();
  481. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
  482. //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
  483. linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
  484. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
  485. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
  486. break;
  487. case ConduitStyle.Vertical_Right_Right:
  488. path.AddLine(this.Width, 0, this.Width, this.Height);
  489. path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
  490. path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
  491. path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
  492. path.CloseAllFigures();
  493. linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
  494. //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
  495. linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);
  496. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
  497. lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
  498. break;
  499. case ConduitStyle.Vertical_Tilt_Left:
  500. double angleLeft = Math.Atan((this.ClientRectangle.Width - conduitWidth) / (double)this.ClientRectangle.Height);
  501. angleLeft = angleLeft / Math.PI * 180f;
  502. path.AddArc(new Rectangle(this.ClientRectangle.Left - 1, ClientRectangle.Top - conduitWidth, conduitWidth * 2, conduitWidth * 2), 180, -1 * (float)angleLeft);
  503. path.AddLine(new Point(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Bottom), new Point(this.ClientRectangle.Right, this.ClientRectangle.Bottom));
  504. path.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth * 2, this.ClientRectangle.Bottom - conduitWidth, conduitWidth * 2, conduitWidth * 2), 0, -1 * (float)angleLeft);
  505. path.AddLine(new Point(this.ClientRectangle.Left + conduitWidth, this.ClientRectangle.Top), new Point(this.ClientRectangle.Left, this.ClientRectangle.Top));
  506. path.CloseAllFigures();
  507. linePath.AddArc(new Rectangle(this.ClientRectangle.Left + conduitWidth / 2, this.ClientRectangle.Top - conduitWidth / 2, conduitWidth, conduitWidth), 185, -1 * (float)angleLeft - 5);
  508. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth - conduitWidth / 2, this.ClientRectangle.Bottom - conduitWidth / 2, conduitWidth, conduitWidth), -1 * (float)angleLeft, (float)angleLeft);
  509. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Left - 1, ClientRectangle.Top - conduitWidth, conduitWidth * 2, conduitWidth * 2), startAngle = 180, sweepAngle = -1 * (float)angleLeft });
  510. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - conduitWidth * 2, this.ClientRectangle.Bottom - conduitWidth, conduitWidth * 2, conduitWidth * 2), startAngle = 0, sweepAngle = -1 * (float)angleLeft });
  511. tileLine.Add(new Point[]
  512. {
  513. new Point((int)(this.ClientRectangle.Left + conduitWidth),this.ClientRectangle.Top),
  514. new Point((int)(this.ClientRectangle.Right-conduitWidth+Math.Cos(Math.PI * (angleLeft / 180.00F)) * conduitWidth),(int)(this.ClientRectangle.Bottom-Math.Sin(Math.PI * (angleLeft / 180.00F)) * conduitWidth))
  515. });
  516. tileLine.Add(new Point[]
  517. {
  518. new Point((int)(this.ClientRectangle.Left-1+conduitWidth-Math.Cos(Math.PI * (angleLeft / 180.00F)) * conduitWidth),(int)(this.ClientRectangle.Top+Math.Sin(Math.PI * (angleLeft / 180.00F)) * conduitWidth)),
  519. new Point(this.ClientRectangle.Right-conduitWidth,this.ClientRectangle.Bottom)
  520. });
  521. break;
  522. case ConduitStyle.Vertical_Tilt_Right:
  523. double angleRight = Math.Atan((this.ClientRectangle.Width - conduitWidth) / (double)this.ClientRectangle.Height);
  524. angleRight = angleRight / Math.PI * 180f;
  525. path.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth * 2, ClientRectangle.Top - conduitWidth, conduitWidth * 2, conduitWidth * 2), 0, (float)angleRight);
  526. path.AddLine(new Point(this.ClientRectangle.Left + conduitWidth, this.ClientRectangle.Bottom), new Point(this.ClientRectangle.Left, this.ClientRectangle.Bottom));
  527. path.AddArc(new Rectangle(this.ClientRectangle.Left - 1, this.ClientRectangle.Bottom - conduitWidth, conduitWidth * 2, conduitWidth * 2), 180, (float)angleRight);
  528. path.AddLine(new Point(this.ClientRectangle.Right - conduitWidth, this.ClientRectangle.Top), new Point(this.ClientRectangle.Right, this.ClientRectangle.Top));
  529. path.CloseAllFigures();
  530. linePath.AddArc(new Rectangle(this.ClientRectangle.Right - conduitWidth - conduitWidth / 2, this.ClientRectangle.Top - conduitWidth / 2, conduitWidth, conduitWidth), -5, (float)angleRight + 5);
  531. linePath.AddArc(new Rectangle(this.ClientRectangle.Left + conduitWidth / 2, this.ClientRectangle.Bottom - conduitWidth / 2, conduitWidth, conduitWidth), 180 + (float)angleRight, -1 * (float)angleRight);
  532. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - conduitWidth * 2, ClientRectangle.Top - conduitWidth, conduitWidth * 2, conduitWidth * 2), startAngle = 0, sweepAngle = (float)angleRight });
  533. lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Left - 1, this.ClientRectangle.Bottom - conduitWidth, conduitWidth * 2, conduitWidth * 2), startAngle = 180, sweepAngle = (float)angleRight });
  534. tileLine.Add(new Point[]
  535. {
  536. new Point((int)(this.ClientRectangle.Right - conduitWidth),this.ClientRectangle.Top),
  537. new Point((int)(this.ClientRectangle.Left + conduitWidth - Math.Cos(Math.PI * (angleRight / 180.00F)) * conduitWidth),(int)(this.ClientRectangle.Bottom-Math.Sin(Math.PI * (angleRight / 180.00F)) * conduitWidth))
  538. });
  539. tileLine.Add(new Point[]
  540. {
  541. new Point((int)(this.ClientRectangle.Right - conduitWidth+Math.Cos(Math.PI * (angleRight / 180.00F)) * conduitWidth),(int)(this.ClientRectangle.Top+Math.Sin(Math.PI * (angleRight / 180.00F)) * conduitWidth)),
  542. new Point(this.ClientRectangle.Left + conduitWidth,this.ClientRectangle.Bottom)
  543. });
  544. break;
  545. #endregion
  546. }
  547. base.Region = new Region(path);
  548. g.FillPath(new SolidBrush(conduitColor), path);
  549. //渐变色
  550. int _intPenWidth = intPenWidth;
  551. if (conduitStyle.ToString().Contains("Tilt"))
  552. {
  553. _intPenWidth = conduitWidth;
  554. }
  555. int intCount = _intPenWidth / 2 / 4;
  556. for (int i = 0; i < intCount; i++)
  557. {
  558. int _penWidth = _intPenWidth / 2 - 4 * i;
  559. if (_penWidth <= 0)
  560. _penWidth = 1;
  561. g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
  562. if (_penWidth == 1)
  563. break;
  564. }
  565. g.SetGDIHigh();
  566. //使用抗锯齿画圆角
  567. foreach (var item in lstArcs)
  568. {
  569. g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
  570. }
  571. if (tileLine.Count > 0)
  572. {
  573. foreach (var item in tileLine)
  574. {
  575. g.DrawLine(new Pen(new SolidBrush(this.BackColor)), item[0], item[1]);
  576. }
  577. }
  578. //液体流动
  579. if (LiquidDirection != LiquidDirection.None)
  580. {
  581. Pen p = new Pen(new SolidBrush(liquidColor), 4);
  582. p.DashPattern = new float[] { 6, 6 };
  583. p.DashOffset = intLineLeft * (LiquidDirection == LiquidDirection.Forward ? -1 : 1);
  584. g.DrawPath(p, linePath);
  585. }
  586. }
  587. /// <summary>
  588. /// Class ArcEntity.
  589. /// </summary>
  590. class ArcEntity
  591. {
  592. /// <summary>
  593. /// Gets or sets the rect.
  594. /// </summary>
  595. /// <value>The rect.</value>
  596. public Rectangle rect { get; set; }
  597. /// <summary>
  598. /// Gets or sets the start angle.
  599. /// </summary>
  600. /// <value>The start angle.</value>
  601. public float startAngle { get; set; }
  602. /// <summary>
  603. /// Gets or sets the sweep angle.
  604. /// </summary>
  605. /// <value>The sweep angle.</value>
  606. public float sweepAngle { get; set; }
  607. }
  608. }
  609. /// <summary>
  610. /// Enum LiquidDirection
  611. /// </summary>
  612. public enum LiquidDirection
  613. {
  614. /// <summary>
  615. /// The none
  616. /// </summary>
  617. None,
  618. /// <summary>
  619. /// The forward
  620. /// </summary>
  621. Forward,
  622. /// <summary>
  623. /// The backward
  624. /// </summary>
  625. Backward
  626. }
  627. /// <summary>
  628. /// 管道样式Enum ConduitStyle
  629. /// </summary>
  630. public enum ConduitStyle
  631. {
  632. /// <summary>
  633. /// 直线 The horizontal none none
  634. /// </summary>
  635. Horizontal_None_None,
  636. /// <summary>
  637. /// 左上The horizontal up none
  638. /// </summary>
  639. Horizontal_Up_None,
  640. /// <summary>
  641. /// 左下The horizontal down none
  642. /// </summary>
  643. Horizontal_Down_None,
  644. /// <summary>
  645. /// 右上The horizontal none up
  646. /// </summary>
  647. Horizontal_None_Up,
  648. /// <summary>
  649. /// 右下The horizontal none down
  650. /// </summary>
  651. Horizontal_None_Down,
  652. /// <summary>
  653. /// 左下右上The horizontal down up
  654. /// </summary>
  655. Horizontal_Down_Up,
  656. /// <summary>
  657. /// 左上右下The horizontal up down
  658. /// </summary>
  659. Horizontal_Up_Down,
  660. /// <summary>
  661. /// 左上,右上The horizontal up up
  662. /// </summary>
  663. Horizontal_Up_Up,
  664. /// <summary>
  665. /// 左下右下The horizontal down down
  666. /// </summary>
  667. Horizontal_Down_Down,
  668. /// <summary>
  669. /// 向上倾斜The horizontal tilt up
  670. /// </summary>
  671. Horizontal_Tilt_Up,
  672. /// <summary>
  673. /// 向下倾斜The horizontal tilt down
  674. /// </summary>
  675. Horizontal_Tilt_Down,
  676. /// <summary>
  677. /// 竖线The vertical none none
  678. /// </summary>
  679. Vertical_None_None,
  680. /// <summary>
  681. /// 上左The vertical left none
  682. /// </summary>
  683. Vertical_Left_None,
  684. /// <summary>
  685. /// 上右The vertical right none
  686. /// </summary>
  687. Vertical_Right_None,
  688. /// <summary>
  689. /// 下左The vertical none left
  690. /// </summary>
  691. Vertical_None_Left,
  692. /// <summary>
  693. /// 下右The vertical none right
  694. /// </summary>
  695. Vertical_None_Right,
  696. /// <summary>
  697. /// 上左下右The vertical left right
  698. /// </summary>
  699. Vertical_Left_Right,
  700. /// <summary>
  701. /// 上右下左The vertical right left
  702. /// </summary>
  703. Vertical_Right_Left,
  704. /// <summary>
  705. /// 上左下左The vertical left left
  706. /// </summary>
  707. Vertical_Left_Left,
  708. /// <summary>
  709. /// 上右下右The vertical right left
  710. /// </summary>
  711. Vertical_Right_Right,
  712. /// <summary>
  713. /// 向左倾斜The vertical tilt
  714. /// </summary>
  715. Vertical_Tilt_Left,
  716. /// <summary>
  717. /// 向右倾斜The vertical tilt right
  718. /// </summary>
  719. Vertical_Tilt_Right
  720. }
  721. }