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 (9 years 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

# 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 g.FillPath(new LinearGradientBrush(rectTabOrigin, startColor, endColor, gradientMode), path);
365 g.DrawPath(PenTabBorder, path);
366
367 // Set no rotate for drawing icon and text
368 Matrix matrixRotate = g.Transform;
369 g.Transform = MatrixIdentity;
370
371 // 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
383 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 {
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 using (Icon rotatedIcon = new Icon(((Form)content).Icon, 16, 16))
395 {
396 g.DrawImage(rotatedIcon.ToBitmap(), rotationPoints);
397 }
398 }
399 else
400 {
401 // Draw the icon normally without any rotation.
402 g.DrawIcon(((Form)content).Icon, RtlTransform(rectImage, dockState));
403 }
404
405 // 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
411 Color textColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.TextColor;
412
413 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
418 // Set rotate back
419 g.Transform = matrixRotate;
420 }
421 catch (Exception)
422 {
423 throw;
424 }
425 }
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 try
435 {
436 if (!DockHelper.IsDockStateAutoHide(dockState))
437 return Rectangle.Empty;
438
439 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
444 int x, y, width, height;
445
446 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 }
483 catch (Exception)
484 {
485 throw;
486 }
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 try
497 {
498 DockState dockState = tab.Content.DockHandler.DockState;
499 Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
500
501 if (rectTabStrip.IsEmpty)
502 return Rectangle.Empty;
503
504 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
511 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 }
521
522 private Rectangle GetTransformedRectangle(DockState dockState, Rectangle rect)
523 {
524 try
525 {
526 if (dockState != DockState.DockLeftAutoHide && dockState != DockState.DockRightAutoHide)
527 return rect;
528
529 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
539 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 }
548
549 protected override IDockContent HitTest(Point ptMouse)
550 {
551 try
552 {
553 foreach (DockState state in DockStates)
554 {
555 Rectangle rectTabStrip = GetLogicalTabStripRectangle(state, true);
556 if (!rectTabStrip.Contains(ptMouse))
557 continue;
558
559 foreach (Pane pane in GetPanes(state))
560 {
561 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 }
568 }
569
570 return null;
571 }
572 catch (Exception)
573 {
574 throw;
575 }
576 }
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 }