diff --git a/.idea/.idea.BnbnavNetClient/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.BnbnavNetClient/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..7ad1bf1 --- /dev/null +++ b/.idea/.idea.BnbnavNetClient/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/BnbnavNetClient.I18Next/AppBuilderExtensions.cs b/BnbnavNetClient.I18Next/AppBuilderExtensions.cs index d1b5fe4..677d11f 100644 --- a/BnbnavNetClient.I18Next/AppBuilderExtensions.cs +++ b/BnbnavNetClient.I18Next/AppBuilderExtensions.cs @@ -1,12 +1,13 @@ using Avalonia; using BnbnavNetClient.I18Next.Services; +using Splat; namespace BnbnavNetClient.I18Next; public static class AppBuilderExtensions { public static AppBuilder UseI18NextLocalization(this AppBuilder appBuilder) { - appBuilder.With(new AvaloniaI18Next()); + Locator.CurrentMutable.RegisterConstant(new AvaloniaI18Next()); return appBuilder; } } diff --git a/BnbnavNetClient.I18Next/BnbnavNetClient.I18Next.csproj b/BnbnavNetClient.I18Next/BnbnavNetClient.I18Next.csproj index e0852aa..7ef3dd0 100644 --- a/BnbnavNetClient.I18Next/BnbnavNetClient.I18Next.csproj +++ b/BnbnavNetClient.I18Next/BnbnavNetClient.I18Next.csproj @@ -1,13 +1,14 @@ - net7.0 + net8.0 + diff --git a/BnbnavNetClient.I18Next/Services/IAvaloniaI18Next.cs b/BnbnavNetClient.I18Next/Services/IAvaloniaI18Next.cs index 50fb10b..e17cd14 100644 --- a/BnbnavNetClient.I18Next/Services/IAvaloniaI18Next.cs +++ b/BnbnavNetClient.I18Next/Services/IAvaloniaI18Next.cs @@ -2,6 +2,9 @@ using System.Reflection; namespace BnbnavNetClient.I18Next.Services; + + +//consider using singleton class since this is only ever used as the instance public interface IAvaloniaI18Next { string this[string key, Dictionary? arguments] { get; } diff --git a/BnbnavNetClient.I18Next/TrString.cs b/BnbnavNetClient.I18Next/TrString.cs index 9c0f549..b883c3b 100644 --- a/BnbnavNetClient.I18Next/TrString.cs +++ b/BnbnavNetClient.I18Next/TrString.cs @@ -1,5 +1,6 @@ using Avalonia; using BnbnavNetClient.I18Next.Services; +using Splat; namespace BnbnavNetClient.I18Next; public sealed class TrString : AvaloniaObject @@ -36,7 +37,7 @@ public IEnumerable Arguments public TrString() { - _tr = AvaloniaLocator.Current.GetRequiredService(); + _tr = Locator.Current.GetService() ?? throw new InvalidOperationException("AvaloniaI18Next must be registered for TrString to be constructed"); } public override string ToString() diff --git a/BnbnavNetClient.I18Next/TranslateExtension.cs b/BnbnavNetClient.I18Next/TranslateExtension.cs index 67da8f7..86fba94 100644 --- a/BnbnavNetClient.I18Next/TranslateExtension.cs +++ b/BnbnavNetClient.I18Next/TranslateExtension.cs @@ -2,6 +2,7 @@ using Avalonia; using Avalonia.Markup.Xaml; using BnbnavNetClient.I18Next.Services; +using Splat; namespace BnbnavNetClient.I18Next; @@ -11,6 +12,6 @@ public sealed class Tr : MarkupExtension public override object ProvideValue(IServiceProvider serviceProvider) { - return AvaloniaLocator.Current.GetRequiredService()[Key]; + return Locator.Current.GetService()![Key]; } } \ No newline at end of file diff --git a/BnbnavNetClient.Linux/BnbnavNetClient.Linux.csproj b/BnbnavNetClient.Linux/BnbnavNetClient.Linux.csproj index d4b5249..fa3a62f 100644 --- a/BnbnavNetClient.Linux/BnbnavNetClient.Linux.csproj +++ b/BnbnavNetClient.Linux/BnbnavNetClient.Linux.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 Linux diff --git a/BnbnavNetClient.Linux/Program.cs b/BnbnavNetClient.Linux/Program.cs index 46fee32..523d957 100644 --- a/BnbnavNetClient.Linux/Program.cs +++ b/BnbnavNetClient.Linux/Program.cs @@ -7,6 +7,7 @@ using BnbnavNetClient.Linux.TextToSpeech; using BnbnavNetClient.Services.TextToSpeech; using BnbnavNetClient.Settings; +using Splat; namespace BnbnavNetClient.Linux; @@ -15,6 +16,7 @@ internal class Program public static void Main(string[] args) { BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + Locator.CurrentMutable.RegisterConstant(new SpdTextToSpeechProvider()); } static AppBuilder BuildAvaloniaApp() @@ -27,7 +29,6 @@ static AppBuilder BuildAvaloniaApp() .LogToTrace() .UseReactiveUI() .UseI18NextLocalization() - .With(new SpdTextToSpeechProvider()) .UseSettings(new SettingsManagerJsonFile()); } } \ No newline at end of file diff --git a/BnbnavNetClient.Mac/BnbnavNetClient.Mac.csproj b/BnbnavNetClient.Mac/BnbnavNetClient.Mac.csproj index a1067ec..ac49ccb 100644 --- a/BnbnavNetClient.Mac/BnbnavNetClient.Mac.csproj +++ b/BnbnavNetClient.Mac/BnbnavNetClient.Mac.csproj @@ -1,7 +1,7 @@ - net7.0-macos10.14 + net8.0-macos10.14 Exe diff --git a/BnbnavNetClient.Web/BnbnavNetClient.Web.csproj b/BnbnavNetClient.Web/BnbnavNetClient.Web.csproj index c1c5486..0e3a648 100644 --- a/BnbnavNetClient.Web/BnbnavNetClient.Web.csproj +++ b/BnbnavNetClient.Web/BnbnavNetClient.Web.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 false browser-wasm AppBundle\main.js diff --git a/BnbnavNetClient.Windows/BnbnavNetClient.Windows.csproj b/BnbnavNetClient.Windows/BnbnavNetClient.Windows.csproj index b28d6aa..41a4263 100644 --- a/BnbnavNetClient.Windows/BnbnavNetClient.Windows.csproj +++ b/BnbnavNetClient.Windows/BnbnavNetClient.Windows.csproj @@ -1,7 +1,7 @@  WinExe - net7.0-windows + net8.0-windows true diff --git a/BnbnavNetClient.Windows/Program.cs b/BnbnavNetClient.Windows/Program.cs index 8a561e3..e073cd9 100644 --- a/BnbnavNetClient.Windows/Program.cs +++ b/BnbnavNetClient.Windows/Program.cs @@ -5,6 +5,7 @@ using BnbnavNetClient.I18Next; using BnbnavNetClient.Services.TextToSpeech; using BnbnavNetClient.Settings; +using Splat; namespace BnbnavNetClient.Windows; @@ -14,8 +15,11 @@ class Program // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .StartWithClassicDesktopLifetime(args); + public static void Main(string[] args) + { + BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + Locator.CurrentMutable.RegisterConstant(new WindowsTextToSpeechProvider()); + } // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() @@ -24,6 +28,5 @@ public static AppBuilder BuildAvaloniaApp() .LogToTrace() .UseReactiveUI() .UseI18NextLocalization() - .With(new WindowsTextToSpeechProvider()) .UseSettings(new SettingsManagerJsonFile()); } diff --git a/BnbnavNetClient/App.axaml b/BnbnavNetClient/App.axaml index c39ca5b..35b1f65 100644 --- a/BnbnavNetClient/App.axaml +++ b/BnbnavNetClient/App.axaml @@ -10,8 +10,7 @@ - - + @@ -31,6 +30,9 @@ + diff --git a/BnbnavNetClient/App.axaml.cs b/BnbnavNetClient/App.axaml.cs index 69af2ba..54ef0f0 100644 --- a/BnbnavNetClient/App.axaml.cs +++ b/BnbnavNetClient/App.axaml.cs @@ -7,7 +7,9 @@ using BnbnavNetClient.Views; using System; using System.Globalization; +using BnbnavNetClient.Extensions; using BnbnavNetClient.Services.TextToSpeech; +using Splat; namespace BnbnavNetClient; @@ -16,16 +18,17 @@ public class App : Application public override void Initialize() { AvaloniaXamlLoader.Load(this); - var settings = AvaloniaLocator.Current.GetRequiredService(); + var settings = Locator.Current.GetSettingsManager(); settings.LoadAsync().Wait(); var pseudo = Environment.GetEnvironmentVariable("PSEUDOLOCALIZATION") == "true"; - var i18N = AvaloniaLocator.Current.GetRequiredService(); + var i18N = Locator.Current.GetI18Next(); i18N.Initialize("BnbnavNetClient.locales", pseudo); i18N.CurrentLanguage = new CultureInfo(settings.Settings.Language); - var tts = AvaloniaLocator.Current.GetRequiredService(); - tts.CurrentCulture = CultureInfo.CurrentUICulture; + var tts = Locator.Current.GetService(); + if (tts is not null) + tts.CurrentCulture = CultureInfo.CurrentUICulture; } public override void OnFrameworkInitializationCompleted() diff --git a/BnbnavNetClient/BnbnavNetClient.csproj b/BnbnavNetClient/BnbnavNetClient.csproj index 79733d0..05cb1f1 100644 --- a/BnbnavNetClient/BnbnavNetClient.csproj +++ b/BnbnavNetClient/BnbnavNetClient.csproj @@ -1,7 +1,9 @@  - net7.0 + net8.0 true + true + Recommended @@ -18,14 +20,14 @@ - + - + diff --git a/BnbnavNetClient/Controls/InstructionImageControl.axaml.cs b/BnbnavNetClient/Controls/InstructionImageControl.axaml.cs index 970ed4d..779e52f 100644 --- a/BnbnavNetClient/Controls/InstructionImageControl.axaml.cs +++ b/BnbnavNetClient/Controls/InstructionImageControl.axaml.cs @@ -116,7 +116,7 @@ public override void Render(DrawingContext context) CalculatedRoute.Instruction.InstructionTypes.Merge => "merge", CalculatedRoute.Instruction.InstructionTypes.EnterRoundabout => "enter-roundabout", CalculatedRoute.Instruction.InstructionTypes.LeaveRoundabout => "leave-roundabout", - _ => throw new ArgumentOutOfRangeException() + _ => throw new InvalidOperationException(nameof(_instruction) + " was out of range") }; context.DrawSvgUrl($"avares://BnbnavNetClient/Assets/Instructions/{instructionFile}.svg", bounds); diff --git a/BnbnavNetClient/Extensions/SplatExtensions.cs b/BnbnavNetClient/Extensions/SplatExtensions.cs new file mode 100644 index 0000000..11ff05e --- /dev/null +++ b/BnbnavNetClient/Extensions/SplatExtensions.cs @@ -0,0 +1,14 @@ +using BnbnavNetClient.I18Next.Services; +using BnbnavNetClient.Settings; +using Splat; + +namespace BnbnavNetClient.Extensions; + +public static class SplatExtensions +{ + public static IAvaloniaI18Next GetI18Next(this IReadonlyDependencyResolver me) => + me.GetService() ?? throw new InvalidOperationException("Avalonia I18Next must be registered"); + + public static ISettingsManager GetSettingsManager(this IReadonlyDependencyResolver me) => + me.GetService() ?? throw new InvalidOperationException("Settings manager must be registered"); +} \ No newline at end of file diff --git a/BnbnavNetClient/Helpers/DrawingContextExtensions.cs b/BnbnavNetClient/Helpers/DrawingContextExtensions.cs index 0fd5beb..cecfb9f 100644 --- a/BnbnavNetClient/Helpers/DrawingContextExtensions.cs +++ b/BnbnavNetClient/Helpers/DrawingContextExtensions.cs @@ -24,11 +24,10 @@ public static void DrawSvgUrl(this DrawingContext context, string? url, Rect rec } else { - var assetLoader = AvaloniaLocator.Current.GetService()!; var uri = new Uri(url); - if (assetLoader.Exists(uri)) + if (AssetLoader.Exists(uri)) { - var asset = assetLoader.Open(uri); + var asset = AssetLoader.Open(uri); svg = new SKSvg(); svg.Load(asset); diff --git a/BnbnavNetClient/MapThemeResources.cs b/BnbnavNetClient/MapThemeResources.cs deleted file mode 100644 index b8ae40e..0000000 --- a/BnbnavNetClient/MapThemeResources.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml.Styling; -using Avalonia.Styling; - -namespace BnbnavNetClient; - -public enum MapTheme -{ - Day, - Night -} - -public sealed class MapThemeResources : AvaloniaObject, IResourceProvider -{ - readonly IResourceProvider _day; - readonly IResourceProvider _night; - - IResourceProvider CurrentProvider => Theme == MapTheme.Day ? _day : _night; - - public static readonly StyledProperty ThemeProperty = - AvaloniaProperty.Register(nameof(Theme)); - - public MapTheme Theme - { - get => GetValue(ThemeProperty); - set => SetValue(ThemeProperty, value); - } - - public IResourceHost? Owner => CurrentProvider.Owner; - - public bool HasResources => CurrentProvider.HasResources; - - public MapThemeResources() - { - _day = new ResourceInclude(baseUri: null) { Source = new Uri("avares://BnbnavNetClient/Resources/DayTheme.axaml") }; - _night = new ResourceInclude(baseUri: null) { Source = new Uri("avares://BnbnavNetClient/Resources/NightTheme.axaml") }; - } - - public event EventHandler? OwnerChanged - { - add - { - _day.OwnerChanged += value; - _night.OwnerChanged += value; - } - - remove - { - _day.OwnerChanged -= value; - _night.OwnerChanged -= value; - } - } - - public void AddOwner(IResourceHost owner) - { - _day.AddOwner(owner); - _night.AddOwner(owner); - } - - public void RemoveOwner(IResourceHost owner) - { - _day.RemoveOwner(owner); - _night.RemoveOwner(owner); - } - - public bool TryGetResource(object key, ThemeVariant? theme, out object? value) => CurrentProvider.TryGetResource(key, theme, out value); -} diff --git a/BnbnavNetClient/Models/CalculatedRoute.cs b/BnbnavNetClient/Models/CalculatedRoute.cs index 4a8f821..a25a84b 100644 --- a/BnbnavNetClient/Models/CalculatedRoute.cs +++ b/BnbnavNetClient/Models/CalculatedRoute.cs @@ -1,18 +1,21 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; using Avalonia; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Services; using BnbnavNetClient.Services.TextToSpeech; using ReactiveUI; using ReactiveUI.Fody.Helpers; +using Splat; namespace BnbnavNetClient.Models; -public class CalculatedRoute : ReactiveObject, IDisposable +public sealed class CalculatedRoute : ReactiveObject, IDisposable { readonly MapService _mapService; @@ -43,13 +46,14 @@ public enum InstructionTypes EnterRoundabout, LeaveRoundabout } - + + //TODO: Why are these here? public double TurnAngle => 0; public double? RoundaboutExitAngle => RoundaboutExit is not null ? From?.Line.AngleTo(RoundaboutExit.Line) : null; public string HumanReadableString(int distance) { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); return t["INSTRUCTION_DISTANCE_PROMPT", ("count", distance), ("instruction", InstructionString)]; } @@ -57,10 +61,10 @@ public string InstructionString { get { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); var args = new Dictionary(); if (To is not null) args["road"] = TargetRoadName; - if (RoundaboutExitNumber is not null) args["exit"] = RoundaboutExitNumber.ToString(); + if (RoundaboutExitNumber is not null) args["exit"] = RoundaboutExitNumber.Value.ToString(NumberFormatInfo.CurrentInfo); return InstructionType switch { @@ -90,7 +94,7 @@ public string InstructionString public string Speech(double distance, Instruction? thenInstruction) { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); var log = double.Log10(distance); var roundIncrements = (int) double.Pow(10, log) / 20; if (roundIncrements == 0) roundIncrements = 5; @@ -438,8 +442,8 @@ void UpdateCurrentVoicePrompt() if (!Mute) { - var tts = AvaloniaLocator.Current.GetRequiredService(); - tts.SpeakAsync(CurrentVoicePrompt.Instruction.Speech(BlocksToNextInstruction, + var tts = Locator.Current.GetService(); + tts?.SpeakAsync(CurrentVoicePrompt.Instruction.Speech(BlocksToNextInstruction, DisplayThenInstruction ? ThenInstruction : null)); } } diff --git a/BnbnavNetClient/Models/Landmark.cs b/BnbnavNetClient/Models/Landmark.cs index d0dbce6..a3d3c6e 100644 --- a/BnbnavNetClient/Models/Landmark.cs +++ b/BnbnavNetClient/Models/Landmark.cs @@ -1,9 +1,12 @@ using System; +using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using Avalonia; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Views; +using Splat; namespace BnbnavNetClient.Models; @@ -80,7 +83,7 @@ public static class LandmarkTypeExtensions public static string HumanReadableName(this LandmarkType type) { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); return type switch { LandmarkType.Unknown => "", @@ -120,7 +123,7 @@ public static string HumanReadableName(this LandmarkType type) public static string IconUrl(this LandmarkType type) => $"avares://BnbnavNetClient/Assets/Landmarks/{type.ServerName()}.svg"; public static bool IsLandmark(this LandmarkType type) => type != LandmarkType.Unknown && type != LandmarkType.InternalTemporary && !type.IsLabel(); - public static bool IsLabel(this LandmarkType type) => type.ServerName().StartsWith("label-"); + public static bool IsLabel(this LandmarkType type) => type.ServerName().StartsWith("label-", StringComparison.InvariantCulture); } public class Landmark : MapItem, ISearchable @@ -183,9 +186,10 @@ public TemporaryLandmark(string id, Node node, string name) : base(id, node, nam return null; } - var t = AvaloniaLocator.Current.GetRequiredService(); - var x = Convert.ToInt32(coordinateSearch.Groups["x"].Value); - var z = Convert.ToInt32(coordinateSearch.Groups["z"].Value); - return new TemporaryLandmark($"temp@{x},{z}", new TemporaryNode(x, 0, z, world), t["DROPPED_PIN", ("x", x.ToString()), ("z", z.ToString())]); + // TODO: are these actually supposed to be InvariantCulture? + var t = Locator.Current.GetI18Next(); + var x = int.Parse(coordinateSearch.Groups["x"].Value, CultureInfo.InvariantCulture); + var z = int.Parse(coordinateSearch.Groups["z"].Value, CultureInfo.InvariantCulture); + return new TemporaryLandmark($"temp@{x},{z}", new TemporaryNode(x, 0, z, world), t["DROPPED_PIN", ("x", x.ToString(CultureInfo.InvariantCulture)), ("z", z.ToString(CultureInfo.InvariantCulture))]); } } \ No newline at end of file diff --git a/BnbnavNetClient/Models/Player.cs b/BnbnavNetClient/Models/Player.cs index 284794d..4630f9e 100644 --- a/BnbnavNetClient/Models/Player.cs +++ b/BnbnavNetClient/Models/Player.cs @@ -6,8 +6,10 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Media; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Services; +using Splat; using Timer = System.Timers.Timer; namespace BnbnavNetClient.Models; @@ -24,7 +26,7 @@ public string HumanReadableType { get { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); return t["PLAYER"]; } } diff --git a/BnbnavNetClient/Models/Road.cs b/BnbnavNetClient/Models/Road.cs index e692512..6c57293 100644 --- a/BnbnavNetClient/Models/Road.cs +++ b/BnbnavNetClient/Models/Road.cs @@ -1,7 +1,9 @@ using System; using System.Threading.Tasks; using Avalonia; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; +using Splat; namespace BnbnavNetClient.Models; @@ -40,7 +42,7 @@ public static class RoadTypeExtensions public static string HumanReadableName(this RoadType type) { - var t = AvaloniaLocator.Current.GetRequiredService(); + var t = Locator.Current.GetI18Next(); return type switch { RoadType.Unknown => t["ROAD_TYPE_UNKNOWN"], diff --git a/BnbnavNetClient/Services/BnbnavWebsocketService.cs b/BnbnavNetClient/Services/BnbnavWebsocketService.cs index 64e1873..001ab81 100644 --- a/BnbnavNetClient/Services/BnbnavWebsocketService.cs +++ b/BnbnavNetClient/Services/BnbnavWebsocketService.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; using System.Net.WebSockets; using System.Runtime.CompilerServices; using System.Text.Json; @@ -10,7 +11,7 @@ namespace BnbnavNetClient.Services; -internal sealed class BnbnavWebsocketService +internal sealed class BnbnavWebsocketService : IDisposable { ClientWebSocket _ws = null!; @@ -28,7 +29,7 @@ public async Task ConnectAsync(CancellationToken ct) { "http" => Uri.UriSchemeWs, "https" => Uri.UriSchemeWss, - _ => throw new ArgumentException() + _ => throw new UnreachableException() }, Path = "ws" }; @@ -74,6 +75,10 @@ async Task> NextMessageAsync(CancellationToken ct) return writer.WrittenMemory; } + public void Dispose() + { + throw new NotImplementedException(); + } } [JsonPolymorphic(TypeDiscriminatorPropertyName = "type", IgnoreUnrecognizedTypeDiscriminators = true)] diff --git a/BnbnavNetClient/Services/EditControllers/DummyEditController.cs b/BnbnavNetClient/Services/EditControllers/DummyEditController.cs index a681c47..3d34274 100644 --- a/BnbnavNetClient/Services/EditControllers/DummyEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/DummyEditController.cs @@ -6,10 +6,10 @@ namespace BnbnavNetClient.Services.EditControllers; public class DummyEditController : EditController { - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs _) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { // Dummy - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/EditControllers/EditController.cs b/BnbnavNetClient/Services/EditControllers/EditController.cs index 0a3651b..bd9ec42 100644 --- a/BnbnavNetClient/Services/EditControllers/EditController.cs +++ b/BnbnavNetClient/Services/EditControllers/EditController.cs @@ -6,7 +6,7 @@ namespace BnbnavNetClient.Services.EditControllers; -public enum PointerPressedFlags +public enum PointerPressed { None = 0, DoNotPan = 1 @@ -14,7 +14,7 @@ public enum PointerPressedFlags public abstract class EditController { - public abstract PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args); + public abstract PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args); public abstract void PointerMoved(MapView mapView, PointerEventArgs args); public abstract void PointerReleased(MapView mapView, PointerReleasedEventArgs args); public abstract void Render(MapView mapView, DrawingContext context); diff --git a/BnbnavNetClient/Services/EditControllers/LandmarkEditController.cs b/BnbnavNetClient/Services/EditControllers/LandmarkEditController.cs index f55838e..22fb8f0 100644 --- a/BnbnavNetClient/Services/EditControllers/LandmarkEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/LandmarkEditController.cs @@ -18,12 +18,12 @@ public LandmarkEditController(MapEditorService mapEditorService) _mapEditorService = mapEditorService; } - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { var pointerPos = args.GetPosition(mapView); _initialPointerPosition = pointerPos; - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/EditControllers/NodeJoinEditController.cs b/BnbnavNetClient/Services/EditControllers/NodeJoinEditController.cs index b99eebf..4d49619 100644 --- a/BnbnavNetClient/Services/EditControllers/NodeJoinEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/NodeJoinEditController.cs @@ -42,7 +42,7 @@ bool AppendRoadGhost(Node node) } - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { var pointerPos = args.GetPosition(mapView); @@ -55,7 +55,7 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress // Attempt to join two nodes if (pointerNode is null) { - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } if (pointerNode == _firstNode) @@ -63,12 +63,12 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress _firstNode = null; _nodeSet = false; _roadGhosts.Clear(); - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } if (!AppendRoadGhost(pointerNode)) { - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } _firstNode = null; @@ -89,7 +89,7 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress }; } - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } if (pointerNode is not null) @@ -98,10 +98,10 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress _firstNode = pointerNode; _roadGhosts.Add(pointerNode); mapView.InvalidateVisual(); - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/EditControllers/NodeMoveEditController.cs b/BnbnavNetClient/Services/EditControllers/NodeMoveEditController.cs index 9fa8b94..f3c04ac 100644 --- a/BnbnavNetClient/Services/EditControllers/NodeMoveEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/NodeMoveEditController.cs @@ -18,7 +18,7 @@ public NodeMoveEditController(MapEditorService editorService) _editorService = editorService; } - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { var pointerPos = args.GetPosition(mapView); @@ -26,10 +26,10 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress { _movingNode = node; _movedNode = new Node("temp", node.X, node.Y, node.Z, node.World); - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/EditControllers/SelectEditController.cs b/BnbnavNetClient/Services/EditControllers/SelectEditController.cs index 9356a69..34c2de1 100644 --- a/BnbnavNetClient/Services/EditControllers/SelectEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/SelectEditController.cs @@ -18,12 +18,12 @@ public SelectEditController(MapEditorService mapEditorService) _mapEditorService = mapEditorService; } - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { var pointerPos = args.GetPosition(mapView); _initialPointerPosition = pointerPos; - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/EditControllers/SpliceEditController.cs b/BnbnavNetClient/Services/EditControllers/SpliceEditController.cs index 4cda3a9..0e47caa 100644 --- a/BnbnavNetClient/Services/EditControllers/SpliceEditController.cs +++ b/BnbnavNetClient/Services/EditControllers/SpliceEditController.cs @@ -23,9 +23,9 @@ public SpliceEditController(MapEditorService editorService) this._editorService = editorService; } - public override PointerPressedFlags PointerPressed(MapView mapView, PointerPressedEventArgs args) + public override PointerPressed PointerPressed(MapView mapView, PointerPressedEventArgs args) { - if (_editorService.MapService is null) return PointerPressedFlags.None; + if (_editorService.MapService is null) return EditControllers.PointerPressed.None; var pointerPos = args.GetPosition(mapView); @@ -40,10 +40,10 @@ public override PointerPressedFlags PointerPressed(MapView mapView, PointerPress { ItemsNotToRender.Add(opposite); } - return PointerPressedFlags.DoNotPan; + return EditControllers.PointerPressed.DoNotPan; } - return PointerPressedFlags.None; + return EditControllers.PointerPressed.None; } public override void PointerMoved(MapView mapView, PointerEventArgs args) diff --git a/BnbnavNetClient/Services/MapService.cs b/BnbnavNetClient/Services/MapService.cs index f3c38c4..416cd1f 100644 --- a/BnbnavNetClient/Services/MapService.cs +++ b/BnbnavNetClient/Services/MapService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Globalization; using System.IO; using System.Linq; using System.Net; @@ -15,10 +16,12 @@ using System.Threading; using System.Threading.Tasks; using Avalonia; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Services.NetworkOperations; using DynamicData.Binding; using ReactiveUI.Fody.Helpers; +using Splat; namespace BnbnavNetClient.Services; @@ -61,7 +64,7 @@ public enum RouteOptions DefaultRequestHeaders = { { "User-Agent", new ProductInfoHeaderValue("bnbnav-dotnet", "1.0").ToString() }, - { "X-Bnbnav-Api-Version", ServerApiVersion.ToString() } + { "X-Bnbnav-Api-Version", ServerApiVersion.ToString(CultureInfo.InvariantCulture) } } }; @@ -126,7 +129,7 @@ public static string? AuthenticationToken _players = new Dictionary(); Players = _players.AsReadOnly(); _websocketService = websocketService; - _i18N = AvaloniaLocator.Current.GetRequiredService(); + _i18N = Locator.Current.GetI18Next(); this.WhenAnyValue(x => x.LoggedInUsername).Subscribe(Observer.Create(_ => UpdateLoggedInPlayer())); @@ -143,10 +146,10 @@ void UpdateLoggedInPlayer() return; } - LoggedInPlayer = Players.TryGetValue(LoggedInUsername, out var player) ? player : null; + LoggedInPlayer = Players.GetValueOrDefault(LoggedInUsername); } - public Edge? OppositeEdge(Edge edge, IEnumerable list) + public static Edge? OppositeEdge(Edge edge, IEnumerable list) { var filter = list.Where(x => x.To == edge.From && x.From == edge.To).ToList(); try @@ -238,7 +241,7 @@ async Task HandleBadRequest(HttpResponseMessage resp) async Task HandleUnauthorizedResponse(string path, object? json) { var completionSource = new TaskCompletionSource(); - var showDialog = !PendingRequests.Any(); + var showDialog = PendingRequests.Count == 0; PendingRequests.Add((path, json, completionSource)); if (showDialog) @@ -375,7 +378,7 @@ IEnumerable GenerateTemporaryEdgesFromPointToEdge(Node point, Edge edge, b //Execute the shortest path algorithm to locate the shortest path between the starting node and the ending node var queue = new Dictionary { { startingNode, (startingNode, 0, null) } }; var backtrack = new List<(Node node, int distance, Edge? via)>(); - while (queue.Any()) + while (queue.Count != 0) { ct.ThrowIfCancellationRequested(); var processingNode = queue.MinBy(x => x.Value.distance).Value; @@ -428,7 +431,7 @@ public static async Task DownloadInitialMapAsync() using var jsonDom = JsonDocument.Parse(content); if (jsonDom is null) - throw new NullReferenceException(nameof(jsonDom)); + throw new InvalidOperationException("Error in JSON document."); //TODO: Gracefully fail if there is no such property - this might be a new server w/o landmarks, nodes, etc. @@ -502,8 +505,9 @@ async Task ProcessChangesAsync() { await foreach (var message in _websocketService.GetMessages(CancellationToken.None)) { - string id = message.Id!; - string type = ""; + var id = message.Id!; + var type = ""; + Player? value; switch (message) { case NodeCreated node: @@ -564,9 +568,9 @@ async Task ProcessChangesAsync() case PlayerMoved player: type = nameof(Players); - if (_players.ContainsKey(player.Id!)) + if (_players.TryGetValue(player.Id!, out value)) { - _players[player.Id!].HandlePlayerMovedEvent(player); + value.HandlePlayerMovedEvent(player); } else { @@ -583,9 +587,9 @@ async Task ProcessChangesAsync() break; case PlayerLeft player: type = nameof(Players); - if (_players.ContainsKey(player.Id!)) + if (_players.TryGetValue(player.Id!, out value)) { - _players[player.Id!].HandlePlayerGoneEvent(); + value.HandlePlayerGoneEvent(); _players.Remove(player.Id!); } UpdateWorlds(); diff --git a/BnbnavNetClient/Services/NetworkOperations/LandmarkUpdateOperation.cs b/BnbnavNetClient/Services/NetworkOperations/LandmarkUpdateOperation.cs index 2b89bb4..367accf 100644 --- a/BnbnavNetClient/Services/NetworkOperations/LandmarkUpdateOperation.cs +++ b/BnbnavNetClient/Services/NetworkOperations/LandmarkUpdateOperation.cs @@ -67,13 +67,13 @@ public override void Render(MapView mapView, DrawingContext context) if (_updateAs is not null) { var rect = _updateAs.BoundingRect(mapView); - using (context.PushOpacity(0.5, rect)) + using (context.PushOpacity(0.5)) mapView.DrawLandmark(context, _updateAs, rect); } else if (_toUpdate is not null) - { + { var rect = _toUpdate.BoundingRect(mapView); - using (context.PushOpacity(0.5, rect)) + using (context.PushOpacity(0.5)) mapView.DrawLandmark(context, _toUpdate, rect); } } diff --git a/BnbnavNetClient/Services/NetworkOperations/NodeDeleteOperation.cs b/BnbnavNetClient/Services/NetworkOperations/NodeDeleteOperation.cs index 99f3b1d..be23378 100644 --- a/BnbnavNetClient/Services/NetworkOperations/NodeDeleteOperation.cs +++ b/BnbnavNetClient/Services/NetworkOperations/NodeDeleteOperation.cs @@ -39,7 +39,7 @@ public override void Render(MapView mapView, DrawingContext context) var nodeBorder = (Pen)mapView.FindResource("NodeBorder")!; var nodeBrush = (Brush)mapView.FindResource("NodeFill")!; var rect = _node.BoundingRect(mapView); - using (context.PushOpacity(0.5, rect)) + using (context.PushOpacity(0.5)) context.DrawRectangle(nodeBrush, nodeBorder, rect); } } diff --git a/BnbnavNetClient/Services/NetworkOperations/RoadCreateOperation.cs b/BnbnavNetClient/Services/NetworkOperations/RoadCreateOperation.cs index 32b65d4..f4815bc 100644 --- a/BnbnavNetClient/Services/NetworkOperations/RoadCreateOperation.cs +++ b/BnbnavNetClient/Services/NetworkOperations/RoadCreateOperation.cs @@ -25,7 +25,14 @@ public RoadCreateOperation(MapEditorService editorService, string name, RoadType PendingRoad = new PendingRoad("", name, type.ServerName()); } - + + + static readonly JsonSerializerOptions RoadResponseSerializerOptions = + new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DictionaryKeyPolicy = JsonNamingPolicy.CamelCase + }; public override async Task PerformOperation() { try @@ -36,11 +43,7 @@ public override async Task PerformOperation() Type = _type.ServerName() })).AssertSuccess(); - var roadResponse = await JsonSerializer.DeserializeAsync(response.Stream, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase - }); + var roadResponse = await JsonSerializer.DeserializeAsync(response.Stream, RoadResponseSerializerOptions); PendingRoad.ProvideId(roadResponse!.Id); } catch (HttpRequestException e) @@ -63,7 +66,7 @@ public override void Render(MapView mapView, DrawingContext context) //No need to render anything for a road creation } - class RoadResponse + sealed class RoadResponse { public required string Id { get; set; } } diff --git a/BnbnavNetClient/Settings/AppBuilderExtensions.cs b/BnbnavNetClient/Settings/AppBuilderExtensions.cs index 8b0d33e..b285357 100644 --- a/BnbnavNetClient/Settings/AppBuilderExtensions.cs +++ b/BnbnavNetClient/Settings/AppBuilderExtensions.cs @@ -1,11 +1,12 @@ using Avalonia; +using Splat; namespace BnbnavNetClient.Settings; public static class AppBuilderExtensions { public static AppBuilder UseSettings(this AppBuilder appBuilder, ISettingsManager impl) { - appBuilder.With(impl); + Locator.CurrentMutable.RegisterConstant(impl); return appBuilder; } } diff --git a/BnbnavNetClient/ViewLocator.cs b/BnbnavNetClient/ViewLocator.cs index 90807e9..bc84c26 100644 --- a/BnbnavNetClient/ViewLocator.cs +++ b/BnbnavNetClient/ViewLocator.cs @@ -7,12 +7,12 @@ namespace BnbnavNetClient; public class ViewLocator : IDataTemplate { - public Control? Build(object? data) + public Control? Build(object? param) { - if (data is null) + if (param is null) return null; - var name = data.GetType().FullName!.Replace("ViewModel", "View"); + var name = param.GetType().FullName!.Replace("ViewModel", "View"); var type = Type.GetType(name); if (type != null) diff --git a/BnbnavNetClient/ViewModels/CornerViewModel.cs b/BnbnavNetClient/ViewModels/CornerViewModel.cs index 1e7e630..e3482e1 100644 --- a/BnbnavNetClient/ViewModels/CornerViewModel.cs +++ b/BnbnavNetClient/ViewModels/CornerViewModel.cs @@ -5,11 +5,13 @@ using System.Threading.Tasks; using Avalonia; using Avalonia.Threading; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Models; using BnbnavNetClient.Services; using ReactiveUI; using ReactiveUI.Fody.Helpers; +using Splat; namespace BnbnavNetClient.ViewModels; @@ -88,7 +90,7 @@ public CornerViewModel(MapService mapService, MainViewModel mainViewModel) { _mainViewModel = mainViewModel; MapService = mapService; - _i18N = AvaloniaLocator.Current.GetRequiredService(); + _i18N = Locator.Current.GetI18Next(); this.WhenAnyValue(x => x.CurrentUi).Subscribe(Observer.Create(_ => { diff --git a/BnbnavNetClient/ViewModels/LanguageSelectViewModel.cs b/BnbnavNetClient/ViewModels/LanguageSelectViewModel.cs index b0407e8..83d2ed0 100644 --- a/BnbnavNetClient/ViewModels/LanguageSelectViewModel.cs +++ b/BnbnavNetClient/ViewModels/LanguageSelectViewModel.cs @@ -8,7 +8,9 @@ using System.Linq; using System.Reactive; using System.Reactive.Linq; +using BnbnavNetClient.Extensions; using JetBrains.Annotations; +using Splat; namespace BnbnavNetClient.ViewModels; public sealed class LanguageSelectViewModel : ViewModel @@ -29,9 +31,9 @@ public sealed class LanguageSelectViewModel : ViewModel public LanguageSelectViewModel() { - var settings = AvaloniaLocator.Current.GetRequiredService(); + var settings = Locator.Current.GetSettingsManager(); var presentLanguage = new CultureInfo(settings.Settings.Language); - _tr = AvaloniaLocator.Current.GetRequiredService(); + _tr = Locator.Current.GetI18Next(); ChosenLanguage = new LanguageSelection(presentLanguage); Ok = ReactiveCommand.Create(() => ChosenLanguage.Info); this.WhenAnyValue(me => me.ChosenLanguage) diff --git a/BnbnavNetClient/ViewModels/MainViewModel.cs b/BnbnavNetClient/ViewModels/MainViewModel.cs index 9acd0c7..c6688c3 100644 --- a/BnbnavNetClient/ViewModels/MainViewModel.cs +++ b/BnbnavNetClient/ViewModels/MainViewModel.cs @@ -9,7 +9,9 @@ using BnbnavNetClient.I18Next.Services; using Avalonia; using Avalonia.Controls; +using BnbnavNetClient.Extensions; using BnbnavNetClient.Settings; +using Splat; namespace BnbnavNetClient.ViewModels; @@ -87,9 +89,10 @@ public sealed class MainViewModel : ViewModel public MainViewModel() { MapEditorService = new MapEditorService(); - - _settings = AvaloniaLocator.Current.GetRequiredService(); - _tr = AvaloniaLocator.Current.GetRequiredService(); + + //TODO: Splat has a source generator for this. use it + _settings = Locator.Current.GetSettingsManager(); + _tr = Locator.Current.GetI18Next(); var followMeText = this .WhenAnyValue(me => me.FollowMeEnabled, me => me.LoggedInUsername) .Select(x => x.Item1 ? _tr["FOLLOWING", ("user", x.Item2)] : _tr["FOLLOW_ME"]); @@ -215,7 +218,7 @@ Task ShowAuthenticationPopup() { EditModeToken = null; MapEditorService.EditModeEnabled = false; - cs.SetException(new Exception()); + cs.SetException(new OperationCanceledException()); Popup = null; }); Popup = editModePopup; diff --git a/BnbnavNetClient/ViewModels/NewEdgeFlyoutViewModel.cs b/BnbnavNetClient/ViewModels/NewEdgeFlyoutViewModel.cs index 873d0ed..ba592f8 100644 --- a/BnbnavNetClient/ViewModels/NewEdgeFlyoutViewModel.cs +++ b/BnbnavNetClient/ViewModels/NewEdgeFlyoutViewModel.cs @@ -100,6 +100,7 @@ public NewEdgeFlyoutViewModel(MapEditorService mapEditorService, List node })); } + //TODO: What is this doing here? public void ActivateRoadSyringe() { diff --git a/BnbnavNetClient/Views/MainView.axaml b/BnbnavNetClient/Views/MainView.axaml index 0921d82..a4dd452 100644 --- a/BnbnavNetClient/Views/MainView.axaml +++ b/BnbnavNetClient/Views/MainView.axaml @@ -24,9 +24,9 @@ - - - + + + diff --git a/BnbnavNetClient/Views/MainView.axaml.cs b/BnbnavNetClient/Views/MainView.axaml.cs index 8c97b72..1d1a3d5 100644 --- a/BnbnavNetClient/Views/MainView.axaml.cs +++ b/BnbnavNetClient/Views/MainView.axaml.cs @@ -4,9 +4,11 @@ using Avalonia.Media; using Avalonia.Styling; using Avalonia.Themes.Fluent; +using BnbnavNetClient.Extensions; using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Settings; using BnbnavNetClient.ViewModels; +using Splat; namespace BnbnavNetClient.Views; @@ -17,10 +19,10 @@ public partial class MainView : UserControl public MainView() { - FlowDirection = AvaloniaLocator.Current.GetRequiredService().IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + FlowDirection = Locator.Current.GetI18Next().IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; _whiteTextStyle = new Style(static x => x.OfType()); _whiteTextStyle.Setters.Add(new Setter(TextBlock.ForegroundProperty, new SolidColorBrush(Colors.White))); - _settings = AvaloniaLocator.Current.GetRequiredService(); + _settings = Locator.Current.GetSettingsManager(); InitializeComponent(); } @@ -57,9 +59,7 @@ public async void ColorModeSwitch(object? _, RoutedEventArgs? __) { Application.Current.Styles.Remove(_whiteTextStyle); } - - ((MapThemeResources)Application.Current.Resources.MergedDictionaries[0]).Theme = button.IsNightMode ? MapTheme.Night : MapTheme.Day; - + _settings.Settings.NightMode = button.IsNightMode; await _settings.SaveAsync(); } diff --git a/BnbnavNetClient/Views/MapView.axaml.cs b/BnbnavNetClient/Views/MapView.axaml.cs index bbdf0f6..2921b66 100644 --- a/BnbnavNetClient/Views/MapView.axaml.cs +++ b/BnbnavNetClient/Views/MapView.axaml.cs @@ -20,6 +20,7 @@ using BnbnavNetClient.I18Next.Services; using BnbnavNetClient.Services.EditControllers; using BnbnavNetClient.Services.NetworkOperations; +using Splat; namespace BnbnavNetClient.Views; @@ -40,7 +41,7 @@ public partial class MapView : UserControl public MapView() { - _i18N = AvaloniaLocator.Current.GetRequiredService(); + _i18N = Locator.Current.GetService()!; InitializeComponent(); } @@ -73,7 +74,7 @@ protected override void OnInitialized() if (MapViewModel.IsInEditMode) { var flags = MapViewModel.MapEditorService.EditController.PointerPressed(this, eventArgs); - _disablePan = flags.HasFlag(PointerPressedFlags.DoNotPan); + _disablePan = flags.HasFlag(Services.EditControllers.PointerPressed.DoNotPan); } else { @@ -185,24 +186,6 @@ protected override void OnInitialized() _pointerVelocities.Clear(); }; - // This is the physics part of inertial panning. - Clock = new Clock(); - Clock.Subscribe( - _ => - { - if (_pointerPressing) - return; - - // Stop the timer, don't waste resources. - if (double.Abs(_viewVelocity.X) < 4 && double.Abs(_viewVelocity.Y) < 4) - _viewVelocity = Vector.Zero; - else - MapViewModel.Pan += _viewVelocity / MapViewModel.Scale; - - _viewVelocity /= 1.075; // 1.075 is the friction. - } - ); - //why does this happen to me :sob: MapViewModel .WhenAnyValue(x => x.Pan, x => x.Scale, x => x.Rotation, x => x.RotationOrigin) @@ -327,7 +310,7 @@ void UpdateContextMenuItems() ToWorld(_currentPointerPosition).Deconstruct(out var xd, out var zd); var x = (int)xd; var z = (int)zd; - var landmark = new TemporaryLandmark($"temp@{x},{z}", new TemporaryNode(x, 0, z, MapViewModel.ChosenWorld), _i18N["DROPPED_PIN", ("x", x.ToString()), ("z", z.ToString())]); + var landmark = new TemporaryLandmark($"temp@{x},{z}", new TemporaryNode(x, 0, z, MapViewModel.ChosenWorld), _i18N["DROPPED_PIN", ("x", x.ToString(_i18N.CurrentLanguage.NumberFormat)), ("z", z.ToString(_i18N.CurrentLanguage.NumberFormat))]); MapViewModel.ContextMenuItems.AddRange(new MenuItem[] { @@ -479,7 +462,7 @@ public void DrawEdge(DrawingContext context, RoadType roadType, Point from, Poin } using (context.PushTransform(matrix)) - using (context.PushOpacity(drawGhost ? 0.5 : 1, new Rect(0, 0, length, 10))) + using (context.PushOpacity(drawGhost ? 0.5 : 1)) context.DrawLine(pen, new Point(0, 0), new Point(length, 0)); } @@ -493,7 +476,7 @@ public void DrawLandmark(DrawingContext context, Landmark landmark, Rect rect) { LandmarkType.City => (0.3, 1.15, 60), LandmarkType.Country => (0, 0.3, 120), - _ => throw new ArgumentOutOfRangeException() + _ => throw new ArgumentOutOfRangeException(paramName: nameof(landmark)) }; if (scale < lowerScaleBound || scale > higherScaleBound) return; @@ -543,7 +526,7 @@ public override void Render(DrawingContext context) { //Draw the arrow indicator var instruction = MapViewModel.MapService.CurrentRoute?.CurrentInstruction; - if (instruction is { From: { }, To: { } }) + if (instruction is { From: not null, To: not null }) { var pen = new Pen(new SolidColorBrush(new Color(255, 100, 50, 150)), PenForRoadType(RoadType.Local).Thickness, lineCap: PenLineCap.Round, lineJoin: PenLineJoin.Round); diff --git a/BnbnavNetClient/Views/NewEdgeFlyoutView.axaml b/BnbnavNetClient/Views/NewEdgeFlyoutView.axaml index 6734190..18afb00 100644 --- a/BnbnavNetClient/Views/NewEdgeFlyoutView.axaml +++ b/BnbnavNetClient/Views/NewEdgeFlyoutView.axaml @@ -38,7 +38,7 @@ - diff --git a/Directory.Build.props b/Directory.Build.props index e699076..b37fb29 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,6 +2,6 @@ enable enable - 11.0.0-preview8 + 11.0.7