Files
crystall-punk-14/Content.Client/_CP14/Workplace/CP14WorkplaceWindow.xaml.cs
2025-05-22 21:39:36 +03:00

202 lines
6.2 KiB
C#

using Content.Shared._CP14.Workplace;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client._CP14.Workplace;
[GenerateTypedNameReferences]
public sealed partial class CP14WorkplaceWindow : DefaultWindow
{
private const int AllCategoryId = -1;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ILogManager _log = default!;
[Dependency] private readonly IEntityManager _e = default!;
private readonly CP14ClientWorkplaceSystem _workplace = default!;
public event Action<CP14WorkplaceRecipeEntry>? OnCraft;
private readonly Dictionary<int, LocId> _categories = new();
private CP14WorkplaceState? _cachedState;
private EntityUid? user;
private EntityUid? workplace;
private CP14WorkplaceRecipeEntry? _selectedEntry;
private string _searchFilter = string.Empty;
private ISawmill Sawmill { get; init; }
public CP14WorkplaceWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_workplace = _e.System<CP14ClientWorkplaceSystem>();
Sawmill = _log.GetSawmill("cp14_workplace_window");
SearchBar.OnTextChanged += OnSearchChanged;
CraftButton.OnPressed += OnCraftPressed;
OptionCategories.OnItemSelected += OnCategoryItemSelected;
}
public void UpdateRecipesVisibility()
{
if (_cachedState is null)
return;
CraftsContainer.RemoveAllChildren();
var recipes = new List<CP14WorkplaceRecipeEntry>();
foreach (var entry in _cachedState.Recipes)
{
if (!_prototype.TryIndex(entry.Recipe, out var indexedEntry))
{
Sawmill.Error($"No recipe prototype {entry.Recipe} retrieved from cache found");
continue;
}
if (!ProcessSearchFilter(indexedEntry))
continue;
if (!ProcessSearchCategoryFilter(indexedEntry))
continue;
recipes.Add(entry);
}
foreach (var recipe in recipes)
{
var control = new CP14WorkplaceRecipeControl(recipe);
control.OnSelect += RecipeSelect;
CraftsContainer.AddChild(control);
}
if (_selectedEntry is not null && !recipes.Contains(_selectedEntry.Value))
RecipeSelectNull();
}
public void UpdateState(CP14WorkplaceState state)
{
_cachedState = state;
user = _e.GetEntity(state.User);
workplace = _e.GetEntity(state.Workplace);
_categories.Clear();
OptionCategories.Clear();
OptionCategories.AddItem(Loc.GetString("cp14-recipe-category-all"), AllCategoryId);
//Categories update
var categories = new List<LocId>();
var count = 0;
foreach (var recipe in state.Recipes)
{
if (!_prototype.TryIndex(recipe.Recipe, out var indexedRecipe))
continue;
if(!indexedRecipe.Components.TryGetComponent(CP14WorkplaceRecipeComponent.CompName, out var compData) || compData is not CP14WorkplaceRecipeComponent recipeComp)
continue;
if (recipeComp.Category is null)
continue;
if (categories.Contains(recipeComp.Category.Value))
continue;
categories.Add(recipeComp.Category.Value);
}
categories.Sort((a, b) => string.Compare(Loc.GetString(a), Loc.GetString(b), StringComparison.Ordinal));
foreach (var category in categories)
{
OptionCategories.AddItem(Loc.GetString(category), count);
_categories.Add(count, category);
count++;
}
UpdateRecipesVisibility();
}
private void OnSearchChanged(LineEdit.LineEditEventArgs _)
{
_searchFilter = SearchBar.Text.Trim().ToLowerInvariant();
UpdateRecipesVisibility();
}
private bool ProcessSearchFilter(EntityPrototype indexedEntry)
{
if (_searchFilter == string.Empty)
return true;
return indexedEntry.Name.Contains(_searchFilter);
}
private bool ProcessSearchCategoryFilter(EntityPrototype indexedEntry)
{
// If we are searching through all categories, we simply skip the current filter
if (OptionCategories.SelectedId == AllCategoryId)
return true;
if (!_categories.TryGetValue(OptionCategories.SelectedId, out var selectedCategory))
{
Sawmill.Error($"Non-existent {OptionCategories.SelectedId} category id selected. Filter skipped");
return true;
}
if (!indexedEntry.Components.TryGetValue(CP14WorkplaceRecipeComponent.CompName, out var compData) || compData.Component is not CP14WorkplaceRecipeComponent recipeComp)
return false;
if (recipeComp.Category is null)
return false;
return recipeComp.Category == selectedCategory;
}
private void OnCraftPressed(BaseButton.ButtonEventArgs _)
{
if (_selectedEntry is null)
return;
OnCraft?.Invoke(_selectedEntry.Value);
}
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs obj)
{
OptionCategories.SelectId(obj.Id);
UpdateRecipesVisibility();
}
private void RecipeSelect(CP14WorkplaceRecipeEntry entry, EntityPrototype recipe)
{
_selectedEntry = entry;
ItemView.SetPrototype(recipe);
ItemName.Text = recipe.Name;
ItemDescription.Text = recipe.Description;
ItemRequirements.RemoveAllChildren();
//foreach (var requirement in recipe.Requirements)
//{
// ItemRequirements.AddChild(new CP14WorkbenchRequirementControl(requirement));
//}
CraftButton.Disabled = _workplace.CheckCraftable(entry.Recipe, workplace, user);
}
private void RecipeSelectNull()
{
_selectedEntry = null;
ItemView.SetPrototype(null);
ItemName.Text = string.Empty;
ItemDescription.Text = string.Empty;
ItemRequirements.RemoveAllChildren();
CraftButton.Disabled = true;
}
}