VS2005AutoHideStrip.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. /*******************************************************************************
  2. * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
  3. * 类的信息:
  4. * 1.程序名称:VS2005AutoHideStrip.cs
  5. * 2.功能描述:类文件
  6. * 编辑履历:
  7. * 作者 日期 版本 修改内容
  8. * 陈晓野 2014/09/01 1.00 新建
  9. *******************************************************************************/
  10. using System;
  11. using System.Drawing;
  12. using System.Drawing.Drawing2D;
  13. using System.Windows.Forms;
  14. namespace Dongke.IBOSS.PRD.Basics.DockPanel
  15. {
  16. internal class VS2005AutoHideStrip : AutoHideStripBase
  17. {
  18. private class TabVS2005 : Tab
  19. {
  20. internal TabVS2005(IDockContent content)
  21. : base(content)
  22. {
  23. }
  24. private int m_tabX = 0;
  25. public int TabX
  26. {
  27. get
  28. {
  29. return m_tabX;
  30. }
  31. set
  32. {
  33. m_tabX = value;
  34. }
  35. }
  36. private int m_tabWidth = 0;
  37. public int TabWidth
  38. {
  39. get
  40. {
  41. return m_tabWidth;
  42. }
  43. set
  44. {
  45. m_tabWidth = value;
  46. }
  47. }
  48. }
  49. private const int _ImageHeight = 16;
  50. private const int _ImageWidth = 16;
  51. private const int _ImageGapTop = 2;
  52. private const int _ImageGapLeft = 4;
  53. private const int _ImageGapRight = 2;
  54. private const int _ImageGapBottom = 2;
  55. private const int _TextGapLeft = 0;
  56. private const int _TextGapRight = 0;
  57. private const int _TabGapTop = 3;
  58. private const int _TabGapLeft = 4;
  59. private const int _TabGapBetween = 10;
  60. #region Customizable Properties
  61. public Font TextFont
  62. {
  63. get
  64. {
  65. return DockPanel.Skin.AutoHideStripSkin.TextFont;
  66. }
  67. }
  68. private static StringFormat _stringFormatTabHorizontal;
  69. private StringFormat StringFormatTabHorizontal
  70. {
  71. get
  72. {
  73. if (_stringFormatTabHorizontal == null)
  74. {
  75. _stringFormatTabHorizontal = new StringFormat();
  76. _stringFormatTabHorizontal.Alignment = StringAlignment.Near;
  77. _stringFormatTabHorizontal.LineAlignment = StringAlignment.Center;
  78. _stringFormatTabHorizontal.FormatFlags = StringFormatFlags.NoWrap;
  79. _stringFormatTabHorizontal.Trimming = StringTrimming.None;
  80. }
  81. if (RightToLeft == RightToLeft.Yes)
  82. _stringFormatTabHorizontal.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
  83. else
  84. _stringFormatTabHorizontal.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
  85. return _stringFormatTabHorizontal;
  86. }
  87. }
  88. private static StringFormat _stringFormatTabVertical;
  89. private StringFormat StringFormatTabVertical
  90. {
  91. get
  92. {
  93. if (_stringFormatTabVertical == null)
  94. {
  95. _stringFormatTabVertical = new StringFormat();
  96. _stringFormatTabVertical.Alignment = StringAlignment.Near;
  97. _stringFormatTabVertical.LineAlignment = StringAlignment.Center;
  98. _stringFormatTabVertical.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.DirectionVertical;
  99. _stringFormatTabVertical.Trimming = StringTrimming.None;
  100. }
  101. if (RightToLeft == RightToLeft.Yes)
  102. _stringFormatTabVertical.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
  103. else
  104. _stringFormatTabVertical.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
  105. return _stringFormatTabVertical;
  106. }
  107. }
  108. private static int ImageHeight
  109. {
  110. get
  111. {
  112. return _ImageHeight;
  113. }
  114. }
  115. private static int ImageWidth
  116. {
  117. get
  118. {
  119. return _ImageWidth;
  120. }
  121. }
  122. private static int ImageGapTop
  123. {
  124. get
  125. {
  126. return _ImageGapTop;
  127. }
  128. }
  129. private static int ImageGapLeft
  130. {
  131. get
  132. {
  133. return _ImageGapLeft;
  134. }
  135. }
  136. private static int ImageGapRight
  137. {
  138. get
  139. {
  140. return _ImageGapRight;
  141. }
  142. }
  143. private static int ImageGapBottom
  144. {
  145. get
  146. {
  147. return _ImageGapBottom;
  148. }
  149. }
  150. private static int TextGapLeft
  151. {
  152. get
  153. {
  154. return _TextGapLeft;
  155. }
  156. }
  157. private static int TextGapRight
  158. {
  159. get
  160. {
  161. return _TextGapRight;
  162. }
  163. }
  164. private static int TabGapTop
  165. {
  166. get
  167. {
  168. return _TabGapTop;
  169. }
  170. }
  171. private static int TabGapLeft
  172. {
  173. get
  174. {
  175. return _TabGapLeft;
  176. }
  177. }
  178. private static int TabGapBetween
  179. {
  180. get
  181. {
  182. return _TabGapBetween;
  183. }
  184. }
  185. private static Pen PenTabBorder
  186. {
  187. get
  188. {
  189. return SystemPens.GrayText;
  190. }
  191. }
  192. #endregion
  193. private static Matrix _matrixIdentity = new Matrix();
  194. private static Matrix MatrixIdentity
  195. {
  196. get
  197. {
  198. return _matrixIdentity;
  199. }
  200. }
  201. private static DockState[] _dockStates;
  202. private static DockState[] DockStates
  203. {
  204. get
  205. {
  206. if (_dockStates == null)
  207. {
  208. _dockStates = new DockState[4];
  209. _dockStates[0] = DockState.DockLeftAutoHide;
  210. _dockStates[1] = DockState.DockRightAutoHide;
  211. _dockStates[2] = DockState.DockTopAutoHide;
  212. _dockStates[3] = DockState.DockBottomAutoHide;
  213. }
  214. return _dockStates;
  215. }
  216. }
  217. private static GraphicsPath _graphicsPath;
  218. internal static GraphicsPath GraphicsPath
  219. {
  220. get
  221. {
  222. if (_graphicsPath == null)
  223. _graphicsPath = new GraphicsPath();
  224. return _graphicsPath;
  225. }
  226. }
  227. public VS2005AutoHideStrip(DockPanel panel)
  228. : base(panel)
  229. {
  230. SetStyle(ControlStyles.ResizeRedraw |
  231. ControlStyles.UserPaint |
  232. ControlStyles.AllPaintingInWmPaint |
  233. ControlStyles.OptimizedDoubleBuffer, true);
  234. BackColor = SystemColors.ControlLight;
  235. }
  236. protected override void OnPaint(PaintEventArgs e)
  237. {
  238. Graphics g = e.Graphics;
  239. Color startColor = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.StartColor;
  240. Color endColor = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.EndColor;
  241. LinearGradientMode gradientMode = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.LinearGradientMode;
  242. using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, startColor, endColor, gradientMode))
  243. {
  244. g.FillRectangle(brush, ClientRectangle);
  245. }
  246. DrawTabStrip(g);
  247. }
  248. protected override void OnLayout(LayoutEventArgs levent)
  249. {
  250. CalculateTabs();
  251. base.OnLayout(levent);
  252. }
  253. private void DrawTabStrip(Graphics g)
  254. {
  255. DrawTabStrip(g, DockState.DockTopAutoHide);
  256. DrawTabStrip(g, DockState.DockBottomAutoHide);
  257. DrawTabStrip(g, DockState.DockLeftAutoHide);
  258. DrawTabStrip(g, DockState.DockRightAutoHide);
  259. }
  260. private void DrawTabStrip(Graphics g, DockState dockState)
  261. {
  262. Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
  263. if (rectTabStrip.IsEmpty)
  264. return;
  265. Matrix matrixIdentity = g.Transform;
  266. if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
  267. {
  268. Matrix matrixRotated = new Matrix();
  269. matrixRotated.RotateAt(90, new PointF((float)rectTabStrip.X + (float)rectTabStrip.Height / 2,
  270. (float)rectTabStrip.Y + (float)rectTabStrip.Height / 2));
  271. g.Transform = matrixRotated;
  272. }
  273. foreach (Pane pane in GetPanes(dockState))
  274. {
  275. foreach (TabVS2005 tab in pane.AutoHideTabs)
  276. DrawTab(g, tab);
  277. }
  278. g.Transform = matrixIdentity;
  279. }
  280. private void CalculateTabs()
  281. {
  282. CalculateTabs(DockState.DockTopAutoHide);
  283. CalculateTabs(DockState.DockBottomAutoHide);
  284. CalculateTabs(DockState.DockLeftAutoHide);
  285. CalculateTabs(DockState.DockRightAutoHide);
  286. }
  287. private void CalculateTabs(DockState dockState)
  288. {
  289. Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
  290. int imageHeight = rectTabStrip.Height - ImageGapTop - ImageGapBottom;
  291. int imageWidth = ImageWidth;
  292. if (imageHeight > ImageHeight)
  293. imageWidth = ImageWidth * (imageHeight / ImageHeight);
  294. int x = TabGapLeft + rectTabStrip.X;
  295. foreach (Pane pane in GetPanes(dockState))
  296. {
  297. foreach (TabVS2005 tab in pane.AutoHideTabs)
  298. {
  299. int width = imageWidth + ImageGapLeft + ImageGapRight +
  300. TextRenderer.MeasureText(tab.Content.DockHandler.TabText, TextFont).Width +
  301. TextGapLeft + TextGapRight;
  302. tab.TabX = x;
  303. tab.TabWidth = width;
  304. x += width;
  305. }
  306. x += TabGapBetween;
  307. }
  308. }
  309. private Rectangle RtlTransform(Rectangle rect, DockState dockState)
  310. {
  311. Rectangle rectTransformed;
  312. if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
  313. rectTransformed = rect;
  314. else
  315. rectTransformed = DrawHelper.RtlTransform(this, rect);
  316. return rectTransformed;
  317. }
  318. private GraphicsPath GetTabOutline(TabVS2005 tab, bool transformed, bool rtlTransform)
  319. {
  320. DockState dockState = tab.Content.DockHandler.DockState;
  321. Rectangle rectTab = GetTabRectangle(tab, transformed);
  322. if (rtlTransform)
  323. rectTab = RtlTransform(rectTab, dockState);
  324. bool upTab = (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockBottomAutoHide);
  325. DrawHelper.GetRoundedCornerTab(GraphicsPath, rectTab, upTab);
  326. return GraphicsPath;
  327. }
  328. private void DrawTab(Graphics g, TabVS2005 tab)
  329. {
  330. Rectangle rectTabOrigin = GetTabRectangle(tab);
  331. if (rectTabOrigin.IsEmpty)
  332. return;
  333. DockState dockState = tab.Content.DockHandler.DockState;
  334. IDockContent content = tab.Content;
  335. GraphicsPath path = GetTabOutline(tab, false, true);
  336. Color startColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.StartColor;
  337. Color endColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.EndColor;
  338. LinearGradientMode gradientMode = DockPanel.Skin.AutoHideStripSkin.TabGradient.LinearGradientMode;
  339. g.FillPath(new LinearGradientBrush(rectTabOrigin, startColor, endColor, gradientMode), path);
  340. g.DrawPath(PenTabBorder, path);
  341. // Set no rotate for drawing icon and text
  342. Matrix matrixRotate = g.Transform;
  343. g.Transform = MatrixIdentity;
  344. // Draw the icon
  345. Rectangle rectImage = rectTabOrigin;
  346. rectImage.X += ImageGapLeft;
  347. rectImage.Y += ImageGapTop;
  348. int imageHeight = rectTabOrigin.Height - ImageGapTop - ImageGapBottom;
  349. int imageWidth = ImageWidth;
  350. if (imageHeight > ImageHeight)
  351. imageWidth = ImageWidth * (imageHeight / ImageHeight);
  352. rectImage.Height = imageHeight;
  353. rectImage.Width = imageWidth;
  354. rectImage = GetTransformedRectangle(dockState, rectImage);
  355. if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
  356. {
  357. // The DockState is DockLeftAutoHide or DockRightAutoHide, so rotate the image 90 degrees to the right.
  358. Rectangle rectTransform = RtlTransform(rectImage, dockState);
  359. Point[] rotationPoints =
  360. {
  361. new Point(rectTransform.X + rectTransform.Width, rectTransform.Y),
  362. new Point(rectTransform.X + rectTransform.Width, rectTransform.Y + rectTransform.Height),
  363. new Point(rectTransform.X, rectTransform.Y)
  364. };
  365. using (Icon rotatedIcon = new Icon(((Form)content).Icon, 16, 16))
  366. {
  367. g.DrawImage(rotatedIcon.ToBitmap(), rotationPoints);
  368. }
  369. }
  370. else
  371. {
  372. // Draw the icon normally without any rotation.
  373. g.DrawIcon(((Form)content).Icon, RtlTransform(rectImage, dockState));
  374. }
  375. // Draw the text
  376. Rectangle rectText = rectTabOrigin;
  377. rectText.X += ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
  378. rectText.Width -= ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
  379. rectText = RtlTransform(GetTransformedRectangle(dockState, rectText), dockState);
  380. Color textColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.TextColor;
  381. if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
  382. g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabVertical);
  383. else
  384. g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabHorizontal);
  385. // Set rotate back
  386. g.Transform = matrixRotate;
  387. }
  388. private Rectangle GetLogicalTabStripRectangle(DockState dockState)
  389. {
  390. return GetLogicalTabStripRectangle(dockState, false);
  391. }
  392. private Rectangle GetLogicalTabStripRectangle(DockState dockState, bool transformed)
  393. {
  394. if (!DockHelper.IsDockStateAutoHide(dockState))
  395. return Rectangle.Empty;
  396. int leftPanes = GetPanes(DockState.DockLeftAutoHide).Count;
  397. int rightPanes = GetPanes(DockState.DockRightAutoHide).Count;
  398. int topPanes = GetPanes(DockState.DockTopAutoHide).Count;
  399. int bottomPanes = GetPanes(DockState.DockBottomAutoHide).Count;
  400. int x, y, width, height;
  401. height = MeasureHeight();
  402. if (dockState == DockState.DockLeftAutoHide && leftPanes > 0)
  403. {
  404. x = 0;
  405. y = (topPanes == 0) ? 0 : height;
  406. width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
  407. }
  408. else if (dockState == DockState.DockRightAutoHide && rightPanes > 0)
  409. {
  410. x = Width - height;
  411. if (leftPanes != 0 && x < height)
  412. x = height;
  413. y = (topPanes == 0) ? 0 : height;
  414. width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
  415. }
  416. else if (dockState == DockState.DockTopAutoHide && topPanes > 0)
  417. {
  418. x = leftPanes == 0 ? 0 : height;
  419. y = 0;
  420. width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
  421. }
  422. else if (dockState == DockState.DockBottomAutoHide && bottomPanes > 0)
  423. {
  424. x = leftPanes == 0 ? 0 : height;
  425. y = Height - height;
  426. if (topPanes != 0 && y < height)
  427. y = height;
  428. width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
  429. }
  430. else
  431. return Rectangle.Empty;
  432. if (!transformed)
  433. return new Rectangle(x, y, width, height);
  434. else
  435. return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
  436. }
  437. private Rectangle GetTabRectangle(TabVS2005 tab)
  438. {
  439. return GetTabRectangle(tab, false);
  440. }
  441. private Rectangle GetTabRectangle(TabVS2005 tab, bool transformed)
  442. {
  443. DockState dockState = tab.Content.DockHandler.DockState;
  444. Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
  445. if (rectTabStrip.IsEmpty)
  446. return Rectangle.Empty;
  447. int x = tab.TabX;
  448. int y = rectTabStrip.Y +
  449. (dockState == DockState.DockTopAutoHide || dockState == DockState.DockRightAutoHide ?
  450. 0 : TabGapTop);
  451. int width = tab.TabWidth;
  452. int height = rectTabStrip.Height - TabGapTop;
  453. if (!transformed)
  454. return new Rectangle(x, y, width, height);
  455. else
  456. return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
  457. }
  458. private Rectangle GetTransformedRectangle(DockState dockState, Rectangle rect)
  459. {
  460. if (dockState != DockState.DockLeftAutoHide && dockState != DockState.DockRightAutoHide)
  461. return rect;
  462. PointF[] pts = new PointF[1];
  463. // the center of the rectangle
  464. pts[0].X = (float)rect.X + (float)rect.Width / 2;
  465. pts[0].Y = (float)rect.Y + (float)rect.Height / 2;
  466. Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
  467. Matrix matrix = new Matrix();
  468. matrix.RotateAt(90, new PointF((float)rectTabStrip.X + (float)rectTabStrip.Height / 2,
  469. (float)rectTabStrip.Y + (float)rectTabStrip.Height / 2));
  470. matrix.TransformPoints(pts);
  471. return new Rectangle((int)(pts[0].X - (float)rect.Height / 2 + .5F),
  472. (int)(pts[0].Y - (float)rect.Width / 2 + .5F),
  473. rect.Height, rect.Width);
  474. }
  475. protected override IDockContent HitTest(Point ptMouse)
  476. {
  477. foreach (DockState state in DockStates)
  478. {
  479. Rectangle rectTabStrip = GetLogicalTabStripRectangle(state, true);
  480. if (!rectTabStrip.Contains(ptMouse))
  481. continue;
  482. foreach (Pane pane in GetPanes(state))
  483. {
  484. foreach (TabVS2005 tab in pane.AutoHideTabs)
  485. {
  486. GraphicsPath path = GetTabOutline(tab, true, true);
  487. if (path.IsVisible(ptMouse))
  488. return tab.Content;
  489. }
  490. }
  491. }
  492. return null;
  493. }
  494. protected internal override int MeasureHeight()
  495. {
  496. return Math.Max(ImageGapBottom +
  497. ImageGapTop + ImageHeight,
  498. TextFont.Height) + TabGapTop;
  499. }
  500. protected override void OnRefreshChanges()
  501. {
  502. CalculateTabs();
  503. Invalidate();
  504. }
  505. protected override AutoHideStripBase.Tab CreateTab(IDockContent content)
  506. {
  507. return new TabVS2005(content);
  508. }
  509. }
  510. }