Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Mainform refactoring/WinFormsUI/Docking/DockPane.cs @ 2426

Last change on this file since 2426 was 2134, checked in by gkronber, 15 years ago

Added up to date source of Weifen Luo dock panel suit in a separate project (and added strong name key). Removed binary versions of Weifen Luo dock panel suite and references to it. #687 (Update AdvancedOptimizationFrontend to use more recent version of Weifen Luo Docking library)

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