Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ProgressColor property in ProgressBarHandlers #600

Merged
merged 13 commits into from
Sep 6, 2021
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/WinUI/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; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a Brush.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. However, can we make it progressive? Start by merging this and other PRs related to Color, in order to complete Handlers and allow in Previews to work and port code in a simple way, and as we have to do with other important properties such as convert TextColor to Foreground, update little by little .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i think we could, i added a issue for this #2403

}
}
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) { }
}
}
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 PropertyMapper<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;
}
}
}
}
8 changes: 8 additions & 0 deletions src/Core/src/Platform/Standard/ProgressBarExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.Maui
{
public static class ProgressBarExtensions
rmarinho marked this conversation as resolved.
Show resolved Hide resolved
{
public static void UpdateProgress(this object nothing, IProgress progress) { }
public static void UpdateProgressColor(this object nothing, IProgress progress) { }
}
}
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 @@ -15,6 +15,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 SearchBar = "SearchBar";
public const string ShapeView = "ShapeView";
public const string Slider = "Slider";
Expand Down