/// <summary> /// Remove the container /// </summary> /// <param name="container">container to remove</param> private void RemoveContainer(DockableContainer container) { Debug.Assert(container.Parent != null, "Docked container must be hosted somewere"); container.SetModeEmpty(); DockableContainer containerParent = container.Parent as DockableContainer; if (containerParent == null) { Debug.Assert(container.Parent.Handle == _host.Handle, "Parents of FormsTabbedView should be only DockableContainer or _host"); } else { DockableContainer otherContainer = containerParent.OtherPane(container); Debug.Assert(otherContainer != null, "Container in container means that parent container has contained two containers and a splitter"); FormsTabbedView otherView = otherContainer.SingleChild; FormsTabbedView linkedView = otherContainer.LinkedView; if (otherView == null && linkedView == null) { if (otherContainer.LeftPane != null) { DockableContainer leftPane = otherContainer.LeftPane; DockableContainer rightPane = otherContainer.RightPane; otherContainer.SetModeEmpty(); containerParent.SetModeHSplit(leftPane, rightPane); } else if (otherContainer.TopPane != null) { DockableContainer topPane = otherContainer.TopPane; DockableContainer bottomPane = otherContainer.BottomPane; otherContainer.SetModeEmpty(); containerParent.SetModeVSplit(topPane, bottomPane); } } else { Debug.Assert((otherView == null || linkedView == null), "Other container must have a view"); otherContainer.SetModeEmpty(); if (otherView != null) { containerParent.SetModeSingleChild(otherView); } else { containerParent.SetModeLinked(linkedView); AutoHidePanel linkedPanel = (AutoHidePanel)linkedView.Parent; linkedPanel.RestoreParent = containerParent; Autohide.HideRestoreContainers(linkedPanel); } // If floating container inside host if (containerParent.Parent.Handle == _host.Handle && containerParent.Dock == DockStyle.None) { Debug.Assert(linkedView == null, "Can't have linked view in floating container"); SetViewDock(otherView, DockStyle.None, DockStyle.None, zDockMode.None); } } otherContainer.Parent = null; otherContainer.Splitter.Parent = null; otherContainer.Dispose(); } container.Parent = null; container.Splitter.Parent = null; container.Dispose(); }
/// <summary> /// On apply dock /// </summary> /// <param name="sender">sender of the event</param> /// <param name="e">event arguments</param> private void OnApplyDock(object sender, DockControlEventArgs e) { Point screenPoint = Control.MousePosition; DockableContainer containerToDock = (DockableContainer)e.Control; DockableContainer containerWhereToDock = null; if (e.DockMode == zDockMode.Inner) { containerWhereToDock = _guider.GetLeafDockedContainerFromPoint(screenPoint, e.Control); } _layout.DockControl(containerToDock, containerWhereToDock, e.Dock, e.DockMode); }
/// <summary> /// Get the count of visible children /// </summary> /// <param name="container">container</param> /// <returns>count of visible children</returns> private static int GetVisibleChildrenCount(DockableContainer container) { int count = 0; foreach (Control control in container.Controls) { if (control.Visible) { count++; } } return(count); }
/// <summary> /// Dock a form previously added to guider /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <param name="mode">were to dock</param> public void DockControl(DockableContainer containerToDock, DockableContainer containerWhereToDock, DockStyle dock, zDockMode mode) { Debug.Assert(dock != DockStyle.None); if (ShouldDockInHost(containerToDock, containerWhereToDock)) { DockInHost(containerToDock, dock, mode); } else if (ShouldDockInParentContainer(containerToDock, containerWhereToDock)) { DockInParentContainer(containerToDock, containerWhereToDock, dock); } OnShowFloatingWindows(); }
/// <summary> /// Save /// </summary> /// <param name="info">info</param> /// <param name="parentId">parent id identifier</param> /// <param name="xmlForms">forms</param> private void Save(DockableFormInfo info, Guid parentId, XmlNode xmlForms) { XmlDocument xmlDocument = xmlForms.OwnerDocument; XmlNode xmlForm = xmlForms.AppendChild(xmlDocument.CreateElement(XmlTags.TagForm)); XmlNode xmlGuid = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagGuid)); XmlNode xmlAllowedDock = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagAllowedDock)); XmlNode xmlCurrentDock = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagCurrentDock)); XmlNode xmlCurrentMode = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagCurrentMode)); XmlNode xmlIsSelected = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagIsSelected)); XmlNode xmlIsAutoHide = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagIsAutoHide)); XmlNode xmlWidth = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagWidth)); XmlNode xmlHeight = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagHeight)); if (parentId != Guid.Empty) { XmlNode xmlParentGuid = xmlForm.AppendChild(xmlDocument.CreateElement(XmlTags.TagParentGuid)); xmlParentGuid.InnerText = parentId.ToString(); } xmlGuid.InnerText = info.Id.ToString(); xmlAllowedDock.InnerText = info.AllowedDock.ToString(); xmlCurrentMode.InnerText = info.DockMode.ToString(); xmlIsSelected.InnerText = info.IsSelected.ToString().ToLower(); xmlIsAutoHide.InnerText = info.IsAutoHideMode.ToString().ToLower(); DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm); xmlWidth.InnerText = container.Width.ToString(); xmlHeight.InnerText = container.Height.ToString(); if (parentId == Guid.Empty) { if (info.IsAutoHideMode == false) { xmlCurrentDock.InnerText = info.HostContainerDock.ToString(); } else { xmlCurrentDock.InnerText = info.AutoHideSavedDock.ToString(); } } else { xmlCurrentDock.InnerText = info.Dock.ToString(); } }
/// <summary> /// Auto-show the given view /// </summary> /// <param name="view">view to show</param> public void UnsetAutoHideMode(FormsTabbedView view) { AutoHidePanel panel = (AutoHidePanel)view.Parent; DockableContainer container = panel.RestoreParent; DockStyle logicalDock = DockStyle.None; if (LeftAutohideButtons.Remove(panel)) { logicalDock = DockStyle.Left; } else if (RightAutohideButtons.Remove(panel)) { logicalDock = DockStyle.Right; } else if (TopAutohideButtons.Remove(panel)) { logicalDock = DockStyle.Top; } else if (BottomAutohideButtons.Remove(panel)) { logicalDock = DockStyle.Bottom; } else { Debug.Fail("Panel not found"); } _host.Remove(panel); container.SetModeSingleChild(view); OnSetHostContainerDock(view, logicalDock); view.IsAutoHideMode = false; view.PagesPanel.AutoHidden = false; ShowRestoreContainers(panel); ArrangeAutoButtonsPanels(); _autoShowPanel = null; }
/// <summary> /// Gets the child leaf window found at given screen location /// </summary> /// <param name="screenPoint">point in screen coordinates</param> /// <param name="ignored">control to be ignored from search</param> /// <returns>found dockable container</returns> public DockableContainer GetLeafDockedContainerFromPoint(Point screenPoint, Control ignored) { for (int childIndex = 0; childIndex < ControlsCount; childIndex++) { Control child = GetControlAt(childIndex); if (child == ignored) { continue; } if (child.Visible == false) { continue; } DockableContainer container = child as DockableContainer; if (container == null) { continue; } if (container.RectangleToScreen(container.ClientRectangle).Contains(screenPoint) == false) { continue; } if (container.SingleChild != null) { if (container.SingleChild.IsDocked == false) { continue; } return(container); } return(GetLeafDockedContainerFromPoint(container, screenPoint)); } return(null); }
/// <summary> /// Create floating container for the view /// </summary> /// <param name="view">view for which to create floating container</param> /// <param name="bounds">bounds of the floating container</param> /// <returns>floating container</returns> public DockableContainer CreateFloatingContainer(FormsTabbedView view, Rectangle bounds) { DockableContainer container = new DockableContainer(); _host.AddFirst(container); container.Bounds = bounds; container.SetModeSingleChild(view); if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.None)) { SetViewDock(view, DockStyle.None, DockStyle.None, zDockMode.None); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Left)) { DockControl(container, null, DockStyle.Left, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Right)) { DockControl(container, null, DockStyle.Right, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Top)) { DockControl(container, null, DockStyle.Top, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Bottom)) { DockControl(container, null, DockStyle.Bottom, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Fill)) { DockControl(container, null, DockStyle.Fill, zDockMode.Inner); } else { _host.Remove(container); throw new NotSupportedException("Err"); // invalid allowed dock } return(container); }
/// <summary> /// Check if should dock in parent container /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <returns>true if should dock in host</returns> private bool ShouldDockInParentContainer(DockableContainer containerToDock, DockableContainer containerWhereToDock) { if (containerToDock == null) { return(false); } if (containerWhereToDock == null) { return(false); } // Can dock only containers containing single child tabbed view and same allowed dock if (containerWhereToDock.SingleChild != null && containerToDock.SingleChild != null) { return(containerToDock.SingleChild.AllowedDock == containerWhereToDock.SingleChild.AllowedDock); } return(false); }
/// <summary> /// Show restore containers /// </summary> /// <param name="panel">panel</param> private static void ShowRestoreContainers(AutoHidePanel panel) { DockableContainer parentContainer = panel.RestoreParent; ShowRestoreContainer(parentContainer); parentContainer = parentContainer.Parent as DockableContainer; while (parentContainer != null) { if (parentContainer.Visible == false) { ShowRestoreContainer(parentContainer); parentContainer = parentContainer.Parent as DockableContainer; } else { break; } } }
/// <summary> /// Get dock container from point /// </summary> /// <param name="parentContainer">parent container</param> /// <param name="screenPoint">screen point</param> /// <returns>leaf dock container under given screen point</returns> private DockableContainer GetLeafDockedContainerFromPoint(DockableContainer parentContainer, Point screenPoint) { if (parentContainer.SingleChild != null) { return(parentContainer); } if (parentContainer.LeftPane != null) { if (parentContainer.LeftPane.RectangleToScreen(parentContainer.LeftPane.ClientRectangle).Contains(screenPoint)) { return(GetLeafDockedContainerFromPoint(parentContainer.LeftPane, screenPoint)); } else if (parentContainer.RightPane.RectangleToScreen(parentContainer.RightPane.ClientRectangle).Contains(screenPoint)) { return(GetLeafDockedContainerFromPoint(parentContainer.RightPane, screenPoint)); } // Mouse over splitter return(null); } if (parentContainer.TopPane != null) { if (parentContainer.TopPane.RectangleToScreen(parentContainer.TopPane.ClientRectangle).Contains(screenPoint)) { return(GetLeafDockedContainerFromPoint(parentContainer.TopPane, screenPoint)); } else if (parentContainer.BottomPane.RectangleToScreen(parentContainer.BottomPane.ClientRectangle).Contains(screenPoint)) { return(GetLeafDockedContainerFromPoint(parentContainer.BottomPane, screenPoint)); } // Mouse over splitter return(null); } // Mouse over splitter return(null); }
/// <summary> /// Show restore container /// </summary> /// <param name="container">container</param> private static void ShowRestoreContainer(DockableContainer container) { container.Visible = true; container.Splitter.Visible = true; if (container.Parent as DockableContainer != null) { return; } int splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); int containerIndex = container.Parent.Controls.IndexOf(container); if (container.SplitterBefore) { if (splitterIndex - containerIndex != -1) { container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); containerIndex = container.Parent.Controls.IndexOf(container); container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); } } else { if (splitterIndex - containerIndex != 1) { container.Parent.Controls.SetChildIndex(container, splitterIndex - 1); splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); containerIndex = container.Parent.Controls.IndexOf(container); container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); } } }
/// <summary> /// Restore sizes /// </summary> /// <param name="formsSize">form sizes</param> private void RestoreSizes(List <ControlSizeInfo> formsSize) { while (formsSize.Count > 0) { ControlSizeInfo sizeInfo = formsSize[0]; DockableContainer container = HierarchyUtility.GetClosestDockableContainer((Form)sizeInfo.Control); while (container.Parent.Handle != _container.Handle) { container = (DockableContainer)container.Parent; } List <ControlSizeInfo> containersSize = new List <ControlSizeInfo>(); ExtractContainersSizeInfo(container, formsSize, containersSize); for (int index = containersSize.Count - 1; index >= 0; index--) { ControlSizeInfo info = containersSize[index]; info.Control.Width = info.Width; info.Control.Height = info.Height; } } }
/// <summary> /// Add sorted fill containers to the list /// </summary> /// <param name="containers">containers</param> private void AddSortedFillContainers(List <DockableContainer> containers) { List <DockableContainer> containersToBringInFront = new List <DockableContainer>(); foreach (DockableFormInfo info in _dockableForms) { FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm); if (view.HostContainerDock != DockStyle.Fill) { continue; } DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm); while (true) { if (container.Parent as DockableContainer != null) { container = (DockableContainer)container.Parent; } else { break; } } Debug.Assert(_host.Contains(container), "Floating form views must have their parent in form"); if (containersToBringInFront.Contains(container) == false) { containersToBringInFront.Add(container); } } SortContainersBasedOnTheirZOrder(containersToBringInFront); containers.AddRange(containersToBringInFront); }
/// <summary> /// Extract containers size info /// </summary> /// <param name="container">container</param> /// <param name="source">source</param> /// <param name="destination">destination</param> /// <returns>computed container size</returns> private static ControlSizeInfo ExtractContainersSizeInfo(DockableContainer container, List <ControlSizeInfo> source, List <ControlSizeInfo> destination) { DockableContainer currentContainer = container; if (currentContainer.SingleChild != null) { Size size = RemoveViewSizeInfo(currentContainer.SingleChild, source); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return(result); } if (currentContainer.TopPane != null) { ControlSizeInfo topSize = ExtractContainersSizeInfo(container.TopPane, source, destination); ControlSizeInfo bottomSize = ExtractContainersSizeInfo(container.BottomPane, source, destination); Size size = new Size(Math.Max(topSize.Width, bottomSize.Width), topSize.Height + bottomSize.Height + container.TopPane.Splitter.Height); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return(result); } if (currentContainer.LeftPane != null) { ControlSizeInfo leftSize = ExtractContainersSizeInfo(container.LeftPane, source, destination); ControlSizeInfo rightSize = ExtractContainersSizeInfo(container.RightPane, source, destination); Size size = new Size(leftSize.Width + rightSize.Width + container.LeftPane.Splitter.Width, Math.Max(leftSize.Height, rightSize.Height)); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return(result); } throw new NotSupportedException(); }
/// <summary> /// Save the state of the container /// </summary> public void Save() { XmlDocument xmlDocument = new XmlDocument(); XmlNode xmlForms = xmlDocument.AppendChild(xmlDocument.CreateElement(XmlTags.TagForms)); for (int index = 0; index < _host.ControlsCount; index++) { DockableContainer container = _host.GetControlAt(index) as DockableContainer; if (container == null) { continue; } SaveContainer(container, Guid.Empty, xmlForms); } if (Directory.Exists(Path.GetDirectoryName(SavePath)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(SavePath)); } xmlDocument.Save(SavePath); }
/// <summary> /// Accessor of the other pane /// </summary> /// <param name="view">view</param> /// <returns>other pane or null</returns> public DockableContainer OtherPane(DockableContainer view) { if (view == LeftPane) { return(RightPane); } if (view == RightPane) { return(LeftPane); } if (view == TopPane) { return(BottomPane); } if (view == BottomPane) { return(TopPane); } return(null); }
/// <summary> /// Get container under mouse /// </summary> /// <param name="screenLocation">screen location</param> /// <returns>container under mouse</returns> private DockableContainer GetContainerUnderMouse(Point screenLocation) { Control underMouse = GetLeafDockedContainerFromPoint(screenLocation, _movedWindow); while (underMouse != null) { if (underMouse == _movedWindow) { underMouse = null; break; } if (underMouse as DockableContainer != null) { break; } underMouse = underMouse.Parent; } DockableContainer containerUnderMouse = (DockableContainer)underMouse; if (containerUnderMouse != null) { if (containerUnderMouse.SingleChild == null) { containerUnderMouse = null; } if (containerUnderMouse.SingleChild.AllowedDock != _allowedDock) { containerUnderMouse = null; } } return(containerUnderMouse); }
/// <summary> /// Set mode horizontal split /// </summary> /// <param name="leftPane">left pane</param> /// <param name="rightPane">right pane</param> public void SetModeHSplit(DockableContainer leftPane, DockableContainer rightPane) { _linkedView = null; InternalControls.SetModeHSplit(leftPane, rightPane); }
/// <summary> /// Dock the form in host /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="dock">dock</param> /// <param name="mode">mode</param> private void DockInHost(DockableContainer container, DockStyle dock, zDockMode mode) { Rectangle availableBounds = FormWrapper.GetFillScreenRectangle(_host); container.SingleChild.SaveFloatingSize(); container.Splitter.Visible = false; if (_host.Contains(container.Splitter) == false && dock != DockStyle.Fill) { _host.AddLast(container.Splitter); } if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } container.Dock = dock; if (dock != DockStyle.Fill) { container.Splitter.Dock = dock; container.Splitter.Visible = true; } else { container.SingleChild.ButtonsRenderer = new TopTabButtonRenderer(); } // Must call this again after splitter is docked and made visible, to have proper splitter. // Must have this if/else block also before making the splitter visible to prevent flickering if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); if (availableBounds.IsEmpty == false) { if (dock == DockStyle.Left || dock == DockStyle.Right) { if (container.Width >= availableBounds.Width - MinAvailableSize) { container.Width = availableBounds.Width - MinAvailableSize; } } else if (dock == DockStyle.Top || dock == DockStyle.Bottom) { if (container.Height >= availableBounds.Height - MinAvailableSize) { container.Height = availableBounds.Height - MinAvailableSize; } } } } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } SetViewDock(container.SingleChild, dock, dock, mode); }
/// <summary> /// Dock in parent container /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <param name="dock">dock</param> private void DockInParentContainer(DockableContainer containerToDock, DockableContainer containerWhereToDock, DockStyle dock) { FormsTabbedView formTabbedView = containerToDock.SingleChild; FormsTabbedView parentTabbedView = containerWhereToDock.SingleChild; containerToDock.SingleChild.SaveFloatingSize(); containerToDock.Splitter.Visible = false; containerToDock.SetModeEmpty(); if (dock != DockStyle.Fill) { containerWhereToDock.SetModeEmpty(); } RemoveContainer(containerToDock); DockStyle parentDock = DockStyle.None; switch (dock) { case DockStyle.Left: SplitHorizontally(formTabbedView, parentTabbedView, containerWhereToDock); parentDock = DockStyle.Right; break; case DockStyle.Right: SplitHorizontally(parentTabbedView, formTabbedView, containerWhereToDock); parentDock = DockStyle.Left; break; case DockStyle.Top: SplitVertically(formTabbedView, parentTabbedView, containerWhereToDock); parentDock = DockStyle.Bottom; break; case DockStyle.Bottom: SplitVertically(parentTabbedView, formTabbedView, containerWhereToDock); parentDock = DockStyle.Top; break; case DockStyle.Fill: parentDock = parentTabbedView.HostContainerDock; DockFillInParentContainer(formTabbedView, parentTabbedView); OnDestroyFormsTabbedView(formTabbedView); break; default: throw new InvalidOperationException(); } if (parentTabbedView.HostContainerDock != DockStyle.None) { // Keep the parent logical dock if already docked if (parentDock != parentTabbedView.CurrentDock) { SetViewDock(parentTabbedView, parentTabbedView.HostContainerDock, parentDock, parentTabbedView.CurrentDockMode); } parentDock = parentTabbedView.HostContainerDock; } UpdateViewButtons(parentTabbedView); if (dock != DockStyle.Fill) { SetViewDock(formTabbedView, parentDock, dock, parentTabbedView.CurrentDockMode); } }
/// <summary> /// Split two forms in horizontal splitted view /// </summary> /// <param name="leftFormTabbedView">view to dock left</param> /// <param name="rightFormTabbedView">view to dock right</param> /// <param name="parentContainer">parent container which will host the two forms</param> private static void SplitHorizontally(FormsTabbedView leftFormTabbedView, FormsTabbedView rightFormTabbedView, DockableContainer parentContainer) { DockableContainer newRightFormContainer = new DockableContainer(); DockableContainer newLeftFormContainer = new DockableContainer(); parentContainer.SetModeHSplit(newLeftFormContainer, newRightFormContainer); newRightFormContainer.SetModeSingleChild(rightFormTabbedView); newLeftFormContainer.SetModeSingleChild (leftFormTabbedView); }
/// <summary> /// Dock a form previously added to guider /// </summary> /// <param name="info">info about the form to dock</param> /// <param name="dock">how to dock</param> /// <param name="mode">were to dock</param> public void Dock(DockableFormInfo info, DockStyle dock, zDockMode mode) { DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm); _layout.DockControl(container, null, dock, mode); }
/// <summary> /// Show restore container /// </summary> /// <param name="container">container</param> private static void ShowRestoreContainer(DockableContainer container) { container.Visible = true; container.Splitter.Visible = true; if (container.Parent as DockableContainer != null) { return; } int splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); int containerIndex = container.Parent.Controls.IndexOf(container); if (container.SplitterBefore) { if (splitterIndex - containerIndex != -1) { container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); containerIndex = container.Parent.Controls.IndexOf(container); container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); } } else { if (splitterIndex - containerIndex != 1) { container.Parent.Controls.SetChildIndex(container, splitterIndex - 1); splitterIndex = container.Parent.Controls.IndexOf(container.Splitter); containerIndex = container.Parent.Controls.IndexOf(container); container.Parent.Controls.SetChildIndex(container, splitterIndex + 1); } } }
/// <summary> /// Check if should dock in host /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <returns>true if should dock in host</returns> private bool ShouldDockInHost(DockableContainer containerToDock, DockableContainer containerWhereToDock) { if (containerToDock == null) { return false; } if (containerWhereToDock != null) { if (containerWhereToDock.SingleChild != null) { if (containerWhereToDock.SingleChild.HostContainerDock != DockStyle.None) { if (containerToDock.SingleChild != null) { if (containerWhereToDock.SingleChild.AllowedDock == containerToDock.SingleChild.AllowedDock) { return false; } } } } else { return false; } } // Can dock only containers containing single child tabbed view return containerToDock.SingleChild != null; }
/// <summary> /// Set mode vertical split /// </summary> /// <param name="topPane">left pane</param> /// <param name="bottomPane">right pane</param> public void SetModeVSplit(DockableContainer topPane, DockableContainer bottomPane) { _linkedView = null; InternalControls.SetModeVSplit(topPane, bottomPane); }
/// <summary> /// Check if should dock in parent container /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <returns>true if should dock in host</returns> private bool ShouldDockInParentContainer(DockableContainer containerToDock, DockableContainer containerWhereToDock) { if (containerToDock == null) { return false; } if (containerWhereToDock == null) { return false; } // Can dock only containers containing single child tabbed view and same allowed dock if (containerWhereToDock.SingleChild != null && containerToDock.SingleChild != null) { return containerToDock.SingleChild.AllowedDock == containerWhereToDock.SingleChild.AllowedDock; } return false; }
/// <summary> /// Dock the form in host /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="dock">dock</param> /// <param name="mode">mode</param> private void DockInHost(DockableContainer container, DockStyle dock, zDockMode mode) { Rectangle availableBounds = FormWrapper.GetFillScreenRectangle(_host); container.SingleChild.SaveFloatingSize(); container.Splitter.Visible = false; if (_host.Contains(container.Splitter) == false && dock != DockStyle.Fill) { _host.AddLast(container.Splitter); } if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } container.Dock = dock; if (dock != DockStyle.Fill) { container.Splitter.Dock = dock; container.Splitter.Visible = true; } else { container.SingleChild.ButtonsRenderer = new TopTabButtonRenderer(); } // Must call this again after splitter is docked and made visible, to have proper splitter. // Must have this if/else block also before making the splitter visible to prevent flickering if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); if (availableBounds.IsEmpty == false) { if (dock == DockStyle.Left || dock == DockStyle.Right) { if (container.Width >= availableBounds.Width - MinAvailableSize) { container.Width = availableBounds.Width - MinAvailableSize; } } else if (dock == DockStyle.Top || dock == DockStyle.Bottom) { if (container.Height >= availableBounds.Height - MinAvailableSize) { container.Height = availableBounds.Height - MinAvailableSize; } } } } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } SetViewDock(container.SingleChild, dock, dock, mode); }
/// <summary> /// Split two forms in vertically splitted view /// </summary> /// <param name="topFormTabbedView">view to dock top</param> /// <param name="bottomFormTabbedView">view to dock bottom</param> /// <param name="parentContainer">parent container which will host the two forms</param> private static void SplitVertically(FormsTabbedView topFormTabbedView, FormsTabbedView bottomFormTabbedView, DockableContainer parentContainer) { DockableContainer newBottomFormContainer = new DockableContainer(); DockableContainer newTopFormContainer = new DockableContainer(); parentContainer.SetModeVSplit(newTopFormContainer, newBottomFormContainer); newBottomFormContainer.SetModeSingleChild(bottomFormTabbedView); newTopFormContainer.SetModeSingleChild (topFormTabbedView); }
/// <summary> /// Set mode vertical split /// </summary> /// <param name="topPane">left pane</param> /// <param name="bottomPane">right pane</param> public void SetModeVSplit(DockableContainer topPane, DockableContainer bottomPane) { _linkedView = null; InternalControls.SetModeVSplit(topPane, bottomPane); }
/// <summary> /// Dock a form previously added to guider /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <param name="mode">were to dock</param> public void DockControl(DockableContainer containerToDock, DockableContainer containerWhereToDock, DockStyle dock, zDockMode mode) { Debug.Assert(dock != DockStyle.None); if (ShouldDockInHost(containerToDock, containerWhereToDock)) { DockInHost(containerToDock, dock, mode); } else if (ShouldDockInParentContainer(containerToDock, containerWhereToDock)) { DockInParentContainer(containerToDock, containerWhereToDock, dock); } OnShowFloatingWindows(); }
/// <summary> /// Accessor of the other pane /// </summary> /// <param name="view">view</param> /// <returns>other pane or null</returns> public DockableContainer OtherPane(DockableContainer view) { if (view == LeftPane) { return RightPane; } if (view == RightPane) { return LeftPane; } if (view == TopPane) { return BottomPane; } if (view == BottomPane) { return TopPane; } return null; }
/// <summary> /// Create floating container for the view /// </summary> /// <param name="view">view for which to create floating container</param> /// <param name="bounds">bounds of the floating container</param> /// <returns>floating container</returns> public DockableContainer CreateFloatingContainer(FormsTabbedView view, Rectangle bounds) { DockableContainer container = new DockableContainer(); _host.AddFirst(container); container.Bounds = bounds; container.SetModeSingleChild(view); if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.None)) { SetViewDock(view, DockStyle.None, DockStyle.None, zDockMode.None); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Left)) { DockControl(container, null, DockStyle.Left, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Right)) { DockControl(container, null, DockStyle.Right, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Top)) { DockControl(container, null, DockStyle.Top, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Bottom)) { DockControl(container, null, DockStyle.Bottom, zDockMode.Outer); } else if (EnumUtility.Contains(view.AllowedDock, zAllowedDock.Fill)) { DockControl(container, null, DockStyle.Fill, zDockMode.Inner); } else { _host.Remove(container); throw new NotSupportedException("Err"); // invalid allowed dock } return container; }
/// <summary> /// Remove the container /// </summary> /// <param name="container">container to remove</param> private void RemoveContainer(DockableContainer container) { Debug.Assert(container.Parent != null, "Docked container must be hosted somewere"); container.SetModeEmpty(); DockableContainer containerParent = container.Parent as DockableContainer; if (containerParent == null) { Debug.Assert(container.Parent.Handle == _host.Handle, "Parents of FormsTabbedView should be only DockableContainer or _host"); } else { DockableContainer otherContainer = containerParent.OtherPane(container); Debug.Assert(otherContainer != null, "Container in container means that parent container has contained two containers and a splitter"); FormsTabbedView otherView = otherContainer.SingleChild; FormsTabbedView linkedView = otherContainer.LinkedView; if (otherView == null && linkedView == null) { if (otherContainer.LeftPane != null) { DockableContainer leftPane = otherContainer.LeftPane; DockableContainer rightPane = otherContainer.RightPane; otherContainer.SetModeEmpty(); containerParent.SetModeHSplit(leftPane, rightPane); } else if (otherContainer.TopPane != null) { DockableContainer topPane = otherContainer.TopPane; DockableContainer bottomPane = otherContainer.BottomPane; otherContainer.SetModeEmpty(); containerParent.SetModeVSplit(topPane, bottomPane); } } else { Debug.Assert((otherView == null || linkedView == null), "Other container must have a view"); otherContainer.SetModeEmpty(); if (otherView != null) { containerParent.SetModeSingleChild(otherView); } else { containerParent.SetModeLinked(linkedView); AutoHidePanel linkedPanel = (AutoHidePanel)linkedView.Parent; linkedPanel.RestoreParent = containerParent; Autohide.HideRestoreContainers(linkedPanel); } // If floating container inside host if (containerParent.Parent.Handle == _host.Handle && containerParent.Dock == DockStyle.None) { Debug.Assert(linkedView == null, "Can't have linked view in floating container"); SetViewDock(otherView, DockStyle.None, DockStyle.None, zDockMode.None); } } otherContainer.Parent = null; otherContainer.Splitter.Parent = null; otherContainer.Dispose(); } container.Parent = null; container.Splitter.Parent = null; container.Dispose(); }
/// <summary> /// Split two forms in vertically splitted view /// </summary> /// <param name="topFormTabbedView">view to dock top</param> /// <param name="bottomFormTabbedView">view to dock bottom</param> /// <param name="parentContainer">parent container which will host the two forms</param> private static void SplitVertically(FormsTabbedView topFormTabbedView, FormsTabbedView bottomFormTabbedView, DockableContainer parentContainer) { DockableContainer newBottomFormContainer = new DockableContainer(); DockableContainer newTopFormContainer = new DockableContainer(); parentContainer.SetModeVSplit(newTopFormContainer, newBottomFormContainer); newBottomFormContainer.SetModeSingleChild(bottomFormTabbedView); newTopFormContainer.SetModeSingleChild(topFormTabbedView); }
/// <summary> /// Get dock container from point /// </summary> /// <param name="parentContainer">parent container</param> /// <param name="screenPoint">screen point</param> /// <returns>leaf dock container under given screen point</returns> private DockableContainer GetLeafDockedContainerFromPoint(DockableContainer parentContainer, Point screenPoint) { if (parentContainer.SingleChild != null) { return parentContainer; } if (parentContainer.LeftPane != null) { if (parentContainer.LeftPane.RectangleToScreen(parentContainer.LeftPane.ClientRectangle).Contains(screenPoint)) { return GetLeafDockedContainerFromPoint(parentContainer.LeftPane, screenPoint); } else if (parentContainer.RightPane.RectangleToScreen(parentContainer.RightPane.ClientRectangle).Contains(screenPoint)) { return GetLeafDockedContainerFromPoint(parentContainer.RightPane, screenPoint); } // Mouse over splitter return null; } if (parentContainer.TopPane != null) { if (parentContainer.TopPane.RectangleToScreen(parentContainer.TopPane.ClientRectangle).Contains(screenPoint)) { return GetLeafDockedContainerFromPoint(parentContainer.TopPane, screenPoint); } else if (parentContainer.BottomPane.RectangleToScreen(parentContainer.BottomPane.ClientRectangle).Contains(screenPoint)) { return GetLeafDockedContainerFromPoint(parentContainer.BottomPane, screenPoint); } // Mouse over splitter return null; } // Mouse over splitter return null; }
/// <summary> /// Split two forms in horizontal splitted view /// </summary> /// <param name="leftFormTabbedView">view to dock left</param> /// <param name="rightFormTabbedView">view to dock right</param> /// <param name="parentContainer">parent container which will host the two forms</param> private static void SplitHorizontally(FormsTabbedView leftFormTabbedView, FormsTabbedView rightFormTabbedView, DockableContainer parentContainer) { DockableContainer newRightFormContainer = new DockableContainer(); DockableContainer newLeftFormContainer = new DockableContainer(); parentContainer.SetModeHSplit(newLeftFormContainer, newRightFormContainer); newRightFormContainer.SetModeSingleChild(rightFormTabbedView); newLeftFormContainer.SetModeSingleChild(leftFormTabbedView); }
/// <summary> /// Extract containers size info /// </summary> /// <param name="container">container</param> /// <param name="source">source</param> /// <param name="destination">destination</param> /// <returns>computed container size</returns> private static ControlSizeInfo ExtractContainersSizeInfo(DockableContainer container, List<ControlSizeInfo> source, List<ControlSizeInfo> destination) { DockableContainer currentContainer = container; if (currentContainer.SingleChild != null) { Size size = RemoveViewSizeInfo(currentContainer.SingleChild, source); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return result; } if (currentContainer.TopPane != null) { ControlSizeInfo topSize = ExtractContainersSizeInfo(container.TopPane, source, destination); ControlSizeInfo bottomSize = ExtractContainersSizeInfo(container.BottomPane, source, destination); Size size = new Size(Math.Max(topSize.Width, bottomSize.Width), topSize.Height + bottomSize.Height + container.TopPane.Splitter.Height); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return result; } if (currentContainer.LeftPane != null) { ControlSizeInfo leftSize = ExtractContainersSizeInfo(container.LeftPane, source, destination); ControlSizeInfo rightSize = ExtractContainersSizeInfo(container.RightPane, source, destination); Size size = new Size(leftSize.Width + rightSize.Width + container.LeftPane.Splitter.Width, Math.Max(leftSize.Height, rightSize.Height)); ControlSizeInfo result = new ControlSizeInfo(container, size.Width, size.Height); destination.Add(result); return result; } throw new NotSupportedException(); }
/// <summary> /// Dock in parent container /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="containerWhereToDock">container where to dock</param> /// <param name="dock">dock</param> private void DockInParentContainer(DockableContainer containerToDock, DockableContainer containerWhereToDock, DockStyle dock) { FormsTabbedView formTabbedView = containerToDock.SingleChild; FormsTabbedView parentTabbedView = containerWhereToDock.SingleChild; containerToDock.SingleChild.SaveFloatingSize(); containerToDock.Splitter.Visible = false; containerToDock.SetModeEmpty(); if (dock != DockStyle.Fill) { containerWhereToDock.SetModeEmpty(); } RemoveContainer(containerToDock); DockStyle parentDock = DockStyle.None; switch (dock) { case DockStyle.Left: SplitHorizontally(formTabbedView, parentTabbedView, containerWhereToDock); parentDock = DockStyle.Right; break; case DockStyle.Right: SplitHorizontally(parentTabbedView, formTabbedView, containerWhereToDock); parentDock = DockStyle.Left; break; case DockStyle.Top: SplitVertically(formTabbedView, parentTabbedView, containerWhereToDock); parentDock = DockStyle.Bottom; break; case DockStyle.Bottom: SplitVertically(parentTabbedView, formTabbedView, containerWhereToDock); parentDock = DockStyle.Top; break; case DockStyle.Fill: parentDock = parentTabbedView.HostContainerDock; DockFillInParentContainer(formTabbedView, parentTabbedView); OnDestroyFormsTabbedView(formTabbedView); break; default: throw new InvalidOperationException(); } if (parentTabbedView.HostContainerDock != DockStyle.None) { // Keep the parent logical dock if already docked if (parentDock != parentTabbedView.CurrentDock) { SetViewDock(parentTabbedView, parentTabbedView.HostContainerDock, parentDock, parentTabbedView.CurrentDockMode); } parentDock = parentTabbedView.HostContainerDock; } UpdateViewButtons(parentTabbedView); if (dock != DockStyle.Fill) { SetViewDock(formTabbedView, parentDock, dock, parentTabbedView.CurrentDockMode); } }
/// <summary> /// Save container /// </summary> /// <param name="container">container</param> /// <param name="containerOwnerId">container owner id</param> /// <param name="xmlForms">forms node</param> /// <returns>container id</returns> private Guid SaveContainer(DockableContainer container, Guid containerOwnerId, XmlNode xmlForms) { if (container.SingleChild != null) { return SaveView(container.SingleChild, containerOwnerId, xmlForms); } if (container.LinkedView != null) { return SaveView(container.LinkedView, containerOwnerId, xmlForms); } if (container.LeftPane != null) { Guid containerId = SaveContainer(container.LeftPane, containerOwnerId, xmlForms); SaveContainer(container.RightPane, containerId, xmlForms); return containerId; } if (container.TopPane != null) { Guid containerId = SaveContainer(container.TopPane, containerOwnerId, xmlForms); SaveContainer(container.BottomPane, containerId, xmlForms); return containerId; } throw new NotSupportedException(); }
/// <summary> /// Set mode horizontal split /// </summary> /// <param name="leftPane">left pane</param> /// <param name="rightPane">right pane</param> public void SetModeHSplit(DockableContainer leftPane, DockableContainer rightPane) { _linkedView = null; InternalControls.SetModeHSplit(leftPane, rightPane); }
/// <summary> /// Get the count of visible children /// </summary> /// <param name="container">container</param> /// <returns>count of visible children</returns> private static int GetVisibleChildrenCount(DockableContainer container) { int count = 0; foreach (Control control in container.Controls) { if (control.Visible) { count++; } } return count; }
/// <summary> /// Dock the form in host /// </summary> /// <param name="containerToDock">container to dock</param> /// <param name="dock">dock</param> /// <param name="mode">mode</param> private void DockInHost(DockableContainer container, DockStyle dock, zDockMode mode) { container.SingleChild.SaveFloatingSize(); container.Splitter.Visible = false; if (_host.Contains(container.Splitter) == false && dock != DockStyle.Fill) { _host.AddLast(container.Splitter); } if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } container.Dock = dock; if (dock != DockStyle.Fill) { container.Splitter.Dock = dock; container.Splitter.Visible = true; } else { container.SingleChild.ButtonsRenderer = new TopTabButtonRenderer(); } // Must call this again after splitter is docked and made visible, to have proper splitter. // Must have this if/else block also before making the splitter visible to prevent flickering if (mode == zDockMode.Inner) { if (dock != DockStyle.Fill) { _host.MoveFirst(container); _host.MoveFirst(container.Splitter); } } else { if (dock != DockStyle.Fill) { _host.MoveLast(container.Splitter); _host.MoveLast(container); } } SetViewDock(container.SingleChild, dock, dock, mode); }