-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathPlayStopButton.xaml.cs
178 lines (152 loc) · 6.29 KB
/
PlayStopButton.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Numerics;
using AnimatedVisuals;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace LottieViewer
{
/// <summary>
/// Animated button for playing or stopping an animtion.
/// </summary>
public sealed partial class PlayStopButton : UserControl
{
// True iff we should use the animated play-stop button.
static readonly bool IsAnimationSupported =
Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 11);
bool _isHoveredOver;
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register(
"IsChecked",
typeof(bool),
typeof(PlayStopButton),
new PropertyMetadata(false, OnIsCheckedChanged));
public event RoutedEventHandler? Toggled;
public PlayStopButton()
{
this.InitializeComponent();
// Hide the animated or the non-animated view, depending on whether we are on
// a recent-enough OS to support this animations.
if (IsAnimationSupported)
{
_playStopPlayer.Visibility = Visibility.Visible;
_fallbackGrid.Visibility = Visibility.Collapsed;
// Allow color changing when the enabled state changes.
IsEnabledChanged += PlayStopButton_IsEnabledChanged;
}
else
{
_playStopPlayer.Visibility = Visibility.Collapsed;
_fallbackGrid.Visibility = Visibility.Visible;
_playText.Visibility = Visibility.Visible;
_stopText.Visibility = Visibility.Collapsed;
}
// Subscribe to events so we can animate pointer enter and exit.
PointerEntered += PlayStopButton_PointerEntered;
PointerExited += PlayStopButton_PointerExited;
}
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
void PlayStopButton_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
_isHoveredOver = true;
AnimateScale(new Vector3(0.8F));
SetAnimatedVisualColor();
}
void PlayStopButton_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
_isHoveredOver = false;
AnimateScale(Vector3.One);
SetAnimatedVisualColor();
}
static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) =>
((PlayStopButton)d).OnIsCheckedChanged(e);
#pragma warning disable VSTHRD100 // Avoid async void methods
async void OnIsCheckedChanged(DependencyPropertyChangedEventArgs e)
#pragma warning restore VSTHRD100 // Avoid async void methods
{
var isChecked = (bool)e.NewValue;
// Keep the toggle button in sync with the control's IsChecked property.
_playStopButton.IsChecked = isChecked;
if (IsAnimationSupported)
{
// Play the segment that either goes from Play to Stop or Stop to Play.
var startProgress = isChecked ? LottieViewer_04_Playback.M_Play_Click_On : LottieViewer_04_Playback.M_Stop_Click_On;
var endProgress = isChecked ? LottieViewer_04_Playback.M_Play_Click_Off : LottieViewer_04_Playback.M_Stop_Click_Off;
try
{
// Play the animation.
await _playStopPlayer.PlayAsync(startProgress, endProgress, looped: false);
}
catch
{
// Swallow any exceptions from PlayAsync.
}
}
else
{
if (isChecked)
{
_playText.Visibility = Visibility.Collapsed;
_stopText.Visibility = Visibility.Visible;
}
else
{
_playText.Visibility = Visibility.Visible;
_stopText.Visibility = Visibility.Collapsed;
}
}
}
void AnimateScale(Vector3 scale)
{
var compositor = Window.Current.Compositor;
var animation = compositor.CreateVector3KeyFrameAnimation();
animation.InsertKeyFrame(1.0f, scale);
animation.Duration = TimeSpan.FromSeconds(0.333);
animation.Target = "Scale";
_playStopPlayerContainer.StartAnimation(animation);
}
void PlayControl_Toggled(object sender, RoutedEventArgs e)
{
// Keep our IsChecked property in sync with the ToggleButton's IsChecked property.
IsChecked = _playStopButton.IsChecked == true;
// Notify listeners.
Toggled?.Invoke(sender, e);
}
void PlayStopButton_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetAnimatedVisualColor();
}
void SetAnimatedVisualColor()
{
var colorChoice =
_playStopButton.IsEnabled
? (_isHoveredOver ? ColorState.IsEnabledHover : ColorState.IsEnabled)
: ColorState.Disabled;
SetAnimatedVisualColor(colorChoice);
}
void SetAnimatedVisualColor(ColorState colorChoice)
{
_animatedVisual.Foreground = colorChoice switch
{
ColorState.IsEnabled => (Color)Application.Current.Resources["LottieBasic"],
ColorState.IsEnabledHover => (Color)Application.Current.Resources["ForegroundColor"],
ColorState.Disabled => (Color)Application.Current.Resources["DisabledColor"],
_ => throw new InvalidOperationException(),
};
}
enum ColorState
{
IsEnabled,
IsEnabledHover,
Disabled,
}
}
}