Workbench UI improve (#1508)

* grid workbench

* categorization

* Update CP14WorkbenchWindow.xaml.cs

* conditions

* categories
This commit is contained in:
Red
2025-07-08 00:42:34 +03:00
committed by GitHub
parent e7b73354ab
commit 2fc34bface
15 changed files with 333 additions and 104 deletions

View File

@@ -1,14 +1,11 @@
<Control xmlns="https://spacestation14.io">
<Button Name="Button">
<GridContainer Columns="2">
<Button Name="Button"
MaxSize="64 64">
<BoxContainer>
<EntityPrototypeView Name="View"
Margin="0,0,4,0"
MinSize="48 48"
MaxSize="48 48"
Scale="2,2"
HorizontalAlignment="Center"
VerticalExpand="True"/>
<Label Name="Name"/>
</GridContainer>
SetSize="64 64"
Scale="3,3"
HorizontalAlignment="Center"/>
</BoxContainer>
</Button>
</Control>

View File

@@ -39,7 +39,6 @@ public sealed partial class CP14WorkbenchRecipeControl : Control
Button.OnPressed += _ => OnSelect?.Invoke(entry, _recipePrototype);
UpdateColor();
UpdateName();
UpdateView();
}
@@ -51,13 +50,6 @@ public sealed partial class CP14WorkbenchRecipeControl : Control
Button.ModulateSelfOverride = Color.FromHex("#302622");
}
private void UpdateName()
{
var result = _prototype.Index(_recipePrototype.Result);
var counter = _recipePrototype.ResultCount > 1 ? $" x{_recipePrototype.ResultCount}" : "";
Name.Text = $"{Loc.GetString(result.Name)} {counter}" ;
}
private void UpdateView()
{
View.SetPrototype(_recipePrototype.Result);

View File

@@ -12,60 +12,62 @@
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<!-- Search Bar -->
<LineEdit Name="SearchBar" Margin="4" PlaceHolder="Search" HorizontalExpand="True" />
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0" />
</BoxContainer>
<!-- Crafts container -->
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
<BoxContainer Name="CraftsContainer" Orientation="Vertical" HorizontalExpand="True" />
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200" HScrollEnabled="False">
<BoxContainer Name="CraftsContainer" Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Top"/>
</ScrollContainer>
</BoxContainer>
<!-- Craft view (right side UI) -->
<BoxContainer MinWidth="350" Orientation="Vertical" HorizontalExpand="True"
VerticalExpand="True">
<PanelContainer HorizontalExpand="True" VerticalExpand="True">
<!-- Background -->
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BackgroundColor="#41332f" />
</PanelContainer.PanelOverride>
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
<PanelContainer HorizontalExpand="True" VerticalExpand="True">
<!-- Background -->
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BackgroundColor="#41332f" />
</PanelContainer.PanelOverride>
<!-- Content -->
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical">
<!-- Item info -->
<!-- icon -->
<EntityPrototypeView Name="ItemView"
Scale="2,2"
Margin="8"
MinSize="96 96"
MaxSize="96 96"
HorizontalAlignment="Left" />
<!-- Content -->
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical">
<!-- Item info -->
<!-- icon -->
<EntityPrototypeView Name="ItemView"
Scale="2,2"
Margin="8"
MinSize="96 96"
MaxSize="96 96"
HorizontalAlignment="Left" />
<!-- name & description -->
<BoxContainer Margin="5 0 0 0" HorizontalExpand="True" VerticalExpand="True"
Orientation="Vertical">
<RichTextLabel Name="ItemName" Margin="5" />
<RichTextLabel Name="ItemDescription" Margin="5" />
<!-- name & description -->
<BoxContainer Margin="5 0 0 0" HorizontalExpand="True" VerticalExpand="True"
Orientation="Vertical">
<RichTextLabel Name="ItemName" Margin="5" />
<RichTextLabel Name="ItemDescription" Margin="5" />
</BoxContainer>
<controls:HLine Color="#404040" Thickness="2" Margin="0 5" />
<!-- Required title -->
<Label Margin="5 0 0 0" Text="{Loc 'cp14-workbench-recipe-list'}" />
<!-- Craft requirements content -->
<!-- Added by code -->
<BoxContainer
Margin="5 0 0 0"
Name="ItemRequirements"
Orientation="Vertical" VerticalExpand="True"
HorizontalExpand="True" />
<controls:HLine Color="#404040" Thickness="5" Margin="0 5" />
<!-- Craft button -->
<Button Name="CraftButton" Text="{Loc 'cp14-workbench-craft'}" />
</BoxContainer>
<controls:HLine Color="#404040" Thickness="2" Margin="0 5" />
<!-- Required title -->
<Label Margin="5 0 0 0" Text="{Loc 'cp14-workbench-recipe-list'}" />
<!-- Craft requirements content -->
<!-- Added by code -->
<BoxContainer
Margin="5 0 0 0"
Name="ItemRequirements"
Orientation="Vertical" VerticalExpand="True"
HorizontalExpand="True" />
<controls:HLine Color="#404040" Thickness="5" Margin="0 5" />
<!-- Craft button -->
<Button Name="CraftButton" Text="{Loc 'cp14-workbench-craft'}" />
</BoxContainer>
</PanelContainer>
</PanelContainer>
</ScrollContainer>
</BoxContainer>
</BoxContainer>
</BoxContainer>

View File

@@ -3,6 +3,7 @@
* https://github.com/space-wizards/space-station-14/blob/master/LICENSE.TXT
*/
using System.Linq;
using Content.Client._CP14.Skill;
using Content.Shared._CP14.Workbench;
using Content.Shared._CP14.Workbench.Prototypes;
@@ -28,7 +29,13 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
public event Action<CP14WorkbenchUiRecipesEntry>? OnCraft;
private readonly Dictionary<int, LocId> _categories = new();
/// <summary>
/// Used for category dropdown filtering.
/// </summary>
private readonly Dictionary<int, LocId> _categoryIndexes = new();
private Dictionary<LocId, List<CP14WorkbenchUiRecipesEntry>> _categories = new();
private List<CP14WorkbenchUiRecipesEntry> _uncategorized = new();
private CP14WorkbenchUiRecipesState? _cachedState;
private CP14WorkbenchUiRecipesEntry? _selectedEntry;
@@ -50,15 +57,49 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
OptionCategories.OnItemSelected += OnCategoryItemSelected;
}
public void UpdateRecipesVisibility()
private void UpdateRecipesVisibility()
{
if (_cachedState is null)
return;
CraftsContainer.RemoveAllChildren();
var recipes = new List<CP14WorkbenchUiRecipesEntry>();
foreach (var entry in _cachedState.Recipes)
if (_uncategorized.Count > 0 && OptionCategories.SelectedId == AllCategoryId)
{
var uncategorizedGridContainer = new GridContainer();
uncategorizedGridContainer.Columns = 5;
uncategorizedGridContainer.VerticalExpand = true;
CraftsContainer.AddChild(uncategorizedGridContainer);
AddRecipeListToGrid(_uncategorized, uncategorizedGridContainer);
}
foreach (var category in _categories)
{
if (_categoryIndexes.TryGetValue(OptionCategories.SelectedId, out var selectedCategory) &&
category.Key != selectedCategory)
continue;
var categoryLabel = new RichTextLabel();
categoryLabel.Margin = new Thickness(5);
categoryLabel.Text = Loc.GetString(category.Key);
CraftsContainer.AddChild(categoryLabel);
var gridContainer = new GridContainer();
gridContainer.Columns = 5;
gridContainer.VerticalExpand = true;
CraftsContainer.AddChild(gridContainer);
AddRecipeListToGrid(category.Value, gridContainer);
}
if (_selectedEntry is not null && _cachedState.Recipes.Contains(_selectedEntry.Value))
RecipeSelectNull();
}
private void AddRecipeListToGrid(List<CP14WorkbenchUiRecipesEntry> category, GridContainer gridContainer)
{
foreach (var entry in category)
{
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
{
@@ -88,21 +129,11 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
continue;
}
recipes.Add(entry);
}
recipes.Sort(CP14WorkbenchUiRecipesEntry.CompareTo);
foreach (var recipe in recipes)
{
var control = new CP14WorkbenchRecipeControl(recipe);
var control = new CP14WorkbenchRecipeControl(entry);
control.OnSelect += RecipeSelect;
CraftsContainer.AddChild(control);
gridContainer.AddChild(control);
}
if (_selectedEntry is not null && !recipes.Contains(_selectedEntry.Value))
RecipeSelectNull();
}
public void UpdateState(CP14WorkbenchUiRecipesState recipesState)
@@ -112,37 +143,37 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
_cachedState = recipesState;
_categoryIndexes.Clear();
_categories.Clear();
_uncategorized.Clear();
OptionCategories.Clear();
OptionCategories.AddItem(Loc.GetString("cp14-recipe-category-all"), AllCategoryId);
var categories = new List<LocId>();
var count = 0;
foreach (var entry in recipesState.Recipes)
foreach (var entry in recipesState.Recipes.OrderByDescending(e => e.Craftable))
{
if (!_prototype.TryIndex(entry.ProtoId, out var indexedEntry))
continue;
// Populate categories
if (indexedEntry.Category is null)
continue;
if (!_prototype.TryIndex(indexedEntry.Category, out var indexedCategory))
{
_uncategorized.Add(entry);
continue;
}
if (categories.Contains(indexedCategory.Name))
continue;
if (!_categories.TryGetValue(indexedCategory.Name, out var entries))
{
entries = new List<CP14WorkbenchUiRecipesEntry>();
_categories[indexedCategory.Name] = entries;
}
categories.Add(indexedCategory.Name);
entries.Add(entry);
}
categories.Sort((a, b) => string.Compare(Loc.GetString(a), Loc.GetString(b), StringComparison.Ordinal));
foreach (var category in categories)
var count = 0;
foreach (var category in _categories)
{
OptionCategories.AddItem(Loc.GetString(category), count);
_categories.Add(count, category);
OptionCategories.AddItem(Loc.GetString(category.Key), count);
_categoryIndexes.Add(count, category.Key);
count++;
}
@@ -188,7 +219,7 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
if (OptionCategories.SelectedId == AllCategoryId)
return true;
if (!_categories.TryGetValue(OptionCategories.SelectedId, out var selectedCategory))
if (!_categoryIndexes.TryGetValue(OptionCategories.SelectedId, out var selectedCategory))
{
Sawmill.Error($"Non-existent {OptionCategories.SelectedId} category id selected. Filter skipped");
return true;