Skip to content

Commit 0905eb5

Browse files
Merge pull request #184 from CodebreakerApp/183-winui-cancel-game-feature
183 winui cancel game feature
2 parents 088fb90 + 7d50be9 commit 0905eb5

9 files changed

Lines changed: 79 additions & 126 deletions

File tree

src/Codebreaker.WinUI/Codebreaker.WinUI.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,19 @@
4949
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
5050
</ItemGroup>
5151
<ItemGroup>
52-
<PackageReference Include="CNInnovation.Codebreaker.ViewModels" Version="3.6.0-beta.34" />
52+
<PackageReference Include="CNInnovation.Codebreaker.ViewModels" Version="3.7.0-beta.40" />
5353
<PackageReference Include="CommunityToolkit.WinUI.UI" Version="7.1.2" />
5454
<PackageReference Include="CommunityToolkit.WinUI.UI.Animations" Version="7.1.2" />
5555
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
5656
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
5757
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
58-
<PackageReference Include="Microsoft.Identity.Client" Version="4.59.0" />
59-
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
58+
<PackageReference Include="Microsoft.Identity.Client" Version="4.60.3" />
59+
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240428000" />
6060
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.25936-preview" />
6161
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
6262
<PackageReference Include="System.Net.Http" Version="4.3.4" />
6363
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
64-
<PackageReference Include="WinUIEx" Version="2.3.3" />
64+
<PackageReference Include="WinUIEx" Version="2.3.4" />
6565
</ItemGroup>
6666
<ItemGroup>
6767
<Page Update="Views\Templates\CodeBreakerTemplates.xaml">

src/Codebreaker.WinUI/Converters/GameStatusToVisibilityConverter.cs

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/Codebreaker.WinUI/Helpers/PageExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,20 @@ void Callback(object sender, RoutedEventArgs args)
3030
page.Unloaded += Callback;
3131
}
3232

33-
public static IEnumerable<T> FindItemsOfType<T>(this DependencyObject dependencyObject, DependencyObject obj)
33+
public static IEnumerable<T> FindChildrenRecursively<T>(this DependencyObject dependencyObject)
3434
where T : DependencyObject
3535
{
36-
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
36+
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
3737
{
38-
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
38+
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
3939

4040
if (child is null)
4141
yield break;
4242

4343
if (child is T item)
4444
yield return item;
4545

46-
foreach (T childOfChild in dependencyObject.FindItemsOfType<T>(child))
46+
foreach (T childOfChild in child.FindChildrenRecursively<T>())
4747
yield return childOfChild;
4848
}
4949
}

src/Codebreaker.WinUI/Views/Components/GameResultDisplay.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
xmlns:cme="using:CodeBreaker.WinUI.CustomMarkupExtensions"
1111
mc:Ignorable="d">
1212
<UserControl.Resources>
13-
<converter:GameStatusToVisibilityConverter x:Key="GameStatusToVisibilityConverter" />
1413
<animations:ImplicitAnimationSet x:Key="EntranceAnimation">
1514
<animations:OpacityAnimation Duration="0:0:2" From="0" To="1" />
1615
<animations:TranslationAnimation Duration="0:0:1" From="0,-300,0" To="0" />
Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
using Codebreaker.ViewModels;
2-
using System.ComponentModel;
2+
using Codebreaker.ViewModels.Messages;
3+
using CommunityToolkit.Mvvm.Messaging;
34

45
namespace CodeBreaker.WinUI.Views.Components;
56

6-
public sealed partial class GameResultDisplay : UserControl
7+
public sealed partial class GameResultDisplay : UserControl,
8+
IRecipient<GameEndedMessage>,
9+
IRecipient<GameStartedMessage>
710
{
811
public GameResultDisplay()
912
{
13+
WeakReferenceMessenger.Default.RegisterAll(this);
14+
WeakReferenceMessenger.Default.UnregisterAllOnUnloaded(this);
1015
InitializeComponent();
1116
this.GoToState("Default", false);
1217
}
@@ -18,25 +23,11 @@ public GamePageViewModel ViewModel
1823
}
1924

2025
public static readonly DependencyProperty ViewModelProperty =
21-
DependencyProperty.Register(nameof(ViewModel), typeof(GamePageViewModel), typeof(GameResultDisplay), new PropertyMetadata(null, OnViewModelChanged));
26+
DependencyProperty.Register(nameof(ViewModel), typeof(GamePageViewModel), typeof(GameResultDisplay), new PropertyMetadata(null));
2227

23-
private static void OnViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
24-
{
25-
var @this = (GameResultDisplay)d;
26-
@this.ViewModel.PropertyChanged += @this.OnViewModelPropertyChanged;
27-
}
28+
public void Receive(GameEndedMessage message) =>
29+
this.GoToState(message.IsVictory ? "Won" : "Lost");
2830

29-
private void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs args)
30-
{
31-
if (args.PropertyName != nameof(GamePageViewModel.GameStatus))
32-
return;
33-
34-
var stateName = ViewModel.GameStatus switch
35-
{
36-
GameMode.Won => "Won",
37-
GameMode.Lost => "Lost",
38-
_ => "Default"
39-
};
40-
this.GoToState(stateName);
41-
}
31+
public void Receive(GameStartedMessage message) =>
32+
this.GoToState("Default");
4233
}

src/Codebreaker.WinUI/Views/Components/PegSelectionComponent.xaml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,25 @@
77
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
88
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
99
xmlns:vmComponents="using:Codebreaker.ViewModels.Components"
10+
xmlns:models="using:Codebreaker.ViewModels.Models"
1011
xmlns:toolkitConverters="using:CommunityToolkit.WinUI.UI.Converters"
1112
xmlns:cme="using:CodeBreaker.WinUI.CustomMarkupExtensions"
1213
mc:Ignorable="d"
1314
x:Name="ThisControl">
1415

1516
<UserControl.Resources>
1617
<toolkitConverters:BoolToVisibilityConverter x:Key="BoolToVisibility" />
17-
<DataTemplate x:Key="SelectColorTemplate">
18+
<DataTemplate x:Key="SelectColorTemplate" x:DataType="x:String">
1819
<Grid>
19-
<Ellipse Fill="{Binding Mode=OneWay, Converter={StaticResource ColorConverter}}" Width="60" Height="60" />
20+
<Ellipse Fill="{x:Bind Mode=OneWay, Converter={StaticResource ColorConverter}}" Width="60" Height="60" />
2021
</Grid>
2122
</DataTemplate>
22-
<DataTemplate x:Key="SelectColorItemTemplate" x:DataType="vmComponents:SelectedFieldViewModel">
23+
<DataTemplate x:Key="SelectColorItemTemplate" x:DataType="models:Field">
2324
<ComboBox
2425
Margin="04" Width="112"
2526
Height="92"
26-
ItemsSource="{Binding ElementName=ThisControl, Path=DataContext.Game.FieldValues[colors], Mode=OneWay}"
27-
SelectedItem="{x:Bind Path=Value, Mode=TwoWay}"
27+
ItemsSource="{x:Bind PossibleColors, Mode=OneTime}"
28+
SelectedItem="{x:Bind Color, Mode=TwoWay}"
2829
ItemTemplate="{StaticResource SelectColorTemplate}"
2930
PlaceholderText="" HorizontalContentAlignment="Center" FontSize="40" />
3031
</DataTemplate>
@@ -37,18 +38,18 @@
3738
</Grid.ColumnDefinitions>
3839
<ItemsControl
3940
Grid.Column="0"
40-
ItemsSource="{x:Bind Path=ViewModel.Fields, Mode=OneWay}"
41+
ItemsSource="{x:Bind Path=ViewModel.SelectedFields, Mode=OneWay}"
4142
ItemTemplate="{StaticResource SelectColorItemTemplate}">
4243
<ItemsControl.ItemsPanel>
4344
<ItemsPanelTemplate>
4445
<StackPanel Orientation="Horizontal" Margin="15,0,15,10" />
4546
</ItemsPanelTemplate>
4647
</ItemsControl.ItemsPanel>
4748
</ItemsControl>
48-
<Button Command="{x:Bind ViewModel.SetMoveCommand, Mode=OneTime}" Grid.Column="1" Margin="4" VerticalAlignment="Top" Height="92" Width="100">
49+
<Button Command="{x:Bind ViewModel.MakeMoveCommand, Mode=OneTime}" Grid.Column="1" Margin="4" VerticalAlignment="Top" Height="92" Width="100">
4950
<StackPanel Orientation="Vertical" Spacing="5">
50-
<SymbolIcon Symbol="Send" Visibility="{x:Bind ViewModel.SetMoveCommand.IsRunning, Mode=OneWay, Converter={StaticResource BoolToVisibility}, ConverterParameter=True}" />
51-
<ProgressRing Visibility="{x:Bind ViewModel.SetMoveCommand.IsRunning, Mode=OneWay}" />
51+
<SymbolIcon Symbol="Send" Visibility="{x:Bind ViewModel.MakeMoveCommand.IsRunning, Mode=OneWay, Converter={StaticResource BoolToVisibility}, ConverterParameter=True}" />
52+
<ProgressRing Visibility="{x:Bind ViewModel.MakeMoveCommand.IsRunning, Mode=OneWay}" />
5253
<TextBlock Text="{cme:ResourceString Name=PegSelection_MakeMove}" />
5354
</StackPanel>
5455
</Button>

src/Codebreaker.WinUI/Views/Components/PegSelectionComponent.xaml.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using Codebreaker.ViewModels;
2+
using Codebreaker.ViewModels.Messages;
23
using CommunityToolkit.Mvvm.Messaging;
34
using Microsoft.UI.Xaml.Media.Animation;
45

56
namespace CodeBreaker.WinUI.Views.Components;
67

7-
internal sealed partial class PegSelectionComponent : UserControl, IRecipient<GameMoveMessage>
8+
internal sealed partial class PegSelectionComponent : UserControl, IRecipient<MakeMoveMessage>
89
{
910
public PegSelectionComponent()
1011
{
@@ -26,13 +27,14 @@ public GamePageViewModel ViewModel
2627
public static readonly DependencyProperty ViewModelProperty =
2728
DependencyProperty.Register("ViewModel", typeof(GamePageViewModel), typeof(PegSelectionComponent), new PropertyMetadata(null));
2829

29-
public void Receive(GameMoveMessage message)
30+
public void Receive(MakeMoveMessage message)
3031
{
31-
if (message.GameMoveValue is not GameMoveValue.Started)
32+
// Move must be completed already
33+
if (message.IsSet)
3234
return;
3335

3436
var animationService = ConnectedAnimationService.GetForCurrentView();
35-
this.FindItemsOfType<ComboBox>(this)
37+
this.FindChildrenRecursively<ComboBox>()
3638
.Foreach((comboBox, i) => animationService.PrepareToAnimate($"guess{i}", comboBox));
3739
}
3840
}

src/Codebreaker.WinUI/Views/Pages/GamePage.xaml

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
xmlns:cme="using:CodeBreaker.WinUI.CustomMarkupExtensions"
1414
mc:Ignorable="d">
1515
<Page.Resources>
16-
<conv:GameStatusToVisibilityConverter x:Key="GameStatusVisibility" />
1716
<toolkitConverters:BoolToVisibilityConverter x:Key="BoolToVisibility" />
1817
<Style TargetType="InfoBar">
1918
<Setter Property="Margin" Value="0,0,0,30" />
@@ -66,17 +65,10 @@
6665
<!-- The extra grid and the empy (enabled) TextBlock are necessary for showing the tooltip over the (disabled) TextBox. -->
6766
<TextBlock />
6867
<TextBox
69-
IsEnabled="{x:Bind ViewModel.IsNameEnterable, Mode=OneWay}"
7068
Header="{cme:ResourceString Name=GamePage_NameInputHeader}"
7169
PlaceholderText="{cme:ResourceString Name=GamePage_NameInputPlaceholder}"
7270
VerticalAlignment="Center"
73-
Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
74-
<ToolTipService.ToolTip>
75-
<ToolTip
76-
Content="{cme:ResourceString Name=GamePage_NameAlreadyProvidedTooltip}"
77-
IsEnabled="{x:Bind Path=ViewModel.IsNamePredefined, Mode=OneWay}"
78-
Placement="Bottom" />
79-
</ToolTipService.ToolTip>
71+
Text="{x:Bind ViewModel.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
8072
</Grid>
8173
<Button
8274
Grid.Column="1"
@@ -91,14 +83,14 @@
9183
</StackPanel>
9284
</Button>
9385
</Grid>
94-
<components:GameResultDisplay Grid.Row="0" />
86+
<components:GameResultDisplay
87+
Grid.Row="0"
88+
ViewModel="{x:Bind ViewModel}" />
9589
<!--Gamebar section-->
9690
<StackPanel
9791
x:Name="PegSelectionArea"
9892
Orientation="Horizontal"
9993
Grid.Row="1">
100-
<!--
101-
Cancelling the game is not yet implemented in the VM
10294
<Button
10395
Height="92" Margin="0,-6,4,0" Width="100"
10496
ca:Confirm.Enabled="True"
@@ -112,11 +104,11 @@
112104
<ProgressRing Visibility="{x:Bind ViewModel.CancelGameCommand.IsRunning, Mode=OneWay}" />
113105
<TextBlock Text="{cme:ResourceString Name=GamePage_CancelButtonText}" />
114106
</StackPanel>
115-
</Button>-->
116-
<components:PegSelectionComponent
117-
Grid.Row="3"
118-
Margin="65,0,0,0"
119-
ViewModel="{x:Bind ViewModel, Mode=OneWay}" />
107+
</Button>
108+
<components:PegSelectionComponent
109+
Grid.Row="3"
110+
Margin="65,0,0,0"
111+
ViewModel="{x:Bind ViewModel, Mode=OneWay}" />
120112
</StackPanel>
121113
<!--Move section-->
122114
<ScrollViewer Grid.Row="2" Padding="0,0,0,15" x:Name="PegScrollViewer">
@@ -125,7 +117,7 @@
125117
Background="Transparent"
126118
SelectedIndex="-1"
127119
IsHitTestVisible="False"
128-
ItemsSource="{x:Bind ViewModel.GameMoves, Mode=OneWay}"
120+
ItemsSource="{x:Bind ViewModel.Game.Moves, Mode=OneWay}"
129121
ItemTemplate="{StaticResource PegsTemplate}" />
130122
</ScrollViewer>
131123
</Grid>

0 commit comments

Comments
 (0)