diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/UniformSpacingPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/UniformSpacingPanel.cs index 82eeda9f..4aa9dcfd 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/UniformSpacingPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/UniformSpacingPanel.cs @@ -115,7 +115,7 @@ namespace HandyControl.Controls var child = children[i]; if (child == null) continue; - var childSize = new UVSize(_orientation, child.DesiredSize.Width, child.DesiredSize.Height); + var childSize = new PanelUvSize(_orientation, child.DesiredSize); var layoutSlotU = useItemU ? itemU : childSize.U; child.Arrange(isHorizontal ? new Rect(u, v, layoutSlotU, lineV) : new Rect(v, u, lineV, layoutSlotU)); @@ -138,7 +138,7 @@ namespace HandyControl.Controls var child = children[i]; if (child == null) continue; - var childSize = new UVSize(_orientation, child.DesiredSize.Width, child.DesiredSize.Height); + var childSize = new PanelUvSize(_orientation, child.DesiredSize); var layoutSlotU = useItemU ? itemU : childSize.U; child.Arrange(isHorizontal ? new Rect(u, 0, layoutSlotU, lineV) : new Rect(0, u, lineV, layoutSlotU)); @@ -152,9 +152,9 @@ namespace HandyControl.Controls protected override Size MeasureOverride(Size constraint) { - var curLineSize = new UVSize(_orientation); - var panelSize = new UVSize(_orientation); - var uvConstraint = new UVSize(_orientation, constraint.Width, constraint.Height); + var curLineSize = new PanelUvSize(_orientation); + var panelSize = new PanelUvSize(_orientation); + var uvConstraint = new PanelUvSize(_orientation, constraint); var itemWidth = ItemWidth; var itemHeight = ItemHeight; var itemWidthSet = !double.IsNaN(itemWidth); @@ -192,7 +192,7 @@ namespace HandyControl.Controls child.Measure(childConstraint); - var sz = new UVSize( + var sz = new PanelUvSize( _orientation, itemWidthSet ? itemWidth : child.DesiredSize.Width, itemHeightSet ? itemHeight : child.DesiredSize.Height); @@ -207,7 +207,7 @@ namespace HandyControl.Controls { panelSize.U = Math.Max(sz.U, panelSize.U); panelSize.V += sz.V + spacing; - curLineSize = new UVSize(_orientation); + curLineSize = new PanelUvSize(_orientation); } isFirst = true; @@ -251,7 +251,7 @@ namespace HandyControl.Controls child.Measure(layoutSlotSize); - var sz = new UVSize( + var sz = new PanelUvSize( _orientation, itemWidthSet ? itemWidth : child.DesiredSize.Width, itemHeightSet ? itemHeight : child.DesiredSize.Height); @@ -276,8 +276,8 @@ namespace HandyControl.Controls var itemHeight = ItemHeight; double accumulatedV = 0; var itemU = _orientation == Orientation.Horizontal ? itemWidth : itemHeight; - var curLineSize = new UVSize(_orientation); - var uvFinalSize = new UVSize(_orientation, finalSize.Width, finalSize.Height); + var curLineSize = new PanelUvSize(_orientation); + var uvFinalSize = new PanelUvSize(_orientation, finalSize); var itemWidthSet = !double.IsNaN(itemWidth); var itemHeightSet = !double.IsNaN(itemHeight); var useItemU = _orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet; @@ -294,7 +294,7 @@ namespace HandyControl.Controls var child = children[i]; if (child == null) continue; - var sz = new UVSize( + var sz = new PanelUvSize( _orientation, itemWidthSet ? itemWidth : child.DesiredSize.Width, itemHeightSet ? itemHeight : child.DesiredSize.Height); @@ -311,7 +311,7 @@ namespace HandyControl.Controls ArrangeWrapLine(accumulatedV, sz.V, i, ++i, useItemU, itemU, spacing); accumulatedV += sz.V + spacing; - curLineSize = new UVSize(_orientation); + curLineSize = new PanelUvSize(_orientation); } firstInLine = i; @@ -338,60 +338,5 @@ namespace HandyControl.Controls return finalSize; } - - private struct UVSize - { - internal UVSize(Orientation orientation, double width, double height) - { - U = V = 0d; - _orientation = orientation; - Width = width; - Height = height; - } - - internal UVSize(Orientation orientation) - { - U = V = 0d; - _orientation = orientation; - } - - public double U { get; set; } - - public double V { get; set; } - - private readonly Orientation _orientation; - - public double Width - { - get => _orientation == Orientation.Horizontal ? U : V; - private set - { - if (_orientation == Orientation.Horizontal) - { - U = value; - } - else - { - V = value; - } - } - } - - public double Height - { - get => _orientation == Orientation.Horizontal ? V : U; - private set - { - if (_orientation == Orientation.Horizontal) - { - V = value; - } - else - { - U = value; - } - } - } - } } } diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/WaterfallPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/WaterfallPanel.cs index 6ba34088..8415ac30 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/WaterfallPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/WaterfallPanel.cs @@ -2,6 +2,8 @@ using System.Windows; using System.Windows.Controls; using HandyControl.Data; +using HandyControl.Expression.Drawing; +using HandyControl.Tools; namespace HandyControl.Controls { @@ -19,9 +21,30 @@ namespace HandyControl.Controls private static bool IsGroupsValid(object value) => (int) value >= 1; - public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register( - "Orientation", typeof(Orientation), typeof(WaterfallPanel), new FrameworkPropertyMetadata( - Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure)); + public static readonly DependencyProperty AutoGroupProperty = DependencyProperty.Register( + "AutoGroup", typeof(bool), typeof(WaterfallPanel), new FrameworkPropertyMetadata( + ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsMeasure)); + + public bool AutoGroup + { + get => (bool) GetValue(AutoGroupProperty); + set => SetValue(AutoGroupProperty, ValueBoxes.BooleanBox(value)); + } + + public static readonly DependencyProperty DesiredLengthProperty = DependencyProperty.Register( + "DesiredLength", typeof(double), typeof(WaterfallPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, + FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateHelper.IsInRangeOfPosDoubleIncludeZero); + + public double DesiredLength + { + get => (double) GetValue(DesiredLengthProperty); + set => SetValue(DesiredLengthProperty, value); + } + + public static readonly DependencyProperty OrientationProperty = + StackPanel.OrientationProperty.AddOwner(typeof(WaterfallPanel), + new FrameworkPropertyMetadata(Orientation.Horizontal, + FrameworkPropertyMetadataOptions.AffectsMeasure)); public Orientation Orientation { @@ -29,56 +52,98 @@ namespace HandyControl.Controls set => SetValue(OrientationProperty, value); } + private int CaculateGroupCount(Orientation orientation, PanelUvSize size) + { + if (!AutoGroup) + { + return Groups; + } + + var itemLength = DesiredLength; + + if (MathHelper.IsVerySmall(itemLength)) + { + return Groups; + } + + return (int) (size.U / itemLength); + } + + protected override Size ArrangeOverride(Size finalSize) + { + var orientation = Orientation; + var uvConstraint = new PanelUvSize(orientation, finalSize); + + var groups = CaculateGroupCount(orientation, uvConstraint); + if (groups < 1) + { + return finalSize; + } + + var vArr = new double[groups].ToList(); + var itemU = uvConstraint.U / groups; + + var children = InternalChildren; + for (int i = 0, count = children.Count; i < count; i++) + { + var child = children[i]; + if (child == null) + { + continue; + } + + var minIndex = vArr.IndexOf(vArr.Min()); + var minV = vArr[minIndex]; + var childUvSize = new PanelUvSize(orientation, child.DesiredSize); + var childSize = new PanelUvSize(orientation, itemU, childUvSize.V); + var childRectSize = new PanelUvSize(orientation, minIndex * itemU, minV); + + child.Arrange(new Rect(new Point(childRectSize.U, childRectSize.V), childSize.ScreenSize)); + vArr[minIndex] = minV + childUvSize.V; + } + + return finalSize; + } + protected override Size MeasureOverride(Size constraint) { - var groups = Groups; + var orientation = Orientation; + var uvConstraint = new PanelUvSize(orientation, constraint); + + var groups = CaculateGroupCount(orientation, uvConstraint); + if (groups < 1) + { + return constraint; + } + + var vArr = new double[groups].ToList(); + var itemU = uvConstraint.U / groups; + if (double.IsNaN(itemU) || double.IsInfinity(itemU)) + { + return constraint; + } - if (groups < 1) return constraint; var children = InternalChildren; - Size panelSize; - - if (Orientation == Orientation.Horizontal) + for (int i = 0, count = children.Count; i < count; i++) { - var heightArr = new double[groups].ToList(); - var itemWidth = constraint.Width / groups; - if (double.IsNaN(itemWidth) || double.IsInfinity(itemWidth)) return constraint; - - for (int i = 0, count = children.Count; i < count; i++) + var child = children[i]; + if (child == null) { - var child = children[i]; - if (child == null) continue; - - child.Measure(constraint); - var minIndex = heightArr.IndexOf(heightArr.Min()); - var minY = heightArr[minIndex]; - child.Arrange(new Rect(new Point(minIndex * itemWidth, minY), new Size(itemWidth, child.DesiredSize.Height))); - - heightArr[minIndex] = minY + child.DesiredSize.Height; + continue; } - panelSize = new Size(constraint.Width, heightArr.Max()); - } - else - { - var widthArr = new double[groups].ToList(); - var itemHeight = constraint.Height / groups; - if (double.IsNaN(itemHeight) || double.IsInfinity(itemHeight)) return constraint; - for (int i = 0, count = children.Count; i < count; i++) - { - var child = children[i]; - if (child == null) continue; + child.Measure(constraint); - child.Measure(constraint); - var minIndex = widthArr.IndexOf(widthArr.Min()); - var minX = widthArr[minIndex]; - child.Arrange(new Rect(new Point(minX, minIndex * itemHeight), new Size(child.DesiredSize.Width, itemHeight))); + var sz = new PanelUvSize(orientation, child.DesiredSize); + var minIndex = vArr.IndexOf(vArr.Min()); + var minV = vArr[minIndex]; - widthArr[minIndex] = minX + child.DesiredSize.Width; - } - panelSize = new Size(widthArr.Max(), constraint.Height); + vArr[minIndex] = minV + sz.V; } - return panelSize; + uvConstraint = new PanelUvSize(orientation, new Size(uvConstraint.ScreenSize.Width, vArr.Max())); + + return uvConstraint.ScreenSize; } } } diff --git a/src/Shared/HandyControl_Shared/Controls/ProgressBar/CircleProgressBar.cs b/src/Shared/HandyControl_Shared/Controls/ProgressBar/CircleProgressBar.cs index 704d146c..13cb62a7 100644 --- a/src/Shared/HandyControl_Shared/Controls/ProgressBar/CircleProgressBar.cs +++ b/src/Shared/HandyControl_Shared/Controls/ProgressBar/CircleProgressBar.cs @@ -55,7 +55,7 @@ namespace HandyControl.Controls public bool IsIndeterminate { get => (bool) GetValue(IsIndeterminateProperty); - set => SetValue(IsIndeterminateProperty, value); + set => SetValue(IsIndeterminateProperty, ValueBoxes.BooleanBox(value)); } private void SetProgressBarIndicatorAngle() diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs index e622422b..2d6c2e7d 100644 --- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs @@ -99,7 +99,7 @@ namespace HandyControl.Controls public bool ShowSortButton { get => (bool) GetValue(ShowSortButtonProperty); - set => SetValue(ShowSortButtonProperty, value); + set => SetValue(ShowSortButtonProperty, ValueBoxes.BooleanBox(value)); } public override void OnApplyTemplate() diff --git a/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs b/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs index 03236824..113ed356 100644 --- a/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs +++ b/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs @@ -95,7 +95,7 @@ namespace HandyControl.Controls public bool ShowCloseButton { get => (bool) GetValue(ShowCloseButtonProperty); - set => SetValue(ShowCloseButtonProperty, value); + set => SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value)); } /// @@ -116,7 +116,7 @@ namespace HandyControl.Controls public bool ShowContextMenu { get => (bool) GetValue(ShowContextMenuProperty); - set => SetValue(ShowContextMenuProperty, value); + set => SetValue(ShowContextMenuProperty, ValueBoxes.BooleanBox(value)); } /// diff --git a/src/Shared/HandyControl_Shared/Controls/TabControl/TabItem.cs b/src/Shared/HandyControl_Shared/Controls/TabControl/TabItem.cs index 2d299dda..5d62f0d5 100644 --- a/src/Shared/HandyControl_Shared/Controls/TabControl/TabItem.cs +++ b/src/Shared/HandyControl_Shared/Controls/TabControl/TabItem.cs @@ -141,7 +141,7 @@ namespace HandyControl.Controls public bool ShowCloseButton { get => (bool) GetValue(ShowCloseButtonProperty); - set => SetValue(ShowCloseButtonProperty, value); + set => SetValue(ShowCloseButtonProperty, ValueBoxes.BooleanBox(value)); } public static void SetShowCloseButton(DependencyObject element, bool value) diff --git a/src/Shared/HandyControl_Shared/Data/PanelUvSize.cs b/src/Shared/HandyControl_Shared/Data/PanelUvSize.cs new file mode 100644 index 00000000..ff00ac97 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/PanelUvSize.cs @@ -0,0 +1,70 @@ +using System.Windows; +using System.Windows.Controls; + +namespace HandyControl.Data +{ + internal struct PanelUvSize + { + private readonly Orientation _orientation; + + public Size ScreenSize => new(U, V); + + public double U { get; set; } + + public double V { get; set; } + + public double Width + { + get => _orientation == Orientation.Horizontal ? U : V; + private set + { + if (_orientation == Orientation.Horizontal) + { + U = value; + } + else + { + V = value; + } + } + } + + public double Height + { + get => _orientation == Orientation.Horizontal ? V : U; + private set + { + if (_orientation == Orientation.Horizontal) + { + V = value; + } + else + { + U = value; + } + } + } + + public PanelUvSize(Orientation orientation, double width, double height) + { + U = V = 0d; + _orientation = orientation; + Width = width; + Height = height; + } + + public PanelUvSize(Orientation orientation, Size size) + { + U = V = 0d; + _orientation = orientation; + Width = size.Width; + Height = size.Height; + } + + public PanelUvSize(Orientation orientation) + { + U = V = 0d; + _orientation = orientation; + } + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 41640433..0bffa1ee 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -87,6 +87,7 @@ + diff --git a/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs index 86c26970..9233c100 100644 --- a/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs +++ b/src/Shared/HandyControl_Shared/Media/Animation/GeometryAnimation.cs @@ -3,6 +3,7 @@ using System.Text.RegularExpressions; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; +using HandyControl.Data; using HandyControl.Tools; // ReSharper disable PossibleInvalidOperationException @@ -173,7 +174,7 @@ namespace HandyControl.Media.Animation public bool IsCumulative { get => (bool) GetValue(IsCumulativeProperty); - set => SetValue(IsCumulativeProperty, value); + set => SetValue(IsCumulativeProperty, ValueBoxes.BooleanBox(value)); } } }