From 925ac8712995ab7a823e25c1814dd99ae053ca5a Mon Sep 17 00:00:00 2001 From: maj00r Date: Sun, 4 Oct 2026 14:30:53 +0200 Subject: [PATCH] Add several copies from a vehicle's menu in the consist too The copies go right after the vehicle, a whole unit for one of a set. The count flyout is shared with the browser. --- StarterNG/Views/Depot.axaml.cs | 15 +++++++- StarterNG/Views/Depot/AddManyFlyout.cs | 47 +++++++++++++++++++++++++ StarterNG/Views/Depot/VehicleBrowser.cs | 37 ++----------------- StarterNG/Views/Depot/VehicleCards.cs | 9 +++++ 4 files changed, 72 insertions(+), 36 deletions(-) create mode 100644 StarterNG/Views/Depot/AddManyFlyout.cs diff --git a/StarterNG/Views/Depot.axaml.cs b/StarterNG/Views/Depot.axaml.cs index b061ee8..17fa29a 100644 --- a/StarterNG/Views/Depot.axaml.cs +++ b/StarterNG/Views/Depot.axaml.cs @@ -81,7 +81,10 @@ public partial class Depot : UserControl _consist, () => _browser.Selected, InsertTextureAt, _browser.SelectInBrowser); _cards = new VehicleCards(consistStack, _db, _consist, _cargo, _minis, _hand, - RebuildConsist, () => _details.Refresh(), _browser.SelectInBrowser, _drag.ArmCardDrag); + RebuildConsist, () => _details.Refresh(), _browser.SelectInBrowser, _drag.ArmCardDrag) + { + AddCopies = AddCopiesAfter + }; // Hidden still scrolls - it only drops the bar itself. MiniTextures.Sharp(miniPreview); @@ -594,6 +597,16 @@ public partial class Depot : UserControl InsertTexturesAt(texture, at, count); } + /// Copies of the vehicle on a card - a whole unit for one of a set - right after it. + private void AddCopiesAfter(ConsistItem item, int count) + { + int index = _consist.IndexOf(item); + if (index < 0 || item.Cars.Count == 0 || _db.TextureForSkin(item.Cars[0].SkinFile) is not { } texture) + return; + + InsertTexturesAt(texture, index + 1, count); + } + private void InsertTextureAt(VehicleTexture texture, int at) => InsertTexturesAt(texture, at, 1); /// The vehicle count times in a row from at - each staffed as added - and one redraw. diff --git a/StarterNG/Views/Depot/AddManyFlyout.cs b/StarterNG/Views/Depot/AddManyFlyout.cs new file mode 100644 index 0000000..991cc64 --- /dev/null +++ b/StarterNG/Views/Depot/AddManyFlyout.cs @@ -0,0 +1,47 @@ +using System; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Layout; +using Avalonia.Media; + +namespace StarterNG.Views; + +/// Asks how many times to add a vehicle, for the browser and the consist alike. +internal static class AddManyFlyout +{ + public const int Max = 100; + + public static void Show(Control anchor, PlacementMode placement, Action add) + { + var count = new NumericUpDown + { + Minimum = 1, Maximum = Max, Increment = 1, FormatString = "0", Value = 2, MinWidth = 120 + }; + var confirm = new Button { Content = App.Loc["AddVehicle"], HorizontalAlignment = HorizontalAlignment.Right }; + confirm.Classes.Add("Flat"); + confirm.Classes.Add("Accent"); + + var panel = new StackPanel { Spacing = 6, Margin = new Thickness(8), MinWidth = 160 }; + panel.Children.Add(new TextBlock { Text = App.Loc["AddManyCount"], FontWeight = FontWeight.Bold, FontSize = 12 }); + panel.Children.Add(count); + panel.Children.Add(confirm); + + var flyout = new Flyout { Content = panel, Placement = placement }; + void Commit() + { + flyout.Hide(); + add(Math.Clamp((int)(count.Value ?? 1), 1, Max)); + } + + confirm.Click += (_, _) => Commit(); + count.KeyDown += (_, e) => + { + if (e.Key != Key.Enter) return; + e.Handled = true; + Commit(); + }; + flyout.ShowAt(anchor); + count.Focus(); + } +} diff --git a/StarterNG/Views/Depot/VehicleBrowser.cs b/StarterNG/Views/Depot/VehicleBrowser.cs index 6a3930b..6bbada2 100644 --- a/StarterNG/Views/Depot/VehicleBrowser.cs +++ b/StarterNG/Views/Depot/VehicleBrowser.cs @@ -54,8 +54,6 @@ public sealed class VehicleBrowser /// Adds the vehicle to the consist the given number of times. public Action? AddMany { get; set; } - private const int MaxAddMany = 100; - private bool _suppress; private bool _syncingCombos; @@ -363,38 +361,6 @@ public sealed class VehicleBrowser } } - private void ShowAddManyFlyout(Control anchor, VehicleTexture texture) - { - var count = new NumericUpDown - { - Minimum = 1, Maximum = MaxAddMany, Increment = 1, FormatString = "0", Value = 2, MinWidth = 120 - }; - var add = new Button { Content = App.Loc["AddVehicle"], HorizontalAlignment = HorizontalAlignment.Right }; - add.Classes.Add("Flat"); - add.Classes.Add("Accent"); - - var panel = new StackPanel { Spacing = 6, Margin = new Thickness(8), MinWidth = 160 }; - panel.Children.Add(new TextBlock { Text = App.Loc["AddManyCount"], FontWeight = FontWeight.Bold, FontSize = 12 }); - panel.Children.Add(count); - panel.Children.Add(add); - - var flyout = new Flyout { Content = panel, Placement = PlacementMode.Right }; - void Commit() - { - flyout.Hide(); - AddMany?.Invoke(texture, Math.Clamp((int)(count.Value ?? 1), 1, MaxAddMany)); - } - add.Click += (_, _) => Commit(); - count.KeyDown += (_, e) => - { - if (e.Key != Key.Enter) return; - e.Handled = true; - Commit(); - }; - flyout.ShowAt(anchor); - count.Focus(); - } - private void List_OnContextRequested(object? sender, ContextRequestedEventArgs e) { var hit = e.Source as Control; @@ -413,7 +379,8 @@ public sealed class VehicleBrowser var menu = new ContextMenu(); var addMany = new MenuItem { Header = App.Loc["AddMany"], IsEnabled = AddMany is not null }; - addMany.Click += (_, _) => ShowAddManyFlyout(anchor, texture); + addMany.Click += (_, _) => + AddManyFlyout.Show(anchor, PlacementMode.Right, count => AddMany?.Invoke(texture, count)); menu.Items.Add(addMany); menu.Items.Add(new Separator()); diff --git a/StarterNG/Views/Depot/VehicleCards.cs b/StarterNG/Views/Depot/VehicleCards.cs index 00a2701..e3c03b9 100644 --- a/StarterNG/Views/Depot/VehicleCards.cs +++ b/StarterNG/Views/Depot/VehicleCards.cs @@ -33,6 +33,9 @@ public sealed class VehicleCards private readonly List<(Border Frame, ConsistItem Item, Dynamic Car)> _memberChrome = new(); + /// Puts copies of the vehicle on a card right after it, the given number of times. + public Action? AddCopies { get; set; } + private readonly List<(Button Badge, ConsistItem Item)> _driverChrome = new(); public Dynamic? PressedCar { get; set; } @@ -588,6 +591,12 @@ public sealed class VehicleCards { menu.Items.Clear(); + var addMany = new MenuItem { Header = App.Loc["AddMany"], IsEnabled = AddCopies is not null }; + addMany.Click += (_, _) => + AddManyFlyout.Show(anchor, PlacementMode.Top, count => AddCopies?.Invoke(item, count)); + menu.Items.Add(addMany); + menu.Items.Add(new Separator()); + var num = new MenuItem { Header = App.Loc["WagonNumber"] }; num.Click += (_, _) => ShowWagonNumberFlyout(anchor, item.Cars[0]); menu.Items.Add(num);