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, 5 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

# User Rev Content
1 william 140 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 william 638 try
206     {
207     Graphics g = e.Graphics;
208 william 140
209 william 638 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 william 140 {
221 william 638 throw;
222 william 140 }
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 william 638 try
242     {
243     Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
244 william 140
245 william 638 if (rectTabStrip.IsEmpty)
246     return;
247 william 140
248 william 638 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 william 140 }
264 william 638 catch (Exception)
265 william 140 {
266 william 638 throw;
267 william 140 }
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 william 638 try
281     {
282     Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
283 william 140
284 william 638 int imageHeight = rectTabStrip.Height - ImageGapTop - ImageGapBottom;
285     int imageWidth = ImageWidth;
286     if (imageHeight > ImageHeight)
287     imageWidth = ImageWidth * (imageHeight / ImageHeight);
288 william 140
289 william 638 int x = TabGapLeft + rectTabStrip.X;
290     foreach (Pane pane in GetPanes(dockState))
291 william 140 {
292 william 638 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 william 140 }
304     }
305 william 638 catch (Exception)
306     {
307     throw;
308     }
309 william 140 }
310    
311     private Rectangle RtlTransform(Rectangle rect, DockState dockState)
312     {
313 william 638 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 william 140
321 william 638 return rectTransformed;
322     }
323     catch (Exception)
324     {
325     throw;
326     }
327 william 140 }
328    
329     private GraphicsPath GetTabOutline(TabVS2005 tab, bool transformed, bool rtlTransform)
330     {
331 william 638 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 william 140
340 william 638 return GraphicsPath;
341     }
342     catch (Exception)
343     {
344     throw;
345     }
346 william 140 }
347    
348     private void DrawTab(Graphics g, TabVS2005 tab)
349     {
350 william 638 try
351     {
352     Rectangle rectTabOrigin = GetTabRectangle(tab);
353     if (rectTabOrigin.IsEmpty)
354     return;
355 william 140
356 william 638 DockState dockState = tab.Content.DockHandler.DockState;
357     IDockContent content = tab.Content;
358 william 140
359 william 638 GraphicsPath path = GetTabOutline(tab, false, true);
360 william 140
361 william 638 Color startColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.StartColor;
362     Color endColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.EndColor;
363     LinearGradientMode gradientMode = DockPanel.Skin.AutoHideStripSkin.TabGradient.LinearGradientMode;
364 william 640
365     if (rectTabOrigin.Width == 0)
366     {
367     // rectangle width cannot be 0
368     rectTabOrigin.Width = 1;
369     }
370    
371 william 638 g.FillPath(new LinearGradientBrush(rectTabOrigin, startColor, endColor, gradientMode), path);
372     g.DrawPath(PenTabBorder, path);
373 william 140
374 william 638 // Set no rotate for drawing icon and text
375     Matrix matrixRotate = g.Transform;
376     g.Transform = MatrixIdentity;
377 william 140
378 william 638 // 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 william 140
390 william 638 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 william 140 {
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 william 638 using (Icon rotatedIcon = new Icon(((Form)content).Icon, 16, 16))
402     {
403     g.DrawImage(rotatedIcon.ToBitmap(), rotationPoints);
404     }
405     }
406     else
407 william 140 {
408 william 638 // Draw the icon normally without any rotation.
409     g.DrawIcon(((Form)content).Icon, RtlTransform(rectImage, dockState));
410 william 140 }
411    
412 william 638 // 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 william 140
418 william 638 Color textColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.TextColor;
419 william 140
420 william 638 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 william 140
425 william 638 // Set rotate back
426     g.Transform = matrixRotate;
427     }
428     catch (Exception)
429     {
430     throw;
431     }
432 william 140 }
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 william 638 try
442     {
443     if (!DockHelper.IsDockStateAutoHide(dockState))
444     return Rectangle.Empty;
445 william 140
446 william 638 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 william 140
451 william 638 int x, y, width, height;
452 william 140
453 william 638 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 william 140 }
490 william 638 catch (Exception)
491 william 140 {
492 william 638 throw;
493 william 140 }
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 william 638 try
504     {
505     DockState dockState = tab.Content.DockHandler.DockState;
506     Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
507 william 140
508 william 638 if (rectTabStrip.IsEmpty)
509     return Rectangle.Empty;
510 william 140
511 william 638 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 william 140
518 william 638 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 william 140 }
528    
529     private Rectangle GetTransformedRectangle(DockState dockState, Rectangle rect)
530     {
531 william 638 try
532     {
533     if (dockState != DockState.DockLeftAutoHide && dockState != DockState.DockRightAutoHide)
534     return rect;
535 william 140
536 william 638 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 william 140
546 william 638 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 william 140 }
555    
556     protected override IDockContent HitTest(Point ptMouse)
557     {
558 william 638 try
559 william 140 {
560 william 638 foreach (DockState state in DockStates)
561     {
562     Rectangle rectTabStrip = GetLogicalTabStripRectangle(state, true);
563     if (!rectTabStrip.Contains(ptMouse))
564     continue;
565 william 140
566 william 638 foreach (Pane pane in GetPanes(state))
567 william 140 {
568 william 638 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 william 140 }
575     }
576 william 638
577     return null;
578 william 140 }
579 william 638 catch (Exception)
580     {
581     throw;
582     }
583 william 140 }
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     }