Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.7.0/WinFormsUI-2.7.0/Docking/VS2005AutoHideStrip.cs @ 18190

Last change on this file since 18190 was 8616, checked in by mkommend, 12 years ago

#1939: Added DockPanelSuite 2.7.0 to ExtLibs.

File size: 19.3 KB
Line 
1using System;
2using System.Drawing;
3using System.Windows.Forms;
4using System.Drawing.Drawing2D;
5using System.ComponentModel;
6
7namespace 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            Graphics g = e.Graphics;
206
207            Color startColor = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.StartColor;
208            Color endColor = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.EndColor;
209            LinearGradientMode gradientMode = DockPanel.Skin.AutoHideStripSkin.DockStripGradient.LinearGradientMode;
210            using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, startColor, endColor, gradientMode))
211            {
212                g.FillRectangle(brush, ClientRectangle);
213            }
214
215            DrawTabStrip(g);
216        }
217
218        protected override void OnLayout(LayoutEventArgs levent)
219        {
220            CalculateTabs();
221            base.OnLayout(levent);
222        }
223
224        private void DrawTabStrip(Graphics g)
225        {
226            DrawTabStrip(g, DockState.DockTopAutoHide);
227            DrawTabStrip(g, DockState.DockBottomAutoHide);
228            DrawTabStrip(g, DockState.DockLeftAutoHide);
229            DrawTabStrip(g, DockState.DockRightAutoHide);
230        }
231
232        private void DrawTabStrip(Graphics g, DockState dockState)
233        {
234            Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
235
236            if (rectTabStrip.IsEmpty)
237                return;
238
239            Matrix matrixIdentity = g.Transform;
240            if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
241            {
242                Matrix matrixRotated = new Matrix();
243                matrixRotated.RotateAt(90, new PointF((float)rectTabStrip.X + (float)rectTabStrip.Height / 2,
244                    (float)rectTabStrip.Y + (float)rectTabStrip.Height / 2));
245                g.Transform = matrixRotated;
246            }
247
248            foreach (Pane pane in GetPanes(dockState))
249            {
250                foreach (TabVS2005 tab in pane.AutoHideTabs)
251                    DrawTab(g, tab);
252            }
253            g.Transform = matrixIdentity;
254        }
255
256        private void CalculateTabs()
257        {
258            CalculateTabs(DockState.DockTopAutoHide);
259            CalculateTabs(DockState.DockBottomAutoHide);
260            CalculateTabs(DockState.DockLeftAutoHide);
261            CalculateTabs(DockState.DockRightAutoHide);
262        }
263
264        private void CalculateTabs(DockState dockState)
265        {
266            Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
267
268            int imageHeight = rectTabStrip.Height - ImageGapTop - ImageGapBottom;
269            int imageWidth = ImageWidth;
270            if (imageHeight > ImageHeight)
271                imageWidth = ImageWidth * (imageHeight / ImageHeight);
272
273            int x = TabGapLeft + rectTabStrip.X;
274            foreach (Pane pane in GetPanes(dockState))
275            {
276                foreach (TabVS2005 tab in pane.AutoHideTabs)
277                {
278                    int width = imageWidth + ImageGapLeft + ImageGapRight +
279                        TextRenderer.MeasureText(tab.Content.DockHandler.TabText, TextFont).Width +
280                        TextGapLeft + TextGapRight;
281                    tab.TabX = x;
282                    tab.TabWidth = width;
283                    x += width;
284                }
285
286                x += TabGapBetween;
287            }
288        }
289
290        private Rectangle RtlTransform(Rectangle rect, DockState dockState)
291        {
292            Rectangle rectTransformed;
293            if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
294                rectTransformed = rect;
295            else
296                rectTransformed = DrawHelper.RtlTransform(this, rect);
297
298            return rectTransformed;
299        }
300
301        private GraphicsPath GetTabOutline(TabVS2005 tab, bool transformed, bool rtlTransform)
302        {
303            DockState dockState = tab.Content.DockHandler.DockState;
304            Rectangle rectTab = GetTabRectangle(tab, transformed);
305            if (rtlTransform)
306                rectTab = RtlTransform(rectTab, dockState);
307            bool upTab = (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockBottomAutoHide);
308            DrawHelper.GetRoundedCornerTab(GraphicsPath, rectTab, upTab);
309
310            return GraphicsPath;
311        }
312
313        private void DrawTab(Graphics g, TabVS2005 tab)
314        {
315            Rectangle rectTabOrigin = GetTabRectangle(tab);
316            if (rectTabOrigin.IsEmpty)
317                return;
318
319            DockState dockState = tab.Content.DockHandler.DockState;
320            IDockContent content = tab.Content;
321
322            GraphicsPath path = GetTabOutline(tab, false, true);
323
324            Color startColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.StartColor;
325            Color endColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.EndColor;
326            LinearGradientMode gradientMode = DockPanel.Skin.AutoHideStripSkin.TabGradient.LinearGradientMode;
327            g.FillPath(new LinearGradientBrush(rectTabOrigin, startColor, endColor, gradientMode), path);
328            g.DrawPath(PenTabBorder, path);
329
330            // Set no rotate for drawing icon and text
331            Matrix matrixRotate = g.Transform;
332            g.Transform = MatrixIdentity;
333
334            // Draw the icon
335            Rectangle rectImage = rectTabOrigin;
336            rectImage.X += ImageGapLeft;
337            rectImage.Y += ImageGapTop;
338            int imageHeight = rectTabOrigin.Height - ImageGapTop - ImageGapBottom;
339            int imageWidth = ImageWidth;
340            if (imageHeight > ImageHeight)
341                imageWidth = ImageWidth * (imageHeight / ImageHeight);
342            rectImage.Height = imageHeight;
343            rectImage.Width = imageWidth;
344            rectImage = GetTransformedRectangle(dockState, rectImage);
345
346            if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
347            {
348                // The DockState is DockLeftAutoHide or DockRightAutoHide, so rotate the image 90 degrees to the right.
349                Rectangle rectTransform = RtlTransform(rectImage, dockState);
350                Point[] rotationPoints =
351                {
352                    new Point(rectTransform.X + rectTransform.Width, rectTransform.Y),
353                    new Point(rectTransform.X + rectTransform.Width, rectTransform.Y + rectTransform.Height),
354                    new Point(rectTransform.X, rectTransform.Y)
355                };
356
357                using (Icon rotatedIcon = new Icon(((Form)content).Icon, 16, 16))
358                {
359                    g.DrawImage(rotatedIcon.ToBitmap(), rotationPoints);
360                }
361            }
362            else
363            {
364                // Draw the icon normally without any rotation.
365                g.DrawIcon(((Form)content).Icon, RtlTransform(rectImage, dockState));
366            }
367
368            // Draw the text
369            Rectangle rectText = rectTabOrigin;
370            rectText.X += ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
371            rectText.Width -= ImageGapLeft + imageWidth + ImageGapRight + TextGapLeft;
372            rectText = RtlTransform(GetTransformedRectangle(dockState, rectText), dockState);
373
374            Color textColor = DockPanel.Skin.AutoHideStripSkin.TabGradient.TextColor;
375
376            if (dockState == DockState.DockLeftAutoHide || dockState == DockState.DockRightAutoHide)
377                g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabVertical);
378            else
379                g.DrawString(content.DockHandler.TabText, TextFont, new SolidBrush(textColor), rectText, StringFormatTabHorizontal);
380
381            // Set rotate back
382            g.Transform = matrixRotate;
383        }
384
385        private Rectangle GetLogicalTabStripRectangle(DockState dockState)
386        {
387            return GetLogicalTabStripRectangle(dockState, false);
388        }
389
390        private Rectangle GetLogicalTabStripRectangle(DockState dockState, bool transformed)
391        {
392            if (!DockHelper.IsDockStateAutoHide(dockState))
393                return Rectangle.Empty;
394
395            int leftPanes = GetPanes(DockState.DockLeftAutoHide).Count;
396            int rightPanes = GetPanes(DockState.DockRightAutoHide).Count;
397            int topPanes = GetPanes(DockState.DockTopAutoHide).Count;
398            int bottomPanes = GetPanes(DockState.DockBottomAutoHide).Count;
399
400            int x, y, width, height;
401
402            height = MeasureHeight();
403            if (dockState == DockState.DockLeftAutoHide && leftPanes > 0)
404            {
405                x = 0;
406                y = (topPanes == 0) ? 0 : height;
407                width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
408            }
409            else if (dockState == DockState.DockRightAutoHide && rightPanes > 0)
410            {
411                x = Width - height;
412                if (leftPanes != 0 && x < height)
413                    x = height;
414                y = (topPanes == 0) ? 0 : height;
415                width = Height - (topPanes == 0 ? 0 : height) - (bottomPanes == 0 ? 0 : height);
416            }
417            else if (dockState == DockState.DockTopAutoHide && topPanes > 0)
418            {
419                x = leftPanes == 0 ? 0 : height;
420                y = 0;
421                width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
422            }
423            else if (dockState == DockState.DockBottomAutoHide && bottomPanes > 0)
424            {
425                x = leftPanes == 0 ? 0 : height;
426                y = Height - height;
427                if (topPanes != 0 && y < height)
428                    y = height;
429                width = Width - (leftPanes == 0 ? 0 : height) - (rightPanes == 0 ? 0 : height);
430            }
431            else
432                return Rectangle.Empty;
433
434            if (!transformed)
435                return new Rectangle(x, y, width, height);
436            else
437                return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
438        }
439
440        private Rectangle GetTabRectangle(TabVS2005 tab)
441        {
442            return GetTabRectangle(tab, false);
443        }
444
445        private Rectangle GetTabRectangle(TabVS2005 tab, bool transformed)
446        {
447            DockState dockState = tab.Content.DockHandler.DockState;
448            Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
449
450            if (rectTabStrip.IsEmpty)
451                return Rectangle.Empty;
452
453            int x = tab.TabX;
454            int y = rectTabStrip.Y +
455                (dockState == DockState.DockTopAutoHide || dockState == DockState.DockRightAutoHide ?
456                0 : TabGapTop);
457            int width = tab.TabWidth;
458            int height = rectTabStrip.Height - TabGapTop;
459
460            if (!transformed)
461                return new Rectangle(x, y, width, height);
462            else
463                return GetTransformedRectangle(dockState, new Rectangle(x, y, width, height));
464        }
465
466        private Rectangle GetTransformedRectangle(DockState dockState, Rectangle rect)
467        {
468            if (dockState != DockState.DockLeftAutoHide && dockState != DockState.DockRightAutoHide)
469                return rect;
470
471            PointF[] pts = new PointF[1];
472            // the center of the rectangle
473            pts[0].X = (float)rect.X + (float)rect.Width / 2;
474            pts[0].Y = (float)rect.Y + (float)rect.Height / 2;
475            Rectangle rectTabStrip = GetLogicalTabStripRectangle(dockState);
476            Matrix matrix = new Matrix();
477            matrix.RotateAt(90, new PointF((float)rectTabStrip.X + (float)rectTabStrip.Height / 2,
478                (float)rectTabStrip.Y + (float)rectTabStrip.Height / 2));
479            matrix.TransformPoints(pts);
480
481            return new Rectangle((int)(pts[0].X - (float)rect.Height / 2 + .5F),
482                (int)(pts[0].Y - (float)rect.Width / 2 + .5F),
483                rect.Height, rect.Width);
484        }
485
486        protected override IDockContent HitTest(Point ptMouse)
487        {
488            foreach (DockState state in DockStates)
489            {
490                Rectangle rectTabStrip = GetLogicalTabStripRectangle(state, true);
491                if (!rectTabStrip.Contains(ptMouse))
492                    continue;
493
494                foreach (Pane pane in GetPanes(state))
495                {
496                    foreach (TabVS2005 tab in pane.AutoHideTabs)
497                    {
498                        GraphicsPath path = GetTabOutline(tab, true, true);
499                        if (path.IsVisible(ptMouse))
500                            return tab.Content;
501                    }
502                }
503            }
504
505            return null;
506        }
507
508        protected internal override int MeasureHeight()
509        {
510            return Math.Max(ImageGapBottom +
511                ImageGapTop + ImageHeight,
512                TextFont.Height) + TabGapTop;
513        }
514
515        protected override void OnRefreshChanges()
516        {
517            CalculateTabs();
518            Invalidate();
519        }
520
521        protected override AutoHideStripBase.Tab CreateTab(IDockContent content)
522        {
523            return new TabVS2005(content);
524        }
525    }
526}
Note: See TracBrowser for help on using the repository browser.