Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.7.0/WinFormsUI-2.7.0/Docking/VS2005DockPaneStrip.cs @ 9416

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

#1939: Added DockPanelSuite 2.7.0 to ExtLibs.

File size: 57.6 KB
Line 
1using System;
2using System.Drawing;
3using System.Drawing.Drawing2D;
4using System.Windows.Forms;
5using System.ComponentModel;
6using System.Collections;
7using System.Collections.Generic;
8
9namespace WeifenLuo.WinFormsUI.Docking
10{
11    internal class VS2005DockPaneStrip : DockPaneStripBase
12    {
13        private class TabVS2005 : Tab
14        {
15            public TabVS2005(IDockContent content)
16                : base(content)
17            {
18            }
19
20            private int m_tabX;
21            public int TabX
22            {
23                get { return m_tabX; }
24                set { m_tabX = value; }
25            }
26
27            private int m_tabWidth;
28            public int TabWidth
29            {
30                get { return m_tabWidth; }
31                set { m_tabWidth = value; }
32            }
33
34            private int m_maxWidth;
35            public int MaxWidth
36            {
37                get { return m_maxWidth; }
38                set { m_maxWidth = value; }
39            }
40
41            private bool m_flag;
42            protected internal bool Flag
43            {
44                get { return m_flag; }
45                set { m_flag = value; }
46            }
47        }
48
49        protected internal override DockPaneStripBase.Tab CreateTab(IDockContent content)
50        {
51            return new TabVS2005(content);
52        }
53
54        private sealed class InertButton : InertButtonBase
55        {
56            private Bitmap m_image0, m_image1;
57
58            public InertButton(Bitmap image0, Bitmap image1)
59                : base()
60            {
61                m_image0 = image0;
62                m_image1 = image1;
63            }
64
65            private int m_imageCategory = 0;
66            public int ImageCategory
67            {
68                get { return m_imageCategory; }
69                set
70                {
71                    if (m_imageCategory == value)
72                        return;
73
74                    m_imageCategory = value;
75                    Invalidate();
76                }
77            }
78
79            public override Bitmap Image
80            {
81                get { return ImageCategory == 0 ? m_image0 : m_image1; }
82            }
83        }
84
85        #region Constants
86
87        private const int _ToolWindowStripGapTop = 0;
88        private const int _ToolWindowStripGapBottom = 1;
89        private const int _ToolWindowStripGapLeft = 0;
90        private const int _ToolWindowStripGapRight = 0;
91        private const int _ToolWindowImageHeight = 16;
92        private const int _ToolWindowImageWidth = 16;
93        private const int _ToolWindowImageGapTop = 3;
94        private const int _ToolWindowImageGapBottom = 1;
95        private const int _ToolWindowImageGapLeft = 2;
96        private const int _ToolWindowImageGapRight = 0;
97        private const int _ToolWindowTextGapRight = 3;
98        private const int _ToolWindowTabSeperatorGapTop = 3;
99        private const int _ToolWindowTabSeperatorGapBottom = 3;
100
101        private const int _DocumentStripGapTop = 0;
102        private const int _DocumentStripGapBottom = 1;
103        private const int _DocumentTabMaxWidth = 200;
104        private const int _DocumentButtonGapTop = 4;
105        private const int _DocumentButtonGapBottom = 4;
106        private const int _DocumentButtonGapBetween = 0;
107        private const int _DocumentButtonGapRight = 3;
108        private const int _DocumentTabGapTop = 3;
109        private const int _DocumentTabGapLeft = 3;
110        private const int _DocumentTabGapRight = 3;
111        private const int _DocumentIconGapBottom = 2;
112        private const int _DocumentIconGapLeft = 8;
113        private const int _DocumentIconGapRight = 0;
114        private const int _DocumentIconHeight = 16;
115        private const int _DocumentIconWidth = 16;
116        private const int _DocumentTextGapRight = 3;
117
118        #endregion
119
120        #region Members
121
122        private ContextMenuStrip m_selectMenu;
123        private static Bitmap m_imageButtonClose;
124        private InertButton m_buttonClose;
125        private static Bitmap m_imageButtonWindowList;
126        private static Bitmap m_imageButtonWindowListOverflow;
127        private InertButton m_buttonWindowList;
128        private IContainer m_components;
129        private ToolTip m_toolTip;
130        private Font m_font;
131        private Font m_boldFont;
132        private int m_startDisplayingTab = 0;
133        private int m_endDisplayingTab = 0;
134        private int m_firstDisplayingTab = 0;
135        private bool m_documentTabsOverflow = false;
136        private static string m_toolTipSelect;
137        private static string m_toolTipClose;
138        private bool m_closeButtonVisible = false;
139
140        #endregion
141
142        #region Properties
143
144        private Rectangle TabStripRectangle
145        {
146            get
147            {
148                if (Appearance == DockPane.AppearanceStyle.Document)
149                    return TabStripRectangle_Document;
150                else
151                    return TabStripRectangle_ToolWindow;
152            }
153        }
154
155        private Rectangle TabStripRectangle_ToolWindow
156        {
157            get
158            {
159                Rectangle rect = ClientRectangle;
160                return new Rectangle(rect.X, rect.Top + ToolWindowStripGapTop, rect.Width, rect.Height - ToolWindowStripGapTop - ToolWindowStripGapBottom);
161            }
162        }
163
164        private Rectangle TabStripRectangle_Document
165        {
166            get
167            {
168                Rectangle rect = ClientRectangle;
169                return new Rectangle(rect.X, rect.Top + DocumentStripGapTop, rect.Width, rect.Height - DocumentStripGapTop - ToolWindowStripGapBottom);
170            }
171        }
172
173        private Rectangle TabsRectangle
174        {
175            get
176            {
177                if (Appearance == DockPane.AppearanceStyle.ToolWindow)
178                    return TabStripRectangle;
179
180                Rectangle rectWindow = TabStripRectangle;
181                int x = rectWindow.X;
182                int y = rectWindow.Y;
183                int width = rectWindow.Width;
184                int height = rectWindow.Height;
185
186                x += DocumentTabGapLeft;
187                width -= DocumentTabGapLeft +
188                    DocumentTabGapRight +
189                    DocumentButtonGapRight +
190                    ButtonClose.Width +
191                    ButtonWindowList.Width +
192                    2 * DocumentButtonGapBetween;
193
194                return new Rectangle(x, y, width, height);
195            }
196        }
197
198        private ContextMenuStrip SelectMenu
199        {
200            get { return m_selectMenu; }
201        }
202
203        private static Bitmap ImageButtonClose
204        {
205            get
206            {
207                if (m_imageButtonClose == null)
208                    m_imageButtonClose = Resources.DockPane_Close;
209
210                return m_imageButtonClose;
211            }
212        }
213
214        private InertButton ButtonClose
215        {
216            get
217            {
218                if (m_buttonClose == null)
219                {
220                    m_buttonClose = new InertButton(ImageButtonClose, ImageButtonClose);
221                    m_toolTip.SetToolTip(m_buttonClose, ToolTipClose);
222                    m_buttonClose.Click += new EventHandler(Close_Click);
223                    Controls.Add(m_buttonClose);
224                }
225
226                return m_buttonClose;
227            }
228        }
229
230        private static Bitmap ImageButtonWindowList
231        {
232            get
233            {
234                if (m_imageButtonWindowList == null)
235                    m_imageButtonWindowList = Resources.DockPane_Option;
236
237                return m_imageButtonWindowList;
238            }
239        }
240
241        private static Bitmap ImageButtonWindowListOverflow
242        {
243            get
244            {
245                if (m_imageButtonWindowListOverflow == null)
246                    m_imageButtonWindowListOverflow = Resources.DockPane_OptionOverflow;
247
248                return m_imageButtonWindowListOverflow;
249            }
250        }
251
252        private InertButton ButtonWindowList
253        {
254            get
255            {
256                if (m_buttonWindowList == null)
257                {
258                    m_buttonWindowList = new InertButton(ImageButtonWindowList, ImageButtonWindowListOverflow);
259                    m_toolTip.SetToolTip(m_buttonWindowList, ToolTipSelect);
260                    m_buttonWindowList.Click += new EventHandler(WindowList_Click);
261                    Controls.Add(m_buttonWindowList);
262                }
263
264                return m_buttonWindowList;
265            }
266        }
267
268        private static GraphicsPath GraphicsPath
269        {
270            get { return VS2005AutoHideStrip.GraphicsPath; }
271        }
272
273        private IContainer Components
274        {
275            get { return m_components; }
276        }
277
278        public Font TextFont
279        {
280            get { return DockPane.DockPanel.Skin.DockPaneStripSkin.TextFont; }
281        }
282
283        private Font BoldFont
284        {
285            get
286            {
287                if (IsDisposed)
288                    return null;
289
290                if (m_boldFont == null)
291                {
292                    m_font = TextFont;
293                    m_boldFont = new Font(TextFont, FontStyle.Bold);
294                }
295                else if (m_font != TextFont)
296                {
297                    m_boldFont.Dispose();
298                    m_font = TextFont;
299                    m_boldFont = new Font(TextFont, FontStyle.Bold);
300                }
301
302                return m_boldFont;
303            }
304        }
305
306        private int StartDisplayingTab
307        {
308            get { return m_startDisplayingTab; }
309            set
310            {
311                m_startDisplayingTab = value;
312                Invalidate();
313            }
314        }
315
316        private int EndDisplayingTab
317        {
318            get { return m_endDisplayingTab; }
319            set { m_endDisplayingTab = value; }
320        }
321
322        private int FirstDisplayingTab
323        {
324            get { return m_firstDisplayingTab; }
325            set { m_firstDisplayingTab = value; }
326        }
327
328        private bool DocumentTabsOverflow
329        {
330            set
331            {
332                if (m_documentTabsOverflow == value)
333                    return;
334
335                m_documentTabsOverflow = value;
336                if (value)
337                    ButtonWindowList.ImageCategory = 1;
338                else
339                    ButtonWindowList.ImageCategory = 0;
340            }
341        }
342
343        #region Customizable Properties
344
345        private static int ToolWindowStripGapTop
346        {
347            get { return _ToolWindowStripGapTop; }
348        }
349
350        private static int ToolWindowStripGapBottom
351        {
352            get { return _ToolWindowStripGapBottom; }
353        }
354
355        private static int ToolWindowStripGapLeft
356        {
357            get { return _ToolWindowStripGapLeft; }
358        }
359
360        private static int ToolWindowStripGapRight
361        {
362            get { return _ToolWindowStripGapRight; }
363        }
364
365        private static int ToolWindowImageHeight
366        {
367            get { return _ToolWindowImageHeight; }
368        }
369
370        private static int ToolWindowImageWidth
371        {
372            get { return _ToolWindowImageWidth; }
373        }
374
375        private static int ToolWindowImageGapTop
376        {
377            get { return _ToolWindowImageGapTop; }
378        }
379
380        private static int ToolWindowImageGapBottom
381        {
382            get { return _ToolWindowImageGapBottom; }
383        }
384
385        private static int ToolWindowImageGapLeft
386        {
387            get { return _ToolWindowImageGapLeft; }
388        }
389
390        private static int ToolWindowImageGapRight
391        {
392            get { return _ToolWindowImageGapRight; }
393        }
394
395        private static int ToolWindowTextGapRight
396        {
397            get { return _ToolWindowTextGapRight; }
398        }
399
400        private static int ToolWindowTabSeperatorGapTop
401        {
402            get { return _ToolWindowTabSeperatorGapTop; }
403        }
404
405        private static int ToolWindowTabSeperatorGapBottom
406        {
407            get { return _ToolWindowTabSeperatorGapBottom; }
408        }
409
410        private static string ToolTipClose
411        {
412            get
413            {
414                if (m_toolTipClose == null)
415                    m_toolTipClose = Strings.DockPaneStrip_ToolTipClose;
416                return m_toolTipClose;
417            }
418        }
419
420        private static string ToolTipSelect
421        {
422            get
423            {
424                if (m_toolTipSelect == null)
425                    m_toolTipSelect = Strings.DockPaneStrip_ToolTipWindowList;
426                return m_toolTipSelect;
427            }
428        }
429
430        private TextFormatFlags ToolWindowTextFormat
431        {
432            get
433            {
434                TextFormatFlags textFormat = TextFormatFlags.EndEllipsis |
435                    TextFormatFlags.HorizontalCenter |
436                    TextFormatFlags.SingleLine |
437                    TextFormatFlags.VerticalCenter;
438                if (RightToLeft == RightToLeft.Yes)
439                    return textFormat | TextFormatFlags.RightToLeft | TextFormatFlags.Right;
440                else
441                    return textFormat;
442            }
443        }
444
445        private static int DocumentStripGapTop
446        {
447            get { return _DocumentStripGapTop; }
448        }
449
450        private static int DocumentStripGapBottom
451        {
452            get { return _DocumentStripGapBottom; }
453        }
454
455        private TextFormatFlags DocumentTextFormat
456        {
457            get
458            {
459                TextFormatFlags textFormat = TextFormatFlags.EndEllipsis |
460                    TextFormatFlags.SingleLine |
461                    TextFormatFlags.VerticalCenter |
462                    TextFormatFlags.HorizontalCenter;
463                if (RightToLeft == RightToLeft.Yes)
464                    return textFormat | TextFormatFlags.RightToLeft;
465                else
466                    return textFormat;
467            }
468        }
469
470        private static int DocumentTabMaxWidth
471        {
472            get { return _DocumentTabMaxWidth; }
473        }
474
475        private static int DocumentButtonGapTop
476        {
477            get { return _DocumentButtonGapTop; }
478        }
479
480        private static int DocumentButtonGapBottom
481        {
482            get { return _DocumentButtonGapBottom; }
483        }
484
485        private static int DocumentButtonGapBetween
486        {
487            get { return _DocumentButtonGapBetween; }
488        }
489
490        private static int DocumentButtonGapRight
491        {
492            get { return _DocumentButtonGapRight; }
493        }
494
495        private static int DocumentTabGapTop
496        {
497            get { return _DocumentTabGapTop; }
498        }
499
500        private static int DocumentTabGapLeft
501        {
502            get { return _DocumentTabGapLeft; }
503        }
504
505        private static int DocumentTabGapRight
506        {
507            get { return _DocumentTabGapRight; }
508        }
509
510        private static int DocumentIconGapBottom
511        {
512            get { return _DocumentIconGapBottom; }
513        }
514
515        private static int DocumentIconGapLeft
516        {
517            get { return _DocumentIconGapLeft; }
518        }
519
520        private static int DocumentIconGapRight
521        {
522            get { return _DocumentIconGapRight; }
523        }
524
525        private static int DocumentIconWidth
526        {
527            get { return _DocumentIconWidth; }
528        }
529
530        private static int DocumentIconHeight
531        {
532            get { return _DocumentIconHeight; }
533        }
534
535        private static int DocumentTextGapRight
536        {
537            get { return _DocumentTextGapRight; }
538        }
539
540        private static Pen PenToolWindowTabBorder
541        {
542            get { return SystemPens.GrayText; }
543        }
544
545        private static Pen PenDocumentTabActiveBorder
546        {
547            get { return SystemPens.ControlDarkDark; }
548        }
549
550        private static Pen PenDocumentTabInactiveBorder
551        {
552            get { return SystemPens.GrayText; }
553        }
554
555        #endregion
556
557        #endregion
558
559        public VS2005DockPaneStrip(DockPane pane)
560            : base(pane)
561        {
562            SetStyle(ControlStyles.ResizeRedraw |
563                ControlStyles.UserPaint |
564                ControlStyles.AllPaintingInWmPaint |
565                ControlStyles.OptimizedDoubleBuffer, true);
566
567            SuspendLayout();
568
569            m_components = new Container();
570            m_toolTip = new ToolTip(Components);
571            m_selectMenu = new ContextMenuStrip(Components);
572
573            ResumeLayout();
574        }
575
576        protected override void Dispose(bool disposing)
577        {
578            if (disposing)
579            {
580                Components.Dispose();
581                if (m_boldFont != null)
582                {
583                    m_boldFont.Dispose();
584                    m_boldFont = null;
585                }
586            }
587            base.Dispose(disposing);
588        }
589
590        protected internal override int MeasureHeight()
591        {
592            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
593                return MeasureHeight_ToolWindow();
594            else
595                return MeasureHeight_Document();
596        }
597
598        private int MeasureHeight_ToolWindow()
599        {
600            if (DockPane.IsAutoHide || Tabs.Count <= 1)
601                return 0;
602
603            int height = Math.Max(TextFont.Height, ToolWindowImageHeight + ToolWindowImageGapTop + ToolWindowImageGapBottom)
604                + ToolWindowStripGapTop + ToolWindowStripGapBottom;
605
606            return height;
607        }
608
609        private int MeasureHeight_Document()
610        {
611            int height = Math.Max(TextFont.Height + DocumentTabGapTop,
612                ButtonClose.Height + DocumentButtonGapTop + DocumentButtonGapBottom)
613                + DocumentStripGapBottom + DocumentStripGapTop;
614
615            return height;
616        }
617
618        protected override void OnPaint(PaintEventArgs e)
619        {
620            Rectangle rect = TabsRectangle;
621
622            if (Appearance == DockPane.AppearanceStyle.Document)
623            {
624                rect.X -= DocumentTabGapLeft;
625
626                // Add these values back in so that the DockStrip color is drawn
627                // beneath the close button and window list button.
628                rect.Width += DocumentTabGapLeft +
629                    DocumentTabGapRight +
630                    DocumentButtonGapRight +
631                    ButtonClose.Width +
632                    ButtonWindowList.Width;
633
634                // It is possible depending on the DockPanel DocumentStyle to have
635                // a Document without a DockStrip.
636                if (rect.Width > 0 && rect.Height > 0)
637                {
638                    Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.StartColor;
639                    Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.EndColor;
640                    LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.DockStripGradient.LinearGradientMode;
641                    using (LinearGradientBrush brush = new LinearGradientBrush(rect, startColor, endColor, gradientMode))
642                    {
643                        e.Graphics.FillRectangle(brush, rect);
644                    }
645                }
646            }
647            else
648            {
649                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.StartColor;
650                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.EndColor;
651                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.DockStripGradient.LinearGradientMode;
652                using (LinearGradientBrush brush = new LinearGradientBrush(rect, startColor, endColor, gradientMode))
653                {
654                    e.Graphics.FillRectangle(brush, rect);
655                }
656            }
657            base.OnPaint(e);
658            CalculateTabs();
659            if (Appearance == DockPane.AppearanceStyle.Document && DockPane.ActiveContent != null)
660            {
661                if (EnsureDocumentTabVisible(DockPane.ActiveContent, false))
662                    CalculateTabs();
663            }
664
665            DrawTabStrip(e.Graphics);
666        }
667
668        protected override void OnRefreshChanges()
669        {
670            SetInertButtons();
671            Invalidate();
672        }
673
674        protected internal override GraphicsPath GetOutline(int index)
675        {
676
677            if (Appearance == DockPane.AppearanceStyle.Document)
678                return GetOutline_Document(index);
679            else
680                return GetOutline_ToolWindow(index);
681
682        }
683
684        private GraphicsPath GetOutline_Document(int index)
685        {
686            Rectangle rectTab = GetTabRectangle(index);
687            rectTab.X -= rectTab.Height / 2;
688            rectTab.Intersect(TabsRectangle);
689            rectTab = RectangleToScreen(DrawHelper.RtlTransform(this, rectTab));
690            Rectangle rectPaneClient = DockPane.RectangleToScreen(DockPane.ClientRectangle);
691
692            GraphicsPath path = new GraphicsPath();
693            GraphicsPath pathTab = GetTabOutline_Document(Tabs[index], true, true, true);
694            path.AddPath(pathTab, true);
695
696            if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
697            {
698                path.AddLine(rectTab.Right, rectTab.Top, rectPaneClient.Right, rectTab.Top);
699                path.AddLine(rectPaneClient.Right, rectTab.Top, rectPaneClient.Right, rectPaneClient.Top);
700                path.AddLine(rectPaneClient.Right, rectPaneClient.Top, rectPaneClient.Left, rectPaneClient.Top);
701                path.AddLine(rectPaneClient.Left, rectPaneClient.Top, rectPaneClient.Left, rectTab.Top);
702                path.AddLine(rectPaneClient.Left, rectTab.Top, rectTab.Right, rectTab.Top);
703            }
704            else
705            {
706                path.AddLine(rectTab.Right, rectTab.Bottom, rectPaneClient.Right, rectTab.Bottom);
707                path.AddLine(rectPaneClient.Right, rectTab.Bottom, rectPaneClient.Right, rectPaneClient.Bottom);
708                path.AddLine(rectPaneClient.Right, rectPaneClient.Bottom, rectPaneClient.Left, rectPaneClient.Bottom);
709                path.AddLine(rectPaneClient.Left, rectPaneClient.Bottom, rectPaneClient.Left, rectTab.Bottom);
710                path.AddLine(rectPaneClient.Left, rectTab.Bottom, rectTab.Right, rectTab.Bottom);
711            }
712            return path;
713        }
714
715        private GraphicsPath GetOutline_ToolWindow(int index)
716        {
717            Rectangle rectTab = GetTabRectangle(index);
718            rectTab.Intersect(TabsRectangle);
719            rectTab = RectangleToScreen(DrawHelper.RtlTransform(this, rectTab));
720            Rectangle rectPaneClient = DockPane.RectangleToScreen(DockPane.ClientRectangle);
721
722            GraphicsPath path = new GraphicsPath();
723            GraphicsPath pathTab = GetTabOutline(Tabs[index], true, true);
724            path.AddPath(pathTab, true);
725            path.AddLine(rectTab.Left, rectTab.Top, rectPaneClient.Left, rectTab.Top);
726            path.AddLine(rectPaneClient.Left, rectTab.Top, rectPaneClient.Left, rectPaneClient.Top);
727            path.AddLine(rectPaneClient.Left, rectPaneClient.Top, rectPaneClient.Right, rectPaneClient.Top);
728            path.AddLine(rectPaneClient.Right, rectPaneClient.Top, rectPaneClient.Right, rectTab.Top);
729            path.AddLine(rectPaneClient.Right, rectTab.Top, rectTab.Right, rectTab.Top);
730            return path;
731        }
732
733        private void CalculateTabs()
734        {
735            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
736                CalculateTabs_ToolWindow();
737            else
738                CalculateTabs_Document();
739        }
740
741        private void CalculateTabs_ToolWindow()
742        {
743            if (Tabs.Count <= 1 || DockPane.IsAutoHide)
744                return;
745
746            Rectangle rectTabStrip = TabStripRectangle;
747
748            // Calculate tab widths
749            int countTabs = Tabs.Count;
750            foreach (TabVS2005 tab in Tabs)
751            {
752                tab.MaxWidth = GetMaxTabWidth(Tabs.IndexOf(tab));
753                tab.Flag = false;
754            }
755
756            // Set tab whose max width less than average width
757            bool anyWidthWithinAverage = true;
758            int totalWidth = rectTabStrip.Width - ToolWindowStripGapLeft - ToolWindowStripGapRight;
759            int totalAllocatedWidth = 0;
760            int averageWidth = totalWidth / countTabs;
761            int remainedTabs = countTabs;
762            for (anyWidthWithinAverage = true; anyWidthWithinAverage && remainedTabs > 0; )
763            {
764                anyWidthWithinAverage = false;
765                foreach (TabVS2005 tab in Tabs)
766                {
767                    if (tab.Flag)
768                        continue;
769
770                    if (tab.MaxWidth <= averageWidth)
771                    {
772                        tab.Flag = true;
773                        tab.TabWidth = tab.MaxWidth;
774                        totalAllocatedWidth += tab.TabWidth;
775                        anyWidthWithinAverage = true;
776                        remainedTabs--;
777                    }
778                }
779                if (remainedTabs != 0)
780                    averageWidth = (totalWidth - totalAllocatedWidth) / remainedTabs;
781            }
782
783            // If any tab width not set yet, set it to the average width
784            if (remainedTabs > 0)
785            {
786                int roundUpWidth = (totalWidth - totalAllocatedWidth) - (averageWidth * remainedTabs);
787                foreach (TabVS2005 tab in Tabs)
788                {
789                    if (tab.Flag)
790                        continue;
791
792                    tab.Flag = true;
793                    if (roundUpWidth > 0)
794                    {
795                        tab.TabWidth = averageWidth + 1;
796                        roundUpWidth--;
797                    }
798                    else
799                        tab.TabWidth = averageWidth;
800                }
801            }
802
803            // Set the X position of the tabs
804            int x = rectTabStrip.X + ToolWindowStripGapLeft;
805            foreach (TabVS2005 tab in Tabs)
806            {
807                tab.TabX = x;
808                x += tab.TabWidth;
809            }
810        }
811
812        private bool CalculateDocumentTab(Rectangle rectTabStrip, ref int x, int index)
813        {
814            bool overflow = false;
815
816            TabVS2005 tab = Tabs[index] as TabVS2005;
817            tab.MaxWidth = GetMaxTabWidth(index);
818            int width = Math.Min(tab.MaxWidth, DocumentTabMaxWidth);
819            if (x + width < rectTabStrip.Right || index == StartDisplayingTab)
820            {
821                tab.TabX = x;
822                tab.TabWidth = width;
823                EndDisplayingTab = index;
824            }
825            else
826            {
827                tab.TabX = 0;
828                tab.TabWidth = 0;
829                overflow = true;
830            }
831            x += width;
832
833            return overflow;
834        }
835
836        /// <summary>
837        /// Calculate which tabs are displayed and in what order.
838        /// </summary>
839        private void CalculateTabs_Document()
840        {
841            if (m_startDisplayingTab >= Tabs.Count)
842                m_startDisplayingTab = 0;
843
844            Rectangle rectTabStrip = TabsRectangle;
845
846            int x = rectTabStrip.X + rectTabStrip.Height / 2;
847            bool overflow = false;
848
849            // Originally all new documents that were considered overflow
850            // (not enough pane strip space to show all tabs) were added to
851            // the far left (assuming not right to left) and the tabs on the
852            // right were dropped from view. If StartDisplayingTab is not 0
853            // then we are dealing with making sure a specific tab is kept in focus.
854            if (m_startDisplayingTab > 0)
855            {
856                int tempX = x;
857                TabVS2005 tab = Tabs[m_startDisplayingTab] as TabVS2005;
858                tab.MaxWidth = GetMaxTabWidth(m_startDisplayingTab);
859
860                // Add the active tab and tabs to the left
861                for (int i = StartDisplayingTab; i >= 0; i--)
862                    CalculateDocumentTab(rectTabStrip, ref tempX, i);
863
864                // Store which tab is the first one displayed so that it
865                // will be drawn correctly (without part of the tab cut off)
866                FirstDisplayingTab = EndDisplayingTab;
867
868                tempX = x; // Reset X location because we are starting over
869
870                // Start with the first tab displayed - name is a little misleading.
871                // Loop through each tab and set its location. If there is not enough
872                // room for all of them overflow will be returned.
873                for (int i = EndDisplayingTab; i < Tabs.Count; i++)
874                    overflow = CalculateDocumentTab(rectTabStrip, ref tempX, i);
875
876                // If not all tabs are shown then we have an overflow.
877                if (FirstDisplayingTab != 0)
878                    overflow = true;
879            }
880            else
881            {
882                for (int i = StartDisplayingTab; i < Tabs.Count; i++)
883                    overflow = CalculateDocumentTab(rectTabStrip, ref x, i);
884                for (int i = 0; i < StartDisplayingTab; i++)
885                    overflow = CalculateDocumentTab(rectTabStrip, ref x, i);
886
887                FirstDisplayingTab = StartDisplayingTab;
888            }
889
890            if (!overflow)
891            {
892                m_startDisplayingTab = 0;
893                FirstDisplayingTab = 0;
894                x = rectTabStrip.X + rectTabStrip.Height / 2;
895                foreach (TabVS2005 tab in Tabs)
896                {
897                    tab.TabX = x;
898                    x += tab.TabWidth;
899                }
900            }
901            DocumentTabsOverflow = overflow;
902        }
903
904        protected internal override void EnsureTabVisible(IDockContent content)
905        {
906            if (Appearance != DockPane.AppearanceStyle.Document || !Tabs.Contains(content))
907                return;
908
909            CalculateTabs();
910            EnsureDocumentTabVisible(content, true);
911        }
912
913        private bool EnsureDocumentTabVisible(IDockContent content, bool repaint)
914        {
915            int index = Tabs.IndexOf(content);
916            TabVS2005 tab = Tabs[index] as TabVS2005;
917            if (tab.TabWidth != 0)
918                return false;
919
920            StartDisplayingTab = index;
921            if (repaint)
922                Invalidate();
923
924            return true;
925        }
926
927        private int GetMaxTabWidth(int index)
928        {
929            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
930                return GetMaxTabWidth_ToolWindow(index);
931            else
932                return GetMaxTabWidth_Document(index);
933        }
934
935        private int GetMaxTabWidth_ToolWindow(int index)
936        {
937            IDockContent content = Tabs[index].Content;
938            Size sizeString = TextRenderer.MeasureText(content.DockHandler.TabText, TextFont);
939            return ToolWindowImageWidth + sizeString.Width + ToolWindowImageGapLeft
940                + ToolWindowImageGapRight + ToolWindowTextGapRight;
941        }
942
943        private int GetMaxTabWidth_Document(int index)
944        {
945            IDockContent content = Tabs[index].Content;
946
947            int height = GetTabRectangle_Document(index).Height;
948
949            Size sizeText = TextRenderer.MeasureText(content.DockHandler.TabText, BoldFont, new Size(DocumentTabMaxWidth, height), DocumentTextFormat);
950
951            if (DockPane.DockPanel.ShowDocumentIcon)
952                return sizeText.Width + DocumentIconWidth + DocumentIconGapLeft + DocumentIconGapRight + DocumentTextGapRight;
953            else
954                return sizeText.Width + DocumentIconGapLeft + DocumentTextGapRight;
955        }
956
957        private void DrawTabStrip(Graphics g)
958        {
959            if (Appearance == DockPane.AppearanceStyle.Document)
960                DrawTabStrip_Document(g);
961            else
962                DrawTabStrip_ToolWindow(g);
963        }
964
965        private void DrawTabStrip_Document(Graphics g)
966        {
967            int count = Tabs.Count;
968            if (count == 0)
969                return;
970
971            Rectangle rectTabStrip = TabStripRectangle;
972
973            // Draw the tabs
974            Rectangle rectTabOnly = TabsRectangle;
975            Rectangle rectTab = Rectangle.Empty;
976            TabVS2005 tabActive = null;
977            g.SetClip(DrawHelper.RtlTransform(this, rectTabOnly));
978            for (int i = 0; i < count; i++)
979            {
980                rectTab = GetTabRectangle(i);
981                if (Tabs[i].Content == DockPane.ActiveContent)
982                {
983                    tabActive = Tabs[i] as TabVS2005;
984                    continue;
985                }
986                if (rectTab.IntersectsWith(rectTabOnly))
987                    DrawTab(g, Tabs[i] as TabVS2005, rectTab);
988            }
989
990            g.SetClip(rectTabStrip);
991
992            if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
993                g.DrawLine(PenDocumentTabActiveBorder, rectTabStrip.Left, rectTabStrip.Top + 1,
994                    rectTabStrip.Right, rectTabStrip.Top + 1);
995            else
996                g.DrawLine(PenDocumentTabActiveBorder, rectTabStrip.Left, rectTabStrip.Bottom - 1,
997                    rectTabStrip.Right, rectTabStrip.Bottom - 1);
998
999            g.SetClip(DrawHelper.RtlTransform(this, rectTabOnly));
1000            if (tabActive != null)
1001            {
1002                rectTab = GetTabRectangle(Tabs.IndexOf(tabActive));
1003                if (rectTab.IntersectsWith(rectTabOnly))
1004                    DrawTab(g, tabActive, rectTab);
1005            }
1006        }
1007
1008        private void DrawTabStrip_ToolWindow(Graphics g)
1009        {
1010            Rectangle rectTabStrip = TabStripRectangle;
1011
1012            g.DrawLine(PenToolWindowTabBorder, rectTabStrip.Left, rectTabStrip.Top,
1013                rectTabStrip.Right, rectTabStrip.Top);
1014
1015            for (int i = 0; i < Tabs.Count; i++)
1016                DrawTab(g, Tabs[i] as TabVS2005, GetTabRectangle(i));
1017        }
1018
1019        private Rectangle GetTabRectangle(int index)
1020        {
1021            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
1022                return GetTabRectangle_ToolWindow(index);
1023            else
1024                return GetTabRectangle_Document(index);
1025        }
1026
1027        private Rectangle GetTabRectangle_ToolWindow(int index)
1028        {
1029            Rectangle rectTabStrip = TabStripRectangle;
1030
1031            TabVS2005 tab = (TabVS2005)(Tabs[index]);
1032            return new Rectangle(tab.TabX, rectTabStrip.Y, tab.TabWidth, rectTabStrip.Height);
1033        }
1034
1035        private Rectangle GetTabRectangle_Document(int index)
1036        {
1037            Rectangle rectTabStrip = TabStripRectangle;
1038            TabVS2005 tab = (TabVS2005)Tabs[index];
1039
1040            Rectangle rect = new Rectangle();
1041            rect.X = tab.TabX;
1042            rect.Width = tab.TabWidth;
1043            rect.Height = rectTabStrip.Height - DocumentTabGapTop;
1044
1045            if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1046                rect.Y = rectTabStrip.Y + DocumentStripGapBottom;
1047            else
1048                rect.Y = rectTabStrip.Y + DocumentTabGapTop;
1049
1050            return rect;
1051        }
1052
1053        private void DrawTab(Graphics g, TabVS2005 tab, Rectangle rect)
1054        {
1055            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
1056                DrawTab_ToolWindow(g, tab, rect);
1057            else
1058                DrawTab_Document(g, tab, rect);
1059        }
1060
1061        private GraphicsPath GetTabOutline(Tab tab, bool rtlTransform, bool toScreen)
1062        {
1063            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
1064                return GetTabOutline_ToolWindow(tab, rtlTransform, toScreen);
1065            else
1066                return GetTabOutline_Document(tab, rtlTransform, toScreen, false);
1067        }
1068
1069        private GraphicsPath GetTabOutline_ToolWindow(Tab tab, bool rtlTransform, bool toScreen)
1070        {
1071            Rectangle rect = GetTabRectangle(Tabs.IndexOf(tab));
1072            if (rtlTransform)
1073                rect = DrawHelper.RtlTransform(this, rect);
1074            if (toScreen)
1075                rect = RectangleToScreen(rect);
1076
1077            DrawHelper.GetRoundedCornerTab(GraphicsPath, rect, false);
1078            return GraphicsPath;
1079        }
1080
1081        private GraphicsPath GetTabOutline_Document(Tab tab, bool rtlTransform, bool toScreen, bool full)
1082        {
1083            int curveSize = 6;
1084
1085            GraphicsPath.Reset();
1086            Rectangle rect = GetTabRectangle(Tabs.IndexOf(tab));
1087            if (rtlTransform)
1088                rect = DrawHelper.RtlTransform(this, rect);
1089            if (toScreen)
1090                rect = RectangleToScreen(rect);
1091
1092            // Draws the full angle piece for active content (or first tab)
1093            if (tab.Content == DockPane.ActiveContent || full || Tabs.IndexOf(tab) == FirstDisplayingTab)
1094            {
1095                if (RightToLeft == RightToLeft.Yes)
1096                {
1097                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1098                    {
1099                        // For some reason the next line draws a line that is not hidden like it is when drawing the tab strip on top.
1100                        // It is not needed so it has been commented out.
1101                        //GraphicsPath.AddLine(rect.Right, rect.Bottom, rect.Right + rect.Height / 2, rect.Bottom);
1102                        GraphicsPath.AddLine(rect.Right + rect.Height / 2, rect.Top, rect.Right - rect.Height / 2 + curveSize / 2, rect.Bottom - curveSize / 2);
1103                    }
1104                    else
1105                    {
1106                        GraphicsPath.AddLine(rect.Right, rect.Bottom, rect.Right + rect.Height / 2, rect.Bottom);
1107                        GraphicsPath.AddLine(rect.Right + rect.Height / 2, rect.Bottom, rect.Right - rect.Height / 2 + curveSize / 2, rect.Top + curveSize / 2);
1108                    }
1109                }
1110                else
1111                {
1112                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1113                    {
1114                        // For some reason the next line draws a line that is not hidden like it is when drawing the tab strip on top.
1115                        // It is not needed so it has been commented out.
1116                        //GraphicsPath.AddLine(rect.Left, rect.Top, rect.Left - rect.Height / 2, rect.Top);
1117                        GraphicsPath.AddLine(rect.Left - rect.Height / 2, rect.Top, rect.Left + rect.Height / 2 - curveSize / 2, rect.Bottom - curveSize / 2);
1118                    }
1119                    else
1120                    {
1121                        GraphicsPath.AddLine(rect.Left, rect.Bottom, rect.Left - rect.Height / 2, rect.Bottom);
1122                        GraphicsPath.AddLine(rect.Left - rect.Height / 2, rect.Bottom, rect.Left + rect.Height / 2 - curveSize / 2, rect.Top + curveSize / 2);
1123                    }
1124                }
1125            }
1126            // Draws the partial angle for non-active content
1127            else
1128            {
1129                if (RightToLeft == RightToLeft.Yes)
1130                {
1131                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1132                    {
1133                        GraphicsPath.AddLine(rect.Right, rect.Top, rect.Right, rect.Top + rect.Height / 2);
1134                        GraphicsPath.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Right - rect.Height / 2 + curveSize / 2, rect.Bottom - curveSize / 2);
1135                    }
1136                    else
1137                    {
1138                        GraphicsPath.AddLine(rect.Right, rect.Bottom, rect.Right, rect.Bottom - rect.Height / 2);
1139                        GraphicsPath.AddLine(rect.Right, rect.Bottom - rect.Height / 2, rect.Right - rect.Height / 2 + curveSize / 2, rect.Top + curveSize / 2);
1140                    }
1141                }
1142                else
1143                {
1144                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1145                    {
1146                        GraphicsPath.AddLine(rect.Left, rect.Top, rect.Left, rect.Top + rect.Height / 2);
1147                        GraphicsPath.AddLine(rect.Left, rect.Top + rect.Height / 2, rect.Left + rect.Height / 2 - curveSize / 2, rect.Bottom - curveSize / 2);
1148                    }
1149                    else
1150                    {
1151                        GraphicsPath.AddLine(rect.Left, rect.Bottom, rect.Left, rect.Bottom - rect.Height / 2);
1152                        GraphicsPath.AddLine(rect.Left, rect.Bottom - rect.Height / 2, rect.Left + rect.Height / 2 - curveSize / 2, rect.Top + curveSize / 2);
1153                    }
1154                }
1155            }
1156
1157            if (RightToLeft == RightToLeft.Yes)
1158            {
1159                if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1160                {
1161                    // Draws the bottom horizontal line (short side)
1162                    GraphicsPath.AddLine(rect.Right - rect.Height / 2 - curveSize / 2, rect.Bottom, rect.Left + curveSize / 2, rect.Bottom);
1163
1164                    // Drawing the rounded corner is not necessary. The path is automatically connected
1165                    //GraphicsPath.AddArc(new Rectangle(rect.Left, rect.Top, curveSize, curveSize), 180, 90);
1166                }
1167                else
1168                {
1169                    // Draws the bottom horizontal line (short side)
1170                    GraphicsPath.AddLine(rect.Right - rect.Height / 2 - curveSize / 2, rect.Top, rect.Left + curveSize / 2, rect.Top);
1171                    GraphicsPath.AddArc(new Rectangle(rect.Left, rect.Top, curveSize, curveSize), 180, 90);
1172                }
1173            }
1174            else
1175            {
1176                if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1177                {
1178                    // Draws the bottom horizontal line (short side)
1179                    GraphicsPath.AddLine(rect.Left + rect.Height / 2 + curveSize / 2, rect.Bottom, rect.Right - curveSize / 2, rect.Bottom);
1180
1181                    // Drawing the rounded corner is not necessary. The path is automatically connected
1182                    //GraphicsPath.AddArc(new Rectangle(rect.Right - curveSize, rect.Bottom, curveSize, curveSize), 90, -90);
1183                }
1184                else
1185                {
1186                    // Draws the top horizontal line (short side)
1187                    GraphicsPath.AddLine(rect.Left + rect.Height / 2 + curveSize / 2, rect.Top, rect.Right - curveSize / 2, rect.Top);
1188
1189                    // Draws the rounded corner oppposite the angled side
1190                    GraphicsPath.AddArc(new Rectangle(rect.Right - curveSize, rect.Top, curveSize, curveSize), -90, 90);
1191                }
1192            }
1193
1194            if (Tabs.IndexOf(tab) != EndDisplayingTab &&
1195                (Tabs.IndexOf(tab) != Tabs.Count - 1 && Tabs[Tabs.IndexOf(tab) + 1].Content == DockPane.ActiveContent)
1196                && !full)
1197            {
1198                if (RightToLeft == RightToLeft.Yes)
1199                {
1200                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1201                    {
1202                        GraphicsPath.AddLine(rect.Left, rect.Bottom - curveSize / 2, rect.Left, rect.Bottom - rect.Height / 2);
1203                        GraphicsPath.AddLine(rect.Left, rect.Bottom - rect.Height / 2, rect.Left + rect.Height / 2, rect.Top);
1204                    }
1205                    else
1206                    {
1207                        GraphicsPath.AddLine(rect.Left, rect.Top + curveSize / 2, rect.Left, rect.Top + rect.Height / 2);
1208                        GraphicsPath.AddLine(rect.Left, rect.Top + rect.Height / 2, rect.Left + rect.Height / 2, rect.Bottom);
1209                    }
1210                }
1211                else
1212                {
1213                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1214                    {
1215                        GraphicsPath.AddLine(rect.Right, rect.Bottom - curveSize / 2, rect.Right, rect.Bottom - rect.Height / 2);
1216                        GraphicsPath.AddLine(rect.Right, rect.Bottom - rect.Height / 2, rect.Right - rect.Height / 2, rect.Top);
1217                    }
1218                    else
1219                    {
1220                        GraphicsPath.AddLine(rect.Right, rect.Top + curveSize / 2, rect.Right, rect.Top + rect.Height / 2);
1221                        GraphicsPath.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Right - rect.Height / 2, rect.Bottom);
1222                    }
1223                }
1224            }
1225            else
1226            {
1227                // Draw the vertical line opposite the angled side
1228                if (RightToLeft == RightToLeft.Yes)
1229                {
1230                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1231                        GraphicsPath.AddLine(rect.Left, rect.Bottom - curveSize / 2, rect.Left, rect.Top);
1232                    else
1233                        GraphicsPath.AddLine(rect.Left, rect.Top + curveSize / 2, rect.Left, rect.Bottom);
1234                }
1235                else
1236                {
1237                    if (DockPane.DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
1238                        GraphicsPath.AddLine(rect.Right, rect.Bottom - curveSize / 2, rect.Right, rect.Top);
1239                    else
1240                        GraphicsPath.AddLine(rect.Right, rect.Top + curveSize / 2, rect.Right, rect.Bottom);
1241                }
1242            }
1243
1244            return GraphicsPath;
1245        }
1246
1247        private void DrawTab_ToolWindow(Graphics g, TabVS2005 tab, Rectangle rect)
1248        {
1249            Rectangle rectIcon = new Rectangle(
1250                rect.X + ToolWindowImageGapLeft,
1251                rect.Y + rect.Height - 1 - ToolWindowImageGapBottom - ToolWindowImageHeight,
1252                ToolWindowImageWidth, ToolWindowImageHeight);
1253            Rectangle rectText = rectIcon;
1254            rectText.X += rectIcon.Width + ToolWindowImageGapRight;
1255            rectText.Width = rect.Width - rectIcon.Width - ToolWindowImageGapLeft -
1256                ToolWindowImageGapRight - ToolWindowTextGapRight;
1257
1258            Rectangle rectTab = DrawHelper.RtlTransform(this, rect);
1259            rectText = DrawHelper.RtlTransform(this, rectText);
1260            rectIcon = DrawHelper.RtlTransform(this, rectIcon);
1261            GraphicsPath path = GetTabOutline(tab, true, false);
1262            if (DockPane.ActiveContent == tab.Content)
1263            {
1264                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.StartColor;
1265                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.EndColor;
1266                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.LinearGradientMode;
1267                g.FillPath(new LinearGradientBrush(rectTab, startColor, endColor, gradientMode), path);
1268                g.DrawPath(PenToolWindowTabBorder, path);
1269
1270                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.ActiveTabGradient.TextColor;
1271                TextRenderer.DrawText(g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, ToolWindowTextFormat);
1272            }
1273            else
1274            {
1275                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.StartColor;
1276                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.EndColor;
1277                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.LinearGradientMode;
1278                g.FillPath(new LinearGradientBrush(rectTab, startColor, endColor, gradientMode), path);
1279
1280                if (Tabs.IndexOf(DockPane.ActiveContent) != Tabs.IndexOf(tab) + 1)
1281                {
1282                    Point pt1 = new Point(rect.Right, rect.Top + ToolWindowTabSeperatorGapTop);
1283                    Point pt2 = new Point(rect.Right, rect.Bottom - ToolWindowTabSeperatorGapBottom);
1284                    g.DrawLine(PenToolWindowTabBorder, DrawHelper.RtlTransform(this, pt1), DrawHelper.RtlTransform(this, pt2));
1285                }
1286
1287                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.ToolWindowGradient.InactiveTabGradient.TextColor;
1288                TextRenderer.DrawText(g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, ToolWindowTextFormat);
1289            }
1290
1291            if (rectTab.Contains(rectIcon))
1292                g.DrawIcon(tab.Content.DockHandler.Icon, rectIcon);
1293        }
1294
1295        private void DrawTab_Document(Graphics g, TabVS2005 tab, Rectangle rect)
1296        {
1297            if (tab.TabWidth == 0)
1298                return;
1299
1300            Rectangle rectIcon = new Rectangle(
1301                rect.X + DocumentIconGapLeft,
1302                rect.Y + rect.Height - 1 - DocumentIconGapBottom - DocumentIconHeight,
1303                DocumentIconWidth, DocumentIconHeight);
1304            Rectangle rectText = rectIcon;
1305            if (DockPane.DockPanel.ShowDocumentIcon)
1306            {
1307                rectText.X += rectIcon.Width + DocumentIconGapRight;
1308                rectText.Y = rect.Y;
1309                rectText.Width = rect.Width - rectIcon.Width - DocumentIconGapLeft -
1310                    DocumentIconGapRight - DocumentTextGapRight;
1311                rectText.Height = rect.Height;
1312            }
1313            else
1314                rectText.Width = rect.Width - DocumentIconGapLeft - DocumentTextGapRight;
1315
1316            Rectangle rectTab = DrawHelper.RtlTransform(this, rect);
1317            Rectangle rectBack = DrawHelper.RtlTransform(this, rect);
1318            rectBack.Width += rect.X;
1319            rectBack.X = 0;
1320
1321            rectText = DrawHelper.RtlTransform(this, rectText);
1322            rectIcon = DrawHelper.RtlTransform(this, rectIcon);
1323            GraphicsPath path = GetTabOutline(tab, true, false);
1324            if (DockPane.ActiveContent == tab.Content)
1325            {
1326                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.StartColor;
1327                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.EndColor;
1328                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.LinearGradientMode;
1329                g.FillPath(new LinearGradientBrush(rectBack, startColor, endColor, gradientMode), path);
1330                g.DrawPath(PenDocumentTabActiveBorder, path);
1331
1332                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.ActiveTabGradient.TextColor;
1333                if (DockPane.IsActiveDocumentPane)
1334                    TextRenderer.DrawText(g, tab.Content.DockHandler.TabText, BoldFont, rectText, textColor, DocumentTextFormat);
1335                else
1336                    TextRenderer.DrawText(g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, DocumentTextFormat);
1337            }
1338            else
1339            {
1340                Color startColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.StartColor;
1341                Color endColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.EndColor;
1342                LinearGradientMode gradientMode = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.LinearGradientMode;
1343                g.FillPath(new LinearGradientBrush(rectBack, startColor, endColor, gradientMode), path);
1344                g.DrawPath(PenDocumentTabInactiveBorder, path);
1345
1346                Color textColor = DockPane.DockPanel.Skin.DockPaneStripSkin.DocumentGradient.InactiveTabGradient.TextColor;
1347                TextRenderer.DrawText(g, tab.Content.DockHandler.TabText, TextFont, rectText, textColor, DocumentTextFormat);
1348            }
1349
1350            if (rectTab.Contains(rectIcon) && DockPane.DockPanel.ShowDocumentIcon)
1351                g.DrawIcon(tab.Content.DockHandler.Icon, rectIcon);
1352        }
1353
1354        private void WindowList_Click(object sender, EventArgs e)
1355        {
1356            int x = 0;
1357            int y = ButtonWindowList.Location.Y + ButtonWindowList.Height;
1358
1359            SelectMenu.Items.Clear();
1360            foreach (TabVS2005 tab in Tabs)
1361            {
1362                IDockContent content = tab.Content;
1363                ToolStripItem item = SelectMenu.Items.Add(content.DockHandler.TabText, content.DockHandler.Icon.ToBitmap());
1364                item.Tag = tab.Content;
1365                item.Click += new EventHandler(ContextMenuItem_Click);
1366            }
1367            SelectMenu.Show(ButtonWindowList, x, y);
1368        }
1369
1370        private void ContextMenuItem_Click(object sender, EventArgs e)
1371        {
1372            ToolStripMenuItem item = sender as ToolStripMenuItem;
1373            if (item != null)
1374            {
1375                IDockContent content = (IDockContent)item.Tag;
1376                DockPane.ActiveContent = content;
1377            }
1378        }
1379
1380        private void SetInertButtons()
1381        {
1382            if (Appearance == DockPane.AppearanceStyle.ToolWindow)
1383            {
1384                if (m_buttonClose != null)
1385                    m_buttonClose.Left = -m_buttonClose.Width;
1386
1387                if (m_buttonWindowList != null)
1388                    m_buttonWindowList.Left = -m_buttonWindowList.Width;
1389            }
1390            else
1391            {
1392                ButtonClose.Enabled = DockPane.ActiveContent == null ? true : DockPane.ActiveContent.DockHandler.CloseButton;
1393                m_closeButtonVisible = DockPane.ActiveContent == null ? true : DockPane.ActiveContent.DockHandler.CloseButtonVisible;
1394                ButtonClose.Visible = m_closeButtonVisible;
1395                ButtonClose.RefreshChanges();
1396                ButtonWindowList.RefreshChanges();
1397            }
1398        }
1399
1400        protected override void OnLayout(LayoutEventArgs levent)
1401        {
1402            if (Appearance == DockPane.AppearanceStyle.Document)
1403            {
1404                LayoutButtons();
1405                OnRefreshChanges();
1406            }
1407
1408            base.OnLayout(levent);
1409        }
1410
1411        private void LayoutButtons()
1412        {
1413            Rectangle rectTabStrip = TabStripRectangle;
1414
1415            // Set position and size of the buttons
1416            int buttonWidth = ButtonClose.Image.Width;
1417            int buttonHeight = ButtonClose.Image.Height;
1418            int height = rectTabStrip.Height - DocumentButtonGapTop - DocumentButtonGapBottom;
1419            if (buttonHeight < height)
1420            {
1421                buttonWidth = buttonWidth * (height / buttonHeight);
1422                buttonHeight = height;
1423            }
1424            Size buttonSize = new Size(buttonWidth, buttonHeight);
1425
1426            int x = rectTabStrip.X + rectTabStrip.Width - DocumentTabGapLeft
1427                - DocumentButtonGapRight - buttonWidth;
1428            int y = rectTabStrip.Y + DocumentButtonGapTop;
1429            Point point = new Point(x, y);
1430            ButtonClose.Bounds = DrawHelper.RtlTransform(this, new Rectangle(point, buttonSize));
1431
1432            // If the close button is not visible draw the window list button overtop.
1433            // Otherwise it is drawn to the left of the close button.
1434            if (m_closeButtonVisible)
1435                point.Offset(-(DocumentButtonGapBetween + buttonWidth), 0);
1436
1437            ButtonWindowList.Bounds = DrawHelper.RtlTransform(this, new Rectangle(point, buttonSize));
1438        }
1439
1440        private void Close_Click(object sender, EventArgs e)
1441        {
1442            DockPane.CloseActiveContent();
1443        }
1444
1445        protected internal override int HitTest(Point ptMouse)
1446        {
1447            if (!TabsRectangle.Contains(ptMouse))
1448                return -1;
1449
1450            foreach (Tab tab in Tabs)
1451            {
1452                GraphicsPath path = GetTabOutline(tab, true, false);
1453                if (path.IsVisible(ptMouse))
1454                    return Tabs.IndexOf(tab);
1455            }
1456            return -1;
1457        }
1458
1459        protected override void OnMouseHover(EventArgs e)
1460        {
1461            int index = HitTest(PointToClient(Control.MousePosition));
1462            string toolTip = string.Empty;
1463
1464            base.OnMouseHover(e);
1465
1466            if (index != -1)
1467            {
1468                TabVS2005 tab = Tabs[index] as TabVS2005;
1469                if (!String.IsNullOrEmpty(tab.Content.DockHandler.ToolTipText))
1470                    toolTip = tab.Content.DockHandler.ToolTipText;
1471                else if (tab.MaxWidth > tab.TabWidth)
1472                    toolTip = tab.Content.DockHandler.TabText;
1473            }
1474
1475            if (m_toolTip.GetToolTip(this) != toolTip)
1476            {
1477                m_toolTip.Active = false;
1478                m_toolTip.SetToolTip(this, toolTip);
1479                m_toolTip.Active = true;
1480            }
1481
1482            // requires further tracking of mouse hover behavior,
1483            ResetMouseEventArgs();
1484        }
1485
1486        protected override void OnRightToLeftChanged(EventArgs e)
1487        {
1488            base.OnRightToLeftChanged(e);
1489            PerformLayout();
1490        }
1491    }
1492}
Note: See TracBrowser for help on using the repository browser.