using System; using System.Windows.Forms; using System.Drawing; using System.Xml; using System.ComponentModel; namespace DevComponents.DotNetBar { /// /// Represents class that manages document docking UI interaction. /// public class DocumentDockUIManager { #region Private Variables, Constructor private DocumentDockContainer m_DocumentDockContainer=null; private Cursor m_ContainerCursor=null; private DockSite m_Container=null; private Point m_MouseDownPoint=Point.Empty; private bool m_ResizePreview=false; private Form m_Splitter=null; private DocumentDockContainer m_ResizeDockContainer=null; private DocumentBaseContainer m_ResizeDocument=null; private int m_SplitterWidth=3; private bool m_LoadingLayout=false; public DocumentDockUIManager(DockSite container) { m_Container=container; } #endregion #region Properties /// /// Gets or sets the root document dock container object. /// public DocumentDockContainer RootDocumentDockContainer { get {return m_DocumentDockContainer;} set {m_DocumentDockContainer=value;} } /// /// Gets or sets the splitter width used for mouse hit-testing. /// public int SplitterWidth { get { return m_SplitterWidth; } set { m_SplitterWidth = value; } } /// /// Gets or sets the container of the document. /// public DockSite Container { get {return m_Container;} set {m_Container=value;} } #endregion #region Methods /// /// Estimates the docking position and size of a given bar for outline purposes during drag&drop /// /// Bar to find estimated docking position and size for /// Docking information /// Preview Rectangle in screen coordinates. internal Rectangle GetDockPreviewRectangle(Bar bar, ref DockSiteInfo dockInfo) { DocumentBaseContainer referenceDoc=GetDocumentFromBar(dockInfo.MouseOverBar); Rectangle r=Rectangle .Empty; // Handle edge case docking first if (m_Container.Dock!= DockStyle.Fill && (dockInfo.DockLine == 999 || dockInfo.DockLine == -1)) { return GetEdgeDockPreviewRectangle(bar, ref dockInfo); } else if(referenceDoc!=null) { if(dockInfo.MouseOverDockSide==eDockSide.Left) { r=referenceDoc.DisplayBounds; r.Width=r.Width/2; } else if(dockInfo.MouseOverDockSide==eDockSide.Right) { r=referenceDoc.DisplayBounds; r.X+=r.Width/2; r.Width=r.Width/2; } else if(dockInfo.MouseOverDockSide==eDockSide.Top) { r=referenceDoc.DisplayBounds; r.Height=r.Height/2; } else if(dockInfo.MouseOverDockSide==eDockSide.Bottom) { r=referenceDoc.DisplayBounds; r.Y+=r.Height/2; r.Height=r.Height/2; } else if(dockInfo.MouseOverDockSide==eDockSide.Document) { r=referenceDoc.DisplayBounds; } r.Location=m_Container.PointToScreen(r.Location); } else { if (m_Container.Dock == DockStyle.Fill) { r = m_Container.ClientRectangle; r.Location = m_Container.PointToScreen(r.Location); } else if (m_Container.Dock == DockStyle.Right) { r = m_Container.ClientRectangle; r.Location = m_Container.PointToScreen(r.Location); if (r.Width == 0) { r.Width = bar.GetBarDockedSize(eOrientation.Vertical); r.X -= r.Width; } } else if (m_Container.Dock == DockStyle.Left) { r = m_Container.ClientRectangle; r.Location = m_Container.PointToScreen(r.Location); if (r.Width == 0) { r.Width = bar.GetBarDockedSize(eOrientation.Vertical); } } else if (m_Container.Dock == DockStyle.Top) { r = m_Container.ClientRectangle; r.Location = m_Container.PointToScreen(r.Location); if (r.Height == 0) { r.Height = bar.GetBarDockedSize(eOrientation.Horizontal); } } else if (m_Container.Dock == DockStyle.Bottom) { r = m_Container.ClientRectangle; r.Location = m_Container.PointToScreen(r.Location); if (r.Height == 0) { r.Height = bar.GetBarDockedSize(eOrientation.Horizontal); r.Y -= r.Height; } } } return r; } private Rectangle GetEdgeDockPreviewRectangle(Bar bar, ref DockSiteInfo dockInfo) { Rectangle r = Rectangle.Empty; int fullSizeIndex = -1; int partialSizeIndex = -1; if (dockInfo.FullSizeDock) fullSizeIndex = m_Container.GetFullSizeIndex(); else if (dockInfo.PartialSizeDock) partialSizeIndex = m_Container.GetPartialSizeIndex(); // Docks the bar to the edge switch (m_Container.Dock) { case DockStyle.Top: { r.Width = m_Container.ClientRectangle.Width; r.Height = bar.GetBarDockedSize(eOrientation.Horizontal); if (fullSizeIndex >= 0) { r.Width += m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, true).Width; r.Width += m_Container.GetSiteZOrderSize(m_Container.Owner.RightDockSite, true).Width; dockInfo.DockSiteZOrderIndex = fullSizeIndex; } else if (partialSizeIndex >= 0) { // Reduce by the size of the left and right dock site r.Width -= m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, false).Width; r.Width -= m_Container.GetSiteZOrderSize(m_Container.Owner.RightDockSite, false).Width; dockInfo.DockSiteZOrderIndex = partialSizeIndex; } Point p = Point.Empty; if (dockInfo.DockLine == -1) { p = m_Container.PointToScreen(m_Container.ClientRectangle.Location); } else { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.X, m_Container.ClientRectangle.Bottom)); p.Y++; } if (fullSizeIndex >= 0) p.X -= m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, true).Width; else if (partialSizeIndex >= 0) p.X += m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, false).Width; r.Location = p; break; } case DockStyle.Bottom: { r.Width = m_Container.ClientRectangle.Width; r.Height = bar.GetBarDockedSize(eOrientation.Horizontal); if (fullSizeIndex >= 0) { r.Width += m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, true).Width; r.Width += m_Container.GetSiteZOrderSize(m_Container.Owner.RightDockSite, true).Width; dockInfo.DockSiteZOrderIndex = fullSizeIndex; } else if (partialSizeIndex >= 0) { // Reduce by the size of the left and right dock site r.Width -= m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, false).Width; r.Width -= m_Container.GetSiteZOrderSize(m_Container.Owner.RightDockSite, false).Width; dockInfo.DockSiteZOrderIndex = partialSizeIndex; } Point p = Point.Empty; if (dockInfo.DockLine == -1) { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.X, m_Container.ClientRectangle.Y - r.Height)); } else { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.X, m_Container.ClientRectangle.Bottom - r.Height)); p.Y++; } if (fullSizeIndex >= 0) p.X -= m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, true).Width; else if (partialSizeIndex >= 0) p.X += m_Container.GetSiteZOrderSize(m_Container.Owner.LeftDockSite, false).Width; r.Location = p; break; } case DockStyle.Right: { r.Height = m_Container.ClientRectangle.Height; if (fullSizeIndex >= 0) { r.Height += m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, true).Height; r.Height += m_Container.GetSiteZOrderSize(m_Container.Owner.BottomDockSite, true).Height; dockInfo.DockSiteZOrderIndex = fullSizeIndex; } else if (partialSizeIndex >= 0) { // Reduce by the size of the top and bottom dock site r.Height -= m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, false).Height; r.Height -= m_Container.GetSiteZOrderSize(m_Container.Owner.BottomDockSite, false).Height; dockInfo.DockSiteZOrderIndex = partialSizeIndex; } r.Width = bar.GetBarDockedSize(eOrientation.Vertical); Point p = Point.Empty; if (dockInfo.DockLine == -1) { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.X - r.Width, m_Container.ClientRectangle.Y)); } else { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.Right - r.Width, m_Container.ClientRectangle.Y)); p.X--; } if (fullSizeIndex >= 0) p.Y -= m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, true).Height; else if (partialSizeIndex >= 0) p.Y += m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, false).Height; r.Location = p; break; } default: { r.Height = m_Container.ClientRectangle.Height; if (fullSizeIndex >= 0) { r.Height += m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, true).Height; r.Height += m_Container.GetSiteZOrderSize(m_Container.Owner.BottomDockSite, true).Height; dockInfo.DockSiteZOrderIndex = fullSizeIndex; } else if (partialSizeIndex >= 0) { // Reduce by the size of the top and bottom dock site r.Height -= m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, false).Height; r.Height -= m_Container.GetSiteZOrderSize(m_Container.Owner.BottomDockSite, false).Height; dockInfo.DockSiteZOrderIndex = partialSizeIndex; } r.Width = bar.GetBarDockedSize(eOrientation.Vertical); Point p = Point.Empty; if (dockInfo.DockLine == -1) { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.X, m_Container.ClientRectangle.Y)); } else { p = m_Container.PointToScreen(new Point(m_Container.ClientRectangle.Right, m_Container.ClientRectangle.Y)); p.X++; } if (fullSizeIndex >= 0) p.Y -= m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, true).Height; else if (partialSizeIndex >= 0) p.Y += m_Container.GetSiteZOrderSize(m_Container.Owner.TopDockSite, false).Height; r.Location = p; break; } } return r; } /// /// Returns DocumentBaseContainer that holds the reference bar. /// /// Bar to return document container for. /// Returns null if document container cannot be found or reference to the document container. public DocumentBaseContainer GetDocumentFromBar(Bar bar) { if(bar==null) return null; return GetDocumentFromBar(bar,m_DocumentDockContainer); } private DocumentBaseContainer GetDocumentFromBar(Bar bar, DocumentDockContainer dockContainer) { foreach(DocumentBaseContainer doc in dockContainer.Documents) { if(doc is DocumentBarContainer && ((DocumentBarContainer)doc).Bar==bar) return doc; else if(doc is DocumentDockContainer) { DocumentBaseContainer d=GetDocumentFromBar(bar,doc as DocumentDockContainer); if(d!=null) return d; } } return null; } private bool IsAddedInFront(eDockSide dockSide) { if (m_Container.Dock == DockStyle.Left && dockSide == eDockSide.Left || m_Container.Dock == DockStyle.Right && dockSide == eDockSide.Left || m_Container.Dock == DockStyle.Top && dockSide== eDockSide.Top || m_Container.Dock == DockStyle.Bottom && dockSide == eDockSide.Top) return true; return false; } /// /// Docks specified bar by appending it to the container. Bar will be added according to the container's orientation. /// /// Bar to dock. public void Dock(Bar barToDock) { Dock(null,barToDock,eDockSide.None); } /// /// Docks specified bar by appending it to the container. Bar will be added according to the container's orientation. /// /// Bar to dock. /// Side to dock bar at. public void Dock(Bar referenceBar, Bar barToDock, eDockSide dockSide) { if(dockSide==eDockSide.None && barToDock.Parent==m_Container) { ApplyBarStyle(barToDock); return; } if(barToDock.Parent is DockSite && ((DockSite)barToDock.Parent).DocumentDockContainer!=null) ((DockSite)barToDock.Parent).GetDocumentUIManager().UnDock(barToDock); else if(barToDock.Parent is DockSite && barToDock.Parent!=m_Container) ((DockSite)barToDock.Parent).RemoveBar(barToDock); else if (barToDock.Parent != null && barToDock.Parent != m_Container) { if (barToDock.Parent is FloatingContainer) { barToDock.RemoveFromFloatingContainer(); barToDock.SetBarState(eBarState.Docked); } else barToDock.Parent.Controls.Remove(barToDock); } if(!m_LoadingLayout) { // TODO: Add Docking as Document, i.e. add DockContainerItems from barToDock... DocumentBarContainer doc=this.CreateDocumentBarContainer(barToDock); DocumentBaseContainer referenceDoc = this.GetDocumentFromBar(referenceBar); if (referenceBar == null || dockSide == eDockSide.None || referenceBar == barToDock || referenceDoc == null) { if (m_Container.Dock == DockStyle.Fill) m_DocumentDockContainer.Documents.Add(doc); else { eOrientation containerOrientation = eOrientation.Horizontal; // Needed container orientation if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) containerOrientation = eOrientation.Vertical; // Switch orientation when adding new bar if possible if (m_DocumentDockContainer.Orientation != containerOrientation) { if (m_DocumentDockContainer.Documents.Count <= 1) { m_DocumentDockContainer.Orientation = containerOrientation; if (IsAddedInFront(dockSide)) m_DocumentDockContainer.Documents.Insert(0, doc); else m_DocumentDockContainer.Documents.Add(doc); } else { DocumentBaseContainer[] docs = new DocumentBaseContainer[m_DocumentDockContainer.Documents.Count]; m_DocumentDockContainer.Documents.CopyTo(docs); m_DocumentDockContainer.Documents.Clear(); DocumentDockContainer newParent = new DocumentDockContainer(docs, m_DocumentDockContainer.Orientation); newParent.SetLayoutBounds(m_DocumentDockContainer.DisplayBounds); m_DocumentDockContainer.Orientation = containerOrientation; m_DocumentDockContainer.Documents.Add(newParent); if (IsAddedInFront(dockSide)) m_DocumentDockContainer.Documents.Insert(0, doc); else m_DocumentDockContainer.Documents.Add(doc); } } else { if (IsAddedInFront(dockSide)) m_DocumentDockContainer.Documents.Insert(0, doc); else m_DocumentDockContainer.Documents.Add(doc); } } } else { DocumentDockContainer parent=referenceDoc.Parent as DocumentDockContainer; referenceDoc.SetLayoutBounds(Rectangle.Empty); doc.SetLayoutBounds(Rectangle.Empty); if((parent.Orientation==eOrientation.Horizontal && (dockSide==eDockSide.Left || dockSide==eDockSide.Right)) || (parent.Orientation==eOrientation.Vertical && (dockSide==eDockSide.Top || dockSide==eDockSide.Bottom))) { if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom) parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc)+1,doc); else parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),doc); } else if(parent.Documents.Count==1) { // Orientation of the parent dock container can be changed if(parent.Orientation==eOrientation.Vertical) parent.Orientation=eOrientation.Horizontal; else parent.Orientation=eOrientation.Vertical; if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom) parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc)+1,doc); else parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),doc); } else { // New DocumentDockContainer needs to be inserted with appropriate orientation and referenceBar needs // to be moved into it. DocumentDockContainer newParent=new DocumentDockContainer(); if(parent.Orientation==eOrientation.Horizontal) newParent.Orientation=eOrientation.Vertical; else newParent.Orientation=eOrientation.Horizontal; parent.Documents.Insert(parent.Documents.IndexOf(referenceDoc),newParent); parent.Documents.Remove(referenceDoc); if(dockSide==eDockSide.Right || dockSide==eDockSide.Bottom) { newParent.Documents.Add(referenceDoc); newParent.Documents.Add(doc); } else { newParent.Documents.Add(doc); newParent.Documents.Add(referenceDoc); } } } AdjustContainerSize(barToDock, false); } if(m_Container!=null) { if(barToDock.Parent==null) m_Container.Controls.Add(barToDock); ApplyBarStyle(barToDock); m_Container.RecalcLayout(); } else ApplyBarStyle(barToDock); } /// /// Adjusts the size of the dock container if needed after a bar has been docked to it. /// /// Bar object that has been docked. /// Indicates that bar was already docked but its Visible property has changed internal void AdjustContainerSize(Bar barToDock, bool visibleChanged) { if (m_Container.Owner != null && m_Container.Owner.IsLoadingLayout) return; // Adjust the size of the container since it dictates the size of the bars docked inside if (m_Container.Dock != DockStyle.Fill) { DocumentBaseContainer doc = this.GetDocumentFromBar(barToDock); if (doc == null) return; if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) { if (m_Container.Width == 0 || doc.Parent == m_DocumentDockContainer && (m_DocumentDockContainer.Orientation == eOrientation.Horizontal || visibleChanged && m_DocumentDockContainer.Documents.Count == 1)) { int width = barToDock.GetBarDockedSize(eOrientation.Vertical); if (barToDock.Width > 0 && barToDock.Width clientWidth) width = barToDock.MinimumDockSize(eOrientation.Vertical).Width * 2; if (width > clientWidth) width = barToDock.MinimumDockSize(eOrientation.Vertical).Width; } if(doc.LayoutBounds.Width == 0) doc.SetLayoutBounds(new Rectangle(doc.LayoutBounds.X, doc.LayoutBounds.Y, width, doc.LayoutBounds.Height)); width += Dpi.Width(m_DocumentDockContainer.SplitterSize); if (visibleChanged) { if(barToDock.Visible) m_Container.Width += width; else if(m_Container.Width>0) m_Container.Width -= Math.Min(width, m_Container.Width); } else m_Container.Width += width; m_Container.Invalidate(); } } else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) { if (m_Container.Height == 0 || doc.Parent == m_DocumentDockContainer && (m_DocumentDockContainer.Orientation == eOrientation.Vertical || visibleChanged && m_DocumentDockContainer.Documents.Count == 1)) { int height = barToDock.GetBarDockedSize(eOrientation.Horizontal); if (barToDock.Height > 0 && barToDock.Height clientHeight) height = barToDock.MinimumDockSize(eOrientation.Horizontal).Height * 2; if (height > clientHeight) height = barToDock.MinimumDockSize(eOrientation.Horizontal).Height; } if(doc.LayoutBounds.Height == 0) doc.SetLayoutBounds(new Rectangle(doc.LayoutBounds.X, doc.LayoutBounds.Y, doc.LayoutBounds.Width, height)); height += Dpi.Width(m_DocumentDockContainer.SplitterSize); if (visibleChanged) { if (barToDock.Visible) m_Container.Height += height; else if (m_Container.Height > 0) m_Container.Height -= Math.Min(height, m_Container.Height); } else m_Container.Height += height; m_Container.Invalidate(); } } } } private int GetClientWidth() { if (m_Container == null) return 0; return m_Container.GetClientWidth(); } private int GetClientHeight() { if (m_Container == null) return 0; return m_Container.GetClientHeight(); } public void UnDock(Bar barToUnDock) { UnDock(barToUnDock,true); } internal void SaveLastDockInfo(Bar bar, DocumentBarContainer doc, DockSiteInfo info) { if (bar.m_LastDockSiteInfo == null) return; //bar.m_LastDockSiteInfo.LastRelativeDockToBar = null; //bar.m_LastDockSiteInfo.LastRelativeDocumentId = -1; // Tries to find relative dock-to-bar so un-docked bar can be returned back if (!(doc.Parent is DocumentDockContainer)) return; DocumentDockContainer dockParent = (DocumentDockContainer)doc.Parent; DocumentBaseContainer nextBarDocument = GetNextDocument(dockParent, dockParent.Documents.IndexOf(doc)); if (nextBarDocument == null) { DocumentBaseContainer prevBarDocument = GetPreviousDocument(dockParent, dockParent.Documents.IndexOf(doc)); if (prevBarDocument != null) { Bar prevBar = null; if (prevBarDocument is DocumentBarContainer) { prevBar = ((DocumentBarContainer)prevBarDocument).Bar; bar.m_LastDockSiteInfo.LastRelativeDockToBar = prevBar; prevBar.m_LastDockSiteInfo.LastRelativeDockToBar = bar; prevBar.m_LastDockSiteInfo.LastRelativeDocumentId = doc.Id; } bar.m_LastDockSiteInfo.LastRelativeDocumentId = prevBarDocument.Id; if (dockParent.Orientation == eOrientation.Horizontal) { bar.LastDockSide = eDockSide.Right; if (prevBar != null) prevBar.LastDockSide = eDockSide.Left; } else { bar.LastDockSide = eDockSide.Bottom; if (prevBar != null) prevBar.LastDockSide = eDockSide.Top; } } } else { Bar nextBar = null; if (nextBarDocument is DocumentBarContainer) { nextBar = ((DocumentBarContainer)nextBarDocument).Bar; bar.m_LastDockSiteInfo.LastRelativeDockToBar = nextBar; nextBar.m_LastDockSiteInfo.LastRelativeDockToBar = bar; nextBar.m_LastDockSiteInfo.LastRelativeDocumentId = doc.Id; } bar.m_LastDockSiteInfo.LastRelativeDocumentId = nextBarDocument.Id; if (dockParent.Orientation == eOrientation.Horizontal) { bar.LastDockSide = eDockSide.Left; if (nextBar != null) nextBar.LastDockSide = eDockSide.Right; } else { bar.LastDockSide = eDockSide.Top; if (nextBar != null) nextBar.LastDockSide = eDockSide.Bottom; } } if (GetDockSide(bar) != eDockSide.None) bar.m_LastDockSiteInfo.LastDockSiteSide = GetDockSide(bar); } private eDockSide GetDockSide(Bar bar) { if (bar.Parent == null) return eDockSide.None; else if (bar.Parent.Dock == DockStyle.Left) return eDockSide.Left; else if (bar.Parent.Dock == DockStyle.Right) return eDockSide.Right; else if (bar.Parent.Dock == DockStyle.Top) return eDockSide.Top; else if (bar.Parent.Dock == DockStyle.Bottom) return eDockSide.Bottom; else if (bar.Parent.Dock == DockStyle.Fill) return eDockSide.Document; return eDockSide.None; } [EditorBrowsable(EditorBrowsableState.Never)] public void UnDock(Bar barToUnDock, bool removeFromContainer) { DocumentBarContainer doc=m_DocumentDockContainer.GetBarDocumentContainer(barToUnDock); if (barToUnDock.DockSide != eDockSide.None) barToUnDock.LastDockSide = barToUnDock.DockSide; if (doc != null) SaveLastDockInfo(barToUnDock, doc, barToUnDock.m_LastDockSiteInfo); int containerSizeReduction = 0; // Calculate the size reduction of container if needed if (doc != null && m_Container != null && m_Container.Dock != DockStyle.Fill) { if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) { if (doc.Parent != null && doc.Parent == m_DocumentDockContainer && m_DocumentDockContainer.Orientation == eOrientation.Horizontal) containerSizeReduction = barToUnDock.Width + Dpi.Width(m_DocumentDockContainer.SplitterSize); } else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) { if (doc.Parent != null && doc.Parent == m_DocumentDockContainer && m_DocumentDockContainer.Orientation == eOrientation.Vertical) containerSizeReduction = barToUnDock.Height + Dpi.Width(m_DocumentDockContainer.SplitterSize); } } if(doc==null) { if (removeFromContainer && barToUnDock.Parent == m_Container) m_Container.Controls.Remove(barToUnDock); RestoreBarStyle(barToUnDock); return; } DocumentDockContainer parent=doc.Parent as DocumentDockContainer; if(parent!=null) { parent.Documents.Remove(doc); if(parent!=m_DocumentDockContainer) RemoveEmptyContainers(parent); else if(parent.Documents.Count==1 && parent.Documents[0] is DocumentDockContainer) RemoveEmptyContainers(parent.Documents[0] as DocumentDockContainer); } if(m_Container!=null) { if(removeFromContainer) m_Container.Controls.Remove(barToUnDock); RestoreBarStyle(barToUnDock); bool isLoadingLayout = false; if (m_Container.Owner != null) isLoadingLayout = m_Container.Owner.IsLoadingLayout; if (!isLoadingLayout && !m_Container.IsAnyControlVisible) { if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) m_Container.Width = 0; else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) m_Container.Height = 0; } else if (!isLoadingLayout && containerSizeReduction != 0) { if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) m_Container.Width -= containerSizeReduction; else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) m_Container.Height -= containerSizeReduction; } else m_Container.RecalcLayout(); } else RestoreBarStyle(barToUnDock); } private void RemoveEmptyContainers(DocumentDockContainer parent) { while(parent.Documents.Count==0 && parent.Parent!=null && parent.Parent is DocumentDockContainer || parent.Parent!=null && parent.Parent is DocumentDockContainer && (((DocumentDockContainer)parent.Parent).Documents.Count==1 || parent.Documents.Count == 1)) { if(parent.Parent!=null && parent.Parent is DocumentDockContainer && ((DocumentDockContainer)parent.Parent).Documents.Count==1) { // Removes the instances where DocumentDockContainer hosts another one and only one DocumentDockContainer object DocumentDockContainer p=parent.Parent as DocumentDockContainer; p.Orientation = parent.Orientation; p.Documents.Remove(parent); DocumentBaseContainer[] documents=new DocumentBaseContainer[parent.Documents.Count]; parent.Documents.CopyTo(documents); p.Documents.AddRange(documents); parent=p; } else if (parent.Parent != null && parent.Parent is DocumentDockContainer && parent.Documents.Count == 1) { DocumentDockContainer p = parent.Parent as DocumentDockContainer; int index = p.Documents.IndexOf(parent); p.Documents.Remove(parent); DocumentBaseContainer document = parent.Documents[0]; p.Documents.Insert(index, document); parent = p; } else { DocumentDockContainer p=parent.Parent as DocumentDockContainer; p.Documents.Remove(parent); parent=p; } } } private void ApplyBarStyle(Bar bar) { if(m_Container!=null && m_Container.Owner!=null && m_Container.Owner.ApplyDocumentBarStyle && m_Container.Dock == DockStyle.Fill) { BarFunctions.ApplyAutoDocumentBarStyle(bar); } } private void RestoreBarStyle(Bar bar) { if (m_Container != null && m_Container.Owner != null && m_Container.Owner.ApplyDocumentBarStyle && m_Container.Dock == DockStyle.Fill) { BarFunctions.RestoreAutoDocumentBarStyle(bar); } } private DocumentBarContainer CreateDocumentBarContainer(Bar bar) { DocumentBarContainer doc=new DocumentBarContainer(bar); return doc; } private DocumentDockContainer CreateDocumentDockContainer() { DocumentDockContainer dock=new DocumentDockContainer(); return dock; } #endregion #region Mouse Resize Handling /// /// Gets whether document/bar is being resized. /// public bool IsResizingDocument { get { return (m_ResizeDocument != null); } } /// /// Processes OnMouseMove events from DockSite. This routine assumes that mouse messages are received only when mouse is actually over /// the dock site and not containing bars. This is significant because it will receive messages only if mouse is over the splitter /// space between bars. /// /// Mouse event arguments. public void OnMouseMove(MouseEventArgs e) { int x=e.X,y=e.Y; if(e.Button==MouseButtons.None) { Cursor c=this.GetCursor(x,y); if(c==null) { if(m_ContainerCursor!=null) this.Container.Cursor=m_ContainerCursor; m_ContainerCursor=null; } else { if(m_ContainerCursor==null) m_ContainerCursor=this.Container.Cursor; this.Container.Cursor=c; } } else if(e.Button==MouseButtons.Left) { Point p=GetResizeToPoint(x,y); if(p.IsEmpty) return; if(!m_ResizePreview) SplitterMouseMove(p.X,p.Y); else { ResizeTo(p.X,p.Y); m_MouseDownPoint=p; } } } [EditorBrowsable(EditorBrowsableState.Never)] public Cursor GetCursor(int x, int y) { Cursor c=null; DocumentDockContainer context=this.GetContainerFromRoot(x,y); if(context!=null) { if(context.Orientation==eOrientation.Horizontal) c=Cursors.VSplit; else if(context.Orientation==eOrientation.Vertical) c=Cursors.HSplit; } else if (m_Container != null && m_Container.Dock != DockStyle.Fill) { if(m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) c = Cursors.HSplit; else if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) c = Cursors.VSplit; } return c; } public void OnMouseDown(MouseEventArgs e) { int x=e.X, y=e.Y; if(e.Button==MouseButtons.Left) { m_MouseDownPoint=new Point(x,y); DocumentDockContainer context=this.GetContainerFromRoot(x,y); if(context!=null) { m_ResizeDocument=this.GetClosestDocument(context,x,y); if(m_ResizeDocument==null) return; m_ResizeDockContainer=context; if(!m_ResizePreview) { CreateSplitter(); SplitterMouseMove(x,y); } } else if (m_Container != null && m_Container.Dock != DockStyle.Fill) { m_ResizeDockContainer = m_DocumentDockContainer; if (!m_ResizePreview) { CreateSplitter(); SplitterMouseMove(x, y); } } } } public void OnMouseUp(MouseEventArgs e) { if(m_ResizeDockContainer!=null && !m_MouseDownPoint.IsEmpty) { ResizeTo(e.X,e.Y); } m_MouseDownPoint=Point.Empty; m_ResizeDockContainer=null; m_ResizeDocument=null; DestroySplitter(); } public void OnMouseLeave() { if(m_ContainerCursor!=null) this.Container.Cursor=m_ContainerCursor; m_ContainerCursor=null; } private DocumentBaseContainer GetClosestDocument(DocumentDockContainer parent, int x, int y) { DocumentBaseContainer ret=null; eOrientation orientation=parent.Orientation; foreach(DocumentBaseContainer doc in parent.Documents) { if(orientation==eOrientation.Horizontal && doc.DisplayBounds.X>x && doc.Visible) break; else if(orientation==eOrientation.Vertical && doc.DisplayBounds.Y>y && doc.Visible) break; if(doc.Visible) ret=doc; } return ret; } /// /// Returns reference to the DocumentDockContainer that contains specified coordinates. Searches through the Documents collection first. /// /// X coordinate /// Y coordinate /// private DocumentDockContainer GetContainerFromRoot(int x, int y) { return GetContainer(m_DocumentDockContainer,x,y); } private DocumentDockContainer GetContainer(DocumentDockContainer parent, int x, int y) { if(parent==null || !parent.DisplayBounds.Contains(x,y) || !parent.Visible) return null; DocumentDockContainer ret=null; foreach(DocumentBaseContainer doc in parent.Documents) { if(doc is DocumentDockContainer) { ret=this.GetContainer((DocumentDockContainer)doc,x,y); if(ret!=null) break; } } if (ret == null) ret = parent; return ret; } private void CreateSplitter() { if (m_ResizeDockContainer == null) return; if(m_Splitter==null) m_Splitter=BarFunctions.CreateOutlineForm(); } private void SplitterMouseMove(int x, int y) { if(m_Splitter==null || m_ResizeDockContainer==null) return; Rectangle splitterBounds=Rectangle.Empty; // Set splitter size int splitterWidth = Dpi.Width(m_SplitterWidth); if (m_ResizeDockContainer.Orientation == eOrientation.Horizontal && m_ResizeDocument != null || m_ResizeDocument == null && (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right)) { Point p=m_Container.PointToScreen(new Point(x-splitterWidth/2,m_ResizeDockContainer.DisplayBounds.Y)); splitterBounds.X=p.X; splitterBounds.Y=p.Y; splitterBounds.Height=m_ResizeDockContainer.DisplayBounds.Height; splitterBounds.Width=splitterWidth; } else if (m_ResizeDockContainer.Orientation == eOrientation.Vertical && m_ResizeDocument != null || m_ResizeDocument == null && (m_Container.Dock == DockStyle.Bottom || m_Container.Dock == DockStyle.Top)) { Point p=m_Container.PointToScreen(new Point(m_ResizeDockContainer.DisplayBounds.X,y-splitterWidth/2)); splitterBounds.X=p.X; splitterBounds.Y=p.Y; splitterBounds.Width=m_ResizeDockContainer.DisplayBounds.Width; splitterBounds.Height=splitterWidth; } NativeFunctions.SetWindowPos(m_Splitter.Handle,new IntPtr(NativeFunctions.HWND_TOP),splitterBounds.X,splitterBounds.Y,splitterBounds.Width,splitterBounds.Height,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); } private void DestroySplitter() { if(m_Splitter!=null) { m_Splitter.Visible=false; m_Splitter.Dispose(); m_Splitter=null; } } internal Size GetContainerMinimumSize(DocumentDockContainer dockContainer) { Size minimumSize = Size.Empty; foreach (DocumentBaseContainer d in dockContainer.Documents) { Size dm = Size.Empty; if (d is DocumentBarContainer) { if (!((DocumentBarContainer)d).Visible) continue; dm = d.MinimumSize; } else if (d is DocumentDockContainer) { dm = GetContainerMinimumSize(d as DocumentDockContainer); } if (dockContainer.Orientation == eOrientation.Horizontal) { minimumSize.Width += dm.Width + Dpi.Width(dockContainer.SplitterSize); if (dm.Height < minimumSize.Height || minimumSize.Height == 0) minimumSize.Height = dm.Height; } else { minimumSize.Height += dm.Height + Dpi.Width(dockContainer.SplitterSize); if (dm.Width < minimumSize.Width || minimumSize.Width == 0) minimumSize.Width = dm.Width; } } if (minimumSize.Width > 0 && dockContainer.Orientation == eOrientation.Horizontal) minimumSize.Width += Dpi.Width(dockContainer.SplitterSize); else if (minimumSize.Height > 0 && dockContainer.Orientation == eOrientation.Vertical) minimumSize.Height += Dpi.Width(dockContainer.SplitterSize); if (minimumSize.Width == 0) minimumSize.Width = 32; if (minimumSize.Height == 0) minimumSize.Height = 32; return minimumSize; } private Point GetResizeToPoint(int x, int y) { if(m_ResizeDockContainer==null) return Point.Empty; Point resizeTo=new Point(x,y); int xDiff=x-m_MouseDownPoint.X; int yDiff=y-m_MouseDownPoint.Y; if (m_ResizeDocument == null) { // Resizing the dock site if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) { if (m_Container.Dock == DockStyle.Right) xDiff *= -1; Size minimumSize = GetContainerMinimumSize(m_ResizeDockContainer); if (m_ResizeDockContainer.DisplayBounds.Width + xDiff < minimumSize.Width) resizeTo.X -= ((m_ResizeDockContainer.DisplayBounds.Width + xDiff) - minimumSize.Width) * ((m_Container.Dock == DockStyle.Right ? -1 : 1)); else { int clientWidth = GetClientWidth(); int minClientWidth = 32; if (m_Container.Owner != null) minClientWidth = m_Container.Owner.MinimumClientSize.Width; if (clientWidth - xDiff < minClientWidth) resizeTo.X -= (minClientWidth - (clientWidth - xDiff)) * ((m_Container.Dock == DockStyle.Right ? -1 : 1)); } return resizeTo; } else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) { if (m_Container.Dock == DockStyle.Bottom) yDiff *= -1; Size minimumSize = GetContainerMinimumSize(m_ResizeDockContainer); if (m_ResizeDockContainer.DisplayBounds.Height + yDiff < minimumSize.Height) resizeTo.Y -= ((m_ResizeDockContainer.DisplayBounds.Height + yDiff) - minimumSize.Height) * ((m_Container.Dock == DockStyle.Bottom ? -1 : 1)); else { int clientHeight = GetClientHeight(); int minClientHeight = 32; if (m_Container.Owner != null) minClientHeight = m_Container.Owner.MinimumClientSize.Height; if (clientHeight - yDiff < minClientHeight) resizeTo.Y -= (minClientHeight - (clientHeight - yDiff)) * ((m_Container.Dock == DockStyle.Bottom ? -1 : 1)); } return resizeTo; } return Point.Empty; } else if(m_ResizeDockContainer.Orientation==eOrientation.Horizontal) { if(m_ResizeDocument.DisplayBounds.Width+xDiff>=m_ResizeDocument.MinimumSize.Width) { // Verify document next to it DocumentBaseContainer nextDoc=GetNextDocument(m_ResizeDockContainer,m_ResizeDockContainer.Documents.IndexOf(m_ResizeDocument)); if(nextDoc!=null) { if(nextDoc.DisplayBounds.Width-xDiff=m_ResizeDocument.MinimumSize.Height) { DocumentBaseContainer nextDoc=GetNextDocument(m_ResizeDockContainer,m_ResizeDockContainer.Documents.IndexOf(m_ResizeDocument)); if(nextDoc!=null) { if(nextDoc.DisplayBounds.Height-yDiff 0) { DocumentBaseContainer lastDoc = m_DocumentDockContainer.Documents[m_DocumentDockContainer.Documents.Count - 1]; int docWidth = lastDoc.DisplayBounds.Width + xDiff; if (docWidth > lastDoc.MinimumSize.Width) lastDoc.SetLayoutBounds(new Rectangle(lastDoc.DisplayBounds.X, lastDoc.DisplayBounds.Y, docWidth, lastDoc.DisplayBounds.Height)); else ResetLayoutBounds(m_DocumentDockContainer); } m_Container.Width = m_Container.Width + xDiff; if(m_Container.Width <= this.GetContainerMinimumSize(m_DocumentDockContainer).Width) ResetLayoutBounds(m_DocumentDockContainer); } else if (m_Container.Dock == DockStyle.Right && xDiff != 0) { if (m_DocumentDockContainer.Documents.Count > 0) { DocumentBaseContainer lastDoc = m_DocumentDockContainer.Documents[0]; int docWidth = lastDoc.DisplayBounds.Width - xDiff; if (docWidth > lastDoc.MinimumSize.Width) lastDoc.SetLayoutBounds(new Rectangle(lastDoc.DisplayBounds.X, lastDoc.DisplayBounds.Y, docWidth, lastDoc.DisplayBounds.Height)); else ResetLayoutBounds(m_DocumentDockContainer); } m_Container.Width = m_Container.Width - xDiff; if(m_Container.Width <= this.GetContainerMinimumSize(m_DocumentDockContainer).Width) ResetLayoutBounds(m_DocumentDockContainer); } else if (m_Container.Dock == DockStyle.Top && yDiff != 0) { if (m_DocumentDockContainer.Documents.Count > 0) { DocumentBaseContainer lastDoc = m_DocumentDockContainer.Documents[m_DocumentDockContainer.Documents.Count - 1]; int docHeight = lastDoc.DisplayBounds.Height + yDiff; if (docHeight > lastDoc.MinimumSize.Height) lastDoc.SetLayoutBounds(new Rectangle(lastDoc.DisplayBounds.X, lastDoc.DisplayBounds.Y, lastDoc.DisplayBounds.Width, docHeight)); else ResetLayoutBounds(m_DocumentDockContainer); } m_Container.Height = m_Container.Height + yDiff; if(m_Container.Height <= this.GetContainerMinimumSize(m_DocumentDockContainer).Height) ResetLayoutBounds(m_DocumentDockContainer); } else if (m_Container.Dock == DockStyle.Bottom && yDiff != 0) { if (m_DocumentDockContainer.Documents.Count > 0) { DocumentBaseContainer lastDoc = m_DocumentDockContainer.Documents[0]; int docHeight = lastDoc.DisplayBounds.Height - yDiff; if (docHeight > lastDoc.MinimumSize.Height) lastDoc.SetLayoutBounds(new Rectangle(lastDoc.DisplayBounds.X, lastDoc.DisplayBounds.Y, lastDoc.DisplayBounds.Width, docHeight)); else ResetLayoutBounds(m_DocumentDockContainer); } m_Container.Height = m_Container.Height - yDiff; if(m_Container.Height <= this.GetContainerMinimumSize(m_DocumentDockContainer).Height) ResetLayoutBounds(m_DocumentDockContainer); } m_Container.ResumeLayout(); } else if(m_ResizeDockContainer.Orientation==eOrientation.Horizontal && xDiff!=0) { m_ResizeDocument.SetWidth(m_ResizeDocument.DisplayBounds.Width+xDiff); } else if (m_ResizeDockContainer.Orientation == eOrientation.Vertical && yDiff != 0) { m_ResizeDocument.SetHeight(m_ResizeDocument.DisplayBounds.Height+yDiff); } m_Container.RecalcLayout(); if (m_Container.Owner != null) ((IOwner)m_Container.Owner).InvokeUserCustomize(m_ResizeDocument, EventArgs.Empty); } private DocumentBaseContainer GetNextDocument(DocumentDockContainer parent, int refIndex) { int count=parent.Documents.Count; for(int i=refIndex+1;i= 0; i--) { if (parent.Documents[i].Visible) return parent.Documents[i]; } return null; } /// /// Sets the width of the bar that is managed by this document layout. Width can be set only if parent container has /// Horizontal orientation. Note that bar minimum size is respected by this method and /// it will be enforced. If width is less than minimum width bar's width will be set to minimum width. /// /// Reference to bar object. /// Desired width. public void SetBarWidth(Bar bar, int width) { DocumentBarContainer docBar=GetDocumentFromBar(bar) as DocumentBarContainer; if(docBar==null) return; if(docBar.Parent == m_DocumentDockContainer && (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) /*&& (m_DocumentDockContainer.Orientation == eOrientation.Vertical || m_DocumentDockContainer.Documents.Count == 1)*/) { m_Container.SuspendLayout(); int diff = width; if(docBar.DisplayBounds.Width == 0) diff -= bar.GetBarDockedSize(eOrientation.Vertical); else diff -= docBar.DisplayBounds.Width; if (diff != 0) { m_Container.Width += diff; docBar.SetWidth(width); } //((DocumentDockContainer)docBar.Parent).SetWidth(width); m_Container.ResumeLayout(true); } else if (docBar.Parent is DocumentDockContainer && ((DocumentDockContainer)docBar.Parent).Orientation == eOrientation.Vertical) { ((DocumentDockContainer)docBar.Parent).SetWidth(width); } else { if (width < docBar.MinimumSize.Width) width = docBar.MinimumSize.Width; docBar.SetWidth(width); } m_Container.RecalcLayout(); } /// /// Sets the height of the bar that is managed by this document layout. Height can be set only if parent container has /// vertical orientation. Note that bar minimum size is respected by this method and /// it will be enforced. If height is less than minimum height bar's height will be set to minimum height. /// /// Reference to bar object. /// Desired height. public void SetBarHeight(Bar bar, int height) { DocumentBarContainer docBar=GetDocumentFromBar(bar) as DocumentBarContainer; if(docBar==null) return; if (m_Container!=null && (m_Container.Dock == DockStyle.Top || m_Container.Dock== DockStyle.Bottom) && docBar.Parent == m_DocumentDockContainer /*&& (m_DocumentDockContainer.Orientation == eOrientation.Horizontal || m_DocumentDockContainer.Documents.Count == 1)*/) { //m_Container.Height += (height - bar.Height); //m_DocumentDockContainer.SetHeight(height); m_Container.SuspendLayout(); int diff = height; if (docBar.DisplayBounds.Height == 0) diff -= bar.GetBarDockedSize(eOrientation.Vertical); else diff -= docBar.DisplayBounds.Height; m_Container.Height += diff; //((DocumentDockContainer)docBar.Parent).SetHeight(height); docBar.SetHeight(height); m_Container.ResumeLayout(true); } else if (docBar.Parent is DocumentDockContainer && ((DocumentDockContainer)docBar.Parent).Orientation == eOrientation.Horizontal) { ((DocumentDockContainer)docBar.Parent).SetHeight(height); } else { if (height < docBar.MinimumSize.Height) height = docBar.MinimumSize.Height; docBar.SetHeight(height); } m_Container.RecalcLayout(); } #endregion #region Serialization internal void SerializeDefinition(XmlElement parent) { XmlElement docs = null; if (m_Container.Dock == DockStyle.Fill) docs = parent.OwnerDocument.CreateElement(DocumentSerializationXml.Documents); else { docs = parent.OwnerDocument.CreateElement(DocumentSerializationXml.DockSite); docs.SetAttribute(DocumentSerializationXml.DockSiteSize, XmlConvert.ToString((m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) ? m_Container.Width : m_Container.Height)); docs.SetAttribute(DocumentSerializationXml.DockingSide, Enum.GetName(typeof(DockStyle), m_Container.Dock)); } parent.AppendChild(docs); SerializeDocumentDockContainer(docs,m_DocumentDockContainer, true); } internal void SerializeLayout(XmlElement parent) { XmlElement docs = null; if (m_Container.Dock == DockStyle.Fill) docs = parent.OwnerDocument.CreateElement(DocumentSerializationXml.Documents); else { docs = parent.OwnerDocument.CreateElement(DocumentSerializationXml.DockSite); docs.SetAttribute(DocumentSerializationXml.DockSiteSize, XmlConvert.ToString((m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) ? m_Container.Width : m_Container.Height)); docs.SetAttribute(DocumentSerializationXml.DockingSide, Enum.GetName(typeof(DockStyle), m_Container.Dock)); docs.SetAttribute(DocumentSerializationXml.OriginalDockSiteSize, XmlConvert.ToString(m_Container.OriginalSize)); } parent.AppendChild(docs); SerializeDocumentDockContainer(docs,m_DocumentDockContainer,false); } private bool SerializeDocument(DocumentDockContainer instance) { if (instance.Documents.Count == 0) return false; foreach (DocumentBaseContainer doc in instance.Documents) { DocumentBarContainer bar = doc as DocumentBarContainer; if (bar != null) { if (bar.Bar != null && bar.Bar.SaveLayoutChanges) return true; } else return true; } return false; } private void SerializeDocumentDockContainer(XmlElement parent, DocumentDockContainer instance, bool definitionSerialization) { if (!SerializeDocument(instance)) return; XmlElement document = null; document=parent.OwnerDocument.CreateElement(DocumentSerializationXml.DockContainer); parent.AppendChild(document); document.SetAttribute(DocumentSerializationXml.Orientation,XmlConvert.ToString((int)instance.Orientation)); document.SetAttribute(DocumentSerializationXml.Width, instance.LayoutBounds.Width.ToString()); document.SetAttribute(DocumentSerializationXml.Height, instance.LayoutBounds.Height.ToString()); foreach(DocumentBaseContainer doc in instance.Documents) { if(doc is DocumentDockContainer) SerializeDocumentDockContainer(document,(DocumentDockContainer)doc,definitionSerialization); else if(doc is DocumentBarContainer) SerializeDocumentBarContainer(document,(DocumentBarContainer)doc,definitionSerialization); } } private void SerializeDocumentBarContainer(XmlElement parent, DocumentBarContainer instance, bool definitionSerialization) { if(instance.Bar==null || !instance.Bar.SaveLayoutChanges) return; XmlElement barDocument=parent.OwnerDocument.CreateElement(DocumentSerializationXml.BarContainer); parent.AppendChild(barDocument); barDocument.SetAttribute(DocumentSerializationXml.Width,instance.LayoutBounds.Width.ToString()); barDocument.SetAttribute(DocumentSerializationXml.Height,instance.LayoutBounds.Height.ToString()); XmlElement barElement=parent.OwnerDocument.CreateElement(BarSerializationXml.Bar); barDocument.AppendChild(barElement); if(definitionSerialization) instance.Bar.Serialize(barElement); else instance.Bar.SerializeLayout(barElement); } internal void DeserializeLayout(XmlElement parent) { if (parent.Name != DocumentSerializationXml.Documents && parent.Name != DocumentSerializationXml.DockSite || m_LoadingLayout) return; m_LoadingLayout=true; ItemSerializationContext context = new ItemSerializationContext(); try { foreach(XmlElement elem in parent.ChildNodes) { if(elem.Name==DocumentSerializationXml.DockContainer) { context.ItemXmlElement = elem; DeserializeDocumentDockContainer(context,m_DocumentDockContainer,false); break; } } } finally { m_LoadingLayout=false; } if (parent.Name == DocumentSerializationXml.DockSite) { if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) m_Container.Width = XmlConvert.ToInt32(parent.GetAttribute(DocumentSerializationXml.DockSiteSize)); else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) m_Container.Height = XmlConvert.ToInt32(parent.GetAttribute(DocumentSerializationXml.DockSiteSize)); if (parent.HasAttribute(DocumentSerializationXml.OriginalDockSiteSize)) m_Container.OriginalSize = XmlConvert.ToInt32(parent.GetAttribute(DocumentSerializationXml.OriginalDockSiteSize)); } m_Container.RecalcLayout(); } internal void DeserializeDefinition(ItemSerializationContext context) { XmlElement parent = context.ItemXmlElement; if ((parent.Name != DocumentSerializationXml.Documents && parent.Name != DocumentSerializationXml.DockSite) || m_LoadingLayout) return; m_LoadingLayout=true; try { foreach(XmlElement elem in parent.ChildNodes) { if(elem.Name==DocumentSerializationXml.DockContainer) { context.ItemXmlElement = elem; DeserializeDocumentDockContainer(context,m_DocumentDockContainer,true); break; } } if (parent.HasAttribute(DocumentSerializationXml.DockSiteSize)) { if (m_Container.Dock == DockStyle.Left || m_Container.Dock == DockStyle.Right) m_Container.Width = XmlConvert.ToInt32(parent.GetAttribute(DocumentSerializationXml.DockSiteSize)); else if (m_Container.Dock == DockStyle.Top || m_Container.Dock == DockStyle.Bottom) m_Container.Height = XmlConvert.ToInt32(parent.GetAttribute(DocumentSerializationXml.DockSiteSize)); } } finally { m_LoadingLayout=false; } m_Container.RecalcLayout(); } private void DeserializeDocumentDockContainer(ItemSerializationContext context, DocumentDockContainer instance, bool deserializeDefinition) { XmlElement docElement = context.ItemXmlElement; if(docElement.Name!=DocumentSerializationXml.DockContainer) return; instance.Documents.Clear(); instance.Orientation=(eOrientation)XmlConvert.ToInt32(docElement.GetAttribute(DocumentSerializationXml.Orientation)); if (docElement.HasAttribute(DocumentSerializationXml.Width) && docElement.HasAttribute(DocumentSerializationXml.Height)) { instance.SetLayoutBounds(new Rectangle(0,0, XmlConvert.ToInt32(docElement.GetAttribute(DocumentSerializationXml.Width)), XmlConvert.ToInt32(docElement.GetAttribute(DocumentSerializationXml.Height)))); } foreach(XmlElement elem in docElement.ChildNodes) { bool add=true; DocumentBaseContainer doc=DocumentSerializationXml.CreateDocument(elem.Name); context.ItemXmlElement = elem; if(doc is DocumentDockContainer) DeserializeDocumentDockContainer(context,(DocumentDockContainer)doc,deserializeDefinition); else if(doc is DocumentBarContainer) add=DeserializeDocumentBarContainer(context,(DocumentBarContainer)doc,deserializeDefinition); if(add) instance.Documents.Add(doc); } } private bool DeserializeDocumentBarContainer(ItemSerializationContext context, DocumentBarContainer instance, bool deserializeDefinition) { XmlElement docElement = context.ItemXmlElement; if(docElement.Name!=DocumentSerializationXml.BarContainer) return false; instance.SetLayoutBounds(new Rectangle(0,0,XmlConvert.ToInt32(docElement.GetAttribute(DocumentSerializationXml.Width)),XmlConvert.ToInt32(docElement.GetAttribute(DocumentSerializationXml.Height)))); foreach(XmlElement elem in docElement.ChildNodes) { if(elem.Name==BarSerializationXml.Bar) { instance.Bar=m_Container.Owner.Bars[elem.GetAttribute(BarSerializationXml.Name)]; if(deserializeDefinition || instance.Bar==null && elem.HasAttribute(BarSerializationXml.Custom) && XmlConvert.ToBoolean(elem.GetAttribute(BarSerializationXml.Custom))) { // New bar that user has created try to deserialize but if it does not have items ignore it instance.Bar=new Bar(); m_Container.Owner.Bars.Add(instance.Bar); if(deserializeDefinition) instance.Bar.Deserialize(elem, context); else instance.Bar.DeserializeLayout(elem); if(instance.Bar.Items.Count==0 && !deserializeDefinition) { m_Container.Owner.Bars.Remove(instance.Bar); return false; } return true; } if (instance.Bar != null) { instance.Bar.DeserializeLayout(elem); // Restore hidden dock container size so it can be used when bar is shown if (!instance.Bar.IsVisible) { if (instance.LayoutBounds.Height > 0 && (instance.Bar.DockSide == eDockSide.Top || instance.Bar.DockSide == eDockSide.Bottom)) { instance.Bar.Height = instance.LayoutBounds.Height; } else if (instance.LayoutBounds.Width > 0 && (instance.Bar.DockSide == eDockSide.Left || instance.Bar.DockSide == eDockSide.Right)) { instance.Bar.Width = instance.LayoutBounds.Width; } } } else return false; break; } } return true; } #endregion } }