Second piece of Phase D.2a: the ImGui-specific backend that implements
AcDream.UI.Abstractions' IPanelRenderer / IPanelHost. No GameWindow
hookup yet — compiles standalone for clean review before integration.
Packages:
* Hexa.NET.ImGui 2.2.9 (auto-generated from cimgui 1.92.2b)
* Hexa.NET.ImGui.Backends 1.0.18 (consolidated — OpenGL3 is here)
* Silk.NET.Input 2.23.0 + Silk.NET.OpenGL 2.23.0 (matches AcDream.App)
Files:
ImGuiBootstrapper.cs
One-shot static Initialize(glslVersion) / Shutdown() pair. Creates
the ImGui context, applies dark style, enables NavEnableKeyboard,
and boots ImGuiImplOpenGL3. Re-init is a no-op.
SilkInputBridge.cs
Event-driven Silk.NET -> ImGui IO bridge. Subscribes on construction;
Dispose() unsubscribes. Covers:
- KeyDown/Up -> ImGui.AddKeyEvent with modifier latching
(Ctrl/Shift/Alt/Super routed via both ModXxx flags AND named
key events so both IsKeyPressed checks and ImGui shortcut
matching work)
- KeyChar -> AddInputCharacter for text fields
- MouseMove -> AddMousePosEvent
- MouseDown/Up -> AddMouseButtonEvent (L=0, R=1, M=2)
- Scroll -> AddMouseWheelEvent (both axes)
Silk.NET.Input.Key -> ImGuiKey map covers WASD, arrows, modifiers,
letters, digits, function keys. Unmapped keys silently ignored.
BeginFrame(displaySize, dt) sets IO.DisplaySize + IO.DeltaTime.
ImGuiPanelRenderer.cs
IPanelRenderer impl — one-line wrappers on ImGui.Begin/End,
TextUnformatted, SameLine, Separator, ProgressBar. The ONLY place
Hexa.NET.ImGui types appear outside bootstrap/input plumbing. Panels
still never import ImGui.
ImGuiPanelHost.cs
IPanelHost impl. Dictionary keyed by IPanel.Id for idempotent
Register. RenderAll iterates visible panels and calls their Render.
Does NOT call ImGui.NewFrame / ImGui.Render — ownership belongs to
the caller (GameWindow) so GL state is explicit. Diagnostic `Count`
property.
No behavior change yet; next commit wires this into GameWindow behind
ACDREAM_DEVTOOLS=1 and ships the first visible VitalsPanel.
41 lines
1.4 KiB
C#
41 lines
1.4 KiB
C#
using System.Numerics;
|
|
using AcDream.UI.Abstractions;
|
|
|
|
namespace AcDream.UI.ImGui;
|
|
|
|
/// <summary>
|
|
/// <see cref="IPanelRenderer"/> implemented as thin wrappers around
|
|
/// Hexa.NET.ImGui calls. This is the ONLY place where Hexa.NET.ImGui
|
|
/// types appear outside of bootstrap / input-bridge plumbing — panels
|
|
/// that need a feature must extend the abstraction here, not by importing
|
|
/// ImGui in panel files.
|
|
/// </summary>
|
|
public sealed class ImGuiPanelRenderer : IPanelRenderer
|
|
{
|
|
/// <inheritdoc />
|
|
public bool Begin(string title) => Hexa.NET.ImGui.ImGui.Begin(title);
|
|
|
|
/// <inheritdoc />
|
|
public void End() => Hexa.NET.ImGui.ImGui.End();
|
|
|
|
/// <inheritdoc />
|
|
public void Text(string text) => Hexa.NET.ImGui.ImGui.TextUnformatted(text);
|
|
|
|
/// <inheritdoc />
|
|
public void SameLine() => Hexa.NET.ImGui.ImGui.SameLine();
|
|
|
|
/// <inheritdoc />
|
|
public void Separator() => Hexa.NET.ImGui.ImGui.Separator();
|
|
|
|
/// <inheritdoc />
|
|
public void ProgressBar(float fraction, float width, string? overlay = null)
|
|
{
|
|
// Clamp defensively; ImGui clamps internally but the abstraction
|
|
// contract promises to handle out-of-range values.
|
|
if (fraction < 0f) fraction = 0f;
|
|
else if (fraction > 1f) fraction = 1f;
|
|
|
|
var size = new Vector2(width, 0f); // height 0 → ImGui picks based on font
|
|
Hexa.NET.ImGui.ImGui.ProgressBar(fraction, size, overlay ?? string.Empty);
|
|
}
|
|
}
|