* Content - change the (should-be-obsolete) DisposeAllChildren into the more robust RemoveAllChildren. * Remove duplicate calls. --------- Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
302 lines
12 KiB
C#
302 lines
12 KiB
C#
using System.Linq;
|
|
using Content.Client.Cargo.Systems;
|
|
using Content.Client.UserInterface.Controls;
|
|
using Content.Shared.Cargo;
|
|
using Content.Shared.Cargo.Components;
|
|
using Content.Shared.Cargo.Prototypes;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
|
|
|
namespace Content.Client.Cargo.UI
|
|
{
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class CargoConsoleMenu : FancyWindow
|
|
{
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
|
|
private readonly IEntityManager _entityManager;
|
|
private readonly IPrototypeManager _protoManager;
|
|
private readonly CargoSystem _cargoSystem;
|
|
private readonly SpriteSystem _spriteSystem;
|
|
private EntityUid _owner;
|
|
private EntityUid? _station;
|
|
|
|
private readonly EntityQuery<CargoOrderConsoleComponent> _orderConsoleQuery;
|
|
private readonly EntityQuery<StationBankAccountComponent> _bankQuery;
|
|
|
|
public event Action<ButtonEventArgs>? OnItemSelected;
|
|
public event Action<ButtonEventArgs>? OnOrderApproved;
|
|
public event Action<ButtonEventArgs>? OnOrderCanceled;
|
|
|
|
public event Action<ProtoId<CargoAccountPrototype>?, int>? OnAccountAction;
|
|
|
|
public event Action<ButtonEventArgs>? OnToggleUnboundedLimit;
|
|
|
|
private readonly List<string> _categoryStrings = new();
|
|
private string? _category;
|
|
|
|
public List<ProtoId<CargoProductPrototype>> ProductCatalogue = new();
|
|
|
|
public CargoConsoleMenu(EntityUid owner, IEntityManager entMan, IPrototypeManager protoManager, SpriteSystem spriteSystem)
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
_entityManager = entMan;
|
|
_protoManager = protoManager;
|
|
_cargoSystem = entMan.System<CargoSystem>();
|
|
_spriteSystem = spriteSystem;
|
|
_owner = owner;
|
|
|
|
_orderConsoleQuery = _entityManager.GetEntityQuery<CargoOrderConsoleComponent>();
|
|
_bankQuery = _entityManager.GetEntityQuery<StationBankAccountComponent>();
|
|
|
|
Title = entMan.GetComponent<MetaDataComponent>(owner).EntityName;
|
|
|
|
SearchBar.OnTextChanged += OnSearchBarTextChanged;
|
|
Categories.OnItemSelected += OnCategoryItemSelected;
|
|
|
|
if (entMan.TryGetComponent<CargoOrderConsoleComponent>(owner, out var orderConsole))
|
|
{
|
|
var accountProto = _protoManager.Index(orderConsole.Account);
|
|
AccountNameLabel.Text = Loc.GetString("cargo-console-menu-account-name-format",
|
|
("color", accountProto.Color),
|
|
("name", Loc.GetString(accountProto.Name)),
|
|
("code", Loc.GetString(accountProto.Code)));
|
|
}
|
|
|
|
TabContainer.SetTabTitle(0, Loc.GetString("cargo-console-menu-tab-title-orders"));
|
|
TabContainer.SetTabTitle(1, Loc.GetString("cargo-console-menu-tab-title-funds"));
|
|
|
|
ActionOptions.OnItemSelected += idx =>
|
|
{
|
|
ActionOptions.SelectId(idx.Id);
|
|
};
|
|
|
|
TransferSpinBox.IsValid = val =>
|
|
{
|
|
if (!_entityManager.TryGetComponent<CargoOrderConsoleComponent>(owner, out var console) ||
|
|
!_entityManager.TryGetComponent<StationBankAccountComponent>(_station, out var bank))
|
|
return true;
|
|
|
|
return val >= 0 && val <= (int) (console.TransferLimit * bank.Accounts[console.Account]);
|
|
};
|
|
|
|
AccountActionButton.OnPressed += _ =>
|
|
{
|
|
var account = (ProtoId<CargoAccountPrototype>?) ActionOptions.SelectedMetadata;
|
|
OnAccountAction?.Invoke(account, TransferSpinBox.Value);
|
|
};
|
|
|
|
AccountLimitToggleButton.OnPressed += a =>
|
|
{
|
|
OnToggleUnboundedLimit?.Invoke(a);
|
|
};
|
|
}
|
|
|
|
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
SetCategoryText(args.Id);
|
|
PopulateProducts();
|
|
}
|
|
|
|
private void OnSearchBarTextChanged(LineEdit.LineEditEventArgs args)
|
|
{
|
|
PopulateProducts();
|
|
}
|
|
|
|
private void SetCategoryText(int id)
|
|
{
|
|
_category = id == 0 ? null : _categoryStrings[id];
|
|
Categories.SelectId(id);
|
|
}
|
|
|
|
private IEnumerable<CargoProductPrototype> ProductPrototypes
|
|
{
|
|
get
|
|
{
|
|
var allowedGroups = _entityManager.GetComponentOrNull<CargoOrderConsoleComponent>(_owner)?.AllowedGroups;
|
|
|
|
foreach (var cargoPrototypeId in ProductCatalogue)
|
|
{
|
|
var cargoPrototype = _protoManager.Index(cargoPrototypeId);
|
|
|
|
if (!allowedGroups?.Contains(cargoPrototype.Group) ?? false)
|
|
continue;
|
|
|
|
yield return cargoPrototype;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates the list of products that will actually be shown, using the current filters.
|
|
/// </summary>
|
|
public void PopulateProducts()
|
|
{
|
|
Products.RemoveAllChildren();
|
|
var products = ProductPrototypes.ToList();
|
|
products.Sort((x, y) =>
|
|
string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase));
|
|
|
|
var search = SearchBar.Text.Trim().ToLowerInvariant();
|
|
foreach (var prototype in products)
|
|
{
|
|
// if no search or category
|
|
// else if search
|
|
// else if category and not search
|
|
if (search.Length == 0 && _category == null ||
|
|
search.Length != 0 && prototype.Name.ToLowerInvariant().Contains(search) ||
|
|
search.Length != 0 && prototype.Description.ToLowerInvariant().Contains(search) ||
|
|
search.Length == 0 && _category != null && Loc.GetString(prototype.Category).Equals(_category))
|
|
{
|
|
var button = new CargoProductRow
|
|
{
|
|
Product = prototype,
|
|
ProductName = { Text = prototype.Name },
|
|
MainButton = { ToolTip = prototype.Description },
|
|
PointCost = { Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", prototype.Cost.ToString())) },
|
|
Icon = { Texture = _spriteSystem.Frame0(prototype.Icon) },
|
|
};
|
|
button.MainButton.OnPressed += args =>
|
|
{
|
|
OnItemSelected?.Invoke(args);
|
|
};
|
|
Products.AddChild(button);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates the list of products that will actually be shown, using the current filters.
|
|
/// </summary>
|
|
public void PopulateCategories()
|
|
{
|
|
_categoryStrings.Clear();
|
|
Categories.Clear();
|
|
|
|
foreach (var prototype in ProductPrototypes)
|
|
{
|
|
if (!_categoryStrings.Contains(Loc.GetString(prototype.Category)))
|
|
{
|
|
_categoryStrings.Add(Loc.GetString(prototype.Category));
|
|
}
|
|
}
|
|
|
|
_categoryStrings.Sort();
|
|
|
|
// Add "All" category at the top of the list
|
|
_categoryStrings.Insert(0, Loc.GetString("cargo-console-menu-populate-categories-all-text"));
|
|
|
|
foreach (var str in _categoryStrings)
|
|
{
|
|
Categories.AddItem(str);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates the list of orders and requests.
|
|
/// </summary>
|
|
public void PopulateOrders(IEnumerable<CargoOrderData> orders)
|
|
{
|
|
if (!_orderConsoleQuery.TryComp(_owner, out var orderConsole))
|
|
return;
|
|
|
|
Requests.RemoveAllChildren();
|
|
|
|
foreach (var order in orders)
|
|
{
|
|
if (order.Approved)
|
|
continue;
|
|
|
|
var product = _protoManager.Index<EntityPrototype>(order.ProductId);
|
|
var productName = product.Name;
|
|
var account = _protoManager.Index(order.Account);
|
|
|
|
var row = new CargoOrderRow
|
|
{
|
|
Order = order,
|
|
Icon = { Texture = _spriteSystem.Frame0(product) },
|
|
ProductName =
|
|
{
|
|
Text = Loc.GetString(
|
|
"cargo-console-menu-populate-orders-cargo-order-row-product-name-text",
|
|
("productName", productName),
|
|
("orderAmount", order.OrderQuantity),
|
|
("orderRequester", order.Requester),
|
|
("accountColor", account.Color),
|
|
("account", Loc.GetString(account.Code)))
|
|
},
|
|
Description =
|
|
{
|
|
Text = Loc.GetString("cargo-console-menu-order-reason-description",
|
|
("reason", order.Reason))
|
|
}
|
|
};
|
|
row.Cancel.OnPressed += (args) => { OnOrderCanceled?.Invoke(args); };
|
|
|
|
// TODO: Disable based on access.
|
|
row.SetApproveVisible(orderConsole.Mode != CargoOrderConsoleMode.SendToPrimary);
|
|
row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
|
|
Requests.AddChild(row);
|
|
}
|
|
}
|
|
|
|
public void PopulateAccountActions()
|
|
{
|
|
if (!_entityManager.TryGetComponent<StationBankAccountComponent>(_station, out var bank) ||
|
|
!_entityManager.TryGetComponent<CargoOrderConsoleComponent>(_owner, out var console))
|
|
return;
|
|
|
|
var i = 0;
|
|
ActionOptions.Clear();
|
|
ActionOptions.AddItem(Loc.GetString("cargo-console-menu-account-action-option-withdraw"), i);
|
|
i++;
|
|
foreach (var account in bank.Accounts.Keys)
|
|
{
|
|
if (account == console.Account)
|
|
continue;
|
|
var accountProto = _protoManager.Index(account);
|
|
ActionOptions.AddItem(Loc.GetString("cargo-console-menu-account-action-option-transfer",
|
|
("code", Loc.GetString(accountProto.Code))),
|
|
i);
|
|
ActionOptions.SetItemMetadata(i, account);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
public void UpdateStation(EntityUid station)
|
|
{
|
|
_station = station;
|
|
}
|
|
|
|
protected override void FrameUpdate(FrameEventArgs args)
|
|
{
|
|
base.FrameUpdate(args);
|
|
|
|
if (!_bankQuery.TryComp(_station, out var bankAccount) ||
|
|
!_orderConsoleQuery.TryComp(_owner, out var orderConsole))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var balance = _cargoSystem.GetBalanceFromAccount((_station.Value, bankAccount), orderConsole.Account);
|
|
PointsLabel.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", balance));
|
|
TransferLimitLabel.Text = Loc.GetString("cargo-console-menu-account-action-transfer-limit",
|
|
("limit", (int) (balance * orderConsole.TransferLimit)));
|
|
|
|
UnlimitedNotifier.Visible = orderConsole.TransferUnbounded;
|
|
AccountActionButton.Disabled = TransferSpinBox.Value <= 0 ||
|
|
TransferSpinBox.Value > bankAccount.Accounts[orderConsole.Account] * orderConsole.TransferLimit ||
|
|
_timing.CurTime < orderConsole.NextAccountActionTime;
|
|
|
|
OrdersSpacer.Visible = orderConsole.Mode != CargoOrderConsoleMode.PrintSlip;
|
|
Orders.Visible = orderConsole.Mode != CargoOrderConsoleMode.PrintSlip;
|
|
}
|
|
}
|
|
}
|