Free cookie consent management tool by TermsFeed Policy Generator

source: branches/UnloadJobs/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.7.0/WinFormsUI-2.7.0/Docking/DockPanel.cs @ 9174

Last change on this file since 9174 was 9174, checked in by ascheibe, 11 years ago

#2005 fixed memory leaks in GraphVisualization and Docking

File size: 31.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Diagnostics.CodeAnalysis;
5using System.Drawing;
6using System.Windows.Forms;
7
8// To simplify the process of finding the toolbox bitmap resource:
9// #1 Create an internal class called "resfinder" outside of the root namespace.
10// #2 Use "resfinder" in the toolbox bitmap attribute instead of the control name.
11// #3 use the "<default namespace>.<resourcename>" string to locate the resource.
12// See: http://www.bobpowell.net/toolboxbitmap.htm
13internal class resfinder {
14}
15
16namespace WeifenLuo.WinFormsUI.Docking {
17  [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "0#")]
18  public delegate IDockContent DeserializeDockContent(string persistString);
19
20  [LocalizedDescription("DockPanel_Description")]
21  [Designer("System.Windows.Forms.Design.ControlDesigner, System.Design")]
22  [ToolboxBitmap(typeof(resfinder), "WeifenLuo.WinFormsUI.Docking.DockPanel.bmp")]
23  [DefaultProperty("DocumentStyle")]
24  [DefaultEvent("ActiveContentChanged")]
25  public partial class DockPanel : Panel {
26    private FocusManagerImpl m_focusManager;
27    private DockPanelExtender m_extender;
28    private DockPaneCollection m_panes;
29    private FloatWindowCollection m_floatWindows;
30    private AutoHideWindowControl m_autoHideWindow;
31    private DockWindowCollection m_dockWindows;
32    private DockContent m_dummyContent;
33    private Control m_dummyControl;
34
35    public DockPanel() {
36      m_focusManager = new FocusManagerImpl(this);
37      m_extender = new DockPanelExtender(this);
38      m_panes = new DockPaneCollection();
39      m_floatWindows = new FloatWindowCollection();
40
41      SuspendLayout();
42
43      m_autoHideWindow = new AutoHideWindowControl(this);
44      m_autoHideWindow.Visible = false;
45      SetAutoHideWindowParent();
46
47      m_dummyControl = new DummyControl();
48      m_dummyControl.Bounds = new Rectangle(0, 0, 1, 1);
49      Controls.Add(m_dummyControl);
50
51      m_dockWindows = new DockWindowCollection(this);
52      Controls.AddRange(new Control[] {
53        DockWindows[DockState.Document],
54        DockWindows[DockState.DockLeft],
55        DockWindows[DockState.DockRight],
56        DockWindows[DockState.DockTop],
57        DockWindows[DockState.DockBottom]
58        });
59
60      m_dummyContent = new DockContent();
61      ResumeLayout();
62    }
63
64    private Color m_BackColor;
65    /// <summary>
66    /// Determines the color with which the client rectangle will be drawn.
67    /// If this property is used instead of the BackColor it will not have any influence on the borders to the surrounding controls (DockPane).
68    /// The BackColor property changes the borders of surrounding controls (DockPane).
69    /// Alternatively both properties may be used (BackColor to draw and define the color of the borders and DockBackColor to define the color of the client rectangle).
70    /// For Backgroundimages: Set your prefered Image, then set the DockBackColor and the BackColor to the same Color (Control)
71    /// </summary>
72    [Description("Determines the color with which the client rectangle will be drawn.\r\n" +
73        "If this property is used instead of the BackColor it will not have any influence on the borders to the surrounding controls (DockPane).\r\n" +
74        "The BackColor property changes the borders of surrounding controls (DockPane).\r\n" +
75        "Alternatively both properties may be used (BackColor to draw and define the color of the borders and DockBackColor to define the color of the client rectangle).\r\n" +
76        "For Backgroundimages: Set your prefered Image, then set the DockBackColor and the BackColor to the same Color (Control).")]
77    public Color DockBackColor {
78      get {
79        return !m_BackColor.IsEmpty ? m_BackColor : base.BackColor;
80      }
81      set {
82        if (m_BackColor != value) {
83          m_BackColor = value;
84          this.Refresh();
85        }
86      }
87    }
88
89    private bool ShouldSerializeDockBackColor() {
90      return !m_BackColor.IsEmpty;
91    }
92
93    private void ResetDockBackColor() {
94      DockBackColor = Color.Empty;
95    }
96
97    private AutoHideStripBase m_autoHideStripControl = null;
98    internal AutoHideStripBase AutoHideStripControl {
99      get {
100        if (m_autoHideStripControl == null) {
101          m_autoHideStripControl = AutoHideStripFactory.CreateAutoHideStrip(this);
102          Controls.Add(m_autoHideStripControl);
103        }
104        return m_autoHideStripControl;
105      }
106    }
107    internal void ResetAutoHideStripControl() {
108      if (m_autoHideStripControl != null)
109        m_autoHideStripControl.Dispose();
110
111      m_autoHideStripControl = null;
112    }
113
114    private void MdiClientHandleAssigned(object sender, EventArgs e) {
115      SetMdiClient();
116      PerformLayout();
117    }
118
119    private void MdiClient_Layout(object sender, LayoutEventArgs e) {
120      if (DocumentStyle != DocumentStyle.DockingMdi)
121        return;
122
123      foreach (DockPane pane in Panes)
124        if (pane.DockState == DockState.Document)
125          pane.SetContentBounds();
126
127      InvalidateWindowRegion();
128    }
129
130    private bool m_disposed = false;
131    protected override void Dispose(bool disposing) {
132      lock (this) {
133        if (!m_disposed && disposing) {
134          m_focusManager.Dispose();
135          if (m_mdiClientController != null) {
136            m_mdiClientController.HandleAssigned -= new EventHandler(MdiClientHandleAssigned);
137            m_mdiClientController.MdiChildActivate -= new EventHandler(ParentFormMdiChildActivate);
138            m_mdiClientController.Layout -= new LayoutEventHandler(MdiClient_Layout);
139            m_mdiClientController.Dispose();
140          }
141          FloatWindows.Dispose();
142          Panes.Dispose();
143          DummyContent.Dispose();
144
145          foreach (var dw in m_dockWindows) {
146            dw.Dispose();
147          }
148          m_dockWindows = null;
149
150          m_disposed = true;
151        }
152
153        base.Dispose(disposing);
154      }
155    }
156
157    [Browsable(false)]
158    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
159    public IDockContent ActiveAutoHideContent {
160      get { return AutoHideWindow.ActiveContent; }
161      set { AutoHideWindow.ActiveContent = value; }
162    }
163
164    private bool m_allowEndUserDocking = !Win32Helper.IsRunningOnMono;
165    [LocalizedCategory("Category_Docking")]
166    [LocalizedDescription("DockPanel_AllowEndUserDocking_Description")]
167    [DefaultValue(true)]
168    public bool AllowEndUserDocking {
169      get {
170        if (Win32Helper.IsRunningOnMono && m_allowEndUserDocking)
171          m_allowEndUserDocking = false;
172
173        return m_allowEndUserDocking;
174      }
175      set {
176        if (Win32Helper.IsRunningOnMono && value)
177          throw new InvalidOperationException("AllowEndUserDocking can only be false if running on Mono");
178
179        m_allowEndUserDocking = value;
180      }
181    }
182
183    private bool m_allowEndUserNestedDocking = !Win32Helper.IsRunningOnMono;
184    [LocalizedCategory("Category_Docking")]
185    [LocalizedDescription("DockPanel_AllowEndUserNestedDocking_Description")]
186    [DefaultValue(true)]
187    public bool AllowEndUserNestedDocking {
188      get {
189        if (Win32Helper.IsRunningOnMono && m_allowEndUserDocking)
190          m_allowEndUserDocking = false;
191        return m_allowEndUserNestedDocking;
192      }
193      set {
194        if (Win32Helper.IsRunningOnMono && value)
195          throw new InvalidOperationException("AllowEndUserNestedDocking can only be false if running on Mono");
196
197        m_allowEndUserNestedDocking = value;
198      }
199    }
200
201    private DockContentCollection m_contents = new DockContentCollection();
202    [Browsable(false)]
203    public DockContentCollection Contents {
204      get { return m_contents; }
205    }
206
207    internal DockContent DummyContent {
208      get { return m_dummyContent; }
209    }
210
211    private bool m_rightToLeftLayout = false;
212    [DefaultValue(false)]
213    [LocalizedCategory("Appearance")]
214    [LocalizedDescription("DockPanel_RightToLeftLayout_Description")]
215    public bool RightToLeftLayout {
216      get { return m_rightToLeftLayout; }
217      set {
218        if (m_rightToLeftLayout == value)
219          return;
220
221        m_rightToLeftLayout = value;
222        foreach (FloatWindow floatWindow in FloatWindows)
223          floatWindow.RightToLeftLayout = value;
224      }
225    }
226
227    protected override void OnRightToLeftChanged(EventArgs e) {
228      base.OnRightToLeftChanged(e);
229      foreach (FloatWindow floatWindow in FloatWindows) {
230        if (floatWindow.RightToLeft != RightToLeft)
231          floatWindow.RightToLeft = RightToLeft;
232      }
233    }
234
235    private bool m_showDocumentIcon = false;
236    [DefaultValue(false)]
237    [LocalizedCategory("Category_Docking")]
238    [LocalizedDescription("DockPanel_ShowDocumentIcon_Description")]
239    public bool ShowDocumentIcon {
240      get { return m_showDocumentIcon; }
241      set {
242        if (m_showDocumentIcon == value)
243          return;
244
245        m_showDocumentIcon = value;
246        Refresh();
247      }
248    }
249
250    private DocumentTabStripLocation m_documentTabStripLocation = DocumentTabStripLocation.Top;
251    [DefaultValue(DocumentTabStripLocation.Top)]
252    [LocalizedCategory("Category_Docking")]
253    [LocalizedDescription("DockPanel_DocumentTabStripLocation")]
254    public DocumentTabStripLocation DocumentTabStripLocation {
255      get { return m_documentTabStripLocation; }
256      set { m_documentTabStripLocation = value; }
257    }
258
259    [Browsable(false)]
260    public DockPanelExtender Extender {
261      get { return m_extender; }
262    }
263
264    [Browsable(false)]
265    public DockPanelExtender.IDockPaneFactory DockPaneFactory {
266      get { return Extender.DockPaneFactory; }
267    }
268
269    [Browsable(false)]
270    public DockPanelExtender.IFloatWindowFactory FloatWindowFactory {
271      get { return Extender.FloatWindowFactory; }
272    }
273
274    internal DockPanelExtender.IDockPaneCaptionFactory DockPaneCaptionFactory {
275      get { return Extender.DockPaneCaptionFactory; }
276    }
277
278    internal DockPanelExtender.IDockPaneStripFactory DockPaneStripFactory {
279      get { return Extender.DockPaneStripFactory; }
280    }
281
282    internal DockPanelExtender.IAutoHideStripFactory AutoHideStripFactory {
283      get { return Extender.AutoHideStripFactory; }
284    }
285
286    [Browsable(false)]
287    public DockPaneCollection Panes {
288      get { return m_panes; }
289    }
290
291    internal Rectangle DockArea {
292      get {
293        return new Rectangle(DockPadding.Left, DockPadding.Top,
294          ClientRectangle.Width - DockPadding.Left - DockPadding.Right,
295          ClientRectangle.Height - DockPadding.Top - DockPadding.Bottom);
296      }
297    }
298
299    private double m_dockBottomPortion = 0.25;
300    [LocalizedCategory("Category_Docking")]
301    [LocalizedDescription("DockPanel_DockBottomPortion_Description")]
302    [DefaultValue(0.25)]
303    public double DockBottomPortion {
304      get { return m_dockBottomPortion; }
305      set {
306        if (value <= 0)
307          throw new ArgumentOutOfRangeException("value");
308
309        if (value == m_dockBottomPortion)
310          return;
311
312        m_dockBottomPortion = value;
313
314        if (m_dockBottomPortion < 1 && m_dockTopPortion < 1) {
315          if (m_dockTopPortion + m_dockBottomPortion > 1)
316            m_dockTopPortion = 1 - m_dockBottomPortion;
317        }
318
319        PerformLayout();
320      }
321    }
322
323    private double m_dockLeftPortion = 0.25;
324    [LocalizedCategory("Category_Docking")]
325    [LocalizedDescription("DockPanel_DockLeftPortion_Description")]
326    [DefaultValue(0.25)]
327    public double DockLeftPortion {
328      get { return m_dockLeftPortion; }
329      set {
330        if (value <= 0)
331          throw new ArgumentOutOfRangeException("value");
332
333        if (value == m_dockLeftPortion)
334          return;
335
336        m_dockLeftPortion = value;
337
338        if (m_dockLeftPortion < 1 && m_dockRightPortion < 1) {
339          if (m_dockLeftPortion + m_dockRightPortion > 1)
340            m_dockRightPortion = 1 - m_dockLeftPortion;
341        }
342        PerformLayout();
343      }
344    }
345
346    private double m_dockRightPortion = 0.25;
347    [LocalizedCategory("Category_Docking")]
348    [LocalizedDescription("DockPanel_DockRightPortion_Description")]
349    [DefaultValue(0.25)]
350    public double DockRightPortion {
351      get { return m_dockRightPortion; }
352      set {
353        if (value <= 0)
354          throw new ArgumentOutOfRangeException("value");
355
356        if (value == m_dockRightPortion)
357          return;
358
359        m_dockRightPortion = value;
360
361        if (m_dockLeftPortion < 1 && m_dockRightPortion < 1) {
362          if (m_dockLeftPortion + m_dockRightPortion > 1)
363            m_dockLeftPortion = 1 - m_dockRightPortion;
364        }
365        PerformLayout();
366      }
367    }
368
369    private double m_dockTopPortion = 0.25;
370    [LocalizedCategory("Category_Docking")]
371    [LocalizedDescription("DockPanel_DockTopPortion_Description")]
372    [DefaultValue(0.25)]
373    public double DockTopPortion {
374      get { return m_dockTopPortion; }
375      set {
376        if (value <= 0)
377          throw new ArgumentOutOfRangeException("value");
378
379        if (value == m_dockTopPortion)
380          return;
381
382        m_dockTopPortion = value;
383
384        if (m_dockTopPortion < 1 && m_dockBottomPortion < 1) {
385          if (m_dockTopPortion + m_dockBottomPortion > 1)
386            m_dockBottomPortion = 1 - m_dockTopPortion;
387        }
388        PerformLayout();
389      }
390    }
391
392    [Browsable(false)]
393    public DockWindowCollection DockWindows {
394      get { return m_dockWindows; }
395    }
396
397    public void UpdateDockWindowZOrder(DockStyle dockStyle, bool fullPanelEdge) {
398      if (dockStyle == DockStyle.Left) {
399        if (fullPanelEdge)
400          DockWindows[DockState.DockLeft].SendToBack();
401        else
402          DockWindows[DockState.DockLeft].BringToFront();
403      } else if (dockStyle == DockStyle.Right) {
404        if (fullPanelEdge)
405          DockWindows[DockState.DockRight].SendToBack();
406        else
407          DockWindows[DockState.DockRight].BringToFront();
408      } else if (dockStyle == DockStyle.Top) {
409        if (fullPanelEdge)
410          DockWindows[DockState.DockTop].SendToBack();
411        else
412          DockWindows[DockState.DockTop].BringToFront();
413      } else if (dockStyle == DockStyle.Bottom) {
414        if (fullPanelEdge)
415          DockWindows[DockState.DockBottom].SendToBack();
416        else
417          DockWindows[DockState.DockBottom].BringToFront();
418      }
419    }
420
421    [Browsable(false)]
422    public int DocumentsCount {
423      get {
424        int count = 0;
425        foreach (IDockContent content in Documents)
426          count++;
427
428        return count;
429      }
430    }
431
432    public IDockContent[] DocumentsToArray() {
433      int count = DocumentsCount;
434      IDockContent[] documents = new IDockContent[count];
435      int i = 0;
436      foreach (IDockContent content in Documents) {
437        documents[i] = content;
438        i++;
439      }
440
441      return documents;
442    }
443
444    [Browsable(false)]
445    public IEnumerable<IDockContent> Documents {
446      get {
447        foreach (IDockContent content in Contents) {
448          if (content.DockHandler.DockState == DockState.Document)
449            yield return content;
450        }
451      }
452    }
453
454    private Rectangle DocumentRectangle {
455      get {
456        Rectangle rect = DockArea;
457        if (DockWindows[DockState.DockLeft].VisibleNestedPanes.Count != 0) {
458          rect.X += (int)(DockArea.Width * DockLeftPortion);
459          rect.Width -= (int)(DockArea.Width * DockLeftPortion);
460        }
461        if (DockWindows[DockState.DockRight].VisibleNestedPanes.Count != 0)
462          rect.Width -= (int)(DockArea.Width * DockRightPortion);
463        if (DockWindows[DockState.DockTop].VisibleNestedPanes.Count != 0) {
464          rect.Y += (int)(DockArea.Height * DockTopPortion);
465          rect.Height -= (int)(DockArea.Height * DockTopPortion);
466        }
467        if (DockWindows[DockState.DockBottom].VisibleNestedPanes.Count != 0)
468          rect.Height -= (int)(DockArea.Height * DockBottomPortion);
469
470        return rect;
471      }
472    }
473
474    private Control DummyControl {
475      get { return m_dummyControl; }
476    }
477
478    [Browsable(false)]
479    public FloatWindowCollection FloatWindows {
480      get { return m_floatWindows; }
481    }
482
483    private Size m_defaultFloatWindowSize = new Size(300, 300);
484    [Category("Layout")]
485    [LocalizedDescription("DockPanel_DefaultFloatWindowSize_Description")]
486    public Size DefaultFloatWindowSize {
487      get { return m_defaultFloatWindowSize; }
488      set { m_defaultFloatWindowSize = value; }
489    }
490    private bool ShouldSerializeDefaultFloatWindowSize() {
491      return DefaultFloatWindowSize != new Size(300, 300);
492    }
493    private void ResetDefaultFloatWindowSize() {
494      DefaultFloatWindowSize = new Size(300, 300);
495    }
496
497    private DocumentStyle m_documentStyle = DocumentStyle.DockingMdi;
498    [LocalizedCategory("Category_Docking")]
499    [LocalizedDescription("DockPanel_DocumentStyle_Description")]
500    [DefaultValue(DocumentStyle.DockingMdi)]
501    public DocumentStyle DocumentStyle {
502      get { return m_documentStyle; }
503      set {
504        if (value == m_documentStyle)
505          return;
506
507        if (!Enum.IsDefined(typeof(DocumentStyle), value))
508          throw new InvalidEnumArgumentException();
509
510        if (value == DocumentStyle.SystemMdi && DockWindows[DockState.Document].VisibleNestedPanes.Count > 0)
511          throw new InvalidEnumArgumentException();
512
513        m_documentStyle = value;
514
515        SuspendLayout(true);
516
517        SetAutoHideWindowParent();
518        SetMdiClient();
519        InvalidateWindowRegion();
520
521        foreach (IDockContent content in Contents) {
522          if (content.DockHandler.DockState == DockState.Document)
523            content.DockHandler.SetPaneAndVisible(content.DockHandler.Pane);
524        }
525
526        PerformMdiClientLayout();
527
528        ResumeLayout(true, true);
529      }
530    }
531
532    private bool _supprtDeeplyNestedContent = false;
533    [LocalizedCategory("Category_Performance")]
534    [LocalizedDescription("DockPanel_SupportDeeplyNestedContent_Description")]
535    [DefaultValue(false)]
536    public bool SupportDeeplyNestedContent {
537      get { return _supprtDeeplyNestedContent; }
538      set { _supprtDeeplyNestedContent = value; }
539    }
540
541    private int GetDockWindowSize(DockState dockState) {
542      if (dockState == DockState.DockLeft || dockState == DockState.DockRight) {
543        int width = ClientRectangle.Width - DockPadding.Left - DockPadding.Right;
544        int dockLeftSize = m_dockLeftPortion >= 1 ? (int)m_dockLeftPortion : (int)(width * m_dockLeftPortion);
545        int dockRightSize = m_dockRightPortion >= 1 ? (int)m_dockRightPortion : (int)(width * m_dockRightPortion);
546
547        if (dockLeftSize < MeasurePane.MinSize)
548          dockLeftSize = MeasurePane.MinSize;
549        if (dockRightSize < MeasurePane.MinSize)
550          dockRightSize = MeasurePane.MinSize;
551
552        if (dockLeftSize + dockRightSize > width - MeasurePane.MinSize) {
553          int adjust = (dockLeftSize + dockRightSize) - (width - MeasurePane.MinSize);
554          dockLeftSize -= adjust / 2;
555          dockRightSize -= adjust / 2;
556        }
557
558        return dockState == DockState.DockLeft ? dockLeftSize : dockRightSize;
559      } else if (dockState == DockState.DockTop || dockState == DockState.DockBottom) {
560        int height = ClientRectangle.Height - DockPadding.Top - DockPadding.Bottom;
561        int dockTopSize = m_dockTopPortion >= 1 ? (int)m_dockTopPortion : (int)(height * m_dockTopPortion);
562        int dockBottomSize = m_dockBottomPortion >= 1 ? (int)m_dockBottomPortion : (int)(height * m_dockBottomPortion);
563
564        if (dockTopSize < MeasurePane.MinSize)
565          dockTopSize = MeasurePane.MinSize;
566        if (dockBottomSize < MeasurePane.MinSize)
567          dockBottomSize = MeasurePane.MinSize;
568
569        if (dockTopSize + dockBottomSize > height - MeasurePane.MinSize) {
570          int adjust = (dockTopSize + dockBottomSize) - (height - MeasurePane.MinSize);
571          dockTopSize -= adjust / 2;
572          dockBottomSize -= adjust / 2;
573        }
574
575        return dockState == DockState.DockTop ? dockTopSize : dockBottomSize;
576      } else
577        return 0;
578    }
579
580    protected override void OnLayout(LayoutEventArgs levent) {
581      SuspendLayout(true);
582
583      AutoHideStripControl.Bounds = ClientRectangle;
584
585      CalculateDockPadding();
586
587      DockWindows[DockState.DockLeft].Width = GetDockWindowSize(DockState.DockLeft);
588      DockWindows[DockState.DockRight].Width = GetDockWindowSize(DockState.DockRight);
589      DockWindows[DockState.DockTop].Height = GetDockWindowSize(DockState.DockTop);
590      DockWindows[DockState.DockBottom].Height = GetDockWindowSize(DockState.DockBottom);
591
592      AutoHideWindow.Bounds = GetAutoHideWindowBounds(AutoHideWindowRectangle);
593
594      DockWindows[DockState.Document].BringToFront();
595      AutoHideWindow.BringToFront();
596
597      base.OnLayout(levent);
598
599      if (DocumentStyle == DocumentStyle.SystemMdi && MdiClientExists) {
600        SetMdiClientBounds(SystemMdiClientBounds);
601        InvalidateWindowRegion();
602      } else if (DocumentStyle == DocumentStyle.DockingMdi)
603        InvalidateWindowRegion();
604
605      ResumeLayout(true, true);
606    }
607
608    internal Rectangle GetTabStripRectangle(DockState dockState) {
609      return AutoHideStripControl.GetTabStripRectangle(dockState);
610    }
611
612    protected override void OnPaint(PaintEventArgs e) {
613      base.OnPaint(e);
614
615      if (DockBackColor == BackColor) return;
616
617      Graphics g = e.Graphics;
618      SolidBrush bgBrush = new SolidBrush(DockBackColor);
619      g.FillRectangle(bgBrush, ClientRectangle);
620    }
621
622    internal void AddContent(IDockContent content) {
623      if (content == null)
624        throw (new ArgumentNullException());
625
626      if (!Contents.Contains(content)) {
627        Contents.Add(content);
628        OnContentAdded(new DockContentEventArgs(content));
629      }
630    }
631
632    internal void AddPane(DockPane pane) {
633      if (Panes.Contains(pane))
634        return;
635
636      Panes.Add(pane);
637    }
638
639    internal void AddFloatWindow(FloatWindow floatWindow) {
640      if (FloatWindows.Contains(floatWindow))
641        return;
642
643      FloatWindows.Add(floatWindow);
644    }
645
646    private void CalculateDockPadding() {
647      DockPadding.All = 0;
648
649      int height = AutoHideStripControl.MeasureHeight();
650
651      if (AutoHideStripControl.GetNumberOfPanes(DockState.DockLeftAutoHide) > 0)
652        DockPadding.Left = height;
653      if (AutoHideStripControl.GetNumberOfPanes(DockState.DockRightAutoHide) > 0)
654        DockPadding.Right = height;
655      if (AutoHideStripControl.GetNumberOfPanes(DockState.DockTopAutoHide) > 0)
656        DockPadding.Top = height;
657      if (AutoHideStripControl.GetNumberOfPanes(DockState.DockBottomAutoHide) > 0)
658        DockPadding.Bottom = height;
659    }
660
661    internal void RemoveContent(IDockContent content) {
662      if (content == null)
663        throw (new ArgumentNullException());
664
665      if (Contents.Contains(content)) {
666        Contents.Remove(content);
667        OnContentRemoved(new DockContentEventArgs(content));
668      }
669    }
670
671    internal void RemovePane(DockPane pane) {
672      if (!Panes.Contains(pane))
673        return;
674
675      Panes.Remove(pane);
676    }
677
678    internal void RemoveFloatWindow(FloatWindow floatWindow) {
679      if (!FloatWindows.Contains(floatWindow))
680        return;
681
682      FloatWindows.Remove(floatWindow);
683    }
684
685    public void SetPaneIndex(DockPane pane, int index) {
686      int oldIndex = Panes.IndexOf(pane);
687      if (oldIndex == -1)
688        throw (new ArgumentException(Strings.DockPanel_SetPaneIndex_InvalidPane));
689
690      if (index < 0 || index > Panes.Count - 1)
691        if (index != -1)
692          throw (new ArgumentOutOfRangeException(Strings.DockPanel_SetPaneIndex_InvalidIndex));
693
694      if (oldIndex == index)
695        return;
696      if (oldIndex == Panes.Count - 1 && index == -1)
697        return;
698
699      Panes.Remove(pane);
700      if (index == -1)
701        Panes.Add(pane);
702      else if (oldIndex < index)
703        Panes.AddAt(pane, index - 1);
704      else
705        Panes.AddAt(pane, index);
706    }
707
708    public void SuspendLayout(bool allWindows) {
709      FocusManager.SuspendFocusTracking();
710      SuspendLayout();
711      if (allWindows)
712        SuspendMdiClientLayout();
713    }
714
715    public void ResumeLayout(bool performLayout, bool allWindows) {
716      FocusManager.ResumeFocusTracking();
717      ResumeLayout(performLayout);
718      if (allWindows)
719        ResumeMdiClientLayout(performLayout);
720    }
721
722    internal Form ParentForm {
723      get {
724        if (!IsParentFormValid())
725          throw new InvalidOperationException(Strings.DockPanel_ParentForm_Invalid);
726
727        return GetMdiClientController().ParentForm;
728      }
729    }
730
731    private bool IsParentFormValid() {
732      if (DocumentStyle == DocumentStyle.DockingSdi || DocumentStyle == DocumentStyle.DockingWindow)
733        return true;
734
735      if (!MdiClientExists)
736        GetMdiClientController().RenewMdiClient();
737
738      return (MdiClientExists);
739    }
740
741    protected override void OnParentChanged(EventArgs e) {
742      SetAutoHideWindowParent();
743      GetMdiClientController().ParentForm = (this.Parent as Form);
744      base.OnParentChanged(e);
745    }
746
747    private void SetAutoHideWindowParent() {
748      Control parent;
749      if (DocumentStyle == DocumentStyle.DockingMdi ||
750          DocumentStyle == DocumentStyle.SystemMdi)
751        parent = this.Parent;
752      else
753        parent = this;
754      if (AutoHideWindow.Parent != parent) {
755        AutoHideWindow.Parent = parent;
756        AutoHideWindow.BringToFront();
757      }
758    }
759
760    protected override void OnVisibleChanged(EventArgs e) {
761      base.OnVisibleChanged(e);
762
763      if (Visible)
764        SetMdiClient();
765    }
766
767    private Rectangle SystemMdiClientBounds {
768      get {
769        if (!IsParentFormValid() || !Visible)
770          return Rectangle.Empty;
771
772        Rectangle rect = ParentForm.RectangleToClient(RectangleToScreen(DocumentWindowBounds));
773        return rect;
774      }
775    }
776
777    internal Rectangle DocumentWindowBounds {
778      get {
779        Rectangle rectDocumentBounds = DisplayRectangle;
780        if (DockWindows[DockState.DockLeft].Visible) {
781          rectDocumentBounds.X += DockWindows[DockState.DockLeft].Width;
782          rectDocumentBounds.Width -= DockWindows[DockState.DockLeft].Width;
783        }
784        if (DockWindows[DockState.DockRight].Visible)
785          rectDocumentBounds.Width -= DockWindows[DockState.DockRight].Width;
786        if (DockWindows[DockState.DockTop].Visible) {
787          rectDocumentBounds.Y += DockWindows[DockState.DockTop].Height;
788          rectDocumentBounds.Height -= DockWindows[DockState.DockTop].Height;
789        }
790        if (DockWindows[DockState.DockBottom].Visible)
791          rectDocumentBounds.Height -= DockWindows[DockState.DockBottom].Height;
792
793        return rectDocumentBounds;
794
795      }
796    }
797
798    private PaintEventHandler m_dummyControlPaintEventHandler = null;
799    private void InvalidateWindowRegion() {
800      if (DesignMode)
801        return;
802
803      if (m_dummyControlPaintEventHandler == null)
804        m_dummyControlPaintEventHandler = new PaintEventHandler(DummyControl_Paint);
805
806      DummyControl.Paint += m_dummyControlPaintEventHandler;
807      DummyControl.Invalidate();
808    }
809
810    void DummyControl_Paint(object sender, PaintEventArgs e) {
811      DummyControl.Paint -= m_dummyControlPaintEventHandler;
812      UpdateWindowRegion();
813    }
814
815    private void UpdateWindowRegion() {
816      if (this.DocumentStyle == DocumentStyle.DockingMdi)
817        UpdateWindowRegion_ClipContent();
818      else if (this.DocumentStyle == DocumentStyle.DockingSdi ||
819        this.DocumentStyle == DocumentStyle.DockingWindow)
820        UpdateWindowRegion_FullDocumentArea();
821      else if (this.DocumentStyle == DocumentStyle.SystemMdi)
822        UpdateWindowRegion_EmptyDocumentArea();
823    }
824
825    private void UpdateWindowRegion_FullDocumentArea() {
826      SetRegion(null);
827    }
828
829    private void UpdateWindowRegion_EmptyDocumentArea() {
830      Rectangle rect = DocumentWindowBounds;
831      SetRegion(new Rectangle[] { rect });
832    }
833
834    private void UpdateWindowRegion_ClipContent() {
835      int count = 0;
836      foreach (DockPane pane in this.Panes) {
837        if (!pane.Visible || pane.DockState != DockState.Document)
838          continue;
839
840        count++;
841      }
842
843      if (count == 0) {
844        SetRegion(null);
845        return;
846      }
847
848      Rectangle[] rects = new Rectangle[count];
849      int i = 0;
850      foreach (DockPane pane in this.Panes) {
851        if (!pane.Visible || pane.DockState != DockState.Document)
852          continue;
853
854        rects[i] = RectangleToClient(pane.RectangleToScreen(pane.ContentRectangle));
855        i++;
856      }
857
858      SetRegion(rects);
859    }
860
861    private Rectangle[] m_clipRects = null;
862    private void SetRegion(Rectangle[] clipRects) {
863      if (!IsClipRectsChanged(clipRects))
864        return;
865
866      m_clipRects = clipRects;
867
868      if (m_clipRects == null || m_clipRects.GetLength(0) == 0)
869        Region = null;
870      else {
871        Region region = new Region(new Rectangle(0, 0, this.Width, this.Height));
872        foreach (Rectangle rect in m_clipRects)
873          region.Exclude(rect);
874        Region = region;
875      }
876    }
877
878    private bool IsClipRectsChanged(Rectangle[] clipRects) {
879      if (clipRects == null && m_clipRects == null)
880        return false;
881      else if ((clipRects == null) != (m_clipRects == null))
882        return true;
883
884      foreach (Rectangle rect in clipRects) {
885        bool matched = false;
886        foreach (Rectangle rect2 in m_clipRects) {
887          if (rect == rect2) {
888            matched = true;
889            break;
890          }
891        }
892        if (!matched)
893          return true;
894      }
895
896      foreach (Rectangle rect2 in m_clipRects) {
897        bool matched = false;
898        foreach (Rectangle rect in clipRects) {
899          if (rect == rect2) {
900            matched = true;
901            break;
902          }
903        }
904        if (!matched)
905          return true;
906      }
907      return false;
908    }
909
910    private static readonly object ContentAddedEvent = new object();
911    [LocalizedCategory("Category_DockingNotification")]
912    [LocalizedDescription("DockPanel_ContentAdded_Description")]
913    public event EventHandler<DockContentEventArgs> ContentAdded {
914      add { Events.AddHandler(ContentAddedEvent, value); }
915      remove { Events.RemoveHandler(ContentAddedEvent, value); }
916    }
917    protected virtual void OnContentAdded(DockContentEventArgs e) {
918      EventHandler<DockContentEventArgs> handler = (EventHandler<DockContentEventArgs>)Events[ContentAddedEvent];
919      if (handler != null)
920        handler(this, e);
921    }
922
923    private static readonly object ContentRemovedEvent = new object();
924    [LocalizedCategory("Category_DockingNotification")]
925    [LocalizedDescription("DockPanel_ContentRemoved_Description")]
926    public event EventHandler<DockContentEventArgs> ContentRemoved {
927      add { Events.AddHandler(ContentRemovedEvent, value); }
928      remove { Events.RemoveHandler(ContentRemovedEvent, value); }
929    }
930    protected virtual void OnContentRemoved(DockContentEventArgs e) {
931      EventHandler<DockContentEventArgs> handler = (EventHandler<DockContentEventArgs>)Events[ContentRemovedEvent];
932      if (handler != null)
933        handler(this, e);
934    }
935  }
936}
Note: See TracBrowser for help on using the repository browser.