From 830d247eda62e3c916ed6a0504f0bee76881889d Mon Sep 17 00:00:00 2001 From: Jon Kazama Date: Wed, 27 May 2026 21:04:42 +0200 Subject: [PATCH] feat(command-help-window): full R2 migration (ctor-injected + DI-reg) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 — 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. --- HellionChat/Plugin.cs | 2 +- HellionChat/PluginHostFactory.cs | 7 ++- HellionChat/Ui/CommandHelpWindow.cs | 80 +++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/HellionChat/Plugin.cs b/HellionChat/Plugin.cs index 904c820..c9e0ef3 100755 --- a/HellionChat/Plugin.cs +++ b/HellionChat/Plugin.cs @@ -99,7 +99,7 @@ public sealed class Plugin : IAsyncDalamudPlugin internal Ui.Windows.SettingsWindow SettingsWindow { get; private set; } = null!; public DbViewer DbViewer { 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 FirstRunWizard FirstRunWizard { get; private set; } = null!; public DebuggerWindow DebuggerWindow { get; private set; } = null!; diff --git a/HellionChat/PluginHostFactory.cs b/HellionChat/PluginHostFactory.cs index 33b7db7..34fae6e 100644 --- a/HellionChat/PluginHostFactory.cs +++ b/HellionChat/PluginHostFactory.cs @@ -285,7 +285,12 @@ internal static class PluginHostFactory sp.GetRequiredService(), sp.GetRequiredService>() )); - services.AddSingleton(sp => new CommandHelpWindow(sp.GetRequiredService())); + services.AddSingleton(sp => new CommandHelpWindow( + sp.GetRequiredService(), + sp.GetRequiredService(), + sp.GetRequiredService(), + sp.GetRequiredService>() + )); services.AddSingleton(sp => new SeStringDebugger(sp.GetRequiredService())); services.AddSingleton(sp => new DebuggerWindow(sp.GetRequiredService())); services.AddSingleton(sp => new FirstRunWizard(sp.GetRequiredService())); diff --git a/HellionChat/Ui/CommandHelpWindow.cs b/HellionChat/Ui/CommandHelpWindow.cs index 520e75f..ceaadae 100644 --- a/HellionChat/Ui/CommandHelpWindow.cs +++ b/HellionChat/Ui/CommandHelpWindow.cs @@ -1,20 +1,37 @@ +using System.Numerics; using Dalamud.Bindings.ImGui; +using Dalamud.Interface.Utility; using Dalamud.Interface.Windowing; +using Dalamud.Utility; +using HellionChat.Ui.Components; +using HellionChat.Util; using Lumina.Text.ReadOnly; +using Microsoft.Extensions.Logging; namespace HellionChat.Ui; -// Slash-command help popup is offline while the chat input pipeline is -// 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 +internal sealed class CommandHelpWindow : Window { - private readonly Plugin _plugin; + private readonly ChunkRenderer _chunkRenderer; + private readonly Windows.MainWindow _mainWindow; + private readonly Components.InputBar _inputBar; + private readonly ILogger _logger; - internal CommandHelpWindow(Plugin plugin) + private ReadOnlySeString? _commandDescription; + + public CommandHelpWindow( + ChunkRenderer chunkRenderer, + Windows.MainWindow mainWindow, + Components.InputBar inputBar, + ILogger logger + ) : base("command help##chat2-commandhelp") { - _plugin = plugin; + _chunkRenderer = chunkRenderer; + _mainWindow = mainWindow; + _inputBar = inputBar; + _logger = logger; + Flags = ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoTitleBar @@ -22,14 +39,59 @@ public class CommandHelpWindow : Window | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysAutoResize; + RespectCloseHotkey = false; 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) { - IsOpen = false; + _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; + return; + } + + 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() { } + 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); + } }