Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.3.1/WinFormsUI-2.3.1/Docking/VS2005DockPaneStrip.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

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