Skip to content

Commit

Permalink
Implement ProgressColor property in ProgressBarHandlers (#600)
Browse files Browse the repository at this point in the history
* Implement ProgressColor property in ProgressBarHandlers

* Add PortHandler attributes

* Implemented on WinUI too

* Fixed build error

* Fixed build errors

* Added sample

* Fix build error

* Delete unnecessary netstandard extensions

Co-authored-by: Jonathan Dick <[email protected]>
  • Loading branch information
jsuarezruiz and Jonathan Dick authored Sep 6, 2021
1 parent 16772b0 commit 0a1f603
Show file tree
Hide file tree
Showing 17 changed files with 156 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
UpdateProgressColor();
}

[PortHandler]
internal virtual protected void UpdateProgressColor()
{
if (Element == null || Control == null)
Expand Down
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/Windows/ProgressBarRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ void OnControlLoaded(object sender, RoutedEventArgs routedEventArgs)
UpdateProgressColor();
}

[PortHandler]
void UpdateProgressColor()
{
Color color = Element.ProgressColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ protected override void SetBackgroundColor(Color color)
Control.TrackTintColor = color != null ? color.ToUIColor() : null;
}

[PortHandler]
void UpdateProgressColor()
{
Control.ProgressTintColor = Element.ProgressColor == null ? null : Element.ProgressColor.ToUIColor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@
Style="{StaticResource Headline}"/>
<ProgressBar
Progress="0.5"/>
<Label
Text="ProgressColor"
Style="{StaticResource Headline}"/>
<ProgressBar
Progress="0.5"
ProgressColor="Orange"/>
<Label
Text="Disabled"
Style="{StaticResource Headline}"/>
<ProgressBar
IsEnabled="False"
Progress="0.5"/>
<Label
Text="ProgressColor"
Style="{StaticResource Headline}"/>
<ProgressBar
Progress="0.5"
ProgressColor="Orange"/>
<Label
Text="ProgressTo"
Style="{StaticResource Headline}"/>
Expand Down
9 changes: 8 additions & 1 deletion src/Core/src/Core/IProgress.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Microsoft.Maui
using Microsoft.Maui.Graphics;

namespace Microsoft.Maui
{
/// <summary>
/// Represents a View that show progress as a horizontal bar that is filled to a percentage
Expand All @@ -11,5 +13,10 @@ public interface IProgress : IView
/// Progress values less than 0 will be clamped to 0, values greater than 1 will be clamped to 1.
/// </summary>
double Progress { get; }

/// <summary>
/// Get the color of the progress bar.
/// </summary>
Color ProgressColor { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@ public static void MapProgress(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgress(progress);
}

public static void MapProgressColor(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgressColor(progress);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public partial class ProgressBarHandler : ViewHandler<IProgress, object>
protected override object CreateNativeView() => throw new NotImplementedException();

public static void MapProgress(ProgressBarHandler handler, IProgress progress) { }
public static void MapProgressColor(ProgressBarHandler handler, IProgress progress) { }
}
}
15 changes: 14 additions & 1 deletion src/Core/src/Handlers/ProgressBar/ProgressBarHandler.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ namespace Microsoft.Maui.Handlers
{
public partial class ProgressBarHandler : ViewHandler<IProgress, ProgressBar>
{
protected override ProgressBar CreateNativeView() => new ProgressBar { Minimum = 0, Maximum = 1 };
object? _foregroundDefault;

protected override ProgressBar CreateNativeView() =>
new ProgressBar { Minimum = 0, Maximum = 1 };

protected override void ConnectHandler(ProgressBar nativeView)
{
Expand All @@ -18,11 +21,21 @@ protected override void DisconnectHandler(ProgressBar nativeView)
nativeView.ValueChanged -= OnProgressBarValueChanged;
}

void SetupDefaults(ProgressBar nativeView)
{
_foregroundDefault = nativeView.GetForegroundCache();
}

public static void MapProgress(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgress(progress);
}

public static void MapProgressColor(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgressColor(progress, handler._foregroundDefault);
}

void OnProgressBarValueChanged(object? sender, RangeBaseValueChangedEventArgs rangeBaseValueChangedEventArgs)
{
VirtualView?.InvalidateMeasure();
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/ProgressBar/ProgressBarHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public partial class ProgressBarHandler
public static IPropertyMapper<IProgress, ProgressBarHandler> ProgressMapper = new PropertyMapper<IProgress, ProgressBarHandler>(ViewHandler.ViewMapper)
{
[nameof(IProgress.Progress)] = MapProgress,
[nameof(IProgress.ProgressColor)] = MapProgressColor
};

public ProgressBarHandler() : base(ProgressMapper)
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/ProgressBar/ProgressBarHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,10 @@ public static void MapProgress(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgress(progress);
}

public static void MapProgressColor(ProgressBarHandler handler, IProgress progress)
{
handler.NativeView?.UpdateProgressColor(progress);
}
}
}
24 changes: 22 additions & 2 deletions src/Core/src/Platform/Android/ProgressBarExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Android.Content.Res;
using Android.OS;
using Microsoft.Maui.Graphics;
using AProgressBar = Android.Widget.ProgressBar;

namespace Microsoft.Maui
Expand All @@ -12,5 +12,25 @@ public static void UpdateProgress(this AProgressBar nativeProgressBar, IProgress
{
nativeProgressBar.Progress = (int)(progress.Progress * Maximum);
}
}

public static void UpdateProgressColor(this AProgressBar nativeProgressBar, IProgress progress)
{
Color color = progress.ProgressColor;

if (color == null)
{
(nativeProgressBar.Indeterminate ? nativeProgressBar.IndeterminateDrawable :
nativeProgressBar.ProgressDrawable)?.ClearColorFilter();
}
else
{
var tintList = ColorStateList.ValueOf(color.ToNative());

if (nativeProgressBar.Indeterminate)
nativeProgressBar.IndeterminateTintList = tintList;
else
nativeProgressBar.ProgressTintList = tintList;
}
}
}
}
23 changes: 22 additions & 1 deletion src/Core/src/Platform/Windows/ProgressBarExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.UI.Xaml.Controls;

namespace Microsoft.Maui
{
Expand All @@ -8,5 +9,25 @@ public static void UpdateProgress(this ProgressBar nativeProgressBar, IProgress
{
nativeProgressBar.Value = progress.Progress;
}

public static void UpdateProgressColor(this ProgressBar nativeProgressBar, IProgress progress)
{
nativeProgressBar.UpdateProgressColor(progress, null);
}

public static void UpdateProgressColor(this ProgressBar nativeProgressBar, IProgress progress, object? foregroundDefault)
{
Color progressColor = progress.ProgressColor;

if (progressColor.IsDefault())
{
if (foregroundDefault != null)
nativeProgressBar.RestoreForegroundCache(foregroundDefault);
}
else
{
nativeProgressBar.Foreground = progressColor.ToNative();
}
}
}
}
5 changes: 5 additions & 0 deletions src/Core/src/Platform/iOS/ProgressBarExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ public static void UpdateProgress(this UIProgressView nativeProgressBar, IProgre
{
nativeProgressBar.Progress = (float)progress.Progress;
}

public static void UpdateProgressColor(this UIProgressView nativeProgressBar, IProgress progress)
{
nativeProgressBar.ProgressTintColor = progress.ProgressColor?.ToNative();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
using Microsoft.Maui.Handlers;
using System;
using System.Threading.Tasks;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using AProgressBar = Android.Widget.ProgressBar;

namespace Microsoft.Maui.DeviceTests
{
public partial class ProgressBarHandlerTests
{
AProgressBar GetNativeProgressBar(ProgressBarHandler progressBarHandler) =>
(AProgressBar)progressBarHandler.NativeView;
progressBarHandler.NativeView;

double GetNativeProgress(ProgressBarHandler progressBarHandler) =>
(double)GetNativeProgressBar(progressBarHandler).Progress / ProgressBarExtensions.Maximum;
}

Task ValidateNativeProgressColor(IProgress progressBar, Color color, Action action = null) =>
ValidateHasColor(progressBar, color, action);

Task ValidateHasColor(IProgress progressBar, Color color, Action action = null)
{
return InvokeOnMainThreadAsync(() =>
{
var nativeProgressBar = GetNativeProgressBar(CreateHandler(progressBar));
action?.Invoke();
nativeProgressBar.AssertContainsColor(color);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using Xunit;

namespace Microsoft.Maui.DeviceTests
{
[Category("ProgressBarHandler")]
[Category(TestCategory.ProgressBar)]
public partial class ProgressBarHandlerTests : HandlerTestBase<ProgressBarHandler, ProgressBarStub>
{
[Theory(DisplayName = "Progress Initializes Correctly")]
Expand All @@ -26,6 +26,23 @@ public async Task ProgressInitializesCorrectly(double progress)
await ValidatePropertyInitValue(progressBar, () => progressBar.Progress, GetNativeProgress, progressBar.Progress);
}

[Theory(DisplayName = "Progress Color Initializes Correctly")]
[InlineData("#FF0000")]
[InlineData("#00FF00")]
[InlineData("#0000FF")]
public async Task ProgressColorInitializesCorrectly(string colorHex)
{
Color progressColor = Color.FromArgb(colorHex);

var progressBar = new ProgressBarStub()
{
Progress = 0.9,
ProgressColor = progressColor
};

await ValidateNativeProgressColor(progressBar, progressColor);
}

[Fact(DisplayName = "Null Progress Color Doesn't Crash")]
public async Task NullProgressColorDoesntCrash()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
using Microsoft.Maui.Handlers;
using System;
using System.Threading.Tasks;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Handlers;
using UIKit;
using Xunit;

namespace Microsoft.Maui.DeviceTests
{
public partial class ProgressBarHandlerTests
{
UIProgressView GetNativeProgressBar(ProgressBarHandler progressBarHandler) =>
(UIProgressView)progressBarHandler.NativeView;
progressBarHandler.NativeView;

double GetNativeProgress(ProgressBarHandler progressBarHandler) =>
GetNativeProgressBar(progressBarHandler).Progress;
}

async Task ValidateNativeProgressColor(IProgress progressBar, Color color, Action action = null)
{
var expected = await GetValueAsync(progressBar, handler =>
{
var native = GetNativeProgressBar(handler);
action?.Invoke();
return native.ProgressTintColor.ToColor();
});
Assert.Equal(expected, color);
}
}
}
1 change: 1 addition & 0 deletions src/Core/tests/DeviceTests/TestCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static class TestCategory
public const string Layout = "Layout";
public const string Page = "Page";
public const string Picker = "Picker";
public const string ProgressBar = "ProgressBar";
public const string ScrollView = "ScrollView";
public const string SearchBar = "SearchBar";
public const string ShapeView = "ShapeView";
Expand Down

0 comments on commit 0a1f603

Please sign in to comment.