Skip to content

Commit 03981bb

Browse files
committed
Recycle expression animations
1 parent 314addc commit 03981bb

File tree

3 files changed

+88
-49
lines changed

3 files changed

+88
-49
lines changed

Telegram/Controls/Chats/ChatHistoryView.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
using Telegram.ViewModels.Delegates;
1717
using Windows.Devices.Input;
1818
using Windows.Foundation;
19+
using Windows.UI.Composition;
1920
using Windows.UI.Input;
2021
using Windows.UI.Xaml;
21-
using Windows.UI.Xaml.Automation;
2222
using Windows.UI.Xaml.Automation.Peers;
23-
using Windows.UI.Xaml.Automation.Provider;
2423
using Windows.UI.Xaml.Controls;
2524
using Windows.UI.Xaml.Controls.Primitives;
25+
using Windows.UI.Xaml.Hosting;
2626
using Windows.UI.Xaml.Input;
2727
using Windows.UI.Xaml.Media;
2828

@@ -34,6 +34,7 @@ public partial class ChatHistoryView : ListViewEx
3434
public IDialogDelegate Delegate { get; set; }
3535

3636
public ScrollViewer ScrollingHost { get; private set; }
37+
public CompositionPropertySet ScrollingPropertySet { get; private set; }
3738

3839
public bool IsBottomReached
3940
{
@@ -152,6 +153,8 @@ protected override void OnApplyTemplate()
152153
ScrollingHost.DirectManipulationStarted += OnDirectManipulationStarted;
153154
ScrollingHost.AddHandler(PointerWheelChangedEvent, new PointerEventHandler(OnPointerWheelChanged), true);
154155

156+
ScrollingPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(ScrollingHost);
157+
155158
base.OnApplyTemplate();
156159
}
157160

Telegram/Views/ChatView.Bubbles.xaml.cs

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,52 @@ public void ViewVisibleMessages(bool intermediate)
137137
var minMessageTopicIndex = panel.FirstVisibleIndex;
138138
var minMessageTopicValue = default(MessageTopic);
139139

140-
var messages = ElementComposition.GetElementVisual(Messages);
141-
var scroll = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(Messages.ScrollingHost);
142-
var tracker = ElementComposition.GetElementVisual(DateHeaderRelative);
140+
if (_dateHeaderTranslation == null)
141+
{
142+
const string viewportTopExp = $"(reference.Offset.Y + scroll.Translation.Y) - (tracker.Offset.Y - props.Padding)";
143+
const string heightExp = "(this.Target.Size.Y + 8)";
144+
const string offsetExp = $"({viewportTopExp}) + {heightExp}";
145+
const string translationExp = $"-{heightExp} * 2 + {offsetExp}";
146+
147+
//var reference = ElementComposition.GetElementVisual(container);
148+
_dateHeaderTranslation = _dateHeader.Compositor.CreateExpressionAnimation(translationExp);
149+
//_dateHeaderExpression.SetReferenceParameter("reference", reference);
150+
_dateHeaderTranslation.SetReferenceParameter("scroll", Messages.ScrollingPropertySet);
151+
_dateHeaderTranslation.SetReferenceParameter("tracker", _dateHeaderRelative);
152+
_dateHeaderTranslation.SetReferenceParameter("props", _messagesPaddingSet);
153+
}
154+
155+
if (_forumTopicHeaderTranslation == null)
156+
{
157+
const string viewportTopExp = $"(reference.Offset.Y + scroll.Translation.Y) - (tracker.Offset.Y - props.Padding)";
158+
const string heightExp = "(this.Target.Size.Y + 8)";
159+
const string offsetExp = $"({viewportTopExp}) + {heightExp}";
160+
const string translationExp = $"-{heightExp} * 2 + ({offsetExp} - {heightExp})";
161+
const string scaleExp = $"({offsetExp} - {heightExp}) / ({heightExp} * 2)";
162+
163+
//var reference = ElementComposition.GetElementVisual(container);
164+
_forumTopicHeaderTranslation = _forumTopicHeader.Compositor.CreateExpressionAnimation(translationExp);
165+
//_forumTopicHeaderTranslation.SetReferenceParameter("reference", reference);
166+
_forumTopicHeaderTranslation.SetReferenceParameter("scroll", Messages.ScrollingPropertySet);
167+
_forumTopicHeaderTranslation.SetReferenceParameter("tracker", _dateHeaderRelative);
168+
_forumTopicHeaderTranslation.SetReferenceParameter("props", _messagesPaddingSet);
169+
170+
_forumTopicHeaderScale = _forumTopicHeader.Compositor.CreateExpressionAnimation($"Vector3({scaleExp}, {scaleExp}, 0)");
171+
//_forumTopicHeaderScale.SetReferenceParameter("reference", reference);
172+
_forumTopicHeaderScale.SetReferenceParameter("scroll", Messages.ScrollingPropertySet);
173+
_forumTopicHeaderScale.SetReferenceParameter("tracker", _dateHeaderRelative);
174+
_forumTopicHeaderScale.SetReferenceParameter("props", _messagesPaddingSet);
175+
}
176+
177+
if (_stickyPhotoExpression == null)
178+
{
179+
_stickyPhotoExpression = _forumTopicHeader.Compositor.CreateExpressionAnimation();
180+
//animation.SetReferenceParameter("reference", reference);
181+
//animation.SetReferenceParameter("child", ElementComposition.GetElementVisual(container.ContentTemplateRoot));
182+
_stickyPhotoExpression.SetReferenceParameter("scroll", Messages.ScrollingPropertySet);
183+
_stickyPhotoExpression.SetReferenceParameter("messages", _messagesVisual);
184+
_stickyPhotoExpression.SetReferenceParameter("props", _messagesPaddingSet);
185+
}
143186

144187
var top = 0d;
145188
var bottom = 0d;
@@ -186,8 +229,8 @@ public void ViewVisibleMessages(bool intermediate)
186229
{
187230
// We calculate the item position relative to the current viewport manually
188231
// instead of relying on TransformToVisual. This should save us some milliseconds.
189-
top = (container.ActualOffset.Y - Messages.ScrollingHost.VerticalOffset) - (tracker.Offset.Y - _messagesHeaderRootPadding);
190-
bottom = (container.ActualOffset.Y - Messages.ScrollingHost.VerticalOffset) - (messages.Size.Y - _messagesHeaderRootPadding);
232+
top = (container.ActualOffset.Y - Messages.ScrollingHost.VerticalOffset) - (_dateHeaderRelative.Offset.Y - _messagesHeaderRootPadding);
233+
bottom = (container.ActualOffset.Y - Messages.ScrollingHost.VerticalOffset) - (_messagesVisual.Size.Y - _messagesHeaderRootPadding);
191234
}
192235

193236
if (minItem > 0 && i >= panel.FirstVisibleIndex)
@@ -262,19 +305,10 @@ void SetContentOpacity(double value)
262305
{
263306
if (_dateHeaderTracked != container)
264307
{
265-
const string viewportTopExp = $"(reference.Offset.Y + scroll.Translation.Y) - (tracker.Offset.Y - props.Padding)";
266-
const string heightExp = "(this.Target.Size.Y + 8)";
267-
const string offsetExp = $"({viewportTopExp}) + {heightExp}";
268-
const string translationExp = $"-{heightExp} * 2 + {offsetExp}";
269-
270308
var reference = ElementComposition.GetElementVisual(container);
271-
var translation = reference.Compositor.CreateExpressionAnimation(translationExp);
272-
translation.SetReferenceParameter("reference", reference);
273-
translation.SetReferenceParameter("scroll", scroll);
274-
translation.SetReferenceParameter("tracker", tracker);
275-
translation.SetReferenceParameter("props", _messagesPaddingSet);
276-
277-
_dateHeader.StartAnimation("Translation.Y", translation);
309+
_dateHeaderTranslation.SetReferenceParameter("reference", reference);
310+
311+
_dateHeader.StartAnimation("Translation.Y", _dateHeaderTranslation);
278312
_dateHeaderTracked = container;
279313
}
280314
}
@@ -313,27 +347,12 @@ void SetContentOpacity(double value)
313347
{
314348
if (_forumTopicHeaderTracked != container)
315349
{
316-
const string viewportTopExp = $"(reference.Offset.Y + scroll.Translation.Y) - (tracker.Offset.Y - props.Padding)";
317-
const string heightExp = "(this.Target.Size.Y + 8)";
318-
const string offsetExp = $"({viewportTopExp}) + {heightExp}";
319-
const string translationExp = $"-{heightExp} * 2 + ({offsetExp} - {heightExp})";
320-
const string scaleExp = $"({offsetExp} - {heightExp}) / ({heightExp} * 2)";
321-
322350
var reference = ElementComposition.GetElementVisual(container);
323-
var translation = reference.Compositor.CreateExpressionAnimation(translationExp);
324-
translation.SetReferenceParameter("reference", reference);
325-
translation.SetReferenceParameter("scroll", scroll);
326-
translation.SetReferenceParameter("tracker", tracker);
327-
translation.SetReferenceParameter("props", _messagesPaddingSet);
328-
329-
var scale = reference.Compositor.CreateExpressionAnimation($"Vector3({scaleExp}, {scaleExp}, 0)");
330-
scale.SetReferenceParameter("reference", reference);
331-
scale.SetReferenceParameter("scroll", scroll);
332-
scale.SetReferenceParameter("tracker", tracker);
333-
scale.SetReferenceParameter("props", _messagesPaddingSet);
334-
335-
_forumTopicHeader.StartAnimation("Translation.Y", translation);
336-
_forumTopicHeader.StartAnimation("Scale", scale);
351+
_forumTopicHeaderTranslation.SetReferenceParameter("reference", reference);
352+
_forumTopicHeaderScale.SetReferenceParameter("reference", reference);
353+
354+
_forumTopicHeader.StartAnimation("Translation.Y", _forumTopicHeaderTranslation);
355+
_forumTopicHeader.StartAnimation("Scale", _forumTopicHeaderScale);
337356
_forumTopicHeaderTracked = container;
338357
}
339358
}
@@ -359,7 +378,6 @@ bool AnimateStickyPhoto(HyperlinkButton stickyPhotoRoot, MessageProfilePicture s
359378
if (message.HasSenderPhoto && container.ContentTemplateRoot is MessageSelector { ContentTemplateRoot: MessageBubble bubble })
360379
{
361380
var visual = ElementComposition.GetElementVisual(stickyPhotoRoot);
362-
var reference = ElementComposition.GetElementVisual(container);
363381

364382
const string topExp = "(reference.Offset.Y + scroll.Translation.Y) - (messages.Size.Y - props.Padding)";
365383
const string bottomExp = $"(reference.Offset.Y + child.Size.Y + scroll.Translation.Y) - (messages.Size.Y - props.Padding)";
@@ -389,14 +407,13 @@ bool AnimateStickyPhoto(HyperlinkButton stickyPhotoRoot, MessageProfilePicture s
389407
{
390408
if (tracked != container)
391409
{
392-
var animation = reference.Compositor.CreateExpressionAnimation(exp);
393-
animation.SetReferenceParameter("reference", reference);
394-
animation.SetReferenceParameter("scroll", scroll);
395-
animation.SetReferenceParameter("messages", messages);
396-
animation.SetReferenceParameter("child", ElementComposition.GetElementVisual(container.ContentTemplateRoot));
397-
animation.SetReferenceParameter("props", _messagesPaddingSet);
398-
399-
visual.StartAnimation("Translation.Y", animation);
410+
var reference = ElementComposition.GetElementVisual(container);
411+
412+
_stickyPhotoExpression.Expression = exp;
413+
_stickyPhotoExpression.SetReferenceParameter("reference", reference);
414+
_stickyPhotoExpression.SetReferenceParameter("child", ElementComposition.GetElementVisual(container.ContentTemplateRoot));
415+
416+
visual.StartAnimation("Translation.Y", _stickyPhotoExpression);
400417
tracked = container;
401418
}
402419
}

Telegram/Views/ChatView.xaml.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,24 @@ public sealed partial class ChatView : UserControlEx, INavigablePage, ISearchabl
8383
private readonly Visual _rootVisual;
8484

8585
private readonly DispatcherTimer _dateHeaderTimer;
86+
private readonly Visual _dateHeaderRelative;
8687
private readonly Visual _dateHeaderPanel;
8788
private readonly Visual _dateHeader;
8889
private SelectorItem _dateHeaderTracked;
90+
private ExpressionAnimation _dateHeaderTranslation;
91+
8992
private readonly Visual _forumTopicHeaderPanel;
9093
private readonly Visual _forumTopicHeader;
9194
private SelectorItem _forumTopicHeaderTracked;
95+
private ExpressionAnimation _forumTopicHeaderTranslation;
96+
private ExpressionAnimation _forumTopicHeaderScale;
9297

9398
// Optimize by holding these in two structs
9499
private MessageViewModel _stickyPhotoAboveMessage;
95100
private SelectorItem _stickyPhotoAboveTracked;
96101
private MessageViewModel _stickyPhotoBelowMessage;
97102
private SelectorItem _stickyPhotoBelowTracked;
103+
private ExpressionAnimation _stickyPhotoExpression;
98104

99105
private readonly ZoomableListHandler _autocompleteZoomer;
100106
private readonly AnimatedListHandler _autocompleteHandler;
@@ -186,12 +192,14 @@ void AddStrategy(ChatHistoryViewItemType type, DataTemplate template)
186192

187193
DateHeaderRelative.CreateInsetClip();
188194

195+
_dateHeaderRelative = ElementComposition.GetElementVisual(DateHeaderRelative);
189196
_dateHeaderPanel = ElementComposition.GetElementVisual(DateHeaderPanel);
190197
_dateHeader = ElementComposition.GetElementVisual(DateHeader);
191198

192199
_forumTopicHeaderPanel = ElementComposition.GetElementVisual(ForumTopicHeaderPanel);
193200
_forumTopicHeader = ElementComposition.GetElementVisual(ForumTopicHeader);
194201

202+
_messagesVisual = ElementComposition.GetElementVisual(Messages);
195203
_messagesPaddingSet = BootStrapper.Current.Compositor.CreatePropertySet();
196204
_messagesPaddingSet.InsertScalar("Padding", 0);
197205

@@ -819,6 +827,16 @@ private void OnAttachChanged(IEnumerable<MessageViewModel> items)
819827
bubble.UpdateMessageHeader(message);
820828
}
821829

830+
if (_stickyPhotoAboveTracked == container)
831+
{
832+
_stickyPhotoAboveTracked = null;
833+
}
834+
835+
if (_stickyPhotoBelowTracked == container)
836+
{
837+
_stickyPhotoBelowTracked = null;
838+
}
839+
822840
if (ViewModel.IsSavedMessagesTab)
823841
{
824842
return;
@@ -7092,7 +7110,8 @@ private void ClipperOuter_SizeChanged(object sender, SizeChangedEventArgs e)
70927110
//UpdateMessagesHeaderPadding();
70937111
}
70947112

7095-
private CompositionPropertySet _messagesPaddingSet;
7113+
private readonly Visual _messagesVisual;
7114+
private readonly CompositionPropertySet _messagesPaddingSet;
70967115
private float _messagesHeaderRootPadding;
70977116
private float _messagesScrollBarPadding;
70987117
private bool _messagesScrollBarPaddingBottom;

0 commit comments

Comments
 (0)