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: 638
Committed: Sat Jun 8 20:21:53 2013 UTC (10 years, 3 months ago) by william
File size: 21909 byte(s)
Log Message:
+ throw exceptions in VS2005AutoHideStrip - to locate a drawing issue with AutoHide tabs, crashing main form

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     g.FillPath(new LinearGradientBrush(rectTabOrigin, startColor, endColor, gradientMode), path);
365     g.DrawPath(PenTabBorder, path);
366 william 140
367 william 638 // Set no rotate for drawing icon and text
368     Matrix matrixRotate = g.Transform;
369     g.Transform = MatrixIdentity;
370 william 140
371 william 638 // Draw the icon
372     Rectangle rectImage = rectTabOrigin;
373     rectImage.X += ImageGapLeft;
374     rectImage.Y += ImageGapTop;
375     int imageHeight = rectTabOrigin.Height - ImageGapTop - ImageGapBottom;
376     int imageWidth = ImageWidth;
377     if (imageHeight > ImageHeight)
378     imageWidth = ImageWidth * (imageHeight / ImageHeight);
379     rectImage.Height = imageHeight;
380     rectImage.Width = imageWidth;
381     rectImage = GetTransformedRectangle(dockState, rectImage);
382 william 140
383 william 638 if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
384     {
385     // The DockState is DockLeftAutoHide or DockRightAutoHide, so rotate the image 90 degrees to the right.
386     Rectangle rectTransform = RtlTransform(rectImage, dockState);
387     Point[] rotationPoints =
388 william 140 {
389     new Point(rectTransform.X + rectTransform.Width, rectTransform.Y),
390     new Point(rectTransform.X + rectTransform.Width, rectTransform.Y + rectTransform.Height),
391     new Point(rectTransform.X, rectTransform.Y)
392     };
393    
394 william 638 using (Icon rotatedIcon = new Icon(((Form)content).Icon, 16, 16))
395     {
396     g.DrawImage(rotatedIcon.ToBitmap(), rotationPoints);
397     }
398     }
399     else
400 william 140 {
401 william 638 // Draw the icon normally without any rotation.
402     g.DrawIcon(((Form)content).Icon, RtlTransform(rectImage, dockState));
403 william 140 }
404    
405 william 638 // Draw the text
406     Rectangle rectText = rectTabOrigin;
407     rectText.X += ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
408     rectText.Width -= ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
409     rectText = RtlTransform(GetTransformedRectangle(dockState, rectText), dockState);
410 william 140
411 william 638 Color textColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.TextColor;
412 william 140
413 william 638 if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
414     g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabVertical);
415     else
416     g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabHorizontal);
417 william 140
418 william 638 // Set rotate back
419     g.Transform = matrixRotate;
420     }
421     catch (Exception)
422     {
423     throw;
424     }
425 william 140 }
426    
427     private Rectangle GetLogicalTabStripRectangle(DockState dockState)
428     {
429     return GetLogicalTabStripRectangle(dockState, false);
430     }
431    
432     private Rectangle GetLogicalTabStripRectangle(DockState dockState, bool transformed)
433     {
434 william 638 try
435     {
436     if (!DockHelper.IsDockStateAutoHide(dockState))
437     return Rectangle.Empty;
438 william 140
439 william 638 int leftPanes = GetPanes(DockState.DockLeftAutoHide).Count;
440     int rightPanes = GetPanes(DockState.DockRightAutoHide).Count;
441     int topPanes = GetPanes(DockState.DockTopAutoHide).Count;
442     int bottomPanes = GetPanes(DockState.DockBottomAutoHide).Count;
443 william 140
444 william 638 int x, y, width, height;
445 william 140
446 william 638 height = MeasureHeight();
447     if (dockState == DockState.DockLeftAutoHide && leftPanes > 0)
448     {
449     x = 0;
450     y = (topPanes == 0) ? 0 : height;
451     width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
452     }
453     else if (dockState == DockState.DockRightAutoHide && rightPanes > 0)
454     {
455     x = Width - height;
456     if (leftPanes != 0 && x < height)
457     x = height;
458     y = (topPanes == 0) ? 0 : height;
459     width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
460     }
461     else if (dockState == DockState.DockTopAutoHide && topPanes > 0)
462     {
463     x = leftPanes == 0 ? 0 : height;
464     y = 0;
465     width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
466     }
467     else if (dockState == DockState.DockBottomAutoHide && bottomPanes > 0)
468     {
469     x = leftPanes == 0 ? 0 : height;
470     y = Height - height;
471     if (topPanes != 0 && y < height)
472     y = height;
473     width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
474     }
475     else
476     return Rectangle.Empty;
477    
478     if (!transformed)
479     return new Rectangle(x, y, width, height);
480     else
481     return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
482 william 140 }
483 william 638 catch (Exception)
484 william 140 {
485 william 638 throw;
486 william 140 }
487     }
488    
489     private Rectangle GetTabRectangle(TabVS2005 tab)
490     {
491     return GetTabRectangle(tab, false);
492     }
493    
494     private Rectangle GetTabRectangle(TabVS2005 tab, bool transformed)
495     {
496 william 638 try
497     {
498     DockState dockState = tab.Content.DockHandler.DockState;
499     Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
500 william 140
501 william 638 if (rectTabStrip.IsEmpty)
502     return Rectangle.Empty;
503 william 140
504 william 638 int x = tab.TabX;
505     int y = rectTabStrip.Y +
506     (dockState == DockState.DockTopAutoHide || dockState == DockState.DockRightAutoHide ?
507     0 : TabGapTop);
508     int width = tab.TabWidth;
509     int height = rectTabStrip.Height - TabGapTop;
510 william 140
511 william 638 if (!transformed)
512     return new Rectangle(x, y, width, height);
513     else
514     return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
515     }
516     catch (Exception)
517     {
518     throw;
519     }
520 william 140 }
521    
522     private Rectangle GetTransformedRectangle(DockState dockState, Rectangle rect)
523     {
524 william 638 try
525     {
526     if (dockState != DockState.DockLeftAutoHide && dockState != DockState.DockRightAutoHide)
527     return rect;
528 william 140
529 william 638 PointF[] pts = new PointF[1];
530     // the center of the rectangle
531     pts[0].X = (float)rect.X + (float)rect.Width / 2;
532     pts[0].Y = (float)rect.Y + (float)rect.Height / 2;
533     Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
534     Matrix matrix = new Matrix();
535     matrix.RotateAt(90, new PointF((float)rectTabStrip.X + (float)rectTabStrip.Height / 2,
536     (float)rectTabStrip.Y + (float)rectTabStrip.Height / 2));
537     matrix.TransformPoints(pts);
538 william 140
539 william 638 return new Rectangle((int)(pts[0].X - (float)rect.Height / 2 + .5F),
540     (int)(pts[0].Y - (float)rect.Width / 2 + .5F),
541     rect.Height, rect.Width);
542     }
543     catch (Exception)
544     {
545     throw;
546     }
547 william 140 }
548    
549     protected override IDockContent HitTest(Point ptMouse)
550     {
551 william 638 try
552 william 140 {
553 william 638 foreach (DockState state in DockStates)
554     {
555     Rectangle rectTabStrip = GetLogicalTabStripRectangle(state, true);
556     if (!rectTabStrip.Contains(ptMouse))
557     continue;
558 william 140
559 william 638 foreach (Pane pane in GetPanes(state))
560 william 140 {
561 william 638 foreach (TabVS2005 tab in pane.AutoHideTabs)
562     {
563     GraphicsPath path = GetTabOutline(tab, true, true);
564     if (path.IsVisible(ptMouse))
565     return tab.Content;
566     }
567 william 140 }
568     }
569 william 638
570     return null;
571 william 140 }
572 william 638 catch (Exception)
573     {
574     throw;
575     }
576 william 140 }
577    
578     protected internal override int MeasureHeight()
579     {
580     return Math.Max(ImageGapBottom +
581     ImageGapTop + ImageHeight,
582     TextFont.Height) + TabGapTop;
583     }
584    
585     protected override void OnRefreshChanges()
586     {
587     CalculateTabs();
588     Invalidate();
589     }
590    
591     protected override AutoHideStripBase.Tab CreateTab(IDockContent content)
592     {
593     return new TabVS2005(content);
594     }
595     }
596     }