diff --git a/Penumbra/UI/Knowledge/KnowledgeWindow.cs b/Penumbra/UI/Knowledge/KnowledgeWindow.cs
index de1b36b8..b14949de 100644
--- a/Penumbra/UI/Knowledge/KnowledgeWindow.cs
+++ b/Penumbra/UI/Knowledge/KnowledgeWindow.cs
@@ -5,11 +5,12 @@ using Dalamud.Memory;
using ImGuiNET;
using OtterGui.Services;
using OtterGui.Text;
+using Penumbra.String;
namespace Penumbra.UI.Knowledge;
/// Draw the progress information for import.
-public sealed class KnowledgeWindow() : Window("Penumbra Knowledge Window"), IUiService
+public sealed class KnowledgeWindow : Window, IUiService
{
private readonly IReadOnlyList _tabs =
[
@@ -19,7 +20,16 @@ public sealed class KnowledgeWindow() : Window("Penumbra Knowledge Window"), IUi
private IKnowledgeTab? _selected;
private readonly byte[] _filterStore = new byte[256];
- private TerminatedByteString _filter = TerminatedByteString.Empty;
+ private ByteString _lower = ByteString.Empty;
+
+ /// Draw the progress information for import.
+ public KnowledgeWindow()
+ : base("Penumbra Knowledge Window")
+ => SizeConstraints = new WindowSizeConstraints
+ {
+ MaximumSize = new Vector2(10000, 10000),
+ MinimumSize = new Vector2(400, 200),
+ };
public override void Draw()
{
@@ -30,15 +40,23 @@ public sealed class KnowledgeWindow() : Window("Penumbra Knowledge Window"), IUi
private void DrawSelector()
{
- using var child = ImUtf8.Child("KnowledgeSelector"u8, new Vector2(250 * ImUtf8.GlobalScale, ImGui.GetContentRegionAvail().Y), true);
+ using var group = ImUtf8.Group();
+ using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
+ {
+ ImGui.SetNextItemWidth(200 * ImUtf8.GlobalScale);
+ if (ImUtf8.InputText("##Filter"u8, _filterStore, out TerminatedByteString filter, "Filter..."u8))
+ _lower = ByteString.FromSpanUnsafe(filter, true, null, null).AsciiToLowerClone();
+ }
+
+ using var child = ImUtf8.Child("KnowledgeSelector"u8, new Vector2(200 * ImUtf8.GlobalScale, ImGui.GetContentRegionAvail().Y), true);
if (!child)
return;
- ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
- ImUtf8.InputText("##Filter"u8, _filterStore, out _filter, "Filter..."u8);
-
foreach (var tab in _tabs)
{
+ if (!_lower.IsEmpty && tab.SearchTags.IndexOf(_lower.Span) < 0)
+ continue;
+
if (ImUtf8.Selectable(tab.Name, _selected == tab))
_selected = tab;
}
@@ -46,6 +64,13 @@ public sealed class KnowledgeWindow() : Window("Penumbra Knowledge Window"), IUi
private void DrawMain()
{
+ using var group = ImUtf8.Group();
+ using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
+ {
+ ImUtf8.TextFramed(_selected == null ? "No Selection"u8 : _selected.Name, ImGui.GetColorU32(ImGuiCol.FrameBg),
+ new Vector2(ImGui.GetContentRegionAvail().X, 0));
+ }
+
using var child = ImUtf8.Child("KnowledgeMain"u8, ImGui.GetContentRegionAvail(), true);
if (!child || _selected == null)
return;
diff --git a/Penumbra/UI/Knowledge/RaceCodeTab.cs b/Penumbra/UI/Knowledge/RaceCodeTab.cs
index 988506dd..36b048aa 100644
--- a/Penumbra/UI/Knowledge/RaceCodeTab.cs
+++ b/Penumbra/UI/Knowledge/RaceCodeTab.cs
@@ -4,7 +4,7 @@ using Penumbra.GameData.Enums;
namespace Penumbra.UI.Knowledge;
-public sealed class RaceCodeTab : IKnowledgeTab
+public sealed class RaceCodeTab() : IKnowledgeTab
{
public ReadOnlySpan Name
=> "Race Codes"u8;
@@ -14,29 +14,69 @@ public sealed class RaceCodeTab : IKnowledgeTab
public void Draw()
{
- using var table = ImUtf8.Table("table"u8, 4, ImGuiTableFlags.SizingFixedFit);
- if (!table)
- return;
+ var size = new Vector2((ImGui.GetContentRegionAvail().X - ImUtf8.ItemSpacing.X) / 2, 0);
+ using (var table = ImUtf8.Table("adults"u8, 4, ImGuiTableFlags.BordersOuter, size))
+ {
+ if (!table)
+ return;
- ImUtf8.TableHeader("Race Code"u8);
- ImUtf8.TableHeader("Race"u8);
- ImUtf8.TableHeader("Gender"u8);
- ImUtf8.TableHeader("NPC"u8);
+ DrawHeaders();
+ foreach (var gr in Enum.GetValues())
+ {
+ var (gender, race) = gr.Split();
+ if (gender is not Gender.Male and not Gender.Female || race is ModelRace.Unknown)
+ continue;
- foreach (var genderRace in Enum.GetValues())
+ DrawRow(gender, race, false);
+ }
+ }
+
+ ImGui.SameLine();
+
+ using (var table = ImUtf8.Table("children"u8, 4, ImGuiTableFlags.BordersOuter, size))
+ {
+ if (!table)
+ return;
+
+ DrawHeaders();
+ foreach (var race in (ReadOnlySpan)
+ [ModelRace.Midlander, ModelRace.Elezen, ModelRace.Miqote, ModelRace.AuRa, ModelRace.Unknown])
+ {
+ foreach (var gender in (ReadOnlySpan) [Gender.Male, Gender.Female])
+ DrawRow(gender, race, true);
+ }
+ }
+
+ return;
+
+ static void DrawHeaders()
{
ImGui.TableNextColumn();
- ImUtf8.Text(genderRace.ToRaceCode());
-
- var (gender, race) = genderRace.Split();
+ ImUtf8.TableHeader("Race"u8);
ImGui.TableNextColumn();
- ImUtf8.Text($"{race}");
+ ImUtf8.TableHeader("Gender"u8);
+ ImGui.TableNextColumn();
+ ImUtf8.TableHeader("Age"u8);
+ ImGui.TableNextColumn();
+ ImUtf8.TableHeader("Race Code"u8);
+ }
+
+ static void DrawRow(Gender gender, ModelRace race, bool child)
+ {
+ var gr = child
+ ? Names.CombinedRace(gender is Gender.Male ? Gender.MaleNpc : Gender.FemaleNpc, race)
+ : Names.CombinedRace(gender, race);
+ ImGui.TableNextColumn();
+ ImUtf8.Text(race.ToName());
ImGui.TableNextColumn();
- ImUtf8.Text($"{gender}");
+ ImUtf8.Text(gender.ToName());
ImGui.TableNextColumn();
- ImUtf8.Text(((ushort)genderRace & 0xF) != 1 ? "NPC"u8 : "Normal"u8);
+ ImUtf8.Text(child ? "Child"u8 : "Adult"u8);
+
+ ImGui.TableNextColumn();
+ ImUtf8.CopyOnClickSelectable(gr.ToRaceCode());
}
}
}