Cont'd implementation of slide lock..
ADD
WalletWasabi.Gui/Controls/LockScreen/LockScreenImpl.cs
+using Avalonia.Controls;
+
+namespace WalletWasabi.Gui.Controls.LockScreen
+{
+ internal class LockScreenImpl : UserControl
+ {
+ internal virtual void Reset()
+ {
+ IsHitTestVisible = true;
+ }
+ }
+}

MODIFY
WalletWasabi.Gui/Controls/LockScreen/SlideLock.xaml
WalletWasabi.Gui/Controls/LockScreen/SlideLock.xaml
<UserControl.Clock>
<Clock/>
</UserControl.Clock>
+ <UserControl.Styles>
+ <Styles>
+ <Styles.Resources>
+ <Template x:Key="Chevron">
+ <Path Stretch="Uniform"
+ Fill="{DynamicResource ThemeForegroundBrush}"
+ Data="M 478.97852 464.25977
+ L 446.12109 470.33203
+ L 446.12109 478.72461
+ L 478.97852 472.65234
+ L 511.83398 478.72461
+ L 511.83398 470.33203
+ L 478.97852 464.25977 z "/>
+ </Template>
+ </Styles.Resources>
+ <Style Selector="Border.Chevron">
+ <Setter Property="Width" Value="103"/>
+ <Setter Property="Height" Value="50"/>
+ <Setter Property="Child" Value="{StaticResource Chevron}"/>
+ </Style>
+ <Style Selector="Border.Chev1">
+ <Style.Animations>
+ <Animation Duration="0:0:1.5"
+ Easing="CubicEaseInOut"
+ IterationCount="Infinite">
+ <KeyFrame Cue="0%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="100"/>
+ </KeyFrame>
+ <KeyFrame Cue="90%">
+ <Setter Property="Opacity" Value="{Binding $parent[UserControl].Opacity}"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ <KeyFrame Cue="100%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ </Animation>
+ </Style.Animations>
+ </Style>
+ <Style Selector="Border.Chev2">
+ <Style.Animations>
+ <Animation Delay="0:0:0.3"
+ Duration="0:0:1.5"
+ Easing="CubicEaseInOut"
+ IterationCount="Infinite">
+ <KeyFrame Cue="0%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="100"/>
+ </KeyFrame>
+ <KeyFrame Cue="90%">
+ <Setter Property="Opacity" Value="{Binding $parent[UserControl].Opacity}"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ <KeyFrame Cue="100%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ </Animation>
+ </Style.Animations>
+ </Style>
+ <Style Selector="Border.Chev3">
+ <Style.Animations>
+ <Animation Delay="0:0:0.6"
+ Duration="0:0:1.5"
+ Easing="CubicEaseInOut"
+ IterationCount="Infinite">
+ <KeyFrame Cue="0%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="100"/>
+ </KeyFrame>
+ <KeyFrame Cue="90%">
+ <Setter Property="Opacity" Value="{Binding $parent[UserControl].Opacity}"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ <KeyFrame Cue="100%">
+ <Setter Property="Opacity" Value="0"/>
+ <Setter Property="TranslateTransform.Y" Value="0"/>
+ </KeyFrame>
+ </Animation>
+ </Style.Animations>
+ </Style>
+ </Styles>
+ </UserControl.Styles>
<Grid>
<Thumb x:Name="PART_DragThumb">
<Thumb.Template>
<ControlTemplate>
- <Border Background="Blue"/>
+ <Grid Background="{DynamicResource ThemeBackgroundBrush}">
+ <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
+ <Grid>
+ <Border Classes="Chevron Chev1"/>
+ <Border Classes="Chevron Chev2"/>
+ <Border Classes="Chevron Chev3"/>
+ </Grid>
+ <TextBlock Margin="0,110,0,0" Text="Drag and slide up to unlock."/>
+ </StackPanel>
+ </Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>

MODIFY
WalletWasabi.Gui/Controls/LockScreen/SlideLock.xaml.cs
WalletWasabi.Gui/Controls/LockScreen/SlideLock.xaml.cs
@@ -5,14 +5,16 @@ using Avalonia.Input;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Controls.Primitives;
+using ReactiveUI;
+using Avalonia;
namespace WalletWasabi.Gui.Controls.LockScreen
{
- internal class SlideLock : UserControl
+ internal class SlideLock : LockScreenImpl
{
private Thumb DragThumb;
private TranslateTransform DragThumbTransform;
- private bool UnlockInProgress = false;
+ private bool UserDragInProgress, UnlockInProgress, UnlockDone;
private double _offset = 0;
private double Offset
@@ -21,6 +23,8 @@ namespace WalletWasabi.Gui.Controls.LockScreen
set => OnOffsetChanged(value);
}
+ private const double ThresholdPercent = 1 / 6d;
+ private double RealThreshold;
private const double Stiffness = 0.12d;
public SlideLock()
@@ -35,9 +39,20 @@ namespace WalletWasabi.Gui.Controls.LockScreen
DragThumb.DragStarted += OnDragStarted;
DragThumb.RenderTransform = DragThumbTransform;
+ this.WhenAnyValue(x => x.Bounds)
+ .Subscribe(OnBoundsChange);
+
+ OnBoundsChange(this.Bounds);
+
Clock.Subscribe(OnClockTick);
}
+ private void OnBoundsChange(Rect obj)
+ {
+ var newHeight = obj.Height;
+ RealThreshold = newHeight * ThresholdPercent;
+ }
+
private void OnOffsetChanged(double value)
{
_offset = value;
@@ -46,26 +61,53 @@ namespace WalletWasabi.Gui.Controls.LockScreen
private void OnClockTick(TimeSpan CurrentTime)
{
- if (!UnlockInProgress & Offset != 0)
+ if (UnlockDone) return;
+
+ if (!UserDragInProgress & UnlockInProgress)
+ {
+ this.PseudoClasses.Add(":unlocked");
+ UnlockInProgress = false;
+ UnlockDone = true;
+ return;
+ }
+
+ if (!UserDragInProgress & Math.Abs(Offset) > RealThreshold)
+ {
+ UnlockInProgress = true;
+ return;
+ }
+
+ if (!UserDragInProgress && Offset != 0)
{
Offset *= 1 - Stiffness;
}
}
+ private new void Reset()
+ {
+ UnlockDone = false;
+ UnlockInProgress = false;
+ UserDragInProgress = false;
+ Offset = 0;
+ base.Reset();
+ }
+
private void OnDragStarted(object sender, VectorEventArgs e)
{
- UnlockInProgress = true;
+ UserDragInProgress = true;
}
private void OnDragDelta(object sender, VectorEventArgs e)
{
if (e.Vector.Y < 0)
+ {
this.Offset = e.Vector.Y;
}
+ }
private void OnDragCompleted(object sender, VectorEventArgs e)
{
- UnlockInProgress = false;
+ UserDragInProgress = false;
}
private void InitializeComponent()

Cont'd implementation of slide lock..