1 using System; 2 using System.Collections.Generic; 3 using System.Collections.ObjectModel; 4 using System.Drawing; 5 using System.Windows.Forms; 6 7 namespace WeifenLuo.WinFormsUI.Docking 8 { 9 public sealed class VisibleNestedPaneCollection : ReadOnlyCollection<DockPane> 10 { 11 private NestedPaneCollection m_nestedPanes; 12 VisibleNestedPaneCollection(NestedPaneCollection nestedPanes)13 internal VisibleNestedPaneCollection(NestedPaneCollection nestedPanes) 14 : base(new List<DockPane>()) 15 { 16 m_nestedPanes = nestedPanes; 17 } 18 19 public NestedPaneCollection NestedPanes 20 { 21 get { return m_nestedPanes; } 22 } 23 24 public INestedPanesContainer Container 25 { 26 get { return NestedPanes.Container; } 27 } 28 29 public DockState DockState 30 { 31 get { return NestedPanes.DockState; } 32 } 33 34 public bool IsFloat 35 { 36 get { return NestedPanes.IsFloat; } 37 } 38 Refresh()39 internal void Refresh() 40 { 41 Items.Clear(); 42 for (int i=0; i<NestedPanes.Count; i++) 43 { 44 DockPane pane = NestedPanes[i]; 45 NestedDockingStatus status = pane.NestedDockingStatus; 46 status.SetDisplayingStatus(true, status.PreviousPane, status.Alignment, status.Proportion); 47 Items.Add(pane); 48 } 49 50 foreach (DockPane pane in NestedPanes) 51 if (pane.DockState != DockState || pane.IsHidden) 52 { 53 pane.Bounds = Rectangle.Empty; 54 pane.SplitterBounds = Rectangle.Empty; 55 Remove(pane); 56 } 57 58 CalculateBounds(); 59 60 foreach (DockPane pane in this) 61 { 62 NestedDockingStatus status = pane.NestedDockingStatus; 63 pane.Bounds = status.PaneBounds; 64 pane.SplitterBounds = status.SplitterBounds; 65 pane.SplitterAlignment = status.Alignment; 66 } 67 } 68 Remove(DockPane pane)69 private void Remove(DockPane pane) 70 { 71 if (!Contains(pane)) 72 return; 73 74 NestedDockingStatus statusPane = pane.NestedDockingStatus; 75 DockPane lastNestedPane = null; 76 for (int i=Count - 1; i> IndexOf(pane); i--) 77 { 78 if (PatchController.EnableDisplayingPaneFix == true) 79 { 80 if (this[i].NestedDockingStatus.DisplayingPreviousPane == pane) 81 { 82 lastNestedPane = this[i]; 83 break; 84 } 85 } 86 else 87 { 88 if (this[i].NestedDockingStatus.PreviousPane == pane) 89 { 90 lastNestedPane = this[i]; 91 break; 92 } 93 } 94 } 95 96 if (lastNestedPane != null) 97 { 98 int indexLastNestedPane = IndexOf(lastNestedPane); 99 Items.Remove(lastNestedPane); 100 Items[IndexOf(pane)] = lastNestedPane; 101 NestedDockingStatus lastNestedDock = lastNestedPane.NestedDockingStatus; 102 lastNestedDock.SetDisplayingStatus(true, statusPane.DisplayingPreviousPane, statusPane.DisplayingAlignment, statusPane.DisplayingProportion); 103 for (int i=indexLastNestedPane - 1; i>IndexOf(lastNestedPane); i--) 104 { 105 NestedDockingStatus status = this[i].NestedDockingStatus; 106 if (PatchController.EnableDisplayingPaneFix == true) 107 { 108 if (status.DisplayingPreviousPane == pane) 109 status.SetDisplayingStatus(true, lastNestedPane, status.DisplayingAlignment, status.DisplayingProportion); 110 } 111 else 112 { 113 if (status.PreviousPane == pane) 114 status.SetDisplayingStatus(true, lastNestedPane, status.DisplayingAlignment, status.DisplayingProportion); 115 } 116 } 117 } 118 else 119 Items.Remove(pane); 120 121 statusPane.SetDisplayingStatus(false, null, DockAlignment.Left, 0.5); 122 } 123 CalculateBounds()124 private void CalculateBounds() 125 { 126 if (Count == 0) 127 return; 128 129 this[0].NestedDockingStatus.SetDisplayingBounds(Container.DisplayingRectangle, Container.DisplayingRectangle, Rectangle.Empty); 130 131 for (int i=1; i<Count; i++) 132 { 133 DockPane pane = this[i]; 134 NestedDockingStatus status = pane.NestedDockingStatus; 135 DockPane prevPane = status.DisplayingPreviousPane; 136 NestedDockingStatus statusPrev = prevPane.NestedDockingStatus; 137 138 Rectangle rect = statusPrev.PaneBounds; 139 bool bVerticalSplitter = (status.DisplayingAlignment == DockAlignment.Left || status.DisplayingAlignment == DockAlignment.Right); 140 141 Rectangle rectThis = rect; 142 Rectangle rectPrev = rect; 143 Rectangle rectSplitter = rect; 144 if (status.DisplayingAlignment == DockAlignment.Left) 145 { 146 rectThis.Width = (int)((double)rect.Width * status.DisplayingProportion) - (pane.DockPanel.Theme.Measures.SplitterSize / 2); 147 rectSplitter.X = rectThis.X + rectThis.Width; 148 rectSplitter.Width = pane.DockPanel.Theme.Measures.SplitterSize; 149 rectPrev.X = rectSplitter.X + rectSplitter.Width; 150 rectPrev.Width = rect.Width - rectThis.Width - rectSplitter.Width; 151 } 152 else if (status.DisplayingAlignment == DockAlignment.Right) 153 { 154 rectPrev.Width = (rect.Width - (int)((double)rect.Width * status.DisplayingProportion)) - (pane.DockPanel.Theme.Measures.SplitterSize / 2); 155 rectSplitter.X = rectPrev.X + rectPrev.Width; 156 rectSplitter.Width = pane.DockPanel.Theme.Measures.SplitterSize; 157 rectThis.X = rectSplitter.X + rectSplitter.Width; 158 rectThis.Width = rect.Width - rectPrev.Width - rectSplitter.Width; 159 } 160 else if (status.DisplayingAlignment == DockAlignment.Top) 161 { 162 rectThis.Height = (int)((double)rect.Height * status.DisplayingProportion) - (pane.DockPanel.Theme.Measures.SplitterSize / 2); 163 rectSplitter.Y = rectThis.Y + rectThis.Height; 164 rectSplitter.Height = pane.DockPanel.Theme.Measures.SplitterSize; 165 rectPrev.Y = rectSplitter.Y + rectSplitter.Height; 166 rectPrev.Height = rect.Height - rectThis.Height - rectSplitter.Height; 167 } 168 else if (status.DisplayingAlignment == DockAlignment.Bottom) 169 { 170 rectPrev.Height = (rect.Height - (int)((double)rect.Height * status.DisplayingProportion)) - (pane.DockPanel.Theme.Measures.SplitterSize / 2); 171 rectSplitter.Y = rectPrev.Y + rectPrev.Height; 172 rectSplitter.Height = pane.DockPanel.Theme.Measures.SplitterSize; 173 rectThis.Y = rectSplitter.Y + rectSplitter.Height; 174 rectThis.Height = rect.Height - rectPrev.Height - rectSplitter.Height; 175 } 176 else 177 rectThis = Rectangle.Empty; 178 179 rectSplitter.Intersect(rect); 180 rectThis.Intersect(rect); 181 rectPrev.Intersect(rect); 182 status.SetDisplayingBounds(rect, rectThis, rectSplitter); 183 statusPrev.SetDisplayingBounds(statusPrev.LogicalBounds, rectPrev, statusPrev.SplitterBounds); 184 } 185 } 186 } 187 } 188