Layout.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. namespace IndexFormula.Finance
  2. {
  3. using IndexFormula.Finance.DataProvider;
  4. using System;
  5. using System.ComponentModel;
  6. using System.Drawing;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10. public class Layout
  11. {
  12. private int Bar = 0;
  13. public Rectangle ChartRect;
  14. private double[] CLOSE = null;
  15. private Color[] ColorTextColor = new Color[] { Color.DarkGreen, Color.Black, Color.Maroon };
  16. public string CompanyName;
  17. private double[] DATE = null;
  18. public LayoutLabelCollection Labels = new LayoutLabelCollection();
  19. private TextAlign NowAlign;
  20. private Rectangle NowBack = Rectangle.Empty;
  21. private Color NowBackColor = Color.Empty;
  22. private Color NowColor = Color.Black;
  23. private Font NowColorFont = new Font("Verdana", 8f);
  24. private Font NowFont = new Font("Verdana", 8f);
  25. private Rectangle NowFrame = Rectangle.Empty;
  26. private Color NowFrameColor = Color.Empty;
  27. private string NowIcon = "";
  28. private Point NowPos = Point.Empty;
  29. private string NowText = "";
  30. private bool NowUseColor = false;
  31. public long StartTick;
  32. private TypeConverter tcColor = null;
  33. private TypeConverter tcFont = null;
  34. public string URL;
  35. private void AddLabel()
  36. {
  37. LayoutLabel ll = new LayoutLabel();
  38. ll.Back = this.NowBack;
  39. ll.BackColor = this.NowBackColor;
  40. ll.Frame = this.NowFrame;
  41. ll.FrameColor = this.NowFrameColor;
  42. ll.Pos = this.NowPos;
  43. ll.Text = this.NowText;
  44. ll.TextColor = this.NowColor;
  45. ll.UseColor = this.NowUseColor;
  46. ll.Icon = this.NowIcon;
  47. ll.Align = this.NowAlign;
  48. if (this.NowUseColor)
  49. {
  50. ll.TextFont = this.NowColorFont;
  51. }
  52. else
  53. {
  54. ll.TextFont = this.NowFont;
  55. }
  56. this.Labels.Add(ll);
  57. }
  58. private void AdjustNowPos(LayoutLabel ll, SizeF sf, ref Rectangle R, ref Point NowPos)
  59. {
  60. if (ll.Pos != Point.Empty)
  61. {
  62. if (ll.Pos.X < 0)
  63. {
  64. if (ll.Align == TextAlign.Right)
  65. {
  66. NowPos.X = R.Right + ll.Pos.X;
  67. }
  68. else
  69. {
  70. NowPos.X = (R.Right + ll.Pos.X) - ((int) sf.Width);
  71. }
  72. }
  73. else
  74. {
  75. NowPos.X = R.X + ll.Pos.X;
  76. }
  77. if (ll.Pos.Y < 0)
  78. {
  79. NowPos.Y = (R.Bottom + ll.Pos.Y) - ((int) sf.Height);
  80. }
  81. else
  82. {
  83. NowPos.Y = R.Y + ll.Pos.Y;
  84. }
  85. }
  86. }
  87. public int GetColorIndex(double d1, double d2)
  88. {
  89. if (d1 < d2)
  90. {
  91. return 0;
  92. }
  93. if (d1 == d2)
  94. {
  95. return 1;
  96. }
  97. return 2;
  98. }
  99. public double GetLast()
  100. {
  101. if ((this.Bar > 0) && (this.Bar < (this.CLOSE.Length + 1)))
  102. {
  103. return this.CLOSE[this.Bar - 1];
  104. }
  105. return 0.0;
  106. }
  107. private void GetNameValue(string s, out string Name, out string Value)
  108. {
  109. int index = s.IndexOf('=');
  110. if (index > 0)
  111. {
  112. Name = s.Substring(0, index);
  113. Value = s.Substring(index + 1);
  114. if (Value.StartsWith("("))
  115. {
  116. Value = Value.Substring(1);
  117. }
  118. if (Value.EndsWith(")"))
  119. {
  120. Value = Value.Substring(0, Value.Length - 1);
  121. }
  122. }
  123. else
  124. {
  125. Name = s;
  126. Value = "";
  127. }
  128. }
  129. private string GetOneTag(string s, out string Name, out string Value)
  130. {
  131. int num = 0;
  132. for (int i = 0; i < s.Length; i++)
  133. {
  134. if (s[i] == '(')
  135. {
  136. num++;
  137. }
  138. if (s[i] == ')')
  139. {
  140. num--;
  141. }
  142. if ((s[i] == ';') && (num == 0))
  143. {
  144. this.GetNameValue(s.Substring(0, i), out Name, out Value);
  145. return s.Substring(i + 1);
  146. }
  147. }
  148. this.GetNameValue(s, out Name, out Value);
  149. return "";
  150. }
  151. private void InternalParse(string s, Rectangle Rect)
  152. {
  153. while (s != "")
  154. {
  155. string str;
  156. string str2;
  157. int num;
  158. int num2;
  159. s = this.GetOneTag(s, out str, out str2);
  160. switch (str)
  161. {
  162. case "Font":
  163. case "ColorFont":
  164. {
  165. if (this.tcFont == null)
  166. {
  167. this.tcFont = TypeDescriptor.GetConverter(typeof(Font));
  168. }
  169. Font font = (Font) this.tcFont.ConvertFromString(null, CultureInfo.InvariantCulture, str2);
  170. if (str == "Font")
  171. {
  172. this.NowFont = font;
  173. }
  174. else
  175. {
  176. this.NowColorFont = font;
  177. }
  178. continue;
  179. }
  180. default:
  181. {
  182. string str3 = str;
  183. if (str3 == null)
  184. {
  185. continue;
  186. }
  187. str3 = string.IsInterned(str3);
  188. if (str3 == "ChartRect")
  189. {
  190. this.ChartRect = this.ParseRect(Rect, str2);
  191. continue;
  192. }
  193. if (str3 == "Align")
  194. {
  195. if (str2 == "Right")
  196. {
  197. this.NowAlign = TextAlign.Right;
  198. }
  199. else
  200. {
  201. this.NowAlign = TextAlign.Left;
  202. }
  203. continue;
  204. }
  205. if (str3 == "Color")
  206. {
  207. if (this.tcColor == null)
  208. {
  209. this.tcColor = TypeDescriptor.GetConverter(typeof(Color));
  210. }
  211. this.NowColor = (Color) this.tcColor.ConvertFromString(null, CultureInfo.InvariantCulture, str2);
  212. continue;
  213. }
  214. if (str3 == "Back")
  215. {
  216. this.NowBack = this.ParseRect(Rect, str2);
  217. this.NowText = "";
  218. this.NowBackColor = this.NowColor;
  219. this.AddLabel();
  220. this.NowBack = Rectangle.Empty;
  221. continue;
  222. }
  223. if (str3 == "Frame")
  224. {
  225. this.NowFrame = this.ParseRect(Rect, str2);
  226. this.NowText = "";
  227. this.NowFrameColor = this.NowColor;
  228. this.AddLabel();
  229. this.NowFrame = Rectangle.Empty;
  230. continue;
  231. }
  232. if (str3 == "Pos")
  233. {
  234. this.NowPos = this.ParsePoint(Rect, str2);
  235. continue;
  236. }
  237. if (str3 == "Text")
  238. {
  239. this.NowText = str2;
  240. this.NowUseColor = false;
  241. this.AddLabel();
  242. this.NowPos = Point.Empty;
  243. this.NowText = "";
  244. continue;
  245. }
  246. if (str3 == "Icon")
  247. {
  248. this.NowIcon = str2;
  249. this.AddLabel();
  250. this.NowPos = Point.Empty;
  251. this.NowIcon = "";
  252. continue;
  253. }
  254. if (str3 != "ColorText")
  255. {
  256. continue;
  257. }
  258. num = 0;
  259. break;
  260. }
  261. }
  262. Label_028C:
  263. num2 = str2.IndexOf("{", num);
  264. if (num2 >= 0)
  265. {
  266. int index = str2.IndexOf("}", num2);
  267. if (index > 0)
  268. {
  269. this.NowUseColor = false;
  270. this.NowText = str2.Substring(num, num2 - num);
  271. this.AddLabel();
  272. this.NowPos = Point.Empty;
  273. this.NowUseColor = true;
  274. this.NowText = str2.Substring(num2, (index - num2) + 1);
  275. this.AddLabel();
  276. num = index + 1;
  277. goto Label_028C;
  278. }
  279. }
  280. }
  281. }
  282. public void Merge(Layout L)
  283. {
  284. foreach (LayoutLabel label in L.Labels)
  285. {
  286. this.Labels.Add(label);
  287. }
  288. }
  289. private Point ParsePoint(Rectangle R, string s)
  290. {
  291. string[] strArray = s.Split(new char[] { ',' });
  292. try
  293. {
  294. return new Point(R.X + int.Parse(strArray[0]), R.Y + int.Parse(strArray[1]));
  295. }
  296. catch
  297. {
  298. return Point.Empty;
  299. }
  300. }
  301. private Rectangle ParseRect(Rectangle R, string s)
  302. {
  303. string[] strArray = s.Split(new char[] { ',' });
  304. try
  305. {
  306. if (strArray.Length == 4)
  307. {
  308. int num = int.Parse(strArray[0]);
  309. if (num >= 0)
  310. {
  311. R.X += num;
  312. }
  313. else
  314. {
  315. R.X = (R.Right + num) + 1;
  316. }
  317. int num2 = int.Parse(strArray[1]);
  318. if (num2 >= 0)
  319. {
  320. R.Y += num2;
  321. }
  322. else
  323. {
  324. R.Y = (R.Bottom + num2) + 1;
  325. }
  326. int num3 = int.Parse(strArray[2]);
  327. if (num3 > 0)
  328. {
  329. R.Width = num3 - R.Left;
  330. }
  331. else
  332. {
  333. R.Width = ((R.Width + num3) + 1) - R.Left;
  334. }
  335. int num4 = int.Parse(strArray[3]);
  336. if (num4 > 0)
  337. {
  338. R.Height = num4 - R.Top;
  339. }
  340. else
  341. {
  342. R.Height = ((R.Height + num4) + 1) - R.Top;
  343. }
  344. R.Width = Math.Abs(R.Width);
  345. R.Height = Math.Abs(R.Height);
  346. return R;
  347. }
  348. return R;
  349. }
  350. catch
  351. {
  352. return R;
  353. }
  354. }
  355. public static Layout ParseString(string s, Rectangle Rect)
  356. {
  357. Layout layout = new Layout();
  358. layout.InternalParse(s, Rect);
  359. return layout;
  360. }
  361. public void Render(Graphics g, Rectangle R, FormulaChart fc)
  362. {
  363. this.Render(g, R, fc, Point.Empty);
  364. }
  365. public Point Render(Graphics g, Rectangle R, FormulaChart fc, Point NowPos)
  366. {
  367. return this.Render(g, R, fc, NowPos, -1);
  368. }
  369. public Point Render(Graphics g, Rectangle R, FormulaChart fc, Point NowPos, int Bar)
  370. {
  371. this.Bar = Bar;
  372. foreach (LayoutLabel label in this.Labels)
  373. {
  374. if (label.Frame != Rectangle.Empty)
  375. {
  376. g.DrawRectangle(new Pen(label.FrameColor), label.Frame);
  377. }
  378. if (label.Back != Rectangle.Empty)
  379. {
  380. g.FillRectangle(new SolidBrush(label.BackColor), label.Back);
  381. }
  382. int colorIndex = 0;
  383. string text = this.ReplaceText(fc, label.Text, out colorIndex);
  384. SizeF empty = SizeF.Empty;
  385. if ((label.Text != null) && (label.Text != ""))
  386. {
  387. Color textColor;
  388. empty = g.MeasureString(text, label.TextFont);
  389. this.AdjustNowPos(label, empty, ref R, ref NowPos);
  390. if (label.UseColor)
  391. {
  392. textColor = this.ColorTextColor[colorIndex];
  393. }
  394. else
  395. {
  396. textColor = label.TextColor;
  397. }
  398. g.DrawString(text, label.TextFont, new SolidBrush(textColor), (PointF) NowPos);
  399. }
  400. if ((label.Icon != null) && (label.Icon != ""))
  401. {
  402. string imageFile = FormulaHelper.GetImageFile(label.Icon);
  403. if (File.Exists(imageFile))
  404. {
  405. Image image = Image.FromFile(imageFile);
  406. empty = new SizeF((float) image.Width, (float) image.Height);
  407. this.AdjustNowPos(label, empty, ref R, ref NowPos);
  408. g.DrawImage(image, NowPos);
  409. }
  410. }
  411. if (label.Pos.X >= 0)
  412. {
  413. NowPos.X += (int) empty.Width;
  414. }
  415. }
  416. return NowPos;
  417. }
  418. private string ReplaceText(FormulaChart fc, string s, out int ColorIndex)
  419. {
  420. ColorIndex = 0;
  421. while (true)
  422. {
  423. int index = s.IndexOf('{');
  424. int num2 = s.IndexOf('}');
  425. if (num2 <= index)
  426. {
  427. return s;
  428. }
  429. string str = s.Substring(index + 1, (num2 - index) - 1);
  430. int length = str.IndexOf(':');
  431. string format = "";
  432. string strA = str;
  433. if (length > 0)
  434. {
  435. strA = str.Substring(0, length);
  436. format = str.Substring(length + 1);
  437. }
  438. if (strA == "Company")
  439. {
  440. strA = this.CompanyName;
  441. }
  442. else if (strA == "URL")
  443. {
  444. strA = this.URL;
  445. }
  446. else if (strA == "Time")
  447. {
  448. strA = (((DateTime.Now.Ticks - this.StartTick) / 0x2710L)).ToString() + "ms";
  449. }
  450. else
  451. {
  452. IDataProvider dataProvider = fc.DataProvider;
  453. FormulaArea mainArea = fc.MainArea;
  454. this.DATE = dataProvider["DATE"];
  455. this.CLOSE = dataProvider["CLOSE"];
  456. if ((this.CLOSE == null) || (this.CLOSE.Length == 0))
  457. {
  458. return s;
  459. }
  460. if (this.Bar < 0)
  461. {
  462. for (int i = this.CLOSE.Length - 1; i >= 0; i--)
  463. {
  464. if (!double.IsNaN(this.CLOSE[i]))
  465. {
  466. this.Bar = i;
  467. break;
  468. }
  469. }
  470. }
  471. if (this.Bar < 0)
  472. {
  473. this.Bar = 0;
  474. }
  475. if (string.Compare(strA, "D") == 0)
  476. {
  477. if (format == "")
  478. {
  479. format = "dd-MMM-yyyy dddd";
  480. }
  481. string stringData = dataProvider.GetStringData("LastTradeTime");
  482. DateTime def = fc.IndexToDate(this.Bar);
  483. if ((stringData != null) && (stringData != ""))
  484. {
  485. def = FormulaHelper.ToDateDef(stringData, def);
  486. }
  487. strA = def.ToString(format);
  488. }
  489. else
  490. {
  491. string str5 = dataProvider.GetStringData(strA);
  492. if (str5 != null)
  493. {
  494. strA = str5;
  495. }
  496. else
  497. {
  498. try
  499. {
  500. double last = 0.0;
  501. format = mainArea.AxisY.Format;
  502. if (string.Compare(strA, "Change", true) == 0)
  503. {
  504. last = this.GetLast();
  505. if (this.Bar < this.CLOSE.Length)
  506. {
  507. double num6 = this.CLOSE[this.Bar];
  508. ColorIndex = this.GetColorIndex(last, num6);
  509. string str6 = ((num6 - last) / last).ToString("p2");
  510. if (!str6.StartsWith("-"))
  511. {
  512. str6 = "+" + str6;
  513. }
  514. if (format == "")
  515. {
  516. format = "f" + FormulaHelper.TestBestFormat(num6, 2);
  517. }
  518. strA = ((num6 - last)).ToString(format) + "(" + str6 + ")";
  519. }
  520. }
  521. else
  522. {
  523. double naN = 0.0;
  524. if (strA == "LC")
  525. {
  526. naN = this.GetLast();
  527. }
  528. else
  529. {
  530. FormulaData objA = dataProvider[strA];
  531. double[] data = null;
  532. if (!object.Equals(objA, null))
  533. {
  534. data = objA.Data;
  535. }
  536. if ((data != null) && (this.Bar < data.Length))
  537. {
  538. last = this.GetLast();
  539. naN = data[this.Bar];
  540. if (strA == "VOLUME")
  541. {
  542. format = "f0";
  543. ColorIndex = this.GetColorIndex(last, this.CLOSE[this.Bar]);
  544. }
  545. else
  546. {
  547. ColorIndex = this.GetColorIndex(last, naN);
  548. }
  549. }
  550. else
  551. {
  552. naN = double.NaN;
  553. }
  554. }
  555. if (format == "")
  556. {
  557. format = "f" + FormulaHelper.TestBestFormat(naN, 2);
  558. }
  559. strA = FormulaHelper.FormatDouble(naN, format);
  560. }
  561. }
  562. catch
  563. {
  564. strA = "";
  565. }
  566. }
  567. }
  568. }
  569. s = s.Substring(0, index) + strA + s.Substring(num2 + 1);
  570. }
  571. }
  572. public void SetFont(Font F)
  573. {
  574. foreach (LayoutLabel label in this.Labels)
  575. {
  576. label.TextFont = F;
  577. }
  578. }
  579. }
  580. }