diff --git a/src/Files.App.Controls/Storage/RingShape/RingShape.Properties.cs b/src/Files.App.Controls/Storage/RingShape/RingShape.Properties.cs index 349df99af071..d85ff577f316 100644 --- a/src/Files.App.Controls/Storage/RingShape/RingShape.Properties.cs +++ b/src/Files.App.Controls/Storage/RingShape/RingShape.Properties.cs @@ -32,16 +32,16 @@ public partial class RingShape : Path [GeneratedDependencyProperty(DefaultValue = 0.0d)] public partial double RadiusHeight { get; set; } - [GeneratedDependencyProperty] + [GeneratedDependencyProperty(DefaultValue = false)] public partial bool IsCircle { get; set; } [GeneratedDependencyProperty] public partial Point Center { get; set; } - [GeneratedDependencyProperty] + [GeneratedDependencyProperty(DefaultValue = 0.0d)] public partial double ActualRadiusWidth { get; set; } - [GeneratedDependencyProperty] + [GeneratedDependencyProperty(DefaultValue = 0.0d)] public partial double ActualRadiusHeight { get; set; } partial void OnStartAngleChanged(double newValue) diff --git a/src/Files.App.Controls/Storage/RingShape/RingShape.cs b/src/Files.App.Controls/Storage/RingShape/RingShape.cs index 1d88656acd98..8bcc95b2e03c 100644 --- a/src/Files.App.Controls/Storage/RingShape/RingShape.cs +++ b/src/Files.App.Controls/Storage/RingShape/RingShape.cs @@ -1,10 +1,8 @@ // Copyright (c) Files Community // Licensed under the MIT License. -using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Shapes; -using System; using Windows.Foundation; namespace Files.App.Controls.Primitives @@ -18,18 +16,18 @@ public partial class RingShape : Path // Fields - private bool _isUpdating; // Is True when path is updating - private bool _isCircle; // When True, Width and Height are equalized - private Size _equalSize; // Calculated where Width and Height are equal - private double _equalRadius; // Calculated where RadiusWidth and RadiusHeight are equal - private Point _centerPoint; // Center Point within Width and Height bounds - private double _normalizedMinAngle; // Normalized MinAngle between -180 and 540 - private double _normalizedMaxAngle; // Normalized MaxAngle between 0 and 360 - private double _validStartAngle; // The validated StartAngle - private double _validEndAngle; // The validated EndAngle - private double _radiusWidth; // The radius Width - private double _radiusHeight; // The radius Height - private SweepDirection _sweepDirection; // The SweepDirection + private bool _isUpdating; // Is True when path is updating + private bool _isCircle; // When True, Width and Height are equalized + private Size _equalSize; // Calculated where Width and Height are equal + private double _equalRadius; // Calculated where RadiusWidth and RadiusHeight are equal + private Point _centerPoint; // Center Point within Width and Height bounds + private double _normalizedMinAngle; // Normalized MinAngle between -180 and 540 + private double _normalizedMaxAngle; // Normalized MaxAngle between 0 and 360 + private double _validStartAngle; // The validated StartAngle + private double _validEndAngle; // The validated EndAngle + private double _radiusWidth; // The radius Width + private double _radiusHeight; // The radius Height + private SweepDirection _sweepDirection; // The SweepDirection // Constants @@ -168,41 +166,41 @@ public void UpdateSizeAndStroke(DependencyObject d) { RingShape ringShape = (RingShape)d; - AdjustRadiusWidth( ringShape , ringShape.RadiusWidth , ringShape.StrokeThickness ); - AdjustRadiusHeight( ringShape , ringShape.RadiusHeight , ringShape.StrokeThickness ); + AdjustRadiusWidth(ringShape, ringShape.RadiusWidth, ringShape.StrokeThickness); + AdjustRadiusHeight(ringShape, ringShape.RadiusHeight, ringShape.StrokeThickness); - _equalSize = CalculateEqualSize( new Size( ringShape.Width , ringShape.Height ) , ringShape.StrokeThickness ); - _equalRadius = CalculateEqualRadius( ringShape , ringShape.RadiusWidth , ringShape.RadiusHeight , ringShape.StrokeThickness ); + _equalSize = CalculateEqualSize(new Size(ringShape.Width, ringShape.Height), ringShape.StrokeThickness); + _equalRadius = CalculateEqualRadius(ringShape, ringShape.RadiusWidth, ringShape.RadiusHeight, ringShape.StrokeThickness); - _centerPoint = new Point( ringShape.Width / 2 , ringShape.Height / 2 ); + _centerPoint = new Point(ringShape.Width / 2, ringShape.Height / 2); ringShape.Center = _centerPoint; - CalculateAndSetNormalizedAngles( ringShape , ringShape.MinAngle , ringShape.MaxAngle ); + CalculateAndSetNormalizedAngles(ringShape, ringShape.MinAngle, ringShape.MaxAngle); - ValidateAngle( ringShape , ringShape.StartAngle , true ); - ValidateAngle( ringShape , ringShape.EndAngle , false ); + ValidateAngle(ringShape, ringShape.StartAngle, true); + ValidateAngle(ringShape, ringShape.EndAngle, false); } private static EllipseGeometry DrawEllipse(bool IsCircle, Point Center, double EqualRadius, double RadiusWidth, double RadiusHeight) { EllipseGeometry eg; - if ( IsCircle == true ) + if (IsCircle == true) { eg = new EllipseGeometry { - Center = Center , - RadiusX = EqualRadius , - RadiusY = EqualRadius , + Center = Center, + RadiusX = EqualRadius, + RadiusY = EqualRadius, }; } else { eg = new EllipseGeometry { - Center = Center , - RadiusX = RadiusWidth , - RadiusY = RadiusHeight , + Center = Center, + RadiusX = RadiusWidth, + RadiusY = RadiusHeight, }; } @@ -220,7 +218,7 @@ private static PathGeometry DrawArc(RingShape RingShape, SweepDirection SweepDir var arcSegment = new ArcSegment(); - if ( IsCircle == true ) + if (IsCircle == true) { var radius = EqualRadius; @@ -228,11 +226,11 @@ private static PathGeometry DrawArc(RingShape RingShape, SweepDirection SweepDir RingShape.ActualRadiusHeight = radius; // Start Point - pathFigure.StartPoint = ArcStartPoint( SweepDirection , newCenter, StartAngle, radius, radius); + pathFigure.StartPoint = ArcStartPoint(SweepDirection, newCenter, StartAngle, radius, radius); // Arc Segment and End Point - arcSegment = CreateArcSegment( SweepDirection , newCenter , StartAngle , EndAngle , radius , radius ); + arcSegment = CreateArcSegment(SweepDirection, newCenter, StartAngle, EndAngle, radius, radius); } else { @@ -243,63 +241,63 @@ private static PathGeometry DrawArc(RingShape RingShape, SweepDirection SweepDir RingShape.ActualRadiusHeight = radiusHeight; // Start Point - pathFigure.StartPoint = ArcStartPoint( SweepDirection , newCenter , StartAngle , radiusWidth , radiusHeight ); + pathFigure.StartPoint = ArcStartPoint(SweepDirection, newCenter, StartAngle, radiusWidth, radiusHeight); // Arc Segment and End Point - arcSegment = CreateArcSegment( SweepDirection , newCenter , StartAngle , EndAngle , radiusWidth , radiusHeight ); + arcSegment = CreateArcSegment(SweepDirection, newCenter, StartAngle, EndAngle, radiusWidth, radiusHeight); } - pathFigure.Segments.Add( arcSegment ); - pathGeometry.Figures.Add( pathFigure ); + pathFigure.Segments.Add(arcSegment); + pathGeometry.Figures.Add(pathFigure); return pathGeometry; } - private static Point ArcStartPoint(SweepDirection SweepDirection , Point Center, double StartAngle , double RadiusWidth, double RadiusHeight) + private static Point ArcStartPoint(SweepDirection SweepDirection, Point Center, double StartAngle, double RadiusWidth, double RadiusHeight) { var finalPoint = new Point(); // Counterclockwise - if ( SweepDirection == SweepDirection.Counterclockwise ) + if (SweepDirection == SweepDirection.Counterclockwise) { finalPoint = new Point( - Center.X - Math.Sin( StartAngle * DegreesToRadians ) * RadiusWidth , - Center.Y - Math.Cos( StartAngle * DegreesToRadians ) * RadiusHeight ); + Center.X - Math.Sin(StartAngle * DegreesToRadians) * RadiusWidth, + Center.Y - Math.Cos(StartAngle * DegreesToRadians) * RadiusHeight); } // Clockwise else { finalPoint = new Point( - Center.X + Math.Sin( StartAngle * DegreesToRadians ) * RadiusWidth , - Center.Y - Math.Cos( StartAngle * DegreesToRadians ) * RadiusHeight ); + Center.X + Math.Sin(StartAngle * DegreesToRadians) * RadiusWidth, + Center.Y - Math.Cos(StartAngle * DegreesToRadians) * RadiusHeight); } return finalPoint; } - private static ArcSegment CreateArcSegment(SweepDirection SweepDirection , Point Center , double StartAngle, double EndAngle , double RadiusWidth , double RadiusHeight) - { + private static ArcSegment CreateArcSegment(SweepDirection SweepDirection, Point Center, double StartAngle, double EndAngle, double RadiusWidth, double RadiusHeight) + { var finalArcSegment = new ArcSegment(); // Counterclockwise - if ( SweepDirection == SweepDirection.Counterclockwise ) + if (SweepDirection == SweepDirection.Counterclockwise) { finalArcSegment.Point = new Point( - Center.X - Math.Sin( EndAngle * DegreesToRadians ) * RadiusWidth , - Center.Y - Math.Cos( EndAngle * DegreesToRadians ) * RadiusHeight ); + Center.X - Math.Sin(EndAngle * DegreesToRadians) * RadiusWidth, + Center.Y - Math.Cos(EndAngle * DegreesToRadians) * RadiusHeight); - if ( EndAngle < StartAngle ) + if (EndAngle < StartAngle) { - finalArcSegment.IsLargeArc = ( EndAngle - StartAngle ) <= -180.0; + finalArcSegment.IsLargeArc = (EndAngle - StartAngle) <= -180.0; finalArcSegment.SweepDirection = SweepDirection.Clockwise; } else { - finalArcSegment.IsLargeArc = ( EndAngle - StartAngle ) >= 180.0; + finalArcSegment.IsLargeArc = (EndAngle - StartAngle) >= 180.0; finalArcSegment.SweepDirection = SweepDirection.Counterclockwise; } } @@ -308,21 +306,21 @@ private static ArcSegment CreateArcSegment(SweepDirection SweepDirection , Point { finalArcSegment.Point = new Point( - Center.X + Math.Sin( EndAngle * DegreesToRadians ) * RadiusWidth , - Center.Y - Math.Cos( EndAngle * DegreesToRadians ) * RadiusHeight ); + Center.X + Math.Sin(EndAngle * DegreesToRadians) * RadiusWidth, + Center.Y - Math.Cos(EndAngle * DegreesToRadians) * RadiusHeight); //ArcSegment.IsLargeArc = ( EndAngle - StartAngle ) >= 180.0; - if ( EndAngle < StartAngle ) + if (EndAngle < StartAngle) { - finalArcSegment.IsLargeArc = ( EndAngle - StartAngle ) <= -180.0; + finalArcSegment.IsLargeArc = (EndAngle - StartAngle) <= -180.0; finalArcSegment.SweepDirection = SweepDirection.Counterclockwise; } else { - finalArcSegment.IsLargeArc = ( EndAngle - StartAngle ) >= 180.0; + finalArcSegment.IsLargeArc = (EndAngle - StartAngle) >= 180.0; finalArcSegment.SweepDirection = SweepDirection.Clockwise; } } - finalArcSegment.Size = new Size( RadiusWidth , RadiusHeight ); + finalArcSegment.Size = new Size(RadiusWidth, RadiusHeight); return finalArcSegment; } diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.Constants.cs b/src/Files.App.Controls/Storage/StorageBar/StorageBar.Constants.cs deleted file mode 100644 index e662d7c9320a..000000000000 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.Constants.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Files Community -// Licensed under the MIT License. - -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; - -namespace Files.App.Controls -{ - // TemplateParts - [TemplatePart(Name = ContainerPartName, Type = typeof(Grid))] - [TemplatePart(Name = ValueColumnPartName, Type = typeof(ColumnDefinition))] - [TemplatePart(Name = GapColumnPartName, Type = typeof(ColumnDefinition))] - [TemplatePart(Name = TrackColumnPartName, Type = typeof(ColumnDefinition))] - [TemplatePart(Name = ValueBorderPartName, Type = typeof(Border))] - [TemplatePart(Name = TrackBorderPartName, Type = typeof(Border))] - // VisualStates - [TemplateVisualState(Name = SafeStateName, GroupName = ControlStateGroupName)] - [TemplateVisualState(Name = CautionStateName, GroupName = ControlStateGroupName)] - [TemplateVisualState(Name = CriticalStateName, GroupName = ControlStateGroupName)] - [TemplateVisualState(Name = DisabledStateName, GroupName = ControlStateGroupName)] - public partial class StorageBar : RangeBase - { - internal const string ContainerPartName = "PART_Container"; - - internal const string ValueColumnPartName = "PART_ValueColumn"; - internal const string GapColumnPartName = "PART_GapColumn"; - internal const string TrackColumnPartName = "PART_TrackColumn"; - - internal const string ValueBorderPartName = "PART_ValueBar"; - internal const string TrackBorderPartName = "PART_TrackBar"; - - internal const string ControlStateGroupName = "ControlStates"; - - internal const string SafeStateName = "Safe"; - internal const string CautionStateName = "Caution"; - internal const string CriticalStateName = "Critical"; - internal const string DisabledStateName = "Disabled"; - } -} diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.Properties.cs b/src/Files.App.Controls/Storage/StorageBar/StorageBar.Properties.cs index 95dea41d4922..bee33c739576 100644 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.Properties.cs +++ b/src/Files.App.Controls/Storage/StorageBar/StorageBar.Properties.cs @@ -2,16 +2,15 @@ // Licensed under the MIT License. using CommunityToolkit.WinUI; -using Microsoft.UI.Xaml; namespace Files.App.Controls { public partial class StorageBar { - [GeneratedDependencyProperty(DefaultValue = 4.0d)] + [GeneratedDependencyProperty(DefaultValue = 6.0d)] public partial double ValueBarHeight { get; set; } - [GeneratedDependencyProperty(DefaultValue = 2.0d)] + [GeneratedDependencyProperty(DefaultValue = 3.0d)] public partial double TrackBarHeight { get; set; } [GeneratedDependencyProperty(DefaultValue = BarShapes.Round)] @@ -28,57 +27,56 @@ public partial class StorageBar partial void OnValueBarHeightChanged(double newValue) { - UpdateControl(this); + UpdateControl(); } partial void OnTrackBarHeightChanged(double newValue) { - UpdateControl(this); + UpdateControl(); } partial void OnBarShapeChanged(BarShapes newValue) { - UpdateControl(this); + UpdateControl(); } partial void OnPercentChanged(double newValue) { return; //Read-only - - DoubleToPercentage(Value, Minimum, Maximum); - UpdateControl(this); } partial void OnPercentCautionChanged(double newValue) { - UpdateControl(this); + UpdateControl(); } partial void OnPercentCriticalChanged(double newValue) { - UpdateControl(this); + UpdateControl(); } /// protected override void OnValueChanged(double oldValue, double newValue) { - _oldValue = oldValue; base.OnValueChanged(oldValue, newValue); - UpdateValue(this, Value, _oldValue, false, -1.0); + + UpdateValue(Value, _oldValue, false, -1.0); } /// protected override void OnMaximumChanged(double oldValue, double newValue) { base.OnMaximumChanged(oldValue, newValue); - UpdateValue(this, oldValue, newValue, false, -1.0); + + UpdateValue(oldValue, newValue, false, -1.0); } /// protected override void OnMinimumChanged(double oldValue, double newValue) { base.OnMinimumChanged(oldValue, newValue); - UpdateValue(this, oldValue, newValue, false, -1.0); + + UpdateValue(oldValue, newValue, false, -1.0); } } } diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.ThemeResources.xaml b/src/Files.App.Controls/Storage/StorageBar/StorageBar.ThemeResources.xaml deleted file mode 100644 index 692a3f7314f1..000000000000 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.ThemeResources.xaml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - 6 - 2 - - 4,4,4,4 - - - - - - - - - - - - - - - - - - 6 - 2 - - 4,4,4,4 - - - - - - - - - - - - - - - - - - 6 - 2 - - 4,4,4,4 - - - - - - - - - - - - - - - - diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.cs b/src/Files.App.Controls/Storage/StorageBar/StorageBar.cs index 47037c663f6f..236f74f080b8 100644 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.cs +++ b/src/Files.App.Controls/Storage/StorageBar/StorageBar.cs @@ -1,202 +1,131 @@ // Copyright (c) Files Community // Licensed under the MIT License. -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; -using System; using Windows.Foundation; namespace Files.App.Controls { + // TemplateParts + [TemplatePart(Name = TemplatePartName_Container, Type = typeof(Grid))] + [TemplatePart(Name = TemplatePartName_ValueColumn, Type = typeof(ColumnDefinition))] + [TemplatePart(Name = TemplatePartName__GapColumn, Type = typeof(ColumnDefinition))] + [TemplatePart(Name = TemplatePartName_TrackColumn, Type = typeof(ColumnDefinition))] + [TemplatePart(Name = TemplatePartName_ValueBorder, Type = typeof(Border))] + [TemplatePart(Name = TemplatePartName_TrackBorder, Type = typeof(Border))] + // VisualStates + [TemplateVisualState(GroupName = TemplateVisualStateGroupName_ControlStates, Name = TemplateVisualStateName_Safe)] + [TemplateVisualState(GroupName = TemplateVisualStateGroupName_ControlStates, Name = TemplateVisualStateName_Caution)] + [TemplateVisualState(GroupName = TemplateVisualStateGroupName_ControlStates, Name = TemplateVisualStateName_Critical)] + [TemplateVisualState(GroupName = TemplateVisualStateGroupName_ControlStates, Name = TemplateVisualStateName_Disabled)] /// /// Represents percentage ring islands. /// public partial class StorageBar : RangeBase { - // Fields - - double _oldValue; // Stores the previous value + // Constants - double _valueBarMaxWidth; // The maximum width for the Value Bar - double _trackBarMaxWidth; // The maximum width for the Track Bar + private const string TemplatePartName_Container = "PART_Container"; + private const string TemplatePartName_ValueColumn = "PART_ValueColumn"; + private const string TemplatePartName__GapColumn = "PART_GapColumn"; + private const string TemplatePartName_TrackColumn = "PART_TrackColumn"; + private const string TemplatePartName_ValueBorder = "PART_ValueBar"; + private const string TemplatePartName_TrackBorder = "PART_TrackBar"; - Grid? _containerGrid; // Reference to the container Grid - Size? _containerSize; // Reference to the container Size + private const string TemplateVisualStateGroupName_ControlStates = "ControlStates"; + private const string TemplateVisualStateName_Safe = "Safe"; + private const string TemplateVisualStateName_Caution = "Caution"; + private const string TemplateVisualStateName_Critical = "Critical"; + private const string TemplateVisualStateName_Disabled = "Disabled"; - ColumnDefinition? _valueColumn; // Reference to the ValueBar Column - ColumnDefinition? _trackColumn; // Reference to the TrackBar Column - ColumnDefinition? _gapColumn; // Reference to the Gap Column - - Border? _valueBarBorder; // Reference to the Value Bar Border - Border? _trackBarBorder; // Reference to the Track Bar Border + // Fields - BarShapes _barShape; // Reference to the BarShape + Grid _containerGrid = null!; + ColumnDefinition _valueColumn = null!; + ColumnDefinition _trackColumn = null!; + ColumnDefinition _gapColumn = null!; + Border _valueBarBorder = null!; + Border _trackBarBorder = null!; - double _gapWidth; // Stores the Gap between Value and Track Bars - double _smallerHeight; // Stores the smaller between Value and Track Bars + double _oldValue; + Size? _containerSize; + BarShapes _barShape; + double _gapWidth; + double _smallerHeight; // Constructor - /// - /// Initializes an instance of class. - /// + /// Initializes an instance of class. public StorageBar() { DefaultStyleKey = typeof(StorageBar); - - SizeChanged -= StorageBar_SizeChanged; - Unloaded -= StorageBar_Unloaded; - IsEnabledChanged -= StorageBar_IsEnabledChanged; - - SizeChanged += StorageBar_SizeChanged; - Unloaded += StorageBar_Unloaded; - IsEnabledChanged += StorageBar_IsEnabledChanged; } + // Methods + /// protected override void OnApplyTemplate() { base.OnApplyTemplate(); - UpdateInitialLayout(this); - } - #region Handle Property Changes - - /// - /// Handles the IsEnabledChanged event - /// - /// - /// - private void StorageBar_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) - { - UpdateControl(this); - } - - /// - /// Handles the Unloaded event - /// - /// - /// - private void StorageBar_Unloaded(object sender, RoutedEventArgs e) - { - SizeChanged -= StorageBar_SizeChanged; - Unloaded -= StorageBar_Unloaded; - IsEnabledChanged -= StorageBar_IsEnabledChanged; - } - - /// - /// Handles the SizeChanged event - /// - /// - /// - private void StorageBar_SizeChanged(object sender, SizeChangedEventArgs e) - { - Size minSize; - - if ( DesiredSize.Width < MinWidth || DesiredSize.Height < MinHeight || - e.NewSize.Width < MinWidth || e.NewSize.Height < MinHeight ) - { - Width = MinWidth; - Height = MinHeight; - - minSize = new Size( MinWidth , MinHeight ); - } - else - { - minSize = e.NewSize; - } - - UpdateContainer(this, minSize ); - UpdateControl(this); - } - - #endregion - - #region Update functions - - /// - /// Updates the initial layout of the StorageBar control - /// - /// The DependencyObject representing the control. - private void UpdateInitialLayout(DependencyObject d) - { - // Retrieve references to visual elements - _containerGrid = GetTemplateChild(ContainerPartName) as Grid; - - _valueColumn = GetTemplateChild(ValueColumnPartName) as ColumnDefinition; - _trackColumn = GetTemplateChild(TrackColumnPartName) as ColumnDefinition; - _gapColumn = GetTemplateChild(GapColumnPartName) as ColumnDefinition; - - _valueBarBorder = GetTemplateChild(ValueBorderPartName) as Border; - _trackBarBorder = GetTemplateChild(TrackBorderPartName) as Border; + _containerGrid = GetTemplateChild(TemplatePartName_Container) as Grid + ?? throw new MissingFieldException($"Could not find {TemplatePartName_Container} in the given {nameof(StorageBar)}'s style."); + _valueColumn = GetTemplateChild(TemplatePartName_ValueColumn) as ColumnDefinition + ?? throw new MissingFieldException($"Could not find {TemplatePartName_ValueColumn} in the given {nameof(StorageBar)}'s style."); + _trackColumn = GetTemplateChild(TemplatePartName_TrackColumn) as ColumnDefinition + ?? throw new MissingFieldException($"Could not find {TemplatePartName_TrackColumn} in the given {nameof(StorageBar)}'s style."); + _gapColumn = GetTemplateChild(TemplatePartName__GapColumn) as ColumnDefinition + ?? throw new MissingFieldException($"Could not find {TemplatePartName__GapColumn} in the given {nameof(StorageBar)}'s style."); + _valueBarBorder = GetTemplateChild(TemplatePartName_ValueBorder) as Border + ?? throw new MissingFieldException($"Could not find {TemplatePartName_ValueBorder} in the given {nameof(StorageBar)}'s style."); + _trackBarBorder = GetTemplateChild(TemplatePartName_TrackBorder) as Border + ?? throw new MissingFieldException($"Could not find {TemplatePartName_TrackBorder} in the given {nameof(StorageBar)}'s style."); _barShape = BarShape; - ValueBarHeight = ValueBarHeight; - TrackBarHeight = TrackBarHeight; + SizeChanged += StorageBar_SizeChanged; + Unloaded += StorageBar_Unloaded; + IsEnabledChanged += StorageBar_IsEnabledChanged; } - /// - /// Updates the StorageBar control. - /// - /// The DependencyObject representing the control. - private void UpdateControl(DependencyObject d) - { - // 1. Update the Bar Heights - UpdateContainerHeightsAndCorners(this, ValueBarHeight, TrackBarHeight); - - // 2. Set the 3 Column Widths - UpdateColumnWidths(this, Value, Minimum, Maximum); + // Methods - // 3. Update the control's VisualState - UpdateVisualState(this); + private void UpdateControl() + { + UpdateContainerHeightsAndCorners(); + UpdateColumnWidths(); + UpdateVisualState(); } - /// - /// Updates the StorageBar Values. - /// - /// The DependencyObject representing the control. - /// The new Value - /// The old Value - /// Checks if the Percent value is being changed - /// The new Percent value - private void UpdateValue(DependencyObject d, double newValue, double oldValue, bool isPercent, double newPercent) + private void UpdateValue(double newValue, double oldValue, bool isPercent, double newPercent) { _oldValue = oldValue; - var adjustedValue = isPercent ? PercentageToValue(newPercent, Minimum, Maximum) : newValue; - Percent = DoubleToPercentage(adjustedValue, Minimum, Maximum); + var adjustedValue = isPercent ? StorageControlsHelpers.PercentageToValue(newPercent, Minimum, Maximum) : newValue; + Percent = StorageControlsHelpers.DoubleToPercentage(adjustedValue, Minimum, Maximum); - UpdateControl(this); + UpdateControl(); } - /// - /// Updates Container Heights and Bar Corner Radii - /// - /// The DependencyObject representing the control. - /// The ValueBar Height - /// The TrackBar Height - private void UpdateContainerHeightsAndCorners(DependencyObject d, double valueBarHeight, double trackBarHeight) + private void UpdateContainerHeightsAndCorners() { // Finds the larger of the two height values - double calculatedLargerHeight = Math.Max(valueBarHeight, trackBarHeight); - double calculatedSmallerHeight = Math.Min(valueBarHeight, trackBarHeight); + double calculatedLargerHeight = Math.Max(ValueBarHeight, TrackBarHeight); + double calculatedSmallerHeight = Math.Min(ValueBarHeight, TrackBarHeight); - if (_valueBarBorder != null || _trackBarBorder != null || _containerGrid != null) + if (_valueBarBorder != null && _trackBarBorder != null && _containerGrid != null) { - _valueBarBorder.Height = valueBarHeight; - _trackBarBorder.Height = trackBarHeight; + _valueBarBorder.Height = ValueBarHeight; + _trackBarBorder.Height = TrackBarHeight; - if (_barShape == BarShapes.Round) + if (_barShape is BarShapes.Round) { - _valueBarBorder.CornerRadius = new(valueBarHeight / 2); - _trackBarBorder.CornerRadius = new(trackBarHeight / 2); + _valueBarBorder.CornerRadius = new(ValueBarHeight / 2); + _trackBarBorder.CornerRadius = new(TrackBarHeight / 2); } - else if (_barShape == BarShapes.Soft) + else if (_barShape is BarShapes.Soft) { - _valueBarBorder.CornerRadius = new(valueBarHeight / 4); - _trackBarBorder.CornerRadius = new(trackBarHeight / 4); + _valueBarBorder.CornerRadius = new(ValueBarHeight / 4); + _trackBarBorder.CornerRadius = new(TrackBarHeight / 4); } else { @@ -212,27 +141,20 @@ private void UpdateContainerHeightsAndCorners(DependencyObject d, double valueBa } - /// - /// Updates Column Widths and Bar Column assignments - /// - /// The DependencyObject representing the control. - /// The Value - /// The Minimum value - /// The Maximum value - private void UpdateColumnWidths(DependencyObject d, double value, double minValue, double maxValue) + private void UpdateColumnWidths() { - if (_gapColumn != null || _valueColumn != null || _trackColumn != null || _valueBarBorder != null || _trackBarBorder != null) + if (_gapColumn != null && _valueColumn != null && _trackColumn != null && _valueBarBorder != null && _trackBarBorder != null) { if (_containerSize is not Size containerSize) return; if (containerSize.Width > TrackBarHeight || containerSize.Width > ValueBarHeight) { - double valuePercent = DoubleToPercentage(Value, Minimum, Maximum); - double minPercent = DoubleToPercentage(Minimum, Minimum, Maximum); - double maxPercent = DoubleToPercentage(Maximum, Minimum, Maximum); + double valuePercent = StorageControlsHelpers.DoubleToPercentage(Value, Minimum, Maximum); + double minPercent = StorageControlsHelpers.DoubleToPercentage(Minimum, Minimum, Maximum); + double maxPercent = StorageControlsHelpers.DoubleToPercentage(Maximum, Minimum, Maximum); - if (valuePercent <= minPercent) // Value is <= Minimum + if (valuePercent <= minPercent) { _gapColumn.Width = new(1, GridUnitType.Star); _valueColumn.Width = new(1, GridUnitType.Star); @@ -244,7 +166,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu _valueBarBorder.Visibility = Visibility.Collapsed; _trackBarBorder.Visibility = Visibility.Visible; } - else if (valuePercent >= maxPercent) // Value is >= Maximum + else if (valuePercent >= maxPercent) { _gapColumn.Width = new(1, GridUnitType.Star); _valueColumn.Width = new(1, GridUnitType.Star); @@ -264,11 +186,9 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu Grid.SetColumnSpan(_trackBarBorder, 1); Grid.SetColumn(_trackBarBorder, 2); - _valueBarBorder.Visibility = Visibility.Visible; _trackBarBorder.Visibility = Visibility.Visible; - var valueBarHeight = ValueBarHeight; var trackBarHeight = TrackBarHeight; var gapWidth = _gapWidth; @@ -280,8 +200,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu if (valuePercent > minPercent && valuePercent <= minPercent + 2.0) // Between 0% and 2% { - var interpolatedValueBarHeight = CalculateInterpolatedValue( - this, + var interpolatedValueBarHeight = StorageControlsHelpers.CalculateInterpolatedValue( minPercent, Percent, minPercent + 2.0, @@ -289,8 +208,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu valueBarHeight, true); - var interpolatedTrackBarHeight = CalculateInterpolatedValue( - this, + var interpolatedTrackBarHeight = StorageControlsHelpers.CalculateInterpolatedValue( minPercent, Percent, minPercent + 2.0, @@ -298,30 +216,21 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu trackBarHeight, true); - var interpolatedGapWidth = gapWidth; - - if (valueLarger == true) - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + var interpolatedGapWidth = valueLarger + ? StorageControlsHelpers.CalculateInterpolatedValue( minPercent, Percent, minPercent + 2.0, 0.0, gapWidth, - true); - } - else - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + true) + : StorageControlsHelpers.CalculateInterpolatedValue( minPercent, Percent, minPercent + 2.0, 0.0, _smallerHeight, true); - } _valueColumn.MinWidth = interpolatedValueBarHeight; _trackColumn.MinWidth = interpolatedTrackBarHeight; @@ -337,8 +246,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu } else if (valuePercent >= maxPercent - 1.0 && valuePercent < maxPercent) // Between 98% and 100% { - var interpolatedValueBarHeight = CalculateInterpolatedValue( - this, + var interpolatedValueBarHeight = StorageControlsHelpers.CalculateInterpolatedValue( maxPercent - 2.0, Percent, maxPercent, @@ -346,8 +254,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu 0.0, true); - var interpolatedTrackBarHeight = CalculateInterpolatedValue( - this, + var interpolatedTrackBarHeight = StorageControlsHelpers.CalculateInterpolatedValue( maxPercent - 2.0, Percent, maxPercent, @@ -355,30 +262,21 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu 0.0, true); - var interpolatedGapWidth = gapWidth; - - if (valueLarger == true) - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + var interpolatedGapWidth = valueLarger + ? StorageControlsHelpers.CalculateInterpolatedValue( maxPercent - 2.0, Percent, maxPercent, 0.0, _smallerHeight, - true); - } - else - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + true) + : StorageControlsHelpers.CalculateInterpolatedValue( maxPercent - 2.0, Percent, maxPercent, 0.0, gapWidth, true); - } _valueColumn.MinWidth = interpolatedValueBarHeight; _trackColumn.MinWidth = interpolatedTrackBarHeight; @@ -402,30 +300,21 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu _valueColumn.Width = new(calculatedValueWidth); _trackColumn.Width = new(1, GridUnitType.Star); - var interpolatedGapWidth = gapWidth; - - if (valueLarger == true) - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + var interpolatedGapWidth = valueLarger + ? StorageControlsHelpers.CalculateInterpolatedValue( minPercent + 2.0, Percent, maxPercent - 2.0, gapWidth, _smallerHeight, - true); - } - else - { - interpolatedGapWidth = CalculateInterpolatedValue( - this, + true) + : StorageControlsHelpers.CalculateInterpolatedValue( minPercent + 2.0, Percent, maxPercent - 2.0, _smallerHeight, gapWidth, true); - } _gapColumn.Width = new(interpolatedGapWidth); @@ -437,12 +326,7 @@ private void UpdateColumnWidths(DependencyObject d, double value, double minValu } } - /// - /// Updates the ContainerSize taking in control Padding - /// - /// The DependencyObject representing the control. - /// The new Size - private void UpdateContainer(DependencyObject d, Size newSize) + private void UpdateContainer(Size newSize) { double containerWidth = newSize.Width - (Padding.Left + Padding.Right); double containerHeight = newSize.Height - (Padding.Top + Padding.Bottom); @@ -450,149 +334,53 @@ private void UpdateContainer(DependencyObject d, Size newSize) _containerSize = new(containerWidth, containerHeight); } - /// - /// Update the control's VisualState - /// - /// The DependencyObject representing the control. - private void UpdateVisualState(DependencyObject d) + private void UpdateVisualState() { - // First is the control is Disabled - if (IsEnabled == false) - { - VisualStateManager.GoToState(this, DisabledStateName, true); - } - // Then the control is Enabled - else - { - // Is the Percent value equal to or above the PercentCritical value - if (Percent >= PercentCritical) - { - VisualStateManager.GoToState(this, CriticalStateName, true); - } - // Is the Percent value equal to or above the PercentCaution value - else if (Percent >= PercentCaution) - { - VisualStateManager.GoToState(this, CautionStateName, true); - } - // Else we use the Safe State - else - { - VisualStateManager.GoToState(this, SafeStateName, true); - } - } + VisualStateManager.GoToState( + this, + IsEnabled + ? Percent >= PercentCritical + ? TemplateVisualStateName_Critical + : Percent >= PercentCaution + ? TemplateVisualStateName_Caution + : TemplateVisualStateName_Safe + : TemplateVisualStateName_Disabled, + true); } - #endregion - - #region Conversion return functions - - /// - /// Converts a value within a specified range to a percentage. - /// - /// The value to convert. - /// The minimum value of the input range. - /// The maximum value of the input range. - /// The percentage value (between 0 and 100). - private double DoubleToPercentage(double value, double minValue, double maxValue) - { - // Ensure value is within the specified range - if (value < minValue) - { - return 0.0; // Below the range - } - else if (value > maxValue) - { - return 100.0; // Above the range - } - else - { - // Calculate the normalized value - var normalizedValue = (value - minValue) / (maxValue - minValue); - - // Convert to percentage - var percentage = normalizedValue * 100.0; + // Event methods - double roundedPercentage = Math.Round(percentage, 2, MidpointRounding.ToEven); - - return roundedPercentage; - } - } - - /// - /// Converts a percentage within a specified range to a value. - /// - /// The percentage to convert. - /// The minimum value of the input range. - /// The maximum value of the input range. - /// The percentage value (between 0 and 100). - private double PercentageToValue(double percentage, double minValue, double maxValue) + private void StorageBar_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) { - double convertedValue = percentage * (maxValue - minValue) / 100.0; - - // Ensure the converted value stays within the specified range - if (convertedValue < minValue) - convertedValue = minValue; - else if (convertedValue > maxValue) - convertedValue = maxValue; - - return convertedValue; + UpdateControl(); } - /// - /// Calculates an interpolated value based on the provided parameters. - /// - /// The DependencyObject representing the control. - /// The starting value for interpolation. - /// The current value to interpolate. - /// The ending value for interpolation. - /// The starting Output value. - /// The ending Output value. - /// Indicates whether to apply an easing function. - /// The interpolated thickness value. - private double CalculateInterpolatedValue(DependencyObject d, double startValue, double value, double endValue, double startOutput, double endOutput, bool useEasing) + private void StorageBar_SizeChanged(object sender, SizeChangedEventArgs e) { - // Ensure that value is within the range [startValue, endValue] - value = Math.Max(startValue, Math.Min(endValue, value)); - - // Calculate the interpolation factor (t) between 0 and 1 - var t = (value - startValue) / (endValue - startValue); - - double interpolatedOutput; + Size minSize; - if (useEasing) + if (DesiredSize.Width < MinWidth || DesiredSize.Height < MinHeight || + e.NewSize.Width < MinWidth || e.NewSize.Height < MinHeight) { - // Apply an easing function (e.g., quadratic ease-in-out) - //var easedT = EaseInOutFunction(t); - var easedT = EaseOutCubic(t); + Width = MinWidth; + Height = MinHeight; - // Interpolate the thickness - interpolatedOutput = startOutput + easedT * (endOutput - startOutput); + minSize = new Size(MinWidth, MinHeight); } else { - // Interpolate the thickness - interpolatedOutput = startOutput + t * (endOutput - startOutput); + minSize = e.NewSize; } - return interpolatedOutput; + UpdateContainer(minSize); + UpdateControl(); } - /// - /// Example quadratic ease-in-out function - /// - private double EasingInOutFunction(double t) - { - return t < 0.5 ? 2 * t * t : 1 - Math.Pow(-2 * t + 2, 2) / 2; - } - - /// - /// Example ease-out cubic function - /// - static double EaseOutCubic(double t) + private void StorageBar_Unloaded(object sender, RoutedEventArgs e) { - return 1.0 - Math.Pow(1.0 - t, 3.0); + SizeChanged -= StorageBar_SizeChanged; + Unloaded -= StorageBar_Unloaded; + IsEnabledChanged -= StorageBar_IsEnabledChanged; } - - #endregion } } diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml b/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml index e4a2a7819b41..e34925b52793 100644 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml +++ b/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml @@ -4,6 +4,71 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Files.App.Controls"> + + + + + 6 + 2 + + 4,4,4,4 + + + + + + + + + + + + + + + + + + 6 + 2 + + 4,4,4,4 + + + + + + + + + + + + + + + + + + 6 + 2 + + 4,4,4,4 + + + + + + + + + + + + + + +