/************************************************************************************* Extended WPF Toolkit Copyright (C) 2007-2013 Xceed Software Inc. This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license For more features, controls, and fast professional support, pick up the Plus Edition at http://xceed.com/wpf_toolkit Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids ***********************************************************************************/ using System; using System.Windows; using System.Windows.Controls; namespace Xceed.Wpf.Toolkit.Panels { public class RandomPanel : AnimationPanel { #region MinimumWidth Property public static readonly DependencyProperty MinimumWidthProperty = DependencyProperty.Register( "MinimumWidth", typeof( double ), typeof( RandomPanel ), new FrameworkPropertyMetadata( 10d, new PropertyChangedCallback( RandomPanel.OnMinimumWidthChanged ), new CoerceValueCallback( RandomPanel.CoerceMinimumWidth ) ) ); public double MinimumWidth { get { return ( double )this.GetValue( RandomPanel.MinimumWidthProperty ); } set { this.SetValue( RandomPanel.MinimumWidthProperty, value ); } } private static void OnMinimumWidthChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { RandomPanel panel = ( RandomPanel )d; panel.CoerceValue( RandomPanel.MaximumWidthProperty ); panel.InvalidateMeasure(); } private static object CoerceMinimumWidth( DependencyObject d, object baseValue ) { RandomPanel panel = ( RandomPanel )d; double value = ( double )baseValue; if( double.IsNaN( value ) || double.IsInfinity( value ) || ( value < 0d ) ) return DependencyProperty.UnsetValue; double maximum = panel.MaximumWidth; if( value > maximum ) return maximum; return baseValue; } #endregion #region MinimumHeight Property public static readonly DependencyProperty MinimumHeightProperty = DependencyProperty.Register( "MinimumHeight", typeof( double ), typeof( RandomPanel ), new FrameworkPropertyMetadata( 10d, new PropertyChangedCallback( RandomPanel.OnMinimumHeightChanged ), new CoerceValueCallback( RandomPanel.CoerceMinimumHeight ) ) ); public double MinimumHeight { get { return ( double )this.GetValue( RandomPanel.MinimumHeightProperty ); } set { this.SetValue( RandomPanel.MinimumHeightProperty, value ); } } private static void OnMinimumHeightChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { RandomPanel panel = ( RandomPanel )d; panel.CoerceValue( RandomPanel.MaximumHeightProperty ); panel.InvalidateMeasure(); } private static object CoerceMinimumHeight( DependencyObject d, object baseValue ) { RandomPanel panel = ( RandomPanel )d; double value = ( double )baseValue; if( double.IsNaN( value ) || double.IsInfinity( value ) || ( value < 0d ) ) return DependencyProperty.UnsetValue; double maximum = panel.MaximumHeight; if( value > maximum ) return maximum; return baseValue; } #endregion #region MaximumWidth Property public static readonly DependencyProperty MaximumWidthProperty = DependencyProperty.Register( "MaximumWidth", typeof( double ), typeof( RandomPanel ), new FrameworkPropertyMetadata( 100d, new PropertyChangedCallback( RandomPanel.OnMaximumWidthChanged ), new CoerceValueCallback( RandomPanel.CoerceMaximumWidth ) ) ); public double MaximumWidth { get { return ( double )this.GetValue( RandomPanel.MaximumWidthProperty ); } set { this.SetValue( RandomPanel.MaximumWidthProperty, value ); } } private static void OnMaximumWidthChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { RandomPanel panel = ( RandomPanel )d; panel.CoerceValue( RandomPanel.MinimumWidthProperty ); panel.InvalidateMeasure(); } private static object CoerceMaximumWidth( DependencyObject d, object baseValue ) { RandomPanel panel = ( RandomPanel )d; double value = ( double )baseValue; if( double.IsNaN( value ) || double.IsInfinity( value ) || ( value < 0d ) ) return DependencyProperty.UnsetValue; double minimum = panel.MinimumWidth; if( value < minimum ) return minimum; return baseValue; } #endregion #region MaximumHeight Property public static readonly DependencyProperty MaximumHeightProperty = DependencyProperty.Register( "MaximumHeight", typeof( double ), typeof( RandomPanel ), new FrameworkPropertyMetadata( 100d, new PropertyChangedCallback( RandomPanel.OnMaximumHeightChanged ), new CoerceValueCallback( RandomPanel.CoerceMaximumHeight ) ) ); public double MaximumHeight { get { return ( double )this.GetValue( RandomPanel.MaximumHeightProperty ); } set { this.SetValue( RandomPanel.MaximumHeightProperty, value ); } } private static void OnMaximumHeightChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) { RandomPanel panel = ( RandomPanel )d; panel.CoerceValue( RandomPanel.MinimumHeightProperty ); panel.InvalidateMeasure(); } private static object CoerceMaximumHeight( DependencyObject d, object baseValue ) { RandomPanel panel = ( RandomPanel )d; double value = ( double )baseValue; if( double.IsNaN( value ) || double.IsInfinity( value ) || ( value < 0d ) ) return DependencyProperty.UnsetValue; double minimum = panel.MinimumHeight; if( value < minimum ) return minimum; return baseValue; } #endregion #region Seed Property public static readonly DependencyProperty SeedProperty = DependencyProperty.Register( "Seed", typeof( int ), typeof( RandomPanel ), new FrameworkPropertyMetadata( 0, new PropertyChangedCallback( RandomPanel.SeedChanged ) ) ); public int Seed { get { return ( int )this.GetValue( RandomPanel.SeedProperty ); } set { this.SetValue( RandomPanel.SeedProperty, value ); } } private static void SeedChanged( DependencyObject obj, DependencyPropertyChangedEventArgs args ) { if( obj is RandomPanel ) { RandomPanel owner = ( RandomPanel )obj; owner._random = new Random( ( int )args.NewValue ); owner.InvalidateArrange(); } } #endregion #region ActualSize Private Property // Using a DependencyProperty as the backing store for ActualSize. This enables animation, styling, binding, etc... private static readonly DependencyProperty ActualSizeProperty = DependencyProperty.RegisterAttached( "ActualSize", typeof( Size ), typeof( RandomPanel ), new UIPropertyMetadata( new Size() ) ); private static Size GetActualSize( DependencyObject obj ) { return ( Size )obj.GetValue( RandomPanel.ActualSizeProperty ); } private static void SetActualSize( DependencyObject obj, Size value ) { obj.SetValue( RandomPanel.ActualSizeProperty, value ); } #endregion protected override Size MeasureChildrenOverride( UIElementCollection children, Size constraint ) { Size availableSize = new Size( double.PositiveInfinity, double.PositiveInfinity ); foreach( UIElement child in children ) { if( child == null ) continue; Size childSize = new Size( 1d * _random.Next( Convert.ToInt32( MinimumWidth ), Convert.ToInt32( MaximumWidth ) ), 1d * _random.Next( Convert.ToInt32( MinimumHeight ), Convert.ToInt32( MaximumHeight ) ) ); child.Measure( childSize ); RandomPanel.SetActualSize( child, childSize ); } return new Size(); } protected override Size ArrangeChildrenOverride( UIElementCollection children, Size finalSize ) { foreach( UIElement child in children ) { if( child == null ) continue; Size childSize = RandomPanel.GetActualSize( child ); double x = _random.Next( 0, ( int )( Math.Max( finalSize.Width - childSize.Width, 0 ) ) ); double y = _random.Next( 0, ( int )( Math.Max( finalSize.Height - childSize.Height, 0 ) ) ); double width = Math.Min( finalSize.Width, childSize.Width ); double height = Math.Min( finalSize.Height, childSize.Height ); this.ArrangeChild( child, new Rect( new Point( x, y ), new Size( width, height ) ) ); } return finalSize; } #region Private Fields private Random _random = new Random(); #endregion } }