From 23912343eff73bf822d9e7fa21cd9e97890d28f6 Mon Sep 17 00:00:00 2001 From: Dmitry Vodich Date: Thu, 25 Jul 2019 12:28:06 +0300 Subject: [PATCH] Made calculating of DockMinSize for panel based on children DockMinSize --- .../Controls/LayoutGridControl.cs | 50 +++++++++---------- .../Controls/LayoutPanelControl.cs | 12 ++--- .../Layout/ILayoutPositionableElement.cs | 5 ++ .../Layout/LayoutPositionableGroup.cs | 41 +++++++++++++++ 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs index 8d7d9c88..962b5ab7 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs @@ -259,7 +259,7 @@ private void UpdateRowColDefinitions() ColumnDefinitions.Add( new ColumnDefinition() { Width = childModel.IsVisible ? childModel.DockWidth : new GridLength( 0.0, GridUnitType.Pixel ), - MinWidth = childModel.IsVisible ? childModel.DockMinWidth : 0.0 + MinWidth = childModel.IsVisible ? childModel.CalculatedDockMinWidth() : 0.0 } ); Grid.SetColumn( InternalChildren[ iChild ], iColumn ); @@ -298,7 +298,7 @@ private void UpdateRowColDefinitions() RowDefinitions.Add( new RowDefinition() { Height = childModel.IsVisible ? childModel.DockHeight : new GridLength( 0.0, GridUnitType.Pixel ), - MinHeight = childModel.IsVisible ? childModel.DockMinHeight : 0.0 + MinHeight = childModel.IsVisible ? childModel.CalculatedDockMinHeight() : 0.0 } ); Grid.SetRow( InternalChildren[ iChild ], iRow ); @@ -498,54 +498,54 @@ public virtual void AdjustFixedChildrenPanelSizes(Size? parentSize = null) { fixedPanels = layoutChildrenModels.Where(child => child.DockHeight.IsAbsolute).ToList(); relativePanels = layoutChildrenModels.Where(child => !child.DockHeight.IsAbsolute).ToList(); - minimumSize.Width += layoutChildrenModels.Max(child => child.DockMinWidth); - minimumSize.Height += layoutChildrenModels.Sum(child => child.DockMinHeight); + minimumSize.Width += layoutChildrenModels.Max(child => child.CalculatedDockMinWidth()); + minimumSize.Height += layoutChildrenModels.Sum(child => child.CalculatedDockMinHeight()); minimumSize.Height += splitterChildren.Sum(child => child.ActualHeight); currentSize.Width += layoutChildrenModels.Max(child => child.ActualWidth); currentSize.Height += layoutChildrenModels.Sum(child => child.ActualHeight); currentSize.Height += splitterChildren.Sum(child => child.ActualHeight); - preferredMinimumSize.Width += layoutChildrenModels.Max(child => child.DockMinWidth); - preferredMinimumSize.Height += minimumSize.Height + fixedPanels.Sum(child => child.FixedDockHeight) - fixedPanels.Sum(child => child.DockMinHeight); + preferredMinimumSize.Width += layoutChildrenModels.Max(child => child.CalculatedDockMinWidth()); + preferredMinimumSize.Height += minimumSize.Height + fixedPanels.Sum(child => child.FixedDockHeight) - fixedPanels.Sum(child => child.CalculatedDockMinHeight()); } else { fixedPanels = layoutChildrenModels.Where(child => child.DockWidth.IsAbsolute).ToList(); relativePanels = layoutChildrenModels.Where(child => !child.DockWidth.IsAbsolute).ToList(); - minimumSize.Width += layoutChildrenModels.Sum(child => child.DockMinWidth); - minimumSize.Height += layoutChildrenModels.Max(child => child.DockMinHeight); + minimumSize.Width += layoutChildrenModels.Sum(child => child.CalculatedDockMinWidth()); + minimumSize.Height += layoutChildrenModels.Max(child => child.CalculatedDockMinHeight()); minimumSize.Width += splitterChildren.Sum(child => child.ActualWidth); currentSize.Width += layoutChildrenModels.Sum(child => child.ActualWidth); currentSize.Height += layoutChildrenModels.Max(child => child.ActualHeight); currentSize.Width += splitterChildren.Sum(child => child.ActualWidth); - preferredMinimumSize.Height += layoutChildrenModels.Max(child => child.DockMinHeight); - preferredMinimumSize.Width += minimumSize.Width + fixedPanels.Sum(child => child.FixedDockWidth) - fixedPanels.Sum(child => child.DockMinWidth); + preferredMinimumSize.Height += layoutChildrenModels.Max(child => child.CalculatedDockMinHeight()); + preferredMinimumSize.Width += minimumSize.Width + fixedPanels.Sum(child => child.FixedDockWidth) - fixedPanels.Sum(child => child.CalculatedDockMinWidth()); } // Apply corrected sizes for fixed panels. if (Orientation == Orientation.Vertical) { double delta = availableSize.Height - currentSize.Height; - double relativeDelta = relativePanels.Sum(child => child.ActualHeight - child.DockMinHeight); + double relativeDelta = relativePanels.Sum(child => child.ActualHeight - child.CalculatedDockMinHeight()); delta += relativeDelta; foreach (var fixedChild in fixedPanels) { if (minimumSize.Height >= availableSize.Height) { - fixedChild.ResizableAbsoluteDockHeight = fixedChild.DockMinHeight; + fixedChild.ResizableAbsoluteDockHeight = fixedChild.CalculatedDockMinHeight(); } else if (preferredMinimumSize.Height <= availableSize.Height) { fixedChild.ResizableAbsoluteDockHeight = fixedChild.FixedDockHeight; } - else if (relativePanels.All(child => Math.Abs(child.ActualHeight - child.DockMinHeight) <= 1)) + else if (relativePanels.All(child => Math.Abs(child.ActualHeight - child.CalculatedDockMinHeight()) <= 1)) { double panelFraction; int indexOfChild = fixedPanels.IndexOf(fixedChild); if (delta < 0) { double availableHeightLeft = fixedPanels.Where(child => fixedPanels.IndexOf(child) >= indexOfChild) - .Sum(child => child.ActualHeight - child.DockMinHeight); - panelFraction = (fixedChild.ActualHeight - fixedChild.DockMinHeight) / (availableHeightLeft > 0 ? availableHeightLeft : 1); + .Sum(child => child.ActualHeight - child.CalculatedDockMinHeight()); + panelFraction = (fixedChild.ActualHeight - fixedChild.CalculatedDockMinHeight()) / (availableHeightLeft > 0 ? availableHeightLeft : 1); } else { @@ -555,7 +555,7 @@ public virtual void AdjustFixedChildrenPanelSizes(Size? parentSize = null) } double childActualHeight = fixedChild.ActualHeight; - double heightToSet = Math.Max(Math.Round(delta * panelFraction + fixedChild.ActualHeight), fixedChild.DockMinHeight); + double heightToSet = Math.Max(Math.Round(delta * panelFraction + fixedChild.ActualHeight), fixedChild.CalculatedDockMinHeight()); fixedChild.ResizableAbsoluteDockHeight = heightToSet; delta -= heightToSet - childActualHeight; } @@ -564,13 +564,13 @@ public virtual void AdjustFixedChildrenPanelSizes(Size? parentSize = null) else { double delta = availableSize.Width - currentSize.Width; - double relativeDelta = relativePanels.Sum(child => child.ActualWidth - child.DockMinWidth); + double relativeDelta = relativePanels.Sum(child => child.ActualWidth - child.CalculatedDockMinWidth()); delta += relativeDelta; foreach (var fixedChild in fixedPanels) { if (minimumSize.Width >= availableSize.Width) { - fixedChild.ResizableAbsoluteDockWidth = fixedChild.DockMinWidth; + fixedChild.ResizableAbsoluteDockWidth = fixedChild.CalculatedDockMinWidth(); } else if (preferredMinimumSize.Width <= availableSize.Width) { @@ -583,8 +583,8 @@ public virtual void AdjustFixedChildrenPanelSizes(Size? parentSize = null) if (delta < 0) { double availableWidthLeft = fixedPanels.Where(child => fixedPanels.IndexOf(child) >= indexOfChild) - .Sum(child => child.ActualWidth - child.DockMinWidth); - panelFraction = (fixedChild.ActualWidth - fixedChild.DockMinWidth) / (availableWidthLeft > 0 ? availableWidthLeft : 1); + .Sum(child => child.ActualWidth - child.CalculatedDockMinWidth()); + panelFraction = (fixedChild.ActualWidth - fixedChild.CalculatedDockMinWidth()) / (availableWidthLeft > 0 ? availableWidthLeft : 1); } else { @@ -594,7 +594,7 @@ public virtual void AdjustFixedChildrenPanelSizes(Size? parentSize = null) } double childActualWidth = fixedChild.ActualWidth; - double widthToSet = Math.Max(Math.Round(delta * panelFraction + fixedChild.ActualWidth), fixedChild.DockMinWidth); + double widthToSet = Math.Max(Math.Round(delta * panelFraction + fixedChild.ActualWidth), fixedChild.CalculatedDockMinWidth()); fixedChild.ResizableAbsoluteDockWidth = widthToSet; delta -= widthToSet - childActualWidth; } @@ -675,23 +675,23 @@ private void ShowResizerOverlayWindow( LayoutGridResizerControl splitter ) if( Orientation == System.Windows.Controls.Orientation.Horizontal ) { actualSize = new Size( - prevChildActualSize.Width - prevChildModel.DockMinWidth + splitter.ActualWidth + nextChildActualSize.Width - nextChildModel.DockMinWidth, + prevChildActualSize.Width - prevChildModel.CalculatedDockMinWidth() + splitter.ActualWidth + nextChildActualSize.Width - nextChildModel.CalculatedDockMinWidth(), nextChildActualSize.Height ); _resizerGhost.Width = splitter.ActualWidth; _resizerGhost.Height = actualSize.Height; - ptTopLeftScreen.Offset( prevChildModel.DockMinWidth, 0.0 ); + ptTopLeftScreen.Offset( prevChildModel.CalculatedDockMinWidth(), 0.0 ); } else { actualSize = new Size( prevChildActualSize.Width, - prevChildActualSize.Height - prevChildModel.DockMinHeight + splitter.ActualHeight + nextChildActualSize.Height - nextChildModel.DockMinHeight ); + prevChildActualSize.Height - prevChildModel.CalculatedDockMinHeight() + splitter.ActualHeight + nextChildActualSize.Height - nextChildModel.CalculatedDockMinHeight() ); _resizerGhost.Height = splitter.ActualHeight; _resizerGhost.Width = actualSize.Width; - ptTopLeftScreen.Offset( 0.0, prevChildModel.DockMinHeight ); + ptTopLeftScreen.Offset( 0.0, prevChildModel.CalculatedDockMinHeight() ); } _initialStartPoint = splitter.PointToScreenDPIWithoutFlowDirection( new Point() ) - ptTopLeftScreen; diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs index ff385a3a..a1ae5db9 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutPanelControl.cs @@ -68,11 +68,11 @@ protected override void OnFixChildrenDockLengths() else if( childPositionableModel != null && childPositionableModel.DockWidth.IsStar ) { var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; - - var widthToSet = Math.Max( childPositionableModelWidthActualSize.ActualWidth, childPositionableModel.DockMinWidth ); + var childDockMinWidth = childPositionableModel.CalculatedDockMinWidth(); + var widthToSet = Math.Max( childPositionableModelWidthActualSize.ActualWidth, childDockMinWidth ); widthToSet = Math.Min( widthToSet, ActualWidth / 2.0 ); - widthToSet = Math.Max( widthToSet, childPositionableModel.DockMinWidth ); + widthToSet = Math.Max( widthToSet, childDockMinWidth ); childPositionableModel.DockWidth = new GridLength( widthToSet, @@ -110,10 +110,10 @@ protected override void OnFixChildrenDockLengths() else if( childPositionableModel != null && childPositionableModel.DockHeight.IsStar ) { var childPositionableModelWidthActualSize = childPositionableModel as ILayoutPositionableElementWithActualSize; - - var heightToSet = Math.Max( childPositionableModelWidthActualSize.ActualHeight, childPositionableModel.DockMinHeight ); + var childDockMinHeight = childPositionableModel.CalculatedDockMinHeight(); + var heightToSet = Math.Max( childPositionableModelWidthActualSize.ActualHeight, childDockMinHeight ); heightToSet = Math.Min( heightToSet, ActualHeight / 2.0 ); - heightToSet = Math.Max( heightToSet, childPositionableModel.DockMinHeight ); + heightToSet = Math.Max( heightToSet, childDockMinHeight ); childPositionableModel.DockHeight = new GridLength( heightToSet, GridUnitType.Pixel ); } diff --git a/source/Components/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs b/source/Components/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs index 9fe940e7..ce7b3be7 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Layout/ILayoutPositionableElement.cs @@ -48,10 +48,15 @@ double ResizableAbsoluteDockHeight set; } + double CalculatedDockMinWidth(); + double DockMinWidth { get; set; } + + double CalculatedDockMinHeight(); + double DockMinHeight { get; set; diff --git a/source/Components/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs b/source/Components/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs index 589ebdf6..64968322 100644 --- a/source/Components/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs +++ b/source/Components/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs @@ -15,8 +15,11 @@ This program is provided to you under the terms of the Microsoft Public ***********************************************************************************/ using System; +using System.Collections.Generic; using System.Windows; using System.Globalization; +using System.Linq; +using System.Windows.Controls; namespace Xceed.Wpf.AvalonDock.Layout { @@ -207,6 +210,25 @@ public bool CanRepositionItems #endregion + #region CalculatedDockMinWidth + + public double CalculatedDockMinWidth() + { + double childrenDockMinWidth = 0.0; + List visibleChildren = Children.OfType().Where(child => child.IsVisible).ToList(); + ILayoutOrientableGroup orientableGroup = this as ILayoutOrientableGroup; + if (orientableGroup != null && visibleChildren.Any()) + { + childrenDockMinWidth = orientableGroup.Orientation == Orientation.Vertical + ? visibleChildren.Max(child => child.CalculatedDockMinWidth()) + : visibleChildren.Sum(child => child.CalculatedDockMinWidth() + ((Root?.Manager?.GridSplitterWidth ?? 0) * (visibleChildren.Count - 1))); + } + + return Math.Max(this._dockMinWidth, childrenDockMinWidth); + } + + #endregion + #region DockMinWidth private double _dockMinWidth = 25.0; @@ -230,6 +252,25 @@ public double DockMinWidth #endregion + #region CalculatedDockMinHeight + + public double CalculatedDockMinHeight() + { + double childrenDockMinHeight = 0.0; + List visibleChildren = Children.OfType().Where(child => child.IsVisible).ToList(); + ILayoutOrientableGroup orientableGroup = this as ILayoutOrientableGroup; + if (orientableGroup != null && visibleChildren.Any()) + { + childrenDockMinHeight = orientableGroup.Orientation == Orientation.Vertical + ? visibleChildren.Sum(child => child.CalculatedDockMinHeight() + ((Root?.Manager?.GridSplitterHeight ?? 0) * (visibleChildren.Count - 1))) + : visibleChildren.Max(child => child.CalculatedDockMinHeight()); + } + + return Math.Max(this._dockMinHeight, childrenDockMinHeight); + } + + #endregion + #region DockMinHeight private double _dockMinHeight = 25.0;