ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/deps/WeifenLuo.WinFormsUI.Docking/WinFormsUI/Docking/VS2005AutoHideStrip.cs
Revision: 640
Committed: Sat Jun 8 20:31:20 2013 UTC (9 years, 3 months ago) by william
File size: 22096 byte(s)
Log Message:
private void DrawTab(Graphics g, TabVS2005 tab)
* rectTabOrigin.Width cannot be 0, if it is, set it to 1
** this fixes crashes in the main form (or users of autohide tabs)

File Contents

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