feat(studio): Character panel pilot — gmCharacterInfoUI report text + menu-bar picker
Task A — CharacterController (LayoutDesc 0x2100002E)
- CharacterSheet.cs: data record for all fields used by the report sections,
with retail property-id citations per field (DateOfBirth 0x62, TotalPlayTime
0x7d, NumDeaths 0x2b, SkillCredits 0xb5/0xc0, AugmentationStat 0x162,
EncumbranceVal 0x5/0xe6).
- CharacterController.cs: static Bind(layout, data, datFont) wires element
0x1000011d (m_pMainText, confirmed gmCharacterInfoUI::PostInit 0x004b86f0) as
a UiText; LinesProvider builds the report. Report section order mirrors
gmCharacterInfoUI::Update (0x004ba790):
1. UpdatePlayerBirthAgeDeaths 0x004b8cb0 — birth/age/deaths
2. UpdateEnduranceInfo 0x004b8eb0 — vitals (H/S/M cur/max)
3. UpdateInnateAttributeInfo 0x004b87e0 — 6 attrs InqAttribute 1,2,4,3,5,6
= Strength, Endurance, Quickness, Coordination, Focus, Self
4. UpdateFakeSkills 0x004b8930 — skill credits (InqInt 0xb5 / 0xc0)
5. UpdateAugmentations 0x004b9000 — aug name (InqInt 0x162 switch 1..0xb)
6. UpdateLoad 0x004b8a20 — burden cur/max/pct
Element 0x1000011d imports as UiText (Type 12); multi-line text set via
LinesProvider — same pattern as ChatWindowController transcript.
- SampleData.SampleCharacter(): plausible retail-scale CharacterSheet fixture.
- FixtureProvider.Populate case 0x2100002Eu: CharacterController.Bind with
SampleData.SampleCharacter + VitalsDatFont.
- CharacterControllerTests.cs: 10 pure data-wiring + content tests (no GL/dats).
Task B — Studio panel picker → main menu bar
- StudioWindow.OnRender: replaced the floating "Studio" toolbar window (kToolbarH
40px) with ImGui.BeginMainMenuBar / EndMainMenuBar (kMenuBarH 22px). Panel
picker combo now lives in the always-on-top menu bar and cannot be occluded by
Tree/Canvas/Props panes. paneY reduced from 40→22, freeing ~18px for the canvas.
Build: dotnet build green (0 CS errors; DLL-lock warnings are AcDream.App being
live — not compile errors). Full suite: 619 passed, 2 skipped.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c03a241884
commit
4988dd4dfe
6 changed files with 515 additions and 8 deletions
|
|
@ -279,21 +279,43 @@ public sealed class StudioWindow : IDisposable
|
|||
_imgui.BeginFrame((float)dt);
|
||||
|
||||
// ── Layout constants (fixed pane arrangement, FirstUseEver) ──────────────
|
||||
// Toolbar: full width, 40px tall at y=0.
|
||||
// Tree: 280px wide on the left, below toolbar.
|
||||
// MenuBar: always-on-top main menu bar (~22px) — panel picker lives here so it
|
||||
// is never covered by the floating panes (replaces the old 40px toolbar).
|
||||
// Tree: 280px wide on the left, below menu bar.
|
||||
// Canvas: centre strip between tree and properties.
|
||||
// Props: 340px wide on the right, below toolbar.
|
||||
const int kToolbarH = 40;
|
||||
// Props: 340px wide on the right, below menu bar.
|
||||
const int kMenuBarH = 22; // ImGui default main menu bar height
|
||||
const int kTreeW = 280;
|
||||
const int kPropsW = 340;
|
||||
int canvasX = kTreeW;
|
||||
int canvasW = Math.Max(1, iw - kTreeW - kPropsW);
|
||||
int propsX = iw - kPropsW;
|
||||
int paneY = kToolbarH;
|
||||
int paneH = Math.Max(1, ih - kToolbarH);
|
||||
int paneY = kMenuBarH;
|
||||
int paneH = Math.Max(1, ih - kMenuBarH);
|
||||
|
||||
// 5. Toolbar pane — slug picker.
|
||||
string? pickedSlug = _inspector.DrawToolbar(_dumpSlugs, _currentSlug, iw);
|
||||
// 5. Main menu bar — panel picker combo pinned to the window top.
|
||||
// BeginMainMenuBar returns true when the bar is visible (always is); the combo
|
||||
// inside it is always-on-top and is never occluded by Tree/Canvas/Props panes.
|
||||
string? pickedSlug = null;
|
||||
if (ImGuiNET.ImGui.BeginMainMenuBar())
|
||||
{
|
||||
ImGuiNET.ImGui.SetNextItemWidth(300f);
|
||||
string preview = _currentSlug ?? "(none)";
|
||||
if (ImGuiNET.ImGui.BeginCombo("Panel", preview))
|
||||
{
|
||||
foreach (var slug in _dumpSlugs)
|
||||
{
|
||||
bool selected = string.Equals(slug, _currentSlug,
|
||||
System.StringComparison.OrdinalIgnoreCase);
|
||||
if (ImGuiNET.ImGui.Selectable(slug, selected) && !selected)
|
||||
pickedSlug = slug;
|
||||
if (selected)
|
||||
ImGuiNET.ImGui.SetItemDefaultFocus();
|
||||
}
|
||||
ImGuiNET.ImGui.EndCombo();
|
||||
}
|
||||
ImGuiNET.ImGui.EndMainMenuBar();
|
||||
}
|
||||
if (pickedSlug is not null)
|
||||
LoadDumpPanel(pickedSlug);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue