feat(command-help-window): full R2 migration (ctor-injected + DI-reg)

J resurrects CommandHelpWindow from the v1.7.0 stub state:

- Class header public → internal sealed
- Ctor takes 4 DI deps (ChunkRenderer, MainWindow, InputBar, ILogger)
  via Factory-Lambda DI-reg. NO Lender<PayloadHandler> — command-help
  chunks are read-only command-description text with no click-targets
  (per spec §5-J + F W8 consumer audit).
- Draw() calls _chunkRenderer.DrawChunks(desc chunks, wrap: true,
  handler: null, lineWidth: 0f) — null-handler is intentional.
- Plugin.cs property visibility flipped public → internal to satisfy
  CS0053 (analogous to I's InputPreview fix).

K (R3 DebuggerWindow counters) and A2 (Lender + handler.Draw fix) are
the remaining Phase-3 sub-tasks before Polish-Sweep + Smoke-Gate.
This commit is contained in:
2026-05-27 21:04:42 +02:00
parent 8431fbcf80
commit 830d247eda
3 changed files with 78 additions and 11 deletions
+1 -1
View File
@@ -99,7 +99,7 @@ public sealed class Plugin : IAsyncDalamudPlugin
internal Ui.Windows.SettingsWindow SettingsWindow { get; private set; } = null!; internal Ui.Windows.SettingsWindow SettingsWindow { get; private set; } = null!;
public DbViewer DbViewer { get; private set; } = null!; public DbViewer DbViewer { get; private set; } = null!;
internal InputPreview InputPreview { get; private set; } = null!; internal InputPreview InputPreview { get; private set; } = null!;
public CommandHelpWindow CommandHelpWindow { get; private set; } = null!; internal CommandHelpWindow CommandHelpWindow { get; private set; } = null!;
public SeStringDebugger SeStringDebugger { get; private set; } = null!; public SeStringDebugger SeStringDebugger { get; private set; } = null!;
public FirstRunWizard FirstRunWizard { get; private set; } = null!; public FirstRunWizard FirstRunWizard { get; private set; } = null!;
public DebuggerWindow DebuggerWindow { get; private set; } = null!; public DebuggerWindow DebuggerWindow { get; private set; } = null!;
+6 -1
View File
@@ -285,7 +285,12 @@ internal static class PluginHostFactory
sp.GetRequiredService<Ui.Components.InputBar>(), sp.GetRequiredService<Ui.Components.InputBar>(),
sp.GetRequiredService<ILogger<InputPreview>>() sp.GetRequiredService<ILogger<InputPreview>>()
)); ));
services.AddSingleton(sp => new CommandHelpWindow(sp.GetRequiredService<Plugin>())); services.AddSingleton(sp => new CommandHelpWindow(
sp.GetRequiredService<Ui.Components.ChunkRenderer>(),
sp.GetRequiredService<Ui.Windows.MainWindow>(),
sp.GetRequiredService<Ui.Components.InputBar>(),
sp.GetRequiredService<ILogger<CommandHelpWindow>>()
));
services.AddSingleton(sp => new SeStringDebugger(sp.GetRequiredService<Plugin>())); services.AddSingleton(sp => new SeStringDebugger(sp.GetRequiredService<Plugin>()));
services.AddSingleton(sp => new DebuggerWindow(sp.GetRequiredService<Plugin>())); services.AddSingleton(sp => new DebuggerWindow(sp.GetRequiredService<Plugin>()));
services.AddSingleton(sp => new FirstRunWizard(sp.GetRequiredService<Plugin>())); services.AddSingleton(sp => new FirstRunWizard(sp.GetRequiredService<Plugin>()));
+70 -8
View File
@@ -1,20 +1,37 @@
using System.Numerics;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using HellionChat.Ui.Components;
using HellionChat.Util;
using Lumina.Text.ReadOnly; using Lumina.Text.ReadOnly;
using Microsoft.Extensions.Logging;
namespace HellionChat.Ui; namespace HellionChat.Ui;
// Slash-command help popup is offline while the chat input pipeline is internal sealed class CommandHelpWindow : Window
// rebuilt. UpdateContent stays callable so the input layer can keep its
// integration shape, but it always leaves the window closed for now.
public class CommandHelpWindow : Window
{ {
private readonly Plugin _plugin; private readonly ChunkRenderer _chunkRenderer;
private readonly Windows.MainWindow _mainWindow;
private readonly Components.InputBar _inputBar;
private readonly ILogger<CommandHelpWindow> _logger;
internal CommandHelpWindow(Plugin plugin) private ReadOnlySeString? _commandDescription;
public CommandHelpWindow(
ChunkRenderer chunkRenderer,
Windows.MainWindow mainWindow,
Components.InputBar inputBar,
ILogger<CommandHelpWindow> logger
)
: base("command help##chat2-commandhelp") : base("command help##chat2-commandhelp")
{ {
_plugin = plugin; _chunkRenderer = chunkRenderer;
_mainWindow = mainWindow;
_inputBar = inputBar;
_logger = logger;
Flags = Flags =
ImGuiWindowFlags.NoSavedSettings ImGuiWindowFlags.NoSavedSettings
| ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoTitleBar
@@ -22,14 +39,59 @@ public class CommandHelpWindow : Window
| ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoResize
| ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoFocusOnAppearing
| ImGuiWindowFlags.AlwaysAutoResize; | ImGuiWindowFlags.AlwaysAutoResize;
RespectCloseHotkey = false; RespectCloseHotkey = false;
DisableWindowSounds = true; DisableWindowSounds = true;
// Logger injected for future diagnostic hooks (no call-sites yet in R2).
_ = _logger;
// InputBar injected for future integration (no call-sites yet in R2).
_ = _inputBar;
} }
public void UpdateContent(ReadOnlySeString commandDesc) public void UpdateContent(ReadOnlySeString commandDesc)
{ {
_commandDescription = commandDesc;
var width = 350;
var scaledWidth = width * ImGuiHelpers.GlobalScale;
var pos = _mainWindow.LastWindowPos;
switch (Plugin.Config.CommandHelpSide)
{
case CommandHelpSide.Right:
pos.X += _mainWindow.LastWindowSize.X;
break;
case CommandHelpSide.Left:
pos.X -= scaledWidth;
break;
case CommandHelpSide.None:
default:
IsOpen = false; IsOpen = false;
return;
} }
public override void Draw() { } Position = pos;
SizeConstraints = new WindowSizeConstraints
{
// scaledWidth keeps size constraints in the same coordinate space as
// Position so the help window stays correct width at non-100% DPI.
MinimumSize = new Vector2(scaledWidth, 0),
MaximumSize = _mainWindow.LastWindowSize with { X = scaledWidth },
};
IsOpen = true;
}
public override void Draw()
{
if (_commandDescription == null)
return;
var chunks = ChunkUtil
.ToChunks(_commandDescription.Value.ToDalamudString(), ChunkSource.None, null)
.ToList();
// Command-help chunks are read-only description text — no click-targets.
_chunkRenderer.DrawChunks(chunks, wrap: true, handler: null, lineWidth: 0f);
}
} }