Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added LockIn/Assets/Helldivers2.ico
Binary file not shown.
7 changes: 3 additions & 4 deletions LockIn/LockIn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
Expand All @@ -22,9 +22,8 @@
</ItemGroup>

<ItemGroup>
<Resource Include="Assets\FS Sinclair Regular.otf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
<None Remove="Assets\*" />
<Resource Include="Assets\*" />
</ItemGroup>

</Project>
80 changes: 65 additions & 15 deletions LockIn/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LockIn"
xmlns:vm="clr-namespace:LockIn.ViewModels"
xmlns:controls="clr-namespace:LockIn.UserControls"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:MainWindowViewModel, IsDesignTimeCreatable=True}"
Title="Lock In" Height="300" Width="300">
<Grid Background="#151515">
Title="Lock In" Height="275" Width="300"
WindowStartupLocation="CenterScreen"
Icon="./Assets/Helldivers2.ico">

<Grid Background="{StaticResource BlackBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5*"/>
Expand All @@ -17,24 +20,71 @@
</Grid.RowDefinitions>

<TextBlock Grid.Row="0" Text="Helldivers 2 | Lock In"
FontFamily="pack://application:,,,/Assets/#FS Sinclair" FontSize="26"
FontSize="26" FontWeight="Bold"
HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold"
Margin="10,5,0,0" Foreground="{DynamicResource SilverForeground}"/>
Margin="10,5,0,0">

<TextBlock.FontFamily>
<StaticResource ResourceKey="FSSinclair"/>
</TextBlock.FontFamily>

<TextBlock.Foreground>
<StaticResource ResourceKey="SilverForeground"/>
</TextBlock.Foreground>
</TextBlock>

<TextBlock Grid.Row="1" Text="{Binding StatusText}" HorizontalAlignment="Center" VerticalAlignment="Center"
FontFamily="pack://application:,,,/Assets/#FS Sinclair" FontSize="20" FontWeight="Bold"
Foreground="{DynamicResource SilverForeground}"/>
<controls:TypewriterTextBlock Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="20" FontWeight="Bold"
TimePerCharacter="0:0:0.085">
<controls:TypewriterTextBlock.TextToAnimate>
<Binding Path="StatusText" Mode="OneWay"/>
</controls:TypewriterTextBlock.TextToAnimate>

<controls:TypewriterTextBlock.FontFamily>
<StaticResource ResourceKey="FSSinclair"/>
</controls:TypewriterTextBlock.FontFamily>

<controls:TypewriterTextBlock.Foreground>
<StaticResource ResourceKey="SilverForeground"/>
</controls:TypewriterTextBlock.Foreground>
</controls:TypewriterTextBlock>

<Border Grid.Row="2" CornerRadius="1" BorderThickness="2" BorderBrush="#e0e0e0" VerticalAlignment="Bottom" Height="80" Width="50" Margin="0 0 0 5">
<ToggleButton Style="{DynamicResource HelldiverToggleButtonStyle}" IsChecked="{Binding IsLockEnabled}"/>
<Border Grid.Row="2" CornerRadius="1" BorderThickness="2"
VerticalAlignment="Bottom" Height="80" Width="50" Margin="0 0 0 5">
<Border.BorderBrush>
<StaticResource ResourceKey="WhiteForeground"/>
</Border.BorderBrush>

<ToggleButton>
<ToggleButton.Style>
<StaticResource ResourceKey="HelldiverToggleButtonStyle"/>
</ToggleButton.Style>

<ToggleButton.IsChecked>
<Binding Path="IsLockEnabled" Mode="OneWayToSource"/>
</ToggleButton.IsChecked>
</ToggleButton>
</Border>

<TextBlock Grid.Row="3" Text="{Binding LockInText}"
FontFamily="pack://application:,,,/Assets/#FS Sinclair" FontSize="14" FontWeight="Bold"
Foreground="#e0e0e0"
<controls:TypewriterTextBlock Grid.Row="3"
FontSize="14"
FontWeight="Bold"
HorizontalAlignment="Center"
VerticalAlignment="Top"/>
VerticalAlignment="Top"
controls:TypewriterTextBlock.TextToAnimate="{Binding LockInText}">

<controls:TypewriterTextBlock.Text>
<Binding Path="LockInText" Mode="OneWay"/>
</controls:TypewriterTextBlock.Text>

<controls:TypewriterTextBlock.Foreground>
<StaticResource ResourceKey="WhiteForeground"/>
</controls:TypewriterTextBlock.Foreground>

<controls:TypewriterTextBlock.FontFamily>
<StaticResource ResourceKey="FSSinclair"/>
</controls:TypewriterTextBlock.FontFamily>
</controls:TypewriterTextBlock>

</Grid>
</Window>
17 changes: 4 additions & 13 deletions LockIn/Themes.xaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<!-- Dark Blue Background -->
<SolidColorBrush x:Key="DarkBlueBackground" Color="#1A202C"/>

<!-- Silver Foreground -->

<SolidColorBrush x:Key="SilverForeground" Color="#C0C4D2"/>

<!-- Metallic Texture -->
<ImageBrush ImageSource="/Helldivers2UI;component/Resources/MetallicTexture.png"
Stretch="UniformToFill"
TileMode="Tile"
AlignmentX="Center"
AlignmentY="Center"
Opacity=".5" x:Key="MetallicTexture"/>
<SolidColorBrush x:Key="WhiteForeground" Color="#e0e0e0"/>
<SolidColorBrush x:Key="BlackBackground" Color="#151515"/>
<FontFamily x:Key="FSSinclair" >/Assets/#FS Sinclair Regular.otf</FontFamily>

</ResourceDictionary>
8 changes: 8 additions & 0 deletions LockIn/UserControls/TypewriterTextBlock.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<TextBlock x:Class="LockIn.UserControls.TypewriterTextBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
</TextBlock>
69 changes: 69 additions & 0 deletions LockIn/UserControls/TypewriterTextBlock.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Text;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;

namespace LockIn.UserControls;

[ObservableObject]
public partial class TypewriterTextBlock : TextBlock
{
private CancellationTokenSource _cts = new CancellationTokenSource();
public static readonly DependencyProperty TimePerCharacterProperty = DependencyProperty.RegisterAttached("TimePerCharacter", typeof(TimeSpan), typeof(TypewriterTextBlock), new PropertyMetadata(TimeSpan.FromMilliseconds(100)));
public static readonly DependencyProperty TextToAnimateProperty = DependencyProperty.RegisterAttached("TextToAnimate", typeof(string), typeof(TypewriterTextBlock), new PropertyMetadata(string.Empty, OnTextChanged));

public static void SetTimePerCharacter(DependencyObject element, TimeSpan value)
{
element.SetValue(TimePerCharacterProperty, value);
}

public static TimeSpan GetTimePerCharacter(DependencyObject element)
{
return (TimeSpan)element.GetValue(TimePerCharacterProperty);
}

public static void SetTextToAnimate(DependencyObject element, string value)
{
element.SetValue(TextToAnimateProperty, value);
}

public static string GetTextToAnimate(DependencyObject element, string value)
{
return (string)element.GetValue(TextToAnimateProperty);
}

public TypewriterTextBlock()
{

}

private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(d is not TypewriterTextBlock textBlock) return;
if (e.NewValue == e.OldValue) return;
textBlock._cts.Cancel();
textBlock._cts.Dispose();
textBlock._cts = new CancellationTokenSource();
_ = textBlock.AnimateText(e.NewValue.ToString() ?? string.Empty, textBlock._cts.Token);
}

private async Task AnimateText(string textToAnimate, CancellationToken ct = default)
{
if(ct.IsCancellationRequested) return;
TimeSpan timePerCharacter = (TimeSpan)GetValue(TimePerCharacterProperty);
StringBuilder bob = new(textToAnimate.Length);
try
{
foreach (char c in textToAnimate)
{
if (ct.IsCancellationRequested) return;
bob.Append(c);
Text = bob.ToString();
await Task.Delay(timePerCharacter, ct);
}
}
catch (OperationCanceledException)
{
}
}
}
36 changes: 19 additions & 17 deletions LockIn/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
Expand Down Expand Up @@ -46,22 +47,26 @@ private void QuitApplication(object sender, ExitEventArgs e)

private void UpdateLabel()
{
string textToSet = string.Empty;
if (!IsLockEnabled)
{
StatusText = "Disabled";
textToSet = "Disabled";
_gameProcess = null;
return;
}

if (_gameProcess == null || _gameProcess.HasExited)
{
StatusText = "Looking for game...";
_threadSignaller.Set();
}
else
{
StatusText = "Enabled";
if (_gameProcess == null || _gameProcess.HasExited)
{
textToSet = "Looking for game...";
_threadSignaller.Set();
}
else
{
textToSet = "Enabled";
}
}

StatusText = textToSet;
}

private void ThreadFindGame()
Expand All @@ -71,7 +76,11 @@ private void ThreadFindGame()
while (_threadSignaller.WaitOne())
{
if (_applicationExitTokenSource.Token.IsCancellationRequested) return;
Process[] processes = Process.GetProcessesByName("helldivers2");
string processToFind = "helldivers2";
#if DEBUG
processToFind = "notepad";
#endif
Process[] processes = Process.GetProcessesByName(processToFind);
if (processes.Length > 0)
{
_gameProcess = processes.First();
Expand Down Expand Up @@ -122,13 +131,6 @@ private void GameExit(object? sender, EventArgs e)
partial void OnIsLockEnabledChanged(bool value)
{
LockInText = value ? "Unlock" : "Lock In";
}

protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);

if(e.PropertyName != nameof(IsLockEnabled)) return;
Natives.ClipCursor(IntPtr.Zero);
UpdateLabel();
}
Expand Down