Skip to content

Commit

Permalink
Favorites tab for the construction menu (space-wizards#26347)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Arteben and metalgearsloth authored Jun 29, 2024
1 parent 64af030 commit 881c232
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 38 deletions.
30 changes: 17 additions & 13 deletions Content.Client/Construction/UI/ConstructionMenu.xaml
Original file line number Diff line number Diff line change
@@ -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="Horizontal" Align="Center">
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep"/>
<Control MinSize="10 0"/>
<BoxContainer Orientation="Vertical">
<RichTextLabel Name="TargetName"/>
<RichTextLabel Name="TargetDesc"/>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
<BoxContainer Orientation="Horizontal" Align="Center">
<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>
Expand Down
24 changes: 17 additions & 7 deletions Content.Client/Construction/UI/ConstructionMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public interface IConstructionMenuView : IDisposable
// 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; }
Expand All @@ -32,12 +32,13 @@ public interface IConstructionMenuView : IDisposable

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
Expand Down Expand Up @@ -84,10 +85,12 @@ public ConstructionMenu()
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]));
};

Expand All @@ -97,12 +100,14 @@ public ConstructionMenu()
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;

Expand All @@ -112,13 +117,17 @@ public void ResetPlacement()
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()
Expand All @@ -127,6 +136,7 @@ public void ClearRecipeInfo()
TargetName.SetMessage(string.Empty);
TargetDesc.SetMessage(string.Empty);
TargetTexture.Texture = null;
FavoriteButton.Visible = false;
RecipeStepList.Clear();
}
}
Expand Down
97 changes: 79 additions & 18 deletions Content.Client/Construction/UI/ConstructionMenuPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ internal sealed class ConstructionMenuPresenter : IDisposable

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;
Expand Down Expand Up @@ -65,7 +68,7 @@ private bool WindowOpen
else
_constructionView.OpenCentered();

if(_selected != null)
if (_selected != null)
PopulateInfo(_selected);
}
else
Expand Down Expand Up @@ -105,9 +108,10 @@ public ConstructionMenuPresenter()
_constructionView.EraseButtonPressed = b;
};

_constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();

PopulateCategories();
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));

}

public void OnHudCraftingButtonToggled(ButtonToggledEventArgs args)
Expand Down Expand Up @@ -154,6 +158,13 @@ private void OnViewPopulateRecipes(object? sender, (string search, string catago
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)
Expand All @@ -170,10 +181,19 @@ private void OnViewPopulateRecipes(object? sender, (string search, string catago
continue;
}

if (!string.IsNullOrEmpty(category) && category != "construction-category-all")
if (!isEmptyCategory)
{
if (recipe.Category != category)
if (category == _favoriteCatName)
{
if (!_favoritedRecipes.Contains(recipe))
{
continue;
}
}
else if (recipe.Category != category)
{
continue;
}
}

recipes.Add(recipe);
Expand All @@ -189,13 +209,10 @@ private void OnViewPopulateRecipes(object? sender, (string search, string catago
// 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;
Expand All @@ -204,25 +221,49 @@ private void PopulateCategories()
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;

// hard-coded to show favorites if it need
if (isFavorites)
{
categoriesArray[idx++] = _favoriteCatName;
}

for (var i = 0; i < array.Length; i++)
var sortedProtoCategories = uniqueCategories.OrderBy(Loc.GetString);

foreach (var cat in sortedProtoCategories)
{
var category = array[i];
_constructionView.Category.AddItem(Loc.GetString(category), i);
categoriesArray[idx++] = cat;
}

_constructionView.Categories = array;
_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);
Expand All @@ -240,7 +281,7 @@ private void GenerateStepList(ConstructionPrototype prototype, ItemList stepList
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));
Expand Down Expand Up @@ -332,6 +373,26 @@ private void OnSystemUnloaded(object? sender, SystemChangedArgs args)
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 881c232

Please sign in to comment.