Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceSpeedUp/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.3.1/WinFormsUI-2.3.1/Docking/DockPane.cs

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

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

File size: 37.1 KB
Line 
1using System;
2using System.ComponentModel;
3using System.Diagnostics.CodeAnalysis;
4using System.Drawing;
5using System.Security.Permissions;
6using System.Windows.Forms;
7
8namespace WeifenLuo.WinFormsUI.Docking {
9  [ToolboxItem(false)]
10  public partial class DockPane : UserControl, IDockDragSource {
11    public enum AppearanceStyle {
12      ToolWindow,
13      Document
14    }
15
16    private enum HitTestArea {
17      Caption,
18      TabStrip,
19      Content,
20      None
21    }
22
23    private struct HitTestResult {
24      public HitTestArea HitArea;
25      public int Index;
26
27      public HitTestResult(HitTestArea hitTestArea, int index) {
28        HitArea = hitTestArea;
29        Index = index;
30      }
31    }
32
33    private DockPaneCaptionBase m_captionControl;
34    private DockPaneCaptionBase CaptionControl {
35      get { return m_captionControl; }
36    }
37
38    private DockPaneStripBase m_tabStripControl;
39    internal DockPaneStripBase TabStripControl {
40      get { return m_tabStripControl; }
41    }
42
43    internal protected DockPane(IDockContent content, DockState visibleState, bool show) {
44      InternalConstruct(content, visibleState, false, Rectangle.Empty, null, DockAlignment.Right, 0.5, show);
45    }
46
47    [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "1#")]
48    internal protected DockPane(IDockContent content, FloatWindow floatWindow, bool show) {
49      if (floatWindow == null)
50        throw new ArgumentNullException("floatWindow");
51
52      InternalConstruct(content, DockState.Float, false, Rectangle.Empty, floatWindow.NestedPanes.GetDefaultPreviousPane(this), DockAlignment.Right, 0.5, show);
53    }
54
55    internal protected DockPane(IDockContent content, DockPane previousPane, DockAlignment alignment, double proportion, bool show) {
56      if (previousPane == null)
57        throw (new ArgumentNullException("previousPane"));
58      InternalConstruct(content, previousPane.DockState, false, Rectangle.Empty, previousPane, alignment, proportion, show);
59    }
60
61    [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "1#")]
62    internal protected DockPane(IDockContent content, Rectangle floatWindowBounds, bool show) {
63      InternalConstruct(content, DockState.Float, true, floatWindowBounds, null, DockAlignment.Right, 0.5, show);
64    }
65
66    private void InternalConstruct(IDockContent content, DockState dockState, bool flagBounds, Rectangle floatWindowBounds, DockPane prevPane, DockAlignment alignment, double proportion, bool show) {
67      if (dockState == DockState.Hidden || dockState == DockState.Unknown)
68        throw new ArgumentException(Strings.DockPane_SetDockState_InvalidState);
69
70      if (content == null)
71        throw new ArgumentNullException(Strings.DockPane_Constructor_NullContent);
72
73      if (content.DockHandler.DockPanel == null)
74        throw new ArgumentException(Strings.DockPane_Constructor_NullDockPanel);
75
76
77      SuspendLayout();
78      SetStyle(ControlStyles.Selectable, false);
79
80      m_isFloat = (dockState == DockState.Float);
81
82      m_contents = new DockContentCollection();
83      m_displayingContents = new DockContentCollection(this);
84      m_dockPanel = content.DockHandler.DockPanel;
85      m_dockPanel.AddPane(this);
86
87      m_splitter = new SplitterControl(this);
88
89      m_nestedDockingStatus = new NestedDockingStatus(this);
90
91      m_captionControl = DockPanel.DockPaneCaptionFactory.CreateDockPaneCaption(this);
92      m_tabStripControl = DockPanel.DockPaneStripFactory.CreateDockPaneStrip(this);
93      Controls.AddRange(new Control[] { m_captionControl, m_tabStripControl });
94
95      DockPanel.SuspendLayout(true);
96      if (flagBounds)
97        FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this, floatWindowBounds);
98      else if (prevPane != null)
99        DockTo(prevPane.NestedPanesContainer, prevPane, alignment, proportion);
100
101      SetDockState(dockState);
102      if (show)
103        content.DockHandler.Pane = this;
104      else if (this.IsFloat)
105        content.DockHandler.FloatPane = this;
106      else
107        content.DockHandler.PanelPane = this;
108
109      ResumeLayout();
110      DockPanel.ResumeLayout(true, true);
111    }
112
113    protected override void Dispose(bool disposing) {
114      if (disposing) {
115        m_dockState = DockState.Unknown;
116
117        if (NestedPanesContainer != null)
118          NestedPanesContainer.NestedPanes.Remove(this);
119
120        if (DockPanel != null) {
121          DockPanel.RemovePane(this);
122          m_dockPanel = null;
123        }
124
125        Splitter.Dispose();
126        if (m_autoHidePane != null)
127          m_autoHidePane.Dispose();
128      }
129      base.Dispose(disposing);
130    }
131
132    private IDockContent m_activeContent = null;
133    public virtual IDockContent ActiveContent {
134      get { return m_activeContent; }
135      set {
136        if (ActiveContent == value)
137          return;
138
139        if (value != null) {
140          if (!DisplayingContents.Contains(value))
141            throw (new InvalidOperationException(Strings.DockPane_ActiveContent_InvalidValue));
142        } else {
143          if (DisplayingContents.Count != 0)
144            throw (new InvalidOperationException(Strings.DockPane_ActiveContent_InvalidValue));
145        }
146
147        IDockContent oldValue = m_activeContent;
148
149        if (DockPanel.ActiveAutoHideContent == oldValue)
150          DockPanel.ActiveAutoHideContent = null;
151
152        m_activeContent = value;
153
154        if (DockPanel.DocumentStyle == DocumentStyle.DockingMdi && DockState == DockState.Document) {
155          if (m_activeContent != null)
156            m_activeContent.DockHandler.Form.BringToFront();
157        } else {
158          if (m_activeContent != null)
159            m_activeContent.DockHandler.SetVisible();
160          if (oldValue != null && DisplayingContents.Contains(oldValue))
161            oldValue.DockHandler.SetVisible();
162          if (IsActivated && m_activeContent != null)
163            m_activeContent.DockHandler.Activate();
164        }
165
166        if (FloatWindow != null)
167          FloatWindow.SetText();
168
169        if (DockPanel.DocumentStyle == DocumentStyle.DockingMdi &&
170            DockState == DockState.Document)
171          RefreshChanges(false);  // delayed layout to reduce screen flicker
172        else
173          RefreshChanges();
174
175        if (m_activeContent != null)
176          TabStripControl.EnsureTabVisible(m_activeContent);
177      }
178    }
179
180    private bool m_allowDockDragAndDrop = true;
181    public virtual bool AllowDockDragAndDrop {
182      get { return m_allowDockDragAndDrop; }
183      set { m_allowDockDragAndDrop = value; }
184    }
185
186    private IDisposable m_autoHidePane = null;
187    internal IDisposable AutoHidePane {
188      get { return m_autoHidePane; }
189      set { m_autoHidePane = value; }
190    }
191
192    private object m_autoHideTabs = null;
193    internal object AutoHideTabs {
194      get { return m_autoHideTabs; }
195      set { m_autoHideTabs = value; }
196    }
197
198    private object TabPageContextMenu {
199      get {
200        IDockContent content = ActiveContent;
201
202        if (content == null)
203          return null;
204
205        if (content.DockHandler.TabPageContextMenuStrip != null)
206          return content.DockHandler.TabPageContextMenuStrip;
207        else if (content.DockHandler.TabPageContextMenu != null)
208          return content.DockHandler.TabPageContextMenu;
209        else
210          return null;
211      }
212    }
213
214    internal bool HasTabPageContextMenu {
215      get { return TabPageContextMenu != null; }
216    }
217
218    internal void ShowTabPageContextMenu(Control control, Point position) {
219      object menu = TabPageContextMenu;
220
221      if (menu == null)
222        return;
223
224      ContextMenuStrip contextMenuStrip = menu as ContextMenuStrip;
225      if (contextMenuStrip != null) {
226        contextMenuStrip.Show(control, position);
227        return;
228      }
229
230      ContextMenu contextMenu = menu as ContextMenu;
231      if (contextMenu != null)
232        contextMenu.Show(this, position);
233    }
234
235    private Rectangle CaptionRectangle {
236      get {
237        if (!HasCaption)
238          return Rectangle.Empty;
239
240        Rectangle rectWindow = DisplayingRectangle;
241        int x, y, width;
242        x = rectWindow.X;
243        y = rectWindow.Y;
244        width = rectWindow.Width;
245        int height = CaptionControl.MeasureHeight();
246
247        return new Rectangle(x, y, width, height);
248      }
249    }
250
251    internal Rectangle ContentRectangle {
252      get {
253        Rectangle rectWindow = DisplayingRectangle;
254        Rectangle rectCaption = CaptionRectangle;
255        Rectangle rectTabStrip = TabStripRectangle;
256
257        int x = rectWindow.X;
258
259        int y = rectWindow.Y + (rectCaption.IsEmpty ? 0 : rectCaption.Height);
260        if (DockState == DockState.Document && DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Top)
261          y += rectTabStrip.Height;
262
263        int width = rectWindow.Width;
264        int height = rectWindow.Height - rectCaption.Height - rectTabStrip.Height;
265
266        return new Rectangle(x, y, width, height);
267      }
268    }
269
270    internal Rectangle TabStripRectangle {
271      get {
272        if (Appearance == AppearanceStyle.ToolWindow)
273          return TabStripRectangle_ToolWindow;
274        else
275          return TabStripRectangle_Document;
276      }
277    }
278
279    private Rectangle TabStripRectangle_ToolWindow {
280      get {
281        if (DisplayingContents.Count <= 1 || IsAutoHide)
282          return Rectangle.Empty;
283
284        Rectangle rectWindow = DisplayingRectangle;
285
286        int width = rectWindow.Width;
287        int height = TabStripControl.MeasureHeight();
288        int x = rectWindow.X;
289        int y = rectWindow.Bottom - height;
290        Rectangle rectCaption = CaptionRectangle;
291        if (rectCaption.Contains(x, y))
292          y = rectCaption.Y + rectCaption.Height;
293
294        return new Rectangle(x, y, width, height);
295      }
296    }
297
298    private Rectangle TabStripRectangle_Document {
299      get {
300        if (DisplayingContents.Count == 0)
301          return Rectangle.Empty;
302
303        if (DisplayingContents.Count == 1 && DockPanel.DocumentStyle == DocumentStyle.DockingSdi)
304          return Rectangle.Empty;
305
306        Rectangle rectWindow = DisplayingRectangle;
307        int x = rectWindow.X;
308        int width = rectWindow.Width;
309        int height = TabStripControl.MeasureHeight();
310
311        int y = 0;
312        if (DockPanel.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
313          y = rectWindow.Height - height;
314        else
315          y = rectWindow.Y;
316
317        return new Rectangle(x, y, width, height);
318      }
319    }
320
321    public virtual string CaptionText {
322      get { return ActiveContent == null ? string.Empty : ActiveContent.DockHandler.TabText; }
323    }
324
325    private DockContentCollection m_contents;
326    public DockContentCollection Contents {
327      get { return m_contents; }
328    }
329
330    private DockContentCollection m_displayingContents;
331    public DockContentCollection DisplayingContents {
332      get { return m_displayingContents; }
333    }
334
335    private DockPanel m_dockPanel;
336    public DockPanel DockPanel {
337      get { return m_dockPanel; }
338    }
339
340    private bool HasCaption {
341      get {
342        if (DockState == DockState.Document ||
343          DockState == DockState.Hidden ||
344          DockState == DockState.Unknown ||
345          (DockState == DockState.Float && FloatWindow.VisibleNestedPanes.Count <= 1))
346          return false;
347        else
348          return true;
349      }
350    }
351
352    private bool m_isActivated = false;
353    public bool IsActivated {
354      get { return m_isActivated; }
355    }
356    internal void SetIsActivated(bool value) {
357      if (m_isActivated == value)
358        return;
359
360      m_isActivated = value;
361      if (DockState != DockState.Document)
362        RefreshChanges(false);
363      OnIsActivatedChanged(EventArgs.Empty);
364    }
365
366    private bool m_isActiveDocumentPane = false;
367    public bool IsActiveDocumentPane {
368      get { return m_isActiveDocumentPane; }
369    }
370    internal void SetIsActiveDocumentPane(bool value) {
371      if (m_isActiveDocumentPane == value)
372        return;
373
374      m_isActiveDocumentPane = value;
375      if (DockState == DockState.Document)
376        RefreshChanges();
377      OnIsActiveDocumentPaneChanged(EventArgs.Empty);
378    }
379
380    public bool IsDockStateValid(DockState dockState) {
381      foreach (IDockContent content in Contents)
382        if (!content.DockHandler.IsDockStateValid(dockState))
383          return false;
384
385      return true;
386    }
387
388    public bool IsAutoHide {
389      get { return DockHelper.IsDockStateAutoHide(DockState); }
390    }
391
392    public AppearanceStyle Appearance {
393      get { return (DockState == DockState.Document) ? AppearanceStyle.Document : AppearanceStyle.ToolWindow; }
394    }
395
396    internal Rectangle DisplayingRectangle {
397      get { return ClientRectangle; }
398    }
399
400    public void Activate() {
401      if (DockHelper.IsDockStateAutoHide(DockState) && DockPanel.ActiveAutoHideContent != ActiveContent)
402        DockPanel.ActiveAutoHideContent = ActiveContent;
403      else if (!IsActivated && ActiveContent != null)
404        ActiveContent.DockHandler.Activate();
405    }
406
407    internal void AddContent(IDockContent content) {
408      if (Contents.Contains(content))
409        return;
410
411      Contents.Add(content);
412    }
413
414    internal void Close() {
415      Dispose();
416    }
417
418    public void CloseActiveContent() {
419      CloseContent(ActiveContent);
420    }
421
422    internal void CloseContent(IDockContent content) {
423      DockPanel dockPanel = DockPanel;
424      dockPanel.SuspendLayout(true);
425
426      if (content == null)
427        return;
428
429      if (!content.DockHandler.CloseButton)
430        return;
431
432      if (content.DockHandler.HideOnClose)
433        content.DockHandler.Hide();
434      else
435        content.DockHandler.Close();
436
437      dockPanel.ResumeLayout(true, true);
438    }
439
440    private HitTestResult GetHitTest(Point ptMouse) {
441      Point ptMouseClient = PointToClient(ptMouse);
442
443      Rectangle rectCaption = CaptionRectangle;
444      if (rectCaption.Contains(ptMouseClient))
445        return new HitTestResult(HitTestArea.Caption, -1);
446
447      Rectangle rectContent = ContentRectangle;
448      if (rectContent.Contains(ptMouseClient))
449        return new HitTestResult(HitTestArea.Content, -1);
450
451      Rectangle rectTabStrip = TabStripRectangle;
452      if (rectTabStrip.Contains(ptMouseClient))
453        return new HitTestResult(HitTestArea.TabStrip, TabStripControl.HitTest(TabStripControl.PointToClient(ptMouse)));
454
455      return new HitTestResult(HitTestArea.None, -1);
456    }
457
458    private bool m_isHidden = true;
459    public bool IsHidden {
460      get { return m_isHidden; }
461    }
462    private void SetIsHidden(bool value) {
463      if (m_isHidden == value)
464        return;
465
466      m_isHidden = value;
467      if (DockHelper.IsDockStateAutoHide(DockState)) {
468        DockPanel.RefreshAutoHideStrip();
469        DockPanel.PerformLayout();
470      } else if (NestedPanesContainer != null)
471        ((Control)NestedPanesContainer).PerformLayout();
472    }
473
474    protected override void OnLayout(LayoutEventArgs levent) {
475      SetIsHidden(DisplayingContents.Count == 0);
476      if (!IsHidden) {
477        CaptionControl.Bounds = CaptionRectangle;
478        TabStripControl.Bounds = TabStripRectangle;
479
480        SetContentBounds();
481
482        foreach (IDockContent content in Contents) {
483          if (DisplayingContents.Contains(content))
484            if (content.DockHandler.FlagClipWindow && content.DockHandler.Form.Visible)
485              content.DockHandler.FlagClipWindow = false;
486        }
487      }
488
489      base.OnLayout(levent);
490    }
491
492    internal void SetContentBounds() {
493      Rectangle rectContent = ContentRectangle;
494      if (DockState == DockState.Document && DockPanel.DocumentStyle == DocumentStyle.DockingMdi)
495        rectContent = DockPanel.RectangleToMdiClient(RectangleToScreen(rectContent));
496
497      Rectangle rectInactive = new Rectangle(-rectContent.Width, rectContent.Y, rectContent.Width, rectContent.Height);
498      foreach (IDockContent content in Contents)
499        if (content.DockHandler.Pane == this) {
500          if (content == ActiveContent)
501            content.DockHandler.Form.Bounds = rectContent;
502          else
503            content.DockHandler.Form.Bounds = rectInactive;
504        }
505    }
506
507    internal void RefreshChanges() {
508      RefreshChanges(true);
509    }
510
511    private void RefreshChanges(bool performLayout) {
512      if (IsDisposed)
513        return;
514
515      CaptionControl.RefreshChanges();
516      TabStripControl.RefreshChanges();
517      if (DockState == DockState.Float)
518        FloatWindow.RefreshChanges();
519      if (DockHelper.IsDockStateAutoHide(DockState) && DockPanel != null) {
520        DockPanel.RefreshAutoHideStrip();
521        DockPanel.PerformLayout();
522      }
523
524      if (performLayout)
525        PerformLayout();
526    }
527
528    internal void RemoveContent(IDockContent content) {
529      if (!Contents.Contains(content))
530        return;
531
532      Contents.Remove(content);
533    }
534
535    public void SetContentIndex(IDockContent content, int index) {
536      int oldIndex = Contents.IndexOf(content);
537      if (oldIndex == -1)
538        throw (new ArgumentException(Strings.DockPane_SetContentIndex_InvalidContent));
539
540      if (index < 0 || index > Contents.Count - 1)
541        if (index != -1)
542          throw (new ArgumentOutOfRangeException(Strings.DockPane_SetContentIndex_InvalidIndex));
543
544      if (oldIndex == index)
545        return;
546      if (oldIndex == Contents.Count - 1 && index == -1)
547        return;
548
549      Contents.Remove(content);
550      if (index == -1)
551        Contents.Add(content);
552      else if (oldIndex < index)
553        Contents.AddAt(content, index - 1);
554      else
555        Contents.AddAt(content, index);
556
557      RefreshChanges();
558    }
559
560    private void SetParent() {
561      if (DockState == DockState.Unknown || DockState == DockState.Hidden) {
562        SetParent(null);
563        Splitter.Parent = null;
564      } else if (DockState == DockState.Float) {
565        SetParent(FloatWindow);
566        Splitter.Parent = FloatWindow;
567      } else if (DockHelper.IsDockStateAutoHide(DockState)) {
568        SetParent(DockPanel.AutoHideControl);
569        Splitter.Parent = null;
570      } else {
571        SetParent(DockPanel.DockWindows[DockState]);
572        Splitter.Parent = Parent;
573      }
574    }
575
576    private void SetParent(Control value) {
577      if (Parent == value)
578        return;
579
580      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581      // Workaround of .Net Framework bug:
582      // Change the parent of a control with focus may result in the first
583      // MDI child form get activated.
584      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
585      IDockContent contentFocused = GetFocusedContent();
586      if (contentFocused != null)
587        DockPanel.SaveFocus();
588
589      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
590
591      Parent = value;
592
593      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
594      // Workaround of .Net Framework bug:
595      // Change the parent of a control with focus may result in the first
596      // MDI child form get activated.
597      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
598      if (contentFocused != null)
599        contentFocused.DockHandler.Activate();
600      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
601    }
602
603    public new void Show() {
604      Activate();
605    }
606
607    internal void TestDrop(IDockDragSource dragSource, DockOutlineBase dockOutline) {
608      if (!dragSource.CanDockTo(this))
609        return;
610
611      Point ptMouse = Control.MousePosition;
612
613      HitTestResult hitTestResult = GetHitTest(ptMouse);
614      if (hitTestResult.HitArea == HitTestArea.Caption)
615        dockOutline.Show(this, -1);
616      else if (hitTestResult.HitArea == HitTestArea.TabStrip && hitTestResult.Index != -1)
617        dockOutline.Show(this, hitTestResult.Index);
618    }
619
620    internal void ValidateActiveContent() {
621      if (ActiveContent == null) {
622        if (DisplayingContents.Count != 0)
623          ActiveContent = DisplayingContents[0];
624        return;
625      }
626
627      if (DisplayingContents.IndexOf(ActiveContent) >= 0)
628        return;
629
630      IDockContent prevVisible = null;
631      for (int i = Contents.IndexOf(ActiveContent) - 1; i >= 0; i--)
632        if (Contents[i].DockHandler.DockState == DockState) {
633          prevVisible = Contents[i];
634          break;
635        }
636
637      IDockContent nextVisible = null;
638      for (int i = Contents.IndexOf(ActiveContent) + 1; i < Contents.Count; i++)
639        if (Contents[i].DockHandler.DockState == DockState) {
640          nextVisible = Contents[i];
641          break;
642        }
643
644      if (prevVisible != null)
645        ActiveContent = prevVisible;
646      else if (nextVisible != null)
647        ActiveContent = nextVisible;
648      else
649        ActiveContent = null;
650    }
651
652    private static readonly object DockStateChangedEvent = new object();
653    public event EventHandler DockStateChanged {
654      add { Events.AddHandler(DockStateChangedEvent, value); }
655      remove { Events.RemoveHandler(DockStateChangedEvent, value); }
656    }
657    protected virtual void OnDockStateChanged(EventArgs e) {
658      EventHandler handler = (EventHandler)Events[DockStateChangedEvent];
659      if (handler != null)
660        handler(this, e);
661    }
662
663    private static readonly object IsActivatedChangedEvent = new object();
664    public event EventHandler IsActivatedChanged {
665      add { Events.AddHandler(IsActivatedChangedEvent, value); }
666      remove { Events.RemoveHandler(IsActivatedChangedEvent, value); }
667    }
668    protected virtual void OnIsActivatedChanged(EventArgs e) {
669      EventHandler handler = (EventHandler)Events[IsActivatedChangedEvent];
670      if (handler != null)
671        handler(this, e);
672    }
673
674    private static readonly object IsActiveDocumentPaneChangedEvent = new object();
675    public event EventHandler IsActiveDocumentPaneChanged {
676      add { Events.AddHandler(IsActiveDocumentPaneChangedEvent, value); }
677      remove { Events.RemoveHandler(IsActiveDocumentPaneChangedEvent, value); }
678    }
679    protected virtual void OnIsActiveDocumentPaneChanged(EventArgs e) {
680      EventHandler handler = (EventHandler)Events[IsActiveDocumentPaneChangedEvent];
681      if (handler != null)
682        handler(this, e);
683    }
684
685    public DockWindow DockWindow {
686      get { return (m_nestedDockingStatus.NestedPanes == null) ? null : m_nestedDockingStatus.NestedPanes.Container as DockWindow; }
687      set {
688        DockWindow oldValue = DockWindow;
689        if (oldValue == value)
690          return;
691
692        DockTo(value);
693      }
694    }
695
696    public FloatWindow FloatWindow {
697      get { return (m_nestedDockingStatus.NestedPanes == null) ? null : m_nestedDockingStatus.NestedPanes.Container as FloatWindow; }
698      set {
699        FloatWindow oldValue = FloatWindow;
700        if (oldValue == value)
701          return;
702
703        DockTo(value);
704      }
705    }
706
707    private NestedDockingStatus m_nestedDockingStatus;
708    public NestedDockingStatus NestedDockingStatus {
709      get { return m_nestedDockingStatus; }
710    }
711
712    private bool m_isFloat;
713    public bool IsFloat {
714      get { return m_isFloat; }
715    }
716
717    public INestedPanesContainer NestedPanesContainer {
718      get {
719        if (NestedDockingStatus.NestedPanes == null)
720          return null;
721        else
722          return NestedDockingStatus.NestedPanes.Container;
723      }
724    }
725
726    private DockState m_dockState = DockState.Unknown;
727    public DockState DockState {
728      get { return m_dockState; }
729      set {
730        SetDockState(value);
731      }
732    }
733
734    public DockPane SetDockState(DockState value) {
735      if (value == DockState.Unknown || value == DockState.Hidden)
736        throw new InvalidOperationException(Strings.DockPane_SetDockState_InvalidState);
737
738      if ((value == DockState.Float) == this.IsFloat) {
739        InternalSetDockState(value);
740        return this;
741      }
742
743      if (DisplayingContents.Count == 0)
744        return null;
745
746      IDockContent firstContent = null;
747      for (int i = 0; i < DisplayingContents.Count; i++) {
748        IDockContent content = DisplayingContents[i];
749        if (content.DockHandler.IsDockStateValid(value)) {
750          firstContent = content;
751          break;
752        }
753      }
754      if (firstContent == null)
755        return null;
756
757      firstContent.DockHandler.DockState = value;
758      DockPane pane = firstContent.DockHandler.Pane;
759      DockPanel.SuspendLayout(true);
760      for (int i = 0; i < DisplayingContents.Count; i++) {
761        IDockContent content = DisplayingContents[i];
762        if (content.DockHandler.IsDockStateValid(value))
763          content.DockHandler.Pane = pane;
764      }
765      DockPanel.ResumeLayout(true, true);
766      return pane;
767    }
768
769    private void InternalSetDockState(DockState value) {
770      if (m_dockState == value)
771        return;
772
773      DockState oldDockState = m_dockState;
774      INestedPanesContainer oldContainer = NestedPanesContainer;
775
776      m_dockState = value;
777
778      SuspendRefreshStateChange();
779
780      IDockContent contentFocused = GetFocusedContent();
781      if (contentFocused != null)
782        DockPanel.SaveFocus();
783
784      if (!IsFloat)
785        DockWindow = DockPanel.DockWindows[DockState];
786      else if (FloatWindow == null)
787        FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this);
788
789      if (contentFocused != null)
790        DockPanel.ContentFocusManager.Activate(contentFocused);
791
792      ResumeRefreshStateChange(oldContainer, oldDockState);
793    }
794
795    private int m_countRefreshStateChange = 0;
796    private void SuspendRefreshStateChange() {
797      m_countRefreshStateChange++;
798      DockPanel.SuspendLayout(true);
799    }
800
801    private void ResumeRefreshStateChange() {
802      m_countRefreshStateChange--;
803      System.Diagnostics.Debug.Assert(m_countRefreshStateChange >= 0);
804      DockPanel.ResumeLayout(true, true);
805    }
806
807    private bool IsRefreshStateChangeSuspended {
808      get { return m_countRefreshStateChange != 0; }
809    }
810
811    private void ResumeRefreshStateChange(INestedPanesContainer oldContainer, DockState oldDockState) {
812      ResumeRefreshStateChange();
813      RefreshStateChange(oldContainer, oldDockState);
814    }
815
816    private void RefreshStateChange(INestedPanesContainer oldContainer, DockState oldDockState) {
817      lock (this) {
818        if (IsRefreshStateChangeSuspended)
819          return;
820
821        SuspendRefreshStateChange();
822      }
823
824      DockPanel.SuspendLayout(true);
825
826      IDockContent contentFocused = GetFocusedContent();
827      if (contentFocused != null)
828        DockPanel.SaveFocus();
829      SetParent();
830
831      if (ActiveContent != null)
832        ActiveContent.DockHandler.SetDockState(ActiveContent.DockHandler.IsHidden, DockState, ActiveContent.DockHandler.Pane);
833      foreach (IDockContent content in Contents) {
834        if (content.DockHandler.Pane == this)
835          content.DockHandler.SetDockState(content.DockHandler.IsHidden, DockState, content.DockHandler.Pane);
836      }
837
838      if (oldContainer != null) {
839        Control oldContainerControl = (Control)oldContainer;
840        if (oldContainer.DockState == oldDockState && !oldContainerControl.IsDisposed)
841          oldContainerControl.PerformLayout();
842      }
843      if (DockHelper.IsDockStateAutoHide(oldDockState))
844        DockPanel.RefreshActiveAutoHideContent();
845
846      if (NestedPanesContainer.DockState == DockState)
847        ((Control)NestedPanesContainer).PerformLayout();
848      if (DockHelper.IsDockStateAutoHide(DockState))
849        DockPanel.RefreshActiveAutoHideContent();
850
851      if (DockHelper.IsDockStateAutoHide(oldDockState) ||
852        DockHelper.IsDockStateAutoHide(DockState)) {
853        DockPanel.RefreshAutoHideStrip();
854        DockPanel.PerformLayout();
855      }
856
857      ResumeRefreshStateChange();
858
859      if (contentFocused != null)
860        contentFocused.DockHandler.Activate();
861
862      DockPanel.ResumeLayout(true, true);
863
864      if (oldDockState != DockState)
865        OnDockStateChanged(EventArgs.Empty);
866    }
867
868    private IDockContent GetFocusedContent() {
869      IDockContent contentFocused = null;
870      foreach (IDockContent content in Contents) {
871        if (content.DockHandler.Form.ContainsFocus) {
872          contentFocused = content;
873          break;
874        }
875      }
876
877      return contentFocused;
878    }
879
880    public DockPane DockTo(INestedPanesContainer container) {
881      if (container == null)
882        throw new InvalidOperationException(Strings.DockPane_DockTo_NullContainer);
883
884      DockAlignment alignment;
885      if (container.DockState == DockState.DockLeft || container.DockState == DockState.DockRight)
886        alignment = DockAlignment.Bottom;
887      else
888        alignment = DockAlignment.Right;
889
890      return DockTo(container, container.NestedPanes.GetDefaultPreviousPane(this), alignment, 0.5);
891    }
892
893    public DockPane DockTo(INestedPanesContainer container, DockPane previousPane, DockAlignment alignment, double proportion) {
894      if (container == null)
895        throw new InvalidOperationException(Strings.DockPane_DockTo_NullContainer);
896
897      if (container.IsFloat == this.IsFloat) {
898        InternalAddToDockList(container, previousPane, alignment, proportion);
899        return this;
900      }
901
902      IDockContent firstContent = GetFirstContent(container.DockState);
903      if (firstContent == null)
904        return null;
905
906      DockPane pane;
907      DockPanel.DummyContent.DockPanel = DockPanel;
908      if (container.IsFloat)
909        pane = DockPanel.DockPaneFactory.CreateDockPane(DockPanel.DummyContent, (FloatWindow)container, true);
910      else
911        pane = DockPanel.DockPaneFactory.CreateDockPane(DockPanel.DummyContent, container.DockState, true);
912
913      pane.DockTo(container, previousPane, alignment, proportion);
914      SetVisibleContentsToPane(pane);
915      DockPanel.DummyContent.DockPanel = null;
916
917      return pane;
918    }
919
920    private void SetVisibleContentsToPane(DockPane pane) {
921      SetVisibleContentsToPane(pane, ActiveContent);
922    }
923
924    private void SetVisibleContentsToPane(DockPane pane, IDockContent activeContent) {
925      for (int i = 0; i < DisplayingContents.Count; i++) {
926        IDockContent content = DisplayingContents[i];
927        if (content.DockHandler.IsDockStateValid(pane.DockState)) {
928          content.DockHandler.Pane = pane;
929          i--;
930        }
931      }
932
933      if (activeContent.DockHandler.Pane == pane)
934        pane.ActiveContent = activeContent;
935    }
936
937    private void InternalAddToDockList(INestedPanesContainer container, DockPane prevPane, DockAlignment alignment, double proportion) {
938      if ((container.DockState == DockState.Float) != IsFloat)
939        throw new InvalidOperationException(Strings.DockPane_DockTo_InvalidContainer);
940
941      int count = container.NestedPanes.Count;
942      if (container.NestedPanes.Contains(this))
943        count--;
944      if (prevPane == null && count > 0)
945        throw new InvalidOperationException(Strings.DockPane_DockTo_NullPrevPane);
946
947      if (prevPane != null && !container.NestedPanes.Contains(prevPane))
948        throw new InvalidOperationException(Strings.DockPane_DockTo_NoPrevPane);
949
950      if (prevPane == this)
951        throw new InvalidOperationException(Strings.DockPane_DockTo_SelfPrevPane);
952
953      INestedPanesContainer oldContainer = NestedPanesContainer;
954      DockState oldDockState = DockState;
955      container.NestedPanes.Add(this);
956      NestedDockingStatus.SetStatus(container.NestedPanes, prevPane, alignment, proportion);
957
958      if (DockHelper.IsDockWindowState(DockState))
959        m_dockState = container.DockState;
960
961      RefreshStateChange(oldContainer, oldDockState);
962    }
963
964    public void SetNestedDockingProportion(double proportion) {
965      NestedDockingStatus.SetStatus(NestedDockingStatus.NestedPanes, NestedDockingStatus.PreviousPane, NestedDockingStatus.Alignment, proportion);
966      if (NestedPanesContainer != null)
967        ((Control)NestedPanesContainer).PerformLayout();
968    }
969
970    public DockPane Float() {
971      DockPanel.SuspendLayout(true);
972
973      IDockContent activeContent = ActiveContent;
974
975      DockPane floatPane = GetFloatPaneFromContents();
976      if (floatPane == null) {
977        IDockContent firstContent = GetFirstContent(DockState.Float);
978        if (firstContent == null) {
979          DockPanel.ResumeLayout(true, true);
980          return null;
981        }
982        floatPane = DockPanel.DockPaneFactory.CreateDockPane(firstContent, DockState.Float, true);
983      }
984      SetVisibleContentsToPane(floatPane, activeContent);
985
986      DockPanel.ResumeLayout(true, true);
987      return floatPane;
988    }
989
990    private DockPane GetFloatPaneFromContents() {
991      DockPane floatPane = null;
992      for (int i = 0; i < DisplayingContents.Count; i++) {
993        IDockContent content = DisplayingContents[i];
994        if (!content.DockHandler.IsDockStateValid(DockState.Float))
995          continue;
996
997        if (floatPane != null && content.DockHandler.FloatPane != floatPane)
998          return null;
999        else
1000          floatPane = content.DockHandler.FloatPane;
1001      }
1002
1003      return floatPane;
1004    }
1005
1006    private IDockContent GetFirstContent(DockState dockState) {
1007      for (int i = 0; i < DisplayingContents.Count; i++) {
1008        IDockContent content = DisplayingContents[i];
1009        if (content.DockHandler.IsDockStateValid(dockState))
1010          return content;
1011      }
1012      return null;
1013    }
1014
1015    public void RestoreToPanel() {
1016      DockPanel.SuspendLayout(true);
1017
1018      IDockContent activeContent = DockPanel.ActiveContent;
1019
1020      for (int i = DisplayingContents.Count - 1; i >= 0; i--) {
1021        IDockContent content = DisplayingContents[i];
1022        if (content.DockHandler.CheckDockState(false) != DockState.Unknown)
1023          content.DockHandler.IsFloat = false;
1024      }
1025
1026      DockPanel.ResumeLayout(true, true);
1027    }
1028
1029    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
1030    protected override void WndProc(ref Message m) {
1031      if (m.Msg == (int)Win32.Msgs.WM_MOUSEACTIVATE)
1032        Activate();
1033
1034      base.WndProc(ref m);
1035    }
1036
1037    #region IDockDragSource Members
1038
1039    #region IDragSource Members
1040
1041    Control IDragSource.DragControl {
1042      get { return this; }
1043    }
1044
1045    #endregion
1046
1047    bool IDockDragSource.IsDockStateValid(DockState dockState) {
1048      return IsDockStateValid(dockState);
1049    }
1050
1051    bool IDockDragSource.CanDockTo(DockPane pane) {
1052      if (!IsDockStateValid(pane.DockState))
1053        return false;
1054
1055      if (pane == this)
1056        return false;
1057
1058      return true;
1059    }
1060
1061    Rectangle IDockDragSource.BeginDrag(Point ptMouse) {
1062      Point location = PointToScreen(new Point(0, 0));
1063      Size size;
1064
1065      DockPane floatPane = ActiveContent.DockHandler.FloatPane;
1066      if (DockState == DockState.Float || floatPane == null || floatPane.FloatWindow.NestedPanes.Count != 1)
1067        size = DockPanel.DefaultFloatWindowSize;
1068      else
1069        size = floatPane.FloatWindow.Size;
1070
1071      if (ptMouse.X > location.X + size.Width)
1072        location.X += ptMouse.X - (location.X + size.Width) + Measures.SplitterSize;
1073
1074      return new Rectangle(location, size);
1075    }
1076
1077    public void FloatAt(Rectangle floatWindowBounds) {
1078      if (FloatWindow == null || FloatWindow.NestedPanes.Count != 1)
1079        FloatWindow = DockPanel.FloatWindowFactory.CreateFloatWindow(DockPanel, this, floatWindowBounds);
1080      else
1081        FloatWindow.Bounds = floatWindowBounds;
1082
1083      DockState = DockState.Float;
1084    }
1085
1086    public void DockTo(DockPane pane, DockStyle dockStyle, int contentIndex) {
1087      if (dockStyle == DockStyle.Fill) {
1088        IDockContent activeContent = ActiveContent;
1089        for (int i = Contents.Count - 1; i >= 0; i--) {
1090          IDockContent c = Contents[i];
1091          if (c.DockHandler.DockState == DockState) {
1092            c.DockHandler.Pane = pane;
1093            if (contentIndex != -1)
1094              pane.SetContentIndex(c, contentIndex);
1095          }
1096        }
1097        pane.ActiveContent = activeContent;
1098      } else {
1099        if (dockStyle == DockStyle.Left)
1100          DockTo(pane.NestedPanesContainer, pane, DockAlignment.Left, 0.5);
1101        else if (dockStyle == DockStyle.Right)
1102          DockTo(pane.NestedPanesContainer, pane, DockAlignment.Right, 0.5);
1103        else if (dockStyle == DockStyle.Top)
1104          DockTo(pane.NestedPanesContainer, pane, DockAlignment.Top, 0.5);
1105        else if (dockStyle == DockStyle.Bottom)
1106          DockTo(pane.NestedPanesContainer, pane, DockAlignment.Bottom, 0.5);
1107
1108        DockState = pane.DockState;
1109      }
1110    }
1111
1112    public void DockTo(DockPanel panel, DockStyle dockStyle) {
1113      if (panel != DockPanel)
1114        throw new ArgumentException(Strings.IDockDragSource_DockTo_InvalidPanel, "panel");
1115
1116      if (dockStyle == DockStyle.Top)
1117        DockState = DockState.DockTop;
1118      else if (dockStyle == DockStyle.Bottom)
1119        DockState = DockState.DockBottom;
1120      else if (dockStyle == DockStyle.Left)
1121        DockState = DockState.DockLeft;
1122      else if (dockStyle == DockStyle.Right)
1123        DockState = DockState.DockRight;
1124      else if (dockStyle == DockStyle.Fill)
1125        DockState = DockState.Document;
1126    }
1127
1128    #endregion
1129  }
1130}
Note: See TracBrowser for help on using the repository browser.