Favorites tab for the construction menu (#26347)
* Added fovarite button * Some fixes in xaml * added some events for favorite recipes * set methods for presenter * fixes for presenter * added translates * reset seach when you select any category * added some margins * some fixes from compared * fixed PR notes about arrays * deleted controls & margins * did simpleer with arrays * review --------- Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -1,29 +1,33 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4" Margin="0 0 5 0">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 5">
|
||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
|
||||
<OptionButton Name="Category" Access="Public" MinSize="130 0"/>
|
||||
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
|
||||
</BoxContainer>
|
||||
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<Control MinSize="10 0"/>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
|
||||
<Button Name="FavoriteButton" Visible="false" HorizontalExpand="False"
|
||||
HorizontalAlignment="Right" Margin="0 0 0 15"/>
|
||||
<Control>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
|
||||
<BoxContainer Orientation="Horizontal" Align="Center">
|
||||
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep"/>
|
||||
<Control MinSize="10 0"/>
|
||||
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep" Margin="0 0 10 0"/>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<RichTextLabel Name="TargetName"/>
|
||||
<RichTextLabel Name="TargetDesc"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
<ItemList Name="RecipeStepList" Access="Public" VerticalExpand="True"/>
|
||||
<ItemList Name="RecipeStepList" Access="Public" VerticalExpand="True" Margin="0 0 0 5"/>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Button Name="BuildButton" Disabled="True" ToggleMode="True" VerticalExpand="True" SizeFlagsStretchRatio="0.5"/>
|
||||
<Button Name="BuildButton" Disabled="True" ToggleMode="True"
|
||||
VerticalExpand="True" SizeFlagsStretchRatio="0.5"/>
|
||||
<BoxContainer Orientation="Horizontal" VerticalExpand="True" SizeFlagsStretchRatio="0.5">
|
||||
<Button Name="EraseButton" ToggleMode="True" HorizontalExpand="True" SizeFlagsStretchRatio="0.7"/>
|
||||
<Button Name="EraseButton" ToggleMode="True"
|
||||
HorizontalExpand="True" SizeFlagsStretchRatio="0.7"/>
|
||||
<Button Name="ClearButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Content.Client.Construction.UI
|
||||
// It isn't optimal to expose UI controls like this, but the UI control design is
|
||||
// questionable so it can't be helped.
|
||||
string[] Categories { get; set; }
|
||||
OptionButton Category { get; }
|
||||
OptionButton OptionCategories { get; }
|
||||
|
||||
bool EraseButtonPressed { get; set; }
|
||||
bool BuildButtonPressed { get; set; }
|
||||
@@ -32,12 +32,13 @@ namespace Content.Client.Construction.UI
|
||||
|
||||
event EventHandler<(string search, string catagory)> PopulateRecipes;
|
||||
event EventHandler<ItemList.Item?> RecipeSelected;
|
||||
event EventHandler RecipeFavorited;
|
||||
event EventHandler<bool> BuildButtonToggled;
|
||||
event EventHandler<bool> EraseButtonToggled;
|
||||
event EventHandler ClearAllGhosts;
|
||||
|
||||
void ClearRecipeInfo();
|
||||
void SetRecipeInfo(string name, string description, Texture iconTexture, bool isItem);
|
||||
void SetRecipeInfo(string name, string description, Texture iconTexture, bool isItem, bool isFavorite);
|
||||
void ResetPlacement();
|
||||
|
||||
#region Window Control
|
||||
@@ -84,10 +85,12 @@ namespace Content.Client.Construction.UI
|
||||
Recipes.OnItemSelected += obj => RecipeSelected?.Invoke(this, obj.ItemList[obj.ItemIndex]);
|
||||
Recipes.OnItemDeselected += _ => RecipeSelected?.Invoke(this, null);
|
||||
|
||||
SearchBar.OnTextChanged += _ => PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[Category.SelectedId]));
|
||||
Category.OnItemSelected += obj =>
|
||||
SearchBar.OnTextChanged += _ =>
|
||||
PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[OptionCategories.SelectedId]));
|
||||
OptionCategories.OnItemSelected += obj =>
|
||||
{
|
||||
Category.SelectId(obj.Id);
|
||||
OptionCategories.SelectId(obj.Id);
|
||||
SearchBar.SetText(string.Empty);
|
||||
PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[obj.Id]));
|
||||
};
|
||||
|
||||
@@ -97,12 +100,14 @@ namespace Content.Client.Construction.UI
|
||||
ClearButton.OnPressed += _ => ClearAllGhosts?.Invoke(this, EventArgs.Empty);
|
||||
EraseButton.Text = Loc.GetString("construction-menu-eraser-mode");
|
||||
EraseButton.OnToggled += args => EraseButtonToggled?.Invoke(this, args.Pressed);
|
||||
|
||||
FavoriteButton.OnPressed += args => RecipeFavorited?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler? ClearAllGhosts;
|
||||
|
||||
public event EventHandler<(string search, string catagory)>? PopulateRecipes;
|
||||
public event EventHandler<ItemList.Item?>? RecipeSelected;
|
||||
public event EventHandler? RecipeFavorited;
|
||||
public event EventHandler<bool>? BuildButtonToggled;
|
||||
public event EventHandler<bool>? EraseButtonToggled;
|
||||
|
||||
@@ -112,13 +117,17 @@ namespace Content.Client.Construction.UI
|
||||
EraseButton.Pressed = false;
|
||||
}
|
||||
|
||||
public void SetRecipeInfo(string name, string description, Texture iconTexture, bool isItem)
|
||||
public void SetRecipeInfo(
|
||||
string name, string description, Texture iconTexture, bool isItem, bool isFavorite)
|
||||
{
|
||||
BuildButton.Disabled = false;
|
||||
BuildButton.Text = Loc.GetString(isItem ? "construction-menu-place-ghost" : "construction-menu-craft");
|
||||
TargetName.SetMessage(name);
|
||||
TargetDesc.SetMessage(description);
|
||||
TargetTexture.Texture = iconTexture;
|
||||
FavoriteButton.Visible = true;
|
||||
FavoriteButton.Text = Loc.GetString(
|
||||
isFavorite ? "construction-add-favorite-button" : "construction-remove-from-favorite-button");
|
||||
}
|
||||
|
||||
public void ClearRecipeInfo()
|
||||
@@ -127,6 +136,7 @@ namespace Content.Client.Construction.UI
|
||||
TargetName.SetMessage(string.Empty);
|
||||
TargetDesc.SetMessage(string.Empty);
|
||||
TargetTexture.Texture = null;
|
||||
FavoriteButton.Visible = false;
|
||||
RecipeStepList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,10 @@ namespace Content.Client.Construction.UI
|
||||
|
||||
private ConstructionSystem? _constructionSystem;
|
||||
private ConstructionPrototype? _selected;
|
||||
|
||||
private List<ConstructionPrototype> _favoritedRecipes = [];
|
||||
private string _selectedCategory = string.Empty;
|
||||
private string _favoriteCatName = "construction-category-favorites";
|
||||
private string _forAllCategoryName = "construction-category-all";
|
||||
private bool CraftingAvailable
|
||||
{
|
||||
get => _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Visible;
|
||||
@@ -65,7 +68,7 @@ namespace Content.Client.Construction.UI
|
||||
else
|
||||
_constructionView.OpenCentered();
|
||||
|
||||
if(_selected != null)
|
||||
if (_selected != null)
|
||||
PopulateInfo(_selected);
|
||||
}
|
||||
else
|
||||
@@ -105,9 +108,10 @@ namespace Content.Client.Construction.UI
|
||||
_constructionView.EraseButtonPressed = b;
|
||||
};
|
||||
|
||||
_constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();
|
||||
|
||||
PopulateCategories();
|
||||
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
||||
|
||||
}
|
||||
|
||||
public void OnHudCraftingButtonToggled(ButtonToggledEventArgs args)
|
||||
@@ -154,6 +158,13 @@ namespace Content.Client.Construction.UI
|
||||
recipesList.Clear();
|
||||
var recipes = new List<ConstructionPrototype>();
|
||||
|
||||
var isEmptyCategory = string.IsNullOrEmpty(category) || category == _forAllCategoryName;
|
||||
|
||||
if (isEmptyCategory)
|
||||
_selectedCategory = string.Empty;
|
||||
else
|
||||
_selectedCategory = category;
|
||||
|
||||
foreach (var recipe in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||
{
|
||||
if (recipe.Hide)
|
||||
@@ -170,11 +181,20 @@ namespace Content.Client.Construction.UI
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(category) && category != "construction-category-all")
|
||||
if (!isEmptyCategory)
|
||||
{
|
||||
if (category == _favoriteCatName)
|
||||
{
|
||||
if (!_favoritedRecipes.Contains(recipe))
|
||||
{
|
||||
if (recipe.Category != category)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (recipe.Category != category)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
recipes.Add(recipe);
|
||||
}
|
||||
@@ -189,13 +209,10 @@ namespace Content.Client.Construction.UI
|
||||
// There is apparently no way to set which
|
||||
}
|
||||
|
||||
private void PopulateCategories()
|
||||
private void PopulateCategories(string? selectCategory = null)
|
||||
{
|
||||
var uniqueCategories = new HashSet<string>();
|
||||
|
||||
// hard-coded to show all recipes
|
||||
uniqueCategories.Add("construction-category-all");
|
||||
|
||||
foreach (var prototype in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||
{
|
||||
var category = prototype.Category;
|
||||
@@ -204,25 +221,49 @@ namespace Content.Client.Construction.UI
|
||||
uniqueCategories.Add(category);
|
||||
}
|
||||
|
||||
_constructionView.Category.Clear();
|
||||
var isFavorites = _favoritedRecipes.Count > 0;
|
||||
var categoriesArray = new string[isFavorites ? uniqueCategories.Count + 2 : uniqueCategories.Count + 1];
|
||||
|
||||
var array = uniqueCategories.OrderBy(Loc.GetString).ToArray();
|
||||
Array.Sort(array);
|
||||
// hard-coded to show all recipes
|
||||
var idx = 0;
|
||||
categoriesArray[idx++] = _forAllCategoryName;
|
||||
|
||||
for (var i = 0; i < array.Length; i++)
|
||||
// hard-coded to show favorites if it need
|
||||
if (isFavorites)
|
||||
{
|
||||
var category = array[i];
|
||||
_constructionView.Category.AddItem(Loc.GetString(category), i);
|
||||
categoriesArray[idx++] = _favoriteCatName;
|
||||
}
|
||||
|
||||
_constructionView.Categories = array;
|
||||
var sortedProtoCategories = uniqueCategories.OrderBy(Loc.GetString);
|
||||
|
||||
foreach (var cat in sortedProtoCategories)
|
||||
{
|
||||
categoriesArray[idx++] = cat;
|
||||
}
|
||||
|
||||
_constructionView.OptionCategories.Clear();
|
||||
|
||||
for (var i = 0; i < categoriesArray.Length; i++)
|
||||
{
|
||||
_constructionView.OptionCategories.AddItem(Loc.GetString(categoriesArray[i]), i);
|
||||
|
||||
if (!string.IsNullOrEmpty(selectCategory) && selectCategory == categoriesArray[i])
|
||||
_constructionView.OptionCategories.SelectId(i);
|
||||
|
||||
}
|
||||
|
||||
_constructionView.Categories = categoriesArray;
|
||||
}
|
||||
|
||||
private void PopulateInfo(ConstructionPrototype prototype)
|
||||
{
|
||||
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
|
||||
_constructionView.ClearRecipeInfo();
|
||||
_constructionView.SetRecipeInfo(prototype.Name, prototype.Description, spriteSys.Frame0(prototype.Icon), prototype.Type != ConstructionType.Item);
|
||||
|
||||
_constructionView.SetRecipeInfo(
|
||||
prototype.Name, prototype.Description, spriteSys.Frame0(prototype.Icon),
|
||||
prototype.Type != ConstructionType.Item,
|
||||
!_favoritedRecipes.Contains(prototype));
|
||||
|
||||
var stepList = _constructionView.RecipeStepList;
|
||||
GenerateStepList(prototype, stepList);
|
||||
@@ -240,7 +281,7 @@ namespace Content.Client.Construction.UI
|
||||
var text = entry.Arguments != null
|
||||
? Loc.GetString(entry.Localization, entry.Arguments) : Loc.GetString(entry.Localization);
|
||||
|
||||
if (entry.EntryNumber is {} number)
|
||||
if (entry.EntryNumber is { } number)
|
||||
{
|
||||
text = Loc.GetString("construction-presenter-step-wrapper",
|
||||
("step-number", number), ("text", text));
|
||||
@@ -332,6 +373,26 @@ namespace Content.Client.Construction.UI
|
||||
if (args.System is ConstructionSystem) SystemBindingChanged(null);
|
||||
}
|
||||
|
||||
private void OnViewFavoriteRecipe()
|
||||
{
|
||||
if (_selected is not ConstructionPrototype recipe)
|
||||
return;
|
||||
|
||||
if (!_favoritedRecipes.Remove(_selected))
|
||||
_favoritedRecipes.Add(_selected);
|
||||
|
||||
if (_selectedCategory == _favoriteCatName)
|
||||
{
|
||||
if (_favoritedRecipes.Count > 0)
|
||||
OnViewPopulateRecipes(_constructionView, (string.Empty, _favoriteCatName));
|
||||
else
|
||||
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
PopulateInfo(_selected);
|
||||
PopulateCategories(_selectedCategory);
|
||||
}
|
||||
|
||||
private void SystemBindingChanged(ConstructionSystem? newSystem)
|
||||
{
|
||||
if (newSystem is null)
|
||||
|
||||
@@ -10,3 +10,6 @@ construction-category-tiles = Tiles
|
||||
construction-category-utilities = Utilities
|
||||
construction-category-misc = Misc
|
||||
construction-category-clothing = Clothing
|
||||
construction-category-favorites = Favorites
|
||||
construction-add-favorite-button = Add to favorites
|
||||
construction-remove-from-favorite-button = Remove from favorites
|
||||
|
||||
Reference in New Issue
Block a user