Skip to content

Commit

Permalink
ProgressRing Indeterminate State with Lottie Animations (#1858)
Browse files Browse the repository at this point in the history
* squash merge from user/biilai/progressring-lottie

* re-add ProgressRingLoading to solution

* changes from comments

* FindInApplicationResources abstraction

* lottie isPlaying test for rs5+ only

* update lottie animatedVisuals to latest codegen output

* lottie color theming

* tweak lottie radius size

* update lottie animatedVisuals to latest codegen output

* update lottie animatedVisuals to latest codegen output

* fix anonymous namespace indent

* update lottie animatedVisuals to latest codegen output

* bind to progressRing_themeresources

* unexpose strokeThickness api

* rename ComputeCircleSize()

* changes from comments + rebase

* changes from comments

* changes from comments
  • Loading branch information
karkarl authored Feb 19, 2020
1 parent bc7b4a5 commit 5e0e4df
Show file tree
Hide file tree
Showing 24 changed files with 1,016 additions and 150 deletions.
28 changes: 14 additions & 14 deletions dev/Generated/ProgressRing.properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace winrt::Microsoft::UI::Xaml::Controls

#include "ProgressRing.g.cpp"

GlobalDependencyProperty ProgressRingProperties::s_StrokeThicknessProperty{ nullptr };
GlobalDependencyProperty ProgressRingProperties::s_IsIndeterminateProperty{ nullptr };

ProgressRingProperties::ProgressRingProperties()
{
Expand All @@ -22,38 +22,38 @@ ProgressRingProperties::ProgressRingProperties()

void ProgressRingProperties::EnsureProperties()
{
if (!s_StrokeThicknessProperty)
if (!s_IsIndeterminateProperty)
{
s_StrokeThicknessProperty =
s_IsIndeterminateProperty =
InitializeDependencyProperty(
L"StrokeThickness",
winrt::name_of<double>(),
L"IsIndeterminate",
winrt::name_of<bool>(),
winrt::name_of<winrt::ProgressRing>(),
false /* isAttached */,
ValueHelper<double>::BoxedDefaultValue(),
winrt::PropertyChangedCallback(&OnStrokeThicknessPropertyChanged));
ValueHelper<bool>::BoxedDefaultValue(),
winrt::PropertyChangedCallback(&OnIsIndeterminatePropertyChanged));
}
}

void ProgressRingProperties::ClearProperties()
{
s_StrokeThicknessProperty = nullptr;
s_IsIndeterminateProperty = nullptr;
}

void ProgressRingProperties::OnStrokeThicknessPropertyChanged(
void ProgressRingProperties::OnIsIndeterminatePropertyChanged(
winrt::DependencyObject const& sender,
winrt::DependencyPropertyChangedEventArgs const& args)
{
auto owner = sender.as<winrt::ProgressRing>();
winrt::get_self<ProgressRing>(owner)->OnStrokeThicknessPropertyChanged(args);
winrt::get_self<ProgressRing>(owner)->OnIsIndeterminatePropertyChanged(args);
}

void ProgressRingProperties::StrokeThickness(double value)
void ProgressRingProperties::IsIndeterminate(bool value)
{
static_cast<ProgressRing*>(this)->SetValue(s_StrokeThicknessProperty, ValueHelper<double>::BoxValueIfNecessary(value));
static_cast<ProgressRing*>(this)->SetValue(s_IsIndeterminateProperty, ValueHelper<bool>::BoxValueIfNecessary(value));
}

double ProgressRingProperties::StrokeThickness()
bool ProgressRingProperties::IsIndeterminate()
{
return ValueHelper<double>::CastOrUnbox(static_cast<ProgressRing*>(this)->GetValue(s_StrokeThicknessProperty));
return ValueHelper<bool>::CastOrUnbox(static_cast<ProgressRing*>(this)->GetValue(s_IsIndeterminateProperty));
}
10 changes: 5 additions & 5 deletions dev/Generated/ProgressRing.properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ class ProgressRingProperties
public:
ProgressRingProperties();

void StrokeThickness(double value);
double StrokeThickness();
void IsIndeterminate(bool value);
bool IsIndeterminate();

static winrt::DependencyProperty StrokeThicknessProperty() { return s_StrokeThicknessProperty; }
static winrt::DependencyProperty IsIndeterminateProperty() { return s_IsIndeterminateProperty; }

static GlobalDependencyProperty s_StrokeThicknessProperty;
static GlobalDependencyProperty s_IsIndeterminateProperty;

static void EnsureProperties();
static void ClearProperties();

static void OnStrokeThicknessPropertyChanged(
static void OnIsIndeterminatePropertyChanged(
winrt::DependencyObject const& sender,
winrt::DependencyPropertyChangedEventArgs const& args);
};
4 changes: 2 additions & 2 deletions dev/NavigationView/NavigationView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2863,12 +2863,12 @@ int NavigationView::GetSelectedItemIndex()

double NavigationView::GetPaneToggleButtonWidth()
{
return unbox_value<double>(SharedHelpers::FindResource(L"PaneToggleButtonWidth", winrt::Application::Current().Resources(), box_value(c_paneToggleButtonWidth)));
return unbox_value<double>(SharedHelpers::FindInApplicationResources(L"PaneToggleButtonWidth", box_value(c_paneToggleButtonWidth)));
}

double NavigationView::GetPaneToggleButtonHeight()
{
return unbox_value<double>(SharedHelpers::FindResource(L"PaneToggleButtonHeight", winrt::Application::Current().Resources(), box_value(c_paneToggleButtonHeight)));
return unbox_value<double>(SharedHelpers::FindInApplicationResources(L"PaneToggleButtonHeight", box_value(c_paneToggleButtonHeight)));
}

void NavigationView::UpdateTopNavigationWidthCache()
Expand Down
2 changes: 1 addition & 1 deletion dev/NumberBox/NumberBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void NumberBox::OnApplyTemplate()
popupRoot.Shadow(winrt::ThemeShadow{});
auto&& translation = popupRoot.Translation();

const double shadowDepth = unbox_value<double>(SharedHelpers::FindResource(c_numberBoxPopupShadowDepthName, winrt::Application::Current().Resources(), box_value(c_popupShadowDepth)));
const double shadowDepth = unbox_value<double>(SharedHelpers::FindInApplicationResources(c_numberBoxPopupShadowDepthName, box_value(c_popupShadowDepth)));

popupRoot.Translation({ translation.x, translation.y, (float)shadowDepth });
}
Expand Down
5 changes: 5 additions & 0 deletions dev/ProgressRing/IThemedAnimatedVisualSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

struct IThemedAnimatedVisualSource
{
};
109 changes: 108 additions & 1 deletion dev/ProgressRing/InteractionTests/ProgressRingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void ChangeValueTest()
{
Log.Comment("Changing Value of ProgressRing");

UIObject testProgressBar = FindElement.ByName("TestProgressRing");
UIObject testProgressRing = FindElement.ByName("TestProgressRing");
TextBlock valueText = FindElement.ByName<TextBlock>("ValueText");

double oldValue = Convert.ToDouble(valueText.DocumentText);
Expand All @@ -64,5 +64,112 @@ public void ChangeValueTest()
Verify.IsGreaterThan(diff, Convert.ToDouble(0));
}
}

[TestMethod]
public void UpdateMinMaxTest()
{
using (var setup = new TestSetupHelper("ProgressRing Tests"))
{
Log.Comment("Updating Minimum and Maximum value of ProgressRing");

UIObject testProgressRing = FindElement.ByName("TestProgressRing");

TextBlock minimumInputText = FindElement.ByName<TextBlock>("MinimumInputText");
TextBlock maximumInputText = FindElement.ByName<TextBlock>("MaximumInputText");
TextBlock valueText = FindElement.ByName<TextBlock>("ValueText");

double oldMinimumInputText = Convert.ToDouble(minimumInputText.DocumentText);
double oldMaximumInputText = Convert.ToDouble(minimumInputText.DocumentText);

Edit minimumInput = FindElement.ByName<Edit>("MinimumInput");
Edit maximumInput = FindElement.ByName<Edit>("MaximumInput");

minimumInput.SetValue("10");
maximumInput.SetValue("15");

Button updateMinMaxButton = FindElement.ByName<Button>("UpdateMinMaxButton");
updateMinMaxButton.InvokeAndWait();

double newMinimumInputText = Convert.ToDouble(minimumInputText.DocumentText);
double newMaximumInputText = Convert.ToDouble(maximumInputText.DocumentText);

Verify.AreNotSame(oldMinimumInputText, newMinimumInputText, "Minimum updated");
Verify.AreNotSame(oldMaximumInputText, newMaximumInputText, "Maximum updated");

// Below edge cases are handled by Rangebase

Log.Comment("Updating Minimum and Maximum when Maximum < Minimum");

maximumInput.SetValue("5");
updateMinMaxButton.InvokeAndWait();

Verify.AreEqual(Convert.ToDouble(minimumInputText.DocumentText), Convert.ToDouble(maximumInputText.DocumentText), "Maximum updates to equal Minimum");

Log.Comment("Updating Minimum and Maximum when Minimum > Value");

minimumInput.SetValue("15");
updateMinMaxButton.InvokeAndWait();

Verify.AreEqual(Convert.ToDouble(valueText.DocumentText), Convert.ToDouble(minimumInputText.DocumentText), "Value updates to equal Minimum");
Verify.AreEqual(Convert.ToDouble(maximumInputText.DocumentText), Convert.ToDouble(minimumInputText.DocumentText), "Maximum also updates to equal Minimum");

Log.Comment("Updating Minimum and Maximum to be a decimal number");

minimumInput.SetValue("0.1");
maximumInput.SetValue("1.1");

updateMinMaxButton.InvokeAndWait();

double oldValue = Convert.ToDouble(valueText.DocumentText);

Button changeValueButton = FindElement.ByName<Button>("ChangeValueButton");
changeValueButton.InvokeAndWait();

double newValue = Convert.ToDouble(valueText.DocumentText);
double diff = Math.Abs(oldValue - newValue);

Verify.IsGreaterThan(diff, Convert.ToDouble(0), "Value of ProgressRing increments properly within range with decimal Minimum and Maximum");
}
}

[TestMethod]
public void ChangeStateTest()
{
using (var setup = new TestSetupHelper("ProgressRing Tests"))
{
Log.Comment("Verify all properties are set to false by default for testing");

ToggleButton isIndeterminateCheckBox = FindElement.ByName<ToggleButton>("ShowIsDeterminateCheckBox");

TextBlock isIndeterminateText = FindElement.ByName<TextBlock>("ShowIsDeterminateText");
TextBlock isPlayingText = FindElement.ByName<TextBlock>("IsPlayingText");
TextBlock visualStateText = FindElement.ByName<TextBlock>("VisualStateText");

Verify.IsFalse(Convert.ToBoolean(isIndeterminateText.DocumentText));

Log.Comment("All properties to false updates ProgressBar to Determinate");

Verify.AreEqual(visualStateText.DocumentText, "Determinate");

Log.Comment("Verify Lottie animation is inactive when in Determinate state (LottieRoot is hidden)");

Verify.IsFalse(Convert.ToBoolean(isPlayingText.DocumentText));

Log.Comment("IsIndeterminate = true updates ProgressBar to Indeterminate visual state");

isIndeterminateCheckBox.ToggleAndWait();

Verify.IsTrue(Convert.ToBoolean(isIndeterminateText.DocumentText));
Verify.AreEqual(visualStateText.DocumentText, "Indeterminate");

// Lottie animations only support Windows versions rs5 and above
if (PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone5))
{
Log.Comment("Verify Lottie animation is active when in Indeterminate state");

Verify.IsTrue(Convert.ToBoolean(isPlayingText.DocumentText));
}
}
}
}
}
Loading

0 comments on commit 5e0e4df

Please sign in to comment.