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">
|
<DefaultWindow xmlns="https://spacestation14.io">
|
||||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4" Margin="0 0 5 0">
|
||||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 5">
|
||||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
|
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
|
||||||
<OptionButton Name="Category" Access="Public" MinSize="130 0"/>
|
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/>
|
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<Control MinSize="10 0"/>
|
|
||||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
|
||||||
|
<Button Name="FavoriteButton" Visible="false" HorizontalExpand="False"
|
||||||
|
HorizontalAlignment="Right" Margin="0 0 0 15"/>
|
||||||
<Control>
|
<Control>
|
||||||
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
|
||||||
<BoxContainer Orientation="Horizontal" Align="Center">
|
<BoxContainer Orientation="Horizontal" Align="Center">
|
||||||
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep"/>
|
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep" Margin="0 0 10 0"/>
|
||||||
<Control MinSize="10 0"/>
|
|
||||||
<BoxContainer Orientation="Vertical">
|
<BoxContainer Orientation="Vertical">
|
||||||
<RichTextLabel Name="TargetName"/>
|
<RichTextLabel Name="TargetName"/>
|
||||||
<RichTextLabel Name="TargetDesc"/>
|
<RichTextLabel Name="TargetDesc"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
|
</BoxContainer>
|
||||||
</Control>
|
</Control>
|
||||||
<ItemList Name="RecipeStepList" Access="Public" VerticalExpand="True"/>
|
<ItemList Name="RecipeStepList" Access="Public" VerticalExpand="True" Margin="0 0 0 5"/>
|
||||||
<BoxContainer Orientation="Vertical">
|
<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">
|
<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"/>
|
<Button Name="ClearButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</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
|
// It isn't optimal to expose UI controls like this, but the UI control design is
|
||||||
// questionable so it can't be helped.
|
// questionable so it can't be helped.
|
||||||
string[] Categories { get; set; }
|
string[] Categories { get; set; }
|
||||||
OptionButton Category { get; }
|
OptionButton OptionCategories { get; }
|
||||||
|
|
||||||
bool EraseButtonPressed { get; set; }
|
bool EraseButtonPressed { get; set; }
|
||||||
bool BuildButtonPressed { get; set; }
|
bool BuildButtonPressed { get; set; }
|
||||||
@@ -32,12 +32,13 @@ namespace Content.Client.Construction.UI
|
|||||||
|
|
||||||
event EventHandler<(string search, string catagory)> PopulateRecipes;
|
event EventHandler<(string search, string catagory)> PopulateRecipes;
|
||||||
event EventHandler<ItemList.Item?> RecipeSelected;
|
event EventHandler<ItemList.Item?> RecipeSelected;
|
||||||
|
event EventHandler RecipeFavorited;
|
||||||
event EventHandler<bool> BuildButtonToggled;
|
event EventHandler<bool> BuildButtonToggled;
|
||||||
event EventHandler<bool> EraseButtonToggled;
|
event EventHandler<bool> EraseButtonToggled;
|
||||||
event EventHandler ClearAllGhosts;
|
event EventHandler ClearAllGhosts;
|
||||||
|
|
||||||
void ClearRecipeInfo();
|
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();
|
void ResetPlacement();
|
||||||
|
|
||||||
#region Window Control
|
#region Window Control
|
||||||
@@ -84,10 +85,12 @@ namespace Content.Client.Construction.UI
|
|||||||
Recipes.OnItemSelected += obj => RecipeSelected?.Invoke(this, obj.ItemList[obj.ItemIndex]);
|
Recipes.OnItemSelected += obj => RecipeSelected?.Invoke(this, obj.ItemList[obj.ItemIndex]);
|
||||||
Recipes.OnItemDeselected += _ => RecipeSelected?.Invoke(this, null);
|
Recipes.OnItemDeselected += _ => RecipeSelected?.Invoke(this, null);
|
||||||
|
|
||||||
SearchBar.OnTextChanged += _ => PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[Category.SelectedId]));
|
SearchBar.OnTextChanged += _ =>
|
||||||
Category.OnItemSelected += obj =>
|
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]));
|
PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[obj.Id]));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,12 +100,14 @@ namespace Content.Client.Construction.UI
|
|||||||
ClearButton.OnPressed += _ => ClearAllGhosts?.Invoke(this, EventArgs.Empty);
|
ClearButton.OnPressed += _ => ClearAllGhosts?.Invoke(this, EventArgs.Empty);
|
||||||
EraseButton.Text = Loc.GetString("construction-menu-eraser-mode");
|
EraseButton.Text = Loc.GetString("construction-menu-eraser-mode");
|
||||||
EraseButton.OnToggled += args => EraseButtonToggled?.Invoke(this, args.Pressed);
|
EraseButton.OnToggled += args => EraseButtonToggled?.Invoke(this, args.Pressed);
|
||||||
|
|
||||||
|
FavoriteButton.OnPressed += args => RecipeFavorited?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler? ClearAllGhosts;
|
public event EventHandler? ClearAllGhosts;
|
||||||
|
|
||||||
public event EventHandler<(string search, string catagory)>? PopulateRecipes;
|
public event EventHandler<(string search, string catagory)>? PopulateRecipes;
|
||||||
public event EventHandler<ItemList.Item?>? RecipeSelected;
|
public event EventHandler<ItemList.Item?>? RecipeSelected;
|
||||||
|
public event EventHandler? RecipeFavorited;
|
||||||
public event EventHandler<bool>? BuildButtonToggled;
|
public event EventHandler<bool>? BuildButtonToggled;
|
||||||
public event EventHandler<bool>? EraseButtonToggled;
|
public event EventHandler<bool>? EraseButtonToggled;
|
||||||
|
|
||||||
@@ -112,13 +117,17 @@ namespace Content.Client.Construction.UI
|
|||||||
EraseButton.Pressed = false;
|
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.Disabled = false;
|
||||||
BuildButton.Text = Loc.GetString(isItem ? "construction-menu-place-ghost" : "construction-menu-craft");
|
BuildButton.Text = Loc.GetString(isItem ? "construction-menu-place-ghost" : "construction-menu-craft");
|
||||||
TargetName.SetMessage(name);
|
TargetName.SetMessage(name);
|
||||||
TargetDesc.SetMessage(description);
|
TargetDesc.SetMessage(description);
|
||||||
TargetTexture.Texture = iconTexture;
|
TargetTexture.Texture = iconTexture;
|
||||||
|
FavoriteButton.Visible = true;
|
||||||
|
FavoriteButton.Text = Loc.GetString(
|
||||||
|
isFavorite ? "construction-add-favorite-button" : "construction-remove-from-favorite-button");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRecipeInfo()
|
public void ClearRecipeInfo()
|
||||||
@@ -127,6 +136,7 @@ namespace Content.Client.Construction.UI
|
|||||||
TargetName.SetMessage(string.Empty);
|
TargetName.SetMessage(string.Empty);
|
||||||
TargetDesc.SetMessage(string.Empty);
|
TargetDesc.SetMessage(string.Empty);
|
||||||
TargetTexture.Texture = null;
|
TargetTexture.Texture = null;
|
||||||
|
FavoriteButton.Visible = false;
|
||||||
RecipeStepList.Clear();
|
RecipeStepList.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ namespace Content.Client.Construction.UI
|
|||||||
|
|
||||||
private ConstructionSystem? _constructionSystem;
|
private ConstructionSystem? _constructionSystem;
|
||||||
private ConstructionPrototype? _selected;
|
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
|
private bool CraftingAvailable
|
||||||
{
|
{
|
||||||
get => _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Visible;
|
get => _uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Visible;
|
||||||
@@ -65,7 +68,7 @@ namespace Content.Client.Construction.UI
|
|||||||
else
|
else
|
||||||
_constructionView.OpenCentered();
|
_constructionView.OpenCentered();
|
||||||
|
|
||||||
if(_selected != null)
|
if (_selected != null)
|
||||||
PopulateInfo(_selected);
|
PopulateInfo(_selected);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -105,9 +108,10 @@ namespace Content.Client.Construction.UI
|
|||||||
_constructionView.EraseButtonPressed = b;
|
_constructionView.EraseButtonPressed = b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();
|
||||||
|
|
||||||
PopulateCategories();
|
PopulateCategories();
|
||||||
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnHudCraftingButtonToggled(ButtonToggledEventArgs args)
|
public void OnHudCraftingButtonToggled(ButtonToggledEventArgs args)
|
||||||
@@ -154,6 +158,13 @@ namespace Content.Client.Construction.UI
|
|||||||
recipesList.Clear();
|
recipesList.Clear();
|
||||||
var recipes = new List<ConstructionPrototype>();
|
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>())
|
foreach (var recipe in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||||
{
|
{
|
||||||
if (recipe.Hide)
|
if (recipe.Hide)
|
||||||
@@ -170,11 +181,20 @@ namespace Content.Client.Construction.UI
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(category) && category != "construction-category-all")
|
if (!isEmptyCategory)
|
||||||
|
{
|
||||||
|
if (category == _favoriteCatName)
|
||||||
|
{
|
||||||
|
if (!_favoritedRecipes.Contains(recipe))
|
||||||
{
|
{
|
||||||
if (recipe.Category != category)
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (recipe.Category != category)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
recipes.Add(recipe);
|
recipes.Add(recipe);
|
||||||
}
|
}
|
||||||
@@ -189,13 +209,10 @@ namespace Content.Client.Construction.UI
|
|||||||
// There is apparently no way to set which
|
// There is apparently no way to set which
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateCategories()
|
private void PopulateCategories(string? selectCategory = null)
|
||||||
{
|
{
|
||||||
var uniqueCategories = new HashSet<string>();
|
var uniqueCategories = new HashSet<string>();
|
||||||
|
|
||||||
// hard-coded to show all recipes
|
|
||||||
uniqueCategories.Add("construction-category-all");
|
|
||||||
|
|
||||||
foreach (var prototype in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
foreach (var prototype in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||||
{
|
{
|
||||||
var category = prototype.Category;
|
var category = prototype.Category;
|
||||||
@@ -204,25 +221,49 @@ namespace Content.Client.Construction.UI
|
|||||||
uniqueCategories.Add(category);
|
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();
|
// hard-coded to show all recipes
|
||||||
Array.Sort(array);
|
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];
|
categoriesArray[idx++] = _favoriteCatName;
|
||||||
_constructionView.Category.AddItem(Loc.GetString(category), i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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)
|
private void PopulateInfo(ConstructionPrototype prototype)
|
||||||
{
|
{
|
||||||
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
|
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
|
||||||
_constructionView.ClearRecipeInfo();
|
_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;
|
var stepList = _constructionView.RecipeStepList;
|
||||||
GenerateStepList(prototype, stepList);
|
GenerateStepList(prototype, stepList);
|
||||||
@@ -240,7 +281,7 @@ namespace Content.Client.Construction.UI
|
|||||||
var text = entry.Arguments != null
|
var text = entry.Arguments != null
|
||||||
? Loc.GetString(entry.Localization, entry.Arguments) : Loc.GetString(entry.Localization);
|
? 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",
|
text = Loc.GetString("construction-presenter-step-wrapper",
|
||||||
("step-number", number), ("text", text));
|
("step-number", number), ("text", text));
|
||||||
@@ -332,6 +373,26 @@ namespace Content.Client.Construction.UI
|
|||||||
if (args.System is ConstructionSystem) SystemBindingChanged(null);
|
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)
|
private void SystemBindingChanged(ConstructionSystem? newSystem)
|
||||||
{
|
{
|
||||||
if (newSystem is null)
|
if (newSystem is null)
|
||||||
|
|||||||
@@ -10,3 +10,6 @@ construction-category-tiles = Tiles
|
|||||||
construction-category-utilities = Utilities
|
construction-category-utilities = Utilities
|
||||||
construction-category-misc = Misc
|
construction-category-misc = Misc
|
||||||
construction-category-clothing = Clothing
|
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