private void SavePanel(XmlWriter writer, DockPanel panel) { writer.WriteAttributeString("SelectedTab", panel.SelectedTabIndex.ToString()); for (int i = 0; i < panel.TabsCount; i++) { var win = panel.Tabs[i]; writer.WriteStartElement("Window"); writer.WriteAttributeString("Typename", win.SerializationTypename); if (win.UseLayoutData) { writer.WriteStartElement("Data"); win.OnLayoutSerialize(writer); writer.WriteEndElement(); } writer.WriteEndElement(); } for (int i = 0; i < panel.ChildPanelsCount; i++) { var p = panel.ChildPanels[i]; // Skip empty panels if (p.TabsCount == 0) { continue; } writer.WriteStartElement("Panel"); float splitterValue; DockState state = p.TryGetDockState(out splitterValue); writer.WriteAttributeString("DockState", ((int)state).ToString()); writer.WriteAttributeString("SplitterValue", splitterValue.ToString(CultureInfo.InvariantCulture)); SavePanel(writer, p); writer.WriteEndElement(); } }
private void LoadPanel(XmlElement node, DockPanel panel) { int selectedTab = int.Parse(node.GetAttribute("SelectedTab"), CultureInfo.InvariantCulture); // Load docked windows var windows = node.SelectNodes("Window"); if (windows != null) { foreach (XmlElement child in windows) { if (child == null) { continue; } var typename = child.GetAttribute("Typename"); var window = GetWindow(typename); if (window != null) { if (child.SelectSingleNode("Data") is XmlElement data) { window.OnLayoutDeserialize(data); } else { window.OnLayoutDeserialize(); } window.Show(DockState.DockFill, panel); } } } // Load child panels var panels = node.SelectNodes("Panel"); if (panels != null) { foreach (XmlElement child in panels) { if (child == null) { continue; } // Create child panel DockState state = (DockState)int.Parse(child.GetAttribute("DockState"), CultureInfo.InvariantCulture); float splitterValue = float.Parse(child.GetAttribute("SplitterValue"), CultureInfo.InvariantCulture); var p = panel.CreateChildPanel(state, splitterValue); LoadPanel(child, p); // Check if panel has no docked window (due to loading problems or sth) if (p.TabsCount == 0 && p.ChildPanelsCount == 0) { // Remove empty panel Editor.LogWarning("Empty panel inside layout."); p.RemoveIt(); } } } panel.SelectTab(selectedTab); }
private void UpdateRects() { // Cache mouse position _mouse = Application.MousePosition; // Check intersection with any dock panel _toDock = _toMove.MasterPanel.HitTest(ref _mouse, _toMove); // Check dock state to use bool showProxyHints = _toDock != null; bool showBorderHints = showProxyHints; bool showCenterHint = showProxyHints; if (showProxyHints) { // For master panel disable docking at sides //if (_toDock->IsMaster()) // showBorderHints = false; // If moved window has not only tabs but also child panels disable docking as tab if (_toMove.ChildPanelsCount > 0) { showCenterHint = false; } ///// // disable docking windows with one or more dock panels inside if (_toMove.ChildPanelsCount > 0) { showBorderHints = false; } ///// // Get dock area _rectDock = _toDock.DockAreaBounds; // Cache dock rectangles Vector2 size = _rectDock.Size; Vector2 offset = _rectDock.Location; float BorderMargin = 4.0f; float ProxyHintWindowsSize2 = Proxy.HintWindowsSize * 0.5f; float centerX = size.X * 0.5f; float centerY = size.Y * 0.5f; _rUpper = new Rectangle(centerX - ProxyHintWindowsSize2, BorderMargin, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset; _rBottom = new Rectangle(centerX - ProxyHintWindowsSize2, size.Y - Proxy.HintWindowsSize - BorderMargin, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset; _rLeft = new Rectangle(BorderMargin, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset; _rRight = new Rectangle(size.X - Proxy.HintWindowsSize - BorderMargin, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset; _rCenter = new Rectangle(centerX - ProxyHintWindowsSize2, centerY - ProxyHintWindowsSize2, Proxy.HintWindowsSize, Proxy.HintWindowsSize) + offset; // Hit test DockState toSet = DockState.Float; if (showBorderHints) { if (_rUpper.Contains(_mouse)) { toSet = DockState.DockTop; } else if (_rBottom.Contains(_mouse)) { toSet = DockState.DockBottom; } else if (_rLeft.Contains(_mouse)) { toSet = DockState.DockLeft; } else if (_rRight.Contains(_mouse)) { toSet = DockState.DockRight; } } if (showCenterHint && _rCenter.Contains(_mouse)) { toSet = DockState.DockFill; } _toSet = toSet; // Show proxy hint windows Proxy.Down.Position = _rBottom.Location; Proxy.Left.Position = _rLeft.Location; Proxy.Right.Position = _rRight.Location; Proxy.Up.Position = _rUpper.Location; Proxy.Center.Position = _rCenter.Location; } else { _toSet = DockState.Float; } // Update proxy hint windows visibility Proxy.Down.IsVisible = showProxyHints & showBorderHints; Proxy.Left.IsVisible = showProxyHints & showBorderHints; Proxy.Right.IsVisible = showProxyHints & showBorderHints; Proxy.Up.IsVisible = showProxyHints & showBorderHints; Proxy.Center.IsVisible = showProxyHints & showCenterHint; // Calculate proxy/dock/window rectangles if (_toDock == null) { // Floating window over nothing _rectWindow = new Rectangle(_mouse - _dragOffset, _defaultWindowSize); } else { if (_toSet == DockState.Float) { // Floating window over dock panel _rectWindow = new Rectangle(_mouse - _dragOffset, _defaultWindowSize); } else { // Use only part of the dock panel to show hint _rectWindow = CalculateDockRect(_toSet, ref _rectDock); } } // Update proxy window Proxy.Window.ClientBounds = _rectWindow; }