From b3f2937e7bc6c5be8c78906be28c43583f49ef25 Mon Sep 17 00:00:00 2001 From: Sander van Vliet Date: Tue, 8 Aug 2023 20:08:05 +0200 Subject: [PATCH] Add loop mode and count indicator and allow the user to change the loop type --- Changelog.md | 4 +- images/loop-indicator-infinite.png | Bin 0 -> 20321 bytes images/loop-indicator.png | Bin 0 -> 20535 bytes .../DelegateDecorator.cs | 4 +- .../DesignTimeWindowService.cs | 2 +- .../IWindowService.cs | 2 +- .../DesignTimeMainWindowViewModel.cs | 2 +- .../ViewModels/MainWindowViewModel.cs | 31 ++++++++++++++ .../ViewModels/RouteViewModel.cs | 9 ++++ .../Views/MainWindow.axaml | 40 +++++++++++++++++- .../WindowService.cs | 11 ++++- .../Converters/BooleanConverter.cs | 7 ++- 12 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 images/loop-indicator-infinite.png create mode 100644 images/loop-indicator.png diff --git a/Changelog.md b/Changelog.md index adf7cd19..b708a6fd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -15,8 +15,10 @@ Read more about how it works on [the RoadCaptain site](https://roadcaptain.nl/fe - The color scheme of the elevation profile has been changed to provide much clearer indication of the grade - When creating a route, Route Builder no longer will attempt to create a loop for segments that join back on the previous segment. This especially happened for routes summiting on mountain tops in Watopia. - When creating a route and Route Builder detects that you selected a segment that can create a loop, it will now ask you what type of loop you want. You can choose between _No loop_, _Infinite loop_ or _Constrained loop_ where the last one allows you to specify how many times you want to do the loop before exiting it: -![Screenshot of the new make loop dialog](./images/make-loop-dialog.png) +
![Screenshot of the new make loop dialog](./images/make-loop-dialog.png) - When creating a route and the route already contains a loop, Route Builder now no longer asks to create a further loop +- When creating a route with a loop, the segment list now indicates the loop mode (fixed number or infinite) and the number of loops:
![Screenshot of the segment list with the loop indicator](./images/loop-indicator.png)![Screenshot of the segment list with the loop indicator](./images/loop-indicator-infinite.png)
Clicking the indicator allows you to change the loop settings. + ### Runner diff --git a/images/loop-indicator-infinite.png b/images/loop-indicator-infinite.png new file mode 100644 index 0000000000000000000000000000000000000000..2e8f0d9e722691e6c33fb760f75968d3dc80821c GIT binary patch literal 20321 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 W!6Lbu4g!w-?K3sB!qlO034aHQD{p)N literal 0 HcmV?d00001 diff --git a/src/RoadCaptain.App.RouteBuilder/DelegateDecorator.cs b/src/RoadCaptain.App.RouteBuilder/DelegateDecorator.cs index 9d52324c..3d67ef0d 100644 --- a/src/RoadCaptain.App.RouteBuilder/DelegateDecorator.cs +++ b/src/RoadCaptain.App.RouteBuilder/DelegateDecorator.cs @@ -85,9 +85,9 @@ public async Task ShowClearRouteDialog() return await InvokeIfNeededAsync(() => _decorated.ShowClearRouteDialog()); } - public async Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog() + public async Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog(LoopMode? loopMode = null, int? numberOfLoops = null) { - return await InvokeIfNeededAsync(() => _decorated.ShowRouteLoopDialog()); + return await InvokeIfNeededAsync(() => _decorated.ShowRouteLoopDialog(loopMode, numberOfLoops)); } public async Task ShowSaveRouteDialog(string? lastUsedFolder, RouteViewModel routeViewModel) diff --git a/src/RoadCaptain.App.RouteBuilder/DesignTimeWindowService.cs b/src/RoadCaptain.App.RouteBuilder/DesignTimeWindowService.cs index b43b372f..a4102531 100644 --- a/src/RoadCaptain.App.RouteBuilder/DesignTimeWindowService.cs +++ b/src/RoadCaptain.App.RouteBuilder/DesignTimeWindowService.cs @@ -74,7 +74,7 @@ public Task ShowClearRouteDialog() throw new System.NotImplementedException(); } - public Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog() + public Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog(LoopMode? loopMode = null, int? numberOfLoops = null) { throw new System.NotImplementedException(); } diff --git a/src/RoadCaptain.App.RouteBuilder/IWindowService.cs b/src/RoadCaptain.App.RouteBuilder/IWindowService.cs index 6044eaac..9cdccb89 100644 --- a/src/RoadCaptain.App.RouteBuilder/IWindowService.cs +++ b/src/RoadCaptain.App.RouteBuilder/IWindowService.cs @@ -17,7 +17,7 @@ public interface IWindowService : RoadCaptain.App.Shared.IWindowService Task ShowDefaultSportSelectionDialog(SportType sport); Task ShowShouldSaveRouteDialog(); Task ShowClearRouteDialog(); - Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog(); + Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog(LoopMode? loopMode = null, int? numberOfLoops = null); Task ShowSaveRouteDialog(string? lastUsedFolder, RouteViewModel routeViewModel); Task ShowLogInDialog(Window owner); Window? GetCurrentWindow(); diff --git a/src/RoadCaptain.App.RouteBuilder/ViewModels/DesignTimeMainWindowViewModel.cs b/src/RoadCaptain.App.RouteBuilder/ViewModels/DesignTimeMainWindowViewModel.cs index 95da5d59..205fd013 100644 --- a/src/RoadCaptain.App.RouteBuilder/ViewModels/DesignTimeMainWindowViewModel.cs +++ b/src/RoadCaptain.App.RouteBuilder/ViewModels/DesignTimeMainWindowViewModel.cs @@ -6,7 +6,6 @@ using Autofac; using Avalonia.Threading; using Microsoft.Extensions.Configuration; -using RoadCaptain.App.RouteBuilder.UseCases; using RoadCaptain.Ports; using Serilog.Core; @@ -32,6 +31,7 @@ public DesignTimeMainWindowViewModel() { Route.OutputFilePath = @"C:\git\RoadCaptain\test\RoadCaptain.Tests.Unit\GameState\Repro\Rebel.Route-Italian.Villa.Sprint.Loop.json"; Route.Load(); + Route.LoopMode = LoopMode.Infinite; Route.Markers.Add(new MarkerViewModel(new Segment(new List()){ Id = "test", Name="Test", Type = SegmentType.Climb, Sport = SportType.Cycling})); Route.Markers.Add(new MarkerViewModel(new Segment(new List()){ Id = "test", Name="Test", Type = SegmentType.Climb, Sport = SportType.Cycling})); Route.Markers.Add(new MarkerViewModel(new Segment(new List()){ Id = "test", Name="Test", Type = SegmentType.Climb, Sport = SportType.Cycling})); diff --git a/src/RoadCaptain.App.RouteBuilder/ViewModels/MainWindowViewModel.cs b/src/RoadCaptain.App.RouteBuilder/ViewModels/MainWindowViewModel.cs index 5b8ebb99..09c5ea66 100644 --- a/src/RoadCaptain.App.RouteBuilder/ViewModels/MainWindowViewModel.cs +++ b/src/RoadCaptain.App.RouteBuilder/ViewModels/MainWindowViewModel.cs @@ -142,9 +142,39 @@ public MainWindowViewModel(IRouteStore routeStore, ISegmentStore segmentStore, I _ => Route.World != null) .SubscribeTo(this, () => Route.World); + ConfigureLoopCommand = new AsyncRelayCommand( + _ => ConfigureLoop(), + _ => Route.IsLoop) + .SubscribeTo(this, () => Route.Sequence) + .SubscribeTo(this, () => Route.IsLoop); + Version = GetType().Assembly.GetName().Version?.ToString(4) ?? "0.0.0.0"; } + + private async Task ConfigureLoop() + { + var shouldCreateLoop = await _windowService.ShowRouteLoopDialog(Route.LoopMode, Route.NumberOfLoops); + + if (shouldCreateLoop.Mode is LoopMode.Infinite or LoopMode.Constrained) + { + Route.LoopMode = shouldCreateLoop.Mode; + Route.NumberOfLoops = shouldCreateLoop.NumberOfLoops; + this.RaisePropertyChanged(nameof(Route)); + } + else + { + // Clear the loop properties + foreach (var seq in Route.Sequence.Where(s => s.IsLoop)) + { + seq.Type = SegmentSequenceType.Regular; + } + this.RaisePropertyChanged(nameof(Route)); + } + + return CommandResult.Success(); + } + private async Task ResetWorldAndSport() { if (Route.IsTainted) @@ -293,6 +323,7 @@ public List Markers public ICommand SelectSportCommand { get; } public ICommand ResetDefaultSportCommand { get; } public ICommand ResetWorldCommand { get; } + public ICommand ConfigureLoopCommand { get; set; } public Segment? SelectedSegment { diff --git a/src/RoadCaptain.App.RouteBuilder/ViewModels/RouteViewModel.cs b/src/RoadCaptain.App.RouteBuilder/ViewModels/RouteViewModel.cs index 9ddba7fb..64e82c0a 100644 --- a/src/RoadCaptain.App.RouteBuilder/ViewModels/RouteViewModel.cs +++ b/src/RoadCaptain.App.RouteBuilder/ViewModels/RouteViewModel.cs @@ -124,6 +124,14 @@ public int? NumberOfLoops } } + public bool IsLoop + { + get + { + return Sequence.Any(s => s.IsLoop); + } + } + public void StartOn(Segment segment) { if (_world == null) @@ -513,6 +521,7 @@ public void MakeLoop(int startIndex, int endIndex, LoopMode mode, int? numberOfL seqList[endIndex].Model.NextSegmentId = seqList[startIndex].SegmentId; LoopMode = mode; NumberOfLoops = numberOfLoops; + this.RaisePropertyChanged(nameof(IsLoop)); } private void DetermineMarkersForRoute() diff --git a/src/RoadCaptain.App.RouteBuilder/Views/MainWindow.axaml b/src/RoadCaptain.App.RouteBuilder/Views/MainWindow.axaml index fed1a028..2b49fa03 100644 --- a/src/RoadCaptain.App.RouteBuilder/Views/MainWindow.axaml +++ b/src/RoadCaptain.App.RouteBuilder/Views/MainWindow.axaml @@ -13,6 +13,7 @@ xmlns:sharedControls="clr-namespace:RoadCaptain.App.Shared.Controls;assembly=RoadCaptain.App.Shared" xmlns:appConverters="clr-namespace:RoadCaptain.App.RouteBuilder.Converters" xmlns:map="clr-namespace:Codenizer.Avalonia.Map;assembly=Codenizer.Avalonia.Map" + xmlns:roadCaptain="clr-namespace:RoadCaptain;assembly=RoadCaptain" mc:Ignorable="d" x:Class="RoadCaptain.App.RouteBuilder.Views.MainWindow" Icon="avares://RoadCaptain.App.Shared/icon.png" @@ -394,7 +395,44 @@ IsVisible="{Binding Path=LoopImage,Converter={StaticResource NullabilityConverter}}" Width="24" Height="56" /> - + diff --git a/src/RoadCaptain.App.RouteBuilder/WindowService.cs b/src/RoadCaptain.App.RouteBuilder/WindowService.cs index 4c356792..fd005ae7 100644 --- a/src/RoadCaptain.App.RouteBuilder/WindowService.cs +++ b/src/RoadCaptain.App.RouteBuilder/WindowService.cs @@ -104,10 +104,17 @@ public async Task ShowClearRouteDialog() MessageBoxIcon.Question); } - public async Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog() + public async Task<(LoopMode Mode, int? NumberOfLoops)> ShowRouteLoopDialog(LoopMode? loopMode = null, + int? numberOfLoops = null) { var makeLoopDialog = Resolve(); - var makeLoopDialogViewModel = new MakeLoopDialogViewModel(); + var makeLoopDialogViewModel = new MakeLoopDialogViewModel + { + NoLoop = true, + InfiniteLoop = loopMode == LoopMode.Infinite, + ConstrainedLoop = loopMode == LoopMode.Constrained, + NumberOfLoops = numberOfLoops + }; makeLoopDialog.DataContext = makeLoopDialogViewModel; await makeLoopDialog.ShowDialog(CurrentWindow); diff --git a/src/RoadCaptain.App.Shared/Converters/BooleanConverter.cs b/src/RoadCaptain.App.Shared/Converters/BooleanConverter.cs index 7e817e8f..7d9de0b6 100644 --- a/src/RoadCaptain.App.Shared/Converters/BooleanConverter.cs +++ b/src/RoadCaptain.App.Shared/Converters/BooleanConverter.cs @@ -14,7 +14,7 @@ public class BooleanConverter : IValueConverter { if (value is bool boolean) { - if (parameter is string flip && flip == "invert") + if (parameter is string and "invert") { return !boolean; } @@ -22,6 +22,11 @@ public class BooleanConverter : IValueConverter return boolean; } + if (value != null && parameter != null && value.GetType() == parameter.GetType()) + { + return value.Equals(parameter); + } + return value; }