<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>
// 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; }
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
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]));
};
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;
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()
TargetName.SetMessage(string.Empty);
TargetDesc.SetMessage(string.Empty);
TargetTexture.Texture = null;
+ FavoriteButton.Visible = false;
RecipeStepList.Clear();
}
}
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;
else
_constructionView.OpenCentered();
- if(_selected != null)
+ if (_selected != null)
PopulateInfo(_selected);
}
else
_constructionView.EraseButtonPressed = b;
};
+ _constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();
+
PopulateCategories();
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
-
}
public void OnHudCraftingButtonToggled(ButtonToggledEventArgs args)
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)
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);
// 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;
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);
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));
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)
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