Skip to content

Commit

Permalink
Merge pull request #93 from CodebreakerApp/92-animations-and-infomess…
Browse files Browse the repository at this point in the history
…ages

92 animations and infomessages
  • Loading branch information
christiannagel authored Dec 19, 2023
2 parents 27d9cc4 + ffc2a33 commit e273d26
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 19 deletions.
15 changes: 5 additions & 10 deletions src/Codebreaker.ViewModels/Pages/GamePageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ IInfoBarService infoBarService
};
}

/// <summary>
/// Information on the game - messages, errors, etc. See <see cref="InfoBarMessageService"/>.
/// </summary>
public InfoBarService InfoBarMessageService { get; } = new();

private Game? _game;
/// <summary>
/// <see cref="Models.Game"/> instance."/>
Expand Down Expand Up @@ -121,7 +116,7 @@ public Game? Game
/// Updates the <see cref="GameStatus"/> property.
/// Initializes <see cref="Game"/>).
/// Increments the move number.
/// Shows <see cref="IDialogService"/> messages or <see cref="InfoBarMessageService"/> messages with errors.
/// Shows <see cref="IDialogService"/> messages or <see cref="_infoBarService"/> messages with errors.
/// </summary>
/// <returns>A task</returns>
[RelayCommand(AllowConcurrentExecutions = false, FlowExceptionsToTaskScheduler = true)]
Expand Down Expand Up @@ -219,17 +214,17 @@ private async Task SetMoveAsync()
if (isVictory)
{
GameStatus = GameMode.Won;
InfoBarMessageService.New.IsSuccessMessage().WithMessage("Congratulations - you won!").Show();
_infoBarService.New.IsSuccessMessage().WithMessage("Congratulations - you won!").Show();
}
else if (ended)
{
GameStatus = GameMode.Lost;
InfoBarMessageService.New.WithMessage("Sorry, you didn't find the matching colors!").Show();
_infoBarService.New.WithMessage("Sorry, you didn't find the matching colors!").Show();
}
}
catch (Exception ex)
{
InfoBarMessageService.New.WithMessage(ex.Message).IsErrorMessage().Show();
_infoBarService.New.WithMessage(ex.Message).IsErrorMessage().Show();
}
finally
{
Expand All @@ -254,7 +249,7 @@ private void InitializeValues()
ClearSelectedColor();
GameMoves.Clear();
GameStatus = GameMode.NotRunning;
InfoBarMessageService.Clear();
_infoBarService.Clear();
_moveNumber = 0;
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/Codebreaker.WinUI/Helpers/LinqExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace System.Linq;

internal static class LinqExtensions
{
public static IEnumerable<T> Foreach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
action(item);

return enumerable;
}

public static IEnumerable<T> Foreach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
{
int i = 0;

foreach (var item in enumerable)
action(item, i++);

return enumerable;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using Codebreaker.ViewModels;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml.Media.Animation;

namespace CodeBreaker.WinUI.Views.Components;

internal sealed partial class PegSelectionComponent : UserControl
internal sealed partial class PegSelectionComponent : UserControl, IRecipient<GameMoveMessage>
{
public PegSelectionComponent()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register(this);
WeakReferenceMessenger.Default.UnregisterAllOnUnloaded(this);
}

public GamePageViewModel ViewModel
Expand All @@ -22,4 +26,13 @@ public GamePageViewModel ViewModel
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(GamePageViewModel), typeof(PegSelectionComponent), new PropertyMetadata(null));

public void Receive(GameMoveMessage message)
{
if (message.GameMoveValue is not GameMoveValue.Started)
return;

var animationService = ConnectedAnimationService.GetForCurrentView();
this.FindItemsOfType<ComboBox>(this)
.Foreach((comboBox, i) => animationService.PrepareToAnimate($"guess{i}", comboBox));
}
}
14 changes: 8 additions & 6 deletions src/Codebreaker.WinUI/Views/Pages/GamePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@
</Page.Resources>
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Startgame section-->
<Grid
Grid.Row="1"
Grid.Row="0"
ColumnSpacing="25"
Visibility="{x:Bind ViewModel.GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibility}, ConverterParameter=Start}">
<Grid.ColumnDefinitions>
Expand Down Expand Up @@ -85,15 +84,18 @@
<TextBlock Text="{cme:ResourceString Name=GamePage_CancelButtonText}" />
</StackPanel>
</Button>-->
<components:PegSelectionComponent
Grid.Row="2"
ViewModel="{x:Bind ViewModel, Mode=OneWay}" />
<components:PegSelectionComponent
Grid.Row="3"
Margin="65,0,0,0"
ViewModel="{x:Bind ViewModel, Mode=OneWay}" />
</StackPanel>
<!--Move section-->
<ListBox
x:Name="listGameMoves"
Grid.Row="3"
Grid.Row="2"
Background="Transparent"
SelectedIndex="-1"
IsHitTestVisible="False"
Visibility="{x:Bind ViewModel.GameStatus, Mode=OneWay, Converter={StaticResource GameStatusVisibility}, ConverterParameter=Running}"
ItemsSource="{x:Bind ViewModel.GameMoves, Mode=OneWay}"
ItemTemplate="{StaticResource PegsTemplate}" />
Expand Down
30 changes: 29 additions & 1 deletion src/Codebreaker.WinUI/Views/Pages/GamePage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
using Codebreaker.ViewModels;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Shapes;

namespace CodeBreaker.WinUI.Views.Pages;

/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GamePage : Page
public sealed partial class GamePage : Page, IRecipient<GameMoveMessage>
{
public GamePageViewModel ViewModel { get; }

public GamePage()
{
ViewModel = App.GetService<GamePageViewModel>();
InitializeComponent();
WeakReferenceMessenger.Default.Register(this);
WeakReferenceMessenger.Default.UnregisterAllOnUnloaded(this);
}

public void Receive(GameMoveMessage message)
{
if (message.GameMoveValue is not GameMoveValue.Completed)
return;

var selectionAndKeyPegs = message.SelectionAndKeyPegs ?? throw new InvalidOperationException();
var animationService = ConnectedAnimationService.GetForCurrentView();
animationService.DefaultDuration = TimeSpan.FromMilliseconds(500);
var container = listGameMoves.ItemContainerGenerator.ContainerFromItem(selectionAndKeyPegs);
this.FindItemsOfType<Ellipse>(container)
.Foreach((ellipse, i) =>
{
ConnectedAnimation? animation = animationService.GetAnimation($"guess{i}");

// No animation found for this ellipxe -> the ellipse is most likely a key-peg
if (animation is null)
return;

animation.Configuration = new BasicConnectedAnimationConfiguration();
animation.TryStart(ellipse);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=MoveNumber, Mode=OneTime}" FontSize="{ThemeResource LargeFontSize}" Margin="48,0" VerticalAlignment="Center" />
<TextBlock Grid.Column="0" Text="{Binding Path=MoveNumber, Mode=OneTime}" FontSize="{ThemeResource LargeFontSize}" Margin="48,0,10,0" VerticalAlignment="Center" />
<Border Grid.Column="1" Margin="20,0,0,0" Padding="7" x:Name="ShadowTarget">
<ItemsControl ItemsSource="{Binding Path=GuessPegs, Mode=OneTime}">
<ItemsControl.ItemsPanel>
Expand Down

0 comments on commit e273d26

Please sign in to comment.