From a530f5b7e752e12dab830a96de7c67e11aafe774 Mon Sep 17 00:00:00 2001 From: donandren Date: Wed, 9 Mar 2016 22:00:46 +0200 Subject: [PATCH] reformat LayoutTransformControl code --- .../LayoutTransformControl.cs | 279 +++++++++--------- .../LayoutTransformControlTests.cs | 13 +- 2 files changed, 143 insertions(+), 149 deletions(-) diff --git a/src/Perspex.Controls/LayoutTransformControl.cs b/src/Perspex.Controls/LayoutTransformControl.cs index 7c7be3c6f8..74b2c44a45 100644 --- a/src/Perspex.Controls/LayoutTransformControl.cs +++ b/src/Perspex.Controls/LayoutTransformControl.cs @@ -9,7 +9,7 @@ using Perspex.Controls.Primitives; using Perspex.Media; using Perspex.VisualTree; using System; -//using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reactive.Linq; @@ -32,99 +32,61 @@ namespace Perspex.Controls set { SetValue(LayoutTransformProperty, value); } } - /// - /// Acceptable difference between two doubles. - /// - private const double AcceptableDelta = 0.0001; - - /// - /// Number of decimals to round the Matrix to. - /// - private const int DecimalsAfterRound = 4; - - /// - /// RenderTransform/MatrixTransform applied to TransformRoot. - /// - private MatrixTransform _matrixTransform; - - /// - /// Transformation matrix corresponding to _matrixTransform. - /// - private Matrix _transformation; + public Control TransformRoot => _transformRoot ?? + (_transformRoot = this.GetVisualChildren().OfType().FirstOrDefault()); /// - /// Actual DesiredSize of Child element (the value it returned from its MeasureOverride method). + /// Provides the behavior for the "Arrange" pass of layout. /// - private Size _childActualSize = Size.Empty; - - private Control _transformRoot; - - public Control TransformRoot => _transformRoot ?? - (_transformRoot = this.GetVisualChildren().OfType().FirstOrDefault()); - - private IDisposable _transformChangedEvent = null; - - private void OnLayoutTransformChanged(PerspexPropertyChangedEventArgs e) + /// The final area within the parent that this element should use to arrange itself and its children. + /// The actual size used. + protected override Size ArrangeOverride(Size finalSize) { - var newTransform = e.NewValue as Transform; - - if (_transformChangedEvent != null) + if (TransformRoot == null || LayoutTransform == null) { - _transformChangedEvent.Dispose(); - _transformChangedEvent = null; + return base.ArrangeOverride(finalSize); } - if (newTransform != null) + // Determine the largest available size after the transformation + Size finalSizeTransformed = ComputeLargestTransformedSize(finalSize); + if (IsSizeSmaller(finalSizeTransformed, TransformRoot.DesiredSize)) { - _transformChangedEvent = Observable.FromEventPattern( - v => newTransform.Changed += v, v => newTransform.Changed -= v) - .Subscribe(onNext: v => ApplyLayoutTransform()); + // Some elements do not like being given less space than they asked for (ex: TextBlock) + // Bump the working size up to do the right thing by them + finalSizeTransformed = TransformRoot.DesiredSize; } - ApplyLayoutTransform(); - } - - /// - /// Builds the visual tree for the LayoutTransformerControl when a new - /// template is applied. - /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) - { - base.OnTemplateApplied(e); + // Transform the working size to find its width/height + Rect transformedRect = new Rect(0, 0, finalSizeTransformed.Width, finalSizeTransformed.Height).TransformToAABB(_transformation); + // Create the Arrange rect to center the transformed content + Rect finalRect = new Rect( + -transformedRect.X + ((finalSize.Width - transformedRect.Width) / 2), + -transformedRect.Y + ((finalSize.Height - transformedRect.Height) / 2), + finalSizeTransformed.Width, + finalSizeTransformed.Height); - _matrixTransform = new MatrixTransform(); + // Perform an Arrange on TransformRoot (containing Child) + Size arrangedsize; + TransformRoot.Arrange(finalRect); + arrangedsize = TransformRoot.Bounds.Size; - if (null != TransformRoot) + // This is the first opportunity under Silverlight to find out the Child's true DesiredSize + if (IsSizeSmaller(finalSizeTransformed, arrangedsize) && (Size.Empty == _childActualSize)) { - TransformRoot.RenderTransform = _matrixTransform; - TransformRoot.TransformOrigin = new RelativePoint(0, 0, RelativeUnit.Absolute); + //// Unfortunately, all the work so far is invalid because the wrong DesiredSize was used + //// Make a note of the actual DesiredSize + //_childActualSize = arrangedsize; + //// Force a new measure/arrange pass + //InvalidateMeasure(); } - - ApplyLayoutTransform(); - } - - /// - /// Applies the layout transform on the LayoutTransformerControl content. - /// - /// - /// Only used in advanced scenarios (like animating the LayoutTransform). - /// Should be used to notify the LayoutTransformer control that some aspect - /// of its Transform property has changed. - /// - private void ApplyLayoutTransform() - { - if (LayoutTransform == null) return; - - // Get the transform matrix and apply it - _transformation = RoundMatrix(LayoutTransform.Value, DecimalsAfterRound); - - if (null != _matrixTransform) + else { - _matrixTransform.Matrix = _transformation; + // Clear the "need to measure/arrange again" flag + _childActualSize = Size.Empty; } - // New transform means re-layout is necessary - InvalidateMeasure(); + // Return result to perform the transformation + return finalSize; } /// @@ -165,57 +127,100 @@ namespace Perspex.Controls } /// - /// Provides the behavior for the "Arrange" pass of layout. + /// Builds the visual tree for the LayoutTransformerControl when a new + /// template is applied. /// - /// The final area within the parent that this element should use to arrange itself and its children. - /// The actual size used. - protected override Size ArrangeOverride(Size finalSize) + protected override void OnTemplateApplied(TemplateAppliedEventArgs e) { - if (TransformRoot == null || LayoutTransform == null) - { - return base.ArrangeOverride(finalSize); - } + base.OnTemplateApplied(e); - // Determine the largest available size after the transformation - Size finalSizeTransformed = ComputeLargestTransformedSize(finalSize); - if (IsSizeSmaller(finalSizeTransformed, TransformRoot.DesiredSize)) + _matrixTransform = new MatrixTransform(); + + if (null != TransformRoot) { - // Some elements do not like being given less space than they asked for (ex: TextBlock) - // Bump the working size up to do the right thing by them - finalSizeTransformed = TransformRoot.DesiredSize; + TransformRoot.RenderTransform = _matrixTransform; + TransformRoot.TransformOrigin = new RelativePoint(0, 0, RelativeUnit.Absolute); } - // Transform the working size to find its width/height - Rect transformedRect = new Rect(0, 0, finalSizeTransformed.Width, finalSizeTransformed.Height).TransformToAABB(_transformation); - // Create the Arrange rect to center the transformed content - Rect finalRect = new Rect( - -transformedRect.X + ((finalSize.Width - transformedRect.Width) / 2), - -transformedRect.Y + ((finalSize.Height - transformedRect.Height) / 2), - finalSizeTransformed.Width, - finalSizeTransformed.Height); + ApplyLayoutTransform(); + } - // Perform an Arrange on TransformRoot (containing Child) - Size arrangedsize; - TransformRoot.Arrange(finalRect); - arrangedsize = TransformRoot.Bounds.Size; + /// + /// Acceptable difference between two doubles. + /// + private const double AcceptableDelta = 0.0001; - // This is the first opportunity under Silverlight to find out the Child's true DesiredSize - if (IsSizeSmaller(finalSizeTransformed, arrangedsize) && (Size.Empty == _childActualSize)) - { - //// Unfortunately, all the work so far is invalid because the wrong DesiredSize was used - //// Make a note of the actual DesiredSize - //_childActualSize = arrangedsize; - //// Force a new measure/arrange pass - //InvalidateMeasure(); - } - else + /// + /// Number of decimals to round the Matrix to. + /// + private const int DecimalsAfterRound = 4; + + /// + /// Actual DesiredSize of Child element (the value it returned from its MeasureOverride method). + /// + private Size _childActualSize = Size.Empty; + + /// + /// RenderTransform/MatrixTransform applied to TransformRoot. + /// + private MatrixTransform _matrixTransform; + + /// + /// Transformation matrix corresponding to _matrixTransform. + /// + private Matrix _transformation; + private IDisposable _transformChangedEvent = null; + private Control _transformRoot; + /// + /// Returns true if Size a is smaller than Size b in either dimension. + /// + /// Second Size. + /// First Size. + /// True if Size a is smaller than Size b in either dimension. + private static bool IsSizeSmaller(Size a, Size b) + { + return (a.Width + AcceptableDelta < b.Width) || (a.Height + AcceptableDelta < b.Height); + } + + /// + /// Rounds the non-offset elements of a Matrix to avoid issues due to floating point imprecision. + /// + /// Matrix to round. + /// Number of decimal places to round to. + /// Rounded Matrix. + private static Matrix RoundMatrix(Matrix matrix, int decimals) + { + return new Matrix( + Math.Round(matrix.M11, decimals), + Math.Round(matrix.M12, decimals), + Math.Round(matrix.M21, decimals), + Math.Round(matrix.M22, decimals), + matrix.M31, + matrix.M32); + } + + /// + /// Applies the layout transform on the LayoutTransformerControl content. + /// + /// + /// Only used in advanced scenarios (like animating the LayoutTransform). + /// Should be used to notify the LayoutTransformer control that some aspect + /// of its Transform property has changed. + /// + private void ApplyLayoutTransform() + { + if (LayoutTransform == null) return; + + // Get the transform matrix and apply it + _transformation = RoundMatrix(LayoutTransform.Value, DecimalsAfterRound); + + if (null != _matrixTransform) { - // Clear the "need to measure/arrange again" flag - _childActualSize = Size.Empty; + _matrixTransform.Matrix = _transformation; } - // Return result to perform the transformation - return finalSize; + // New transform means re-layout is necessary + InvalidateMeasure(); } /// @@ -361,32 +366,24 @@ namespace Perspex.Controls return computedSize; } - /// - /// Returns true if Size a is smaller than Size b in either dimension. - /// - /// Second Size. - /// First Size. - /// True if Size a is smaller than Size b in either dimension. - private static bool IsSizeSmaller(Size a, Size b) + private void OnLayoutTransformChanged(PerspexPropertyChangedEventArgs e) { - return (a.Width + AcceptableDelta < b.Width) || (a.Height + AcceptableDelta < b.Height); - } + var newTransform = e.NewValue as Transform; - /// - /// Rounds the non-offset elements of a Matrix to avoid issues due to floating point imprecision. - /// - /// Matrix to round. - /// Number of decimal places to round to. - /// Rounded Matrix. - private static Matrix RoundMatrix(Matrix matrix, int decimals) - { - return new Matrix( - Math.Round(matrix.M11, decimals), - Math.Round(matrix.M12, decimals), - Math.Round(matrix.M21, decimals), - Math.Round(matrix.M22, decimals), - matrix.M31, - matrix.M32); + if (_transformChangedEvent != null) + { + _transformChangedEvent.Dispose(); + _transformChangedEvent = null; + } + + if (newTransform != null) + { + _transformChangedEvent = Observable.FromEventPattern( + v => newTransform.Changed += v, v => newTransform.Changed -= v) + .Subscribe(onNext: v => ApplyLayoutTransform()); + } + + ApplyLayoutTransform(); } } } \ No newline at end of file diff --git a/tests/Perspex.Controls.UnitTests/LayoutTransformControlTests.cs b/tests/Perspex.Controls.UnitTests/LayoutTransformControlTests.cs index 946fb9e8b9..10c4caa381 100644 --- a/tests/Perspex.Controls.UnitTests/LayoutTransformControlTests.cs +++ b/tests/Perspex.Controls.UnitTests/LayoutTransformControlTests.cs @@ -223,20 +223,17 @@ namespace Perspex.Controls.UnitTests { LayoutTransform = transform, Template = new FuncControlTemplate( - p => - { - var c = new ContentPresenter() { Content = p.Content }; - //we need to force create visual child - //so the measure after is correct - c.UpdateChild(); - return c; - }) + p => new ContentPresenter() { Content = p.Content }) }; lt.Content = new Rectangle() { Width = width, Height = height }; lt.ApplyTemplate(); + //we need to force create visual child + //so the measure after is correct + (lt.Presenter as ContentPresenter).UpdateChild(); + Assert.NotNull(lt.Presenter?.Child); lt.Measure(Size.Infinity);