From 956b1daaade347aae95841ef5b23e9255f31a738 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 7 Feb 2022 00:50:30 -0500 Subject: [PATCH] feat: add command help --- ChatTwo/Code/InputChannelExt.cs | 2 +- ChatTwo/Configuration.cs | 18 ++++++++ ChatTwo/Resources/Language.Designer.cs | 45 ++++++++++++++++++++ ChatTwo/Resources/Language.resx | 15 +++++++ ChatTwo/Ui/ChatLog.cs | 46 +++++++++++++++++---- ChatTwo/Ui/CommandHelp.cs | 57 ++++++++++++++++++++++++++ ChatTwo/Ui/SettingsTabs/Display.cs | 13 ++++++ 7 files changed, 187 insertions(+), 9 deletions(-) create mode 100755 ChatTwo/Ui/CommandHelp.cs diff --git a/ChatTwo/Code/InputChannelExt.cs b/ChatTwo/Code/InputChannelExt.cs index 9f429a8..3a339ec 100755 --- a/ChatTwo/Code/InputChannelExt.cs +++ b/ChatTwo/Code/InputChannelExt.cs @@ -92,7 +92,7 @@ internal static class InputChannelExt { InputChannel.Shout => new uint[] { 103 }, InputChannel.FreeCompany => new uint[] { 115 }, InputChannel.PvpTeam => new uint[] { 91 }, - InputChannel.NoviceNetwork => new uint[] { 224 }, + InputChannel.NoviceNetwork => new uint[] { 101 }, InputChannel.CrossLinkshell1 => new uint[] { 13 }, InputChannel.CrossLinkshell2 => new uint[] { 14 }, InputChannel.CrossLinkshell3 => new uint[] { 15 }, diff --git a/ChatTwo/Configuration.cs b/ChatTwo/Configuration.cs index d23bcbf..a128110 100755 --- a/ChatTwo/Configuration.cs +++ b/ChatTwo/Configuration.cs @@ -20,6 +20,7 @@ internal class Configuration : IPluginConfiguration { public bool MoreCompactPretty; public bool ShowNoviceNetwork; public bool SidebarTabView; + public CommandHelpSide CommandHelpSide = CommandHelpSide.None; public bool CanMove = true; public bool CanResize = true; public bool ShowTitleBar; @@ -43,6 +44,7 @@ internal class Configuration : IPluginConfiguration { this.MoreCompactPretty = other.MoreCompactPretty; this.ShowNoviceNetwork = other.ShowNoviceNetwork; this.SidebarTabView = other.SidebarTabView; + this.CommandHelpSide = other.CommandHelpSide; this.CanMove = other.CanMove; this.CanResize = other.CanResize; this.ShowTitleBar = other.ShowTitleBar; @@ -169,3 +171,19 @@ internal class Tab { }; } } + +[Serializable] +internal enum CommandHelpSide { + None, + Left, + Right, +} + +internal static class CommandHelpSideExt { + internal static string Name(this CommandHelpSide side) => side switch { + CommandHelpSide.None => Language.CommandHelpSide_None, + CommandHelpSide.Left => Language.CommandHelpSide_Left, + CommandHelpSide.Right => Language.CommandHelpSide_Right, + _ => throw new ArgumentOutOfRangeException(nameof(side), side, null), + }; +} diff --git a/ChatTwo/Resources/Language.Designer.cs b/ChatTwo/Resources/Language.Designer.cs index fc74a7c..4e0c594 100755 --- a/ChatTwo/Resources/Language.Designer.cs +++ b/ChatTwo/Resources/Language.Designer.cs @@ -222,6 +222,33 @@ namespace ChatTwo.Resources { } } + /// + /// Looks up a localized string similar to Left. + /// + internal static string CommandHelpSide_Left { + get { + return ResourceManager.GetString("CommandHelpSide_Left", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to None. + /// + internal static string CommandHelpSide_None { + get { + return ResourceManager.GetString("CommandHelpSide_None", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Right. + /// + internal static string CommandHelpSide_Right { + get { + return ResourceManager.GetString("CommandHelpSide_Right", resourceCulture); + } + } + /// /// Looks up a localized string similar to Click the button to the left to see what's being worked on and what's next.. /// @@ -312,6 +339,24 @@ namespace ChatTwo.Resources { } } + /// + /// Looks up a localized string similar to The side of Chat 2 to display help for commands on.. + /// + internal static string Options_CommandHelpSide_Description { + get { + return ResourceManager.GetString("Options_CommandHelpSide_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Command help side. + /// + internal static string Options_CommandHelpSide_Name { + get { + return ResourceManager.GetString("Options_CommandHelpSide_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Display. /// diff --git a/ChatTwo/Resources/Language.resx b/ChatTwo/Resources/Language.resx index a9c3135..05d9d35 100755 --- a/ChatTwo/Resources/Language.resx +++ b/ChatTwo/Resources/Language.resx @@ -386,4 +386,19 @@ Translators + + None + + + Left + + + Right + + + Command help side + + + The side of Chat 2 to display help for commands on. + diff --git a/ChatTwo/Ui/ChatLog.cs b/ChatTwo/Ui/ChatLog.cs index 954f292..f43db8c 100755 --- a/ChatTwo/Ui/ChatLog.cs +++ b/ChatTwo/Ui/ChatLog.cs @@ -11,6 +11,7 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Interface; using Dalamud.Logging; +using Dalamud.Memory; using ImGuiNET; using ImGuiScene; using Lumina.Excel.GeneratedSheets; @@ -20,7 +21,7 @@ namespace ChatTwo.Ui; internal sealed class ChatLog : IUiComponent { private const string ChatChannelPicker = "chat-channel-picker"; - private PluginUi Ui { get; } + internal PluginUi Ui { get; } internal bool Activate; internal string Chat = string.Empty; @@ -30,8 +31,11 @@ internal sealed class ChatLog : IUiComponent { internal int LastTab { get; private set; } private InputChannel? _tempChannel; private TellTarget? _tellTarget; - private Vector2 _lastWindowSize = Vector2.Zero; private readonly Stopwatch _lastResize = new(); + private CommandHelp? _commandHelp; + + internal Vector2 LastWindowSize { get; private set; } = Vector2.Zero; + internal Vector2 LastWindowPos { get; private set; } = Vector2.Zero; private PayloadHandler PayloadHandler { get; } private Dictionary TextCommandChannels { get; } = new(); @@ -271,7 +275,14 @@ internal sealed class ChatLog : IUiComponent { private HideState _hideState = HideState.None; - public unsafe void Draw() { + public void Draw() { + if (this.DrawChatLog()) { + this._commandHelp?.Draw(); + } + } + + /// true if window was rendered + private unsafe bool DrawChatLog() { // if the chat has no hide state and in a cutscene, set the hide state to cutscene if (this.Ui.Plugin.Config.HideDuringCutscenes && this._hideState == HideState.None && (this.CutsceneActive || this.GposeActive)) { this._hideState = HideState.Cutscene; @@ -293,11 +304,11 @@ internal sealed class ChatLog : IUiComponent { } if (this._hideState is HideState.Cutscene or HideState.User) { - return; + return false; } if (this.Ui.Plugin.Config.HideWhenNotLoggedIn && !this.Ui.Plugin.ClientState.IsLoggedIn) { - return; + return false; } var flags = ImGuiWindowFlags.None; @@ -322,11 +333,12 @@ internal sealed class ChatLog : IUiComponent { if (!ImGui.Begin($"{this.Ui.Plugin.Name}###chat2", flags)) { this._lastViewport = ImGui.GetWindowViewport().NativePtr; ImGui.End(); - return; + return false; } - var resized = this._lastWindowSize != ImGui.GetWindowSize(); - this._lastWindowSize = ImGui.GetWindowSize(); + var resized = this.LastWindowSize != ImGui.GetWindowSize(); + this.LastWindowSize = ImGui.GetWindowSize(); + this.LastWindowPos = ImGui.GetWindowPos(); if (resized) { this._lastResize.Restart(); @@ -522,6 +534,8 @@ internal sealed class ChatLog : IUiComponent { } ImGui.End(); + + return true; } internal void UserHide() { @@ -797,6 +811,22 @@ internal sealed class ChatLog : IUiComponent { data->SelectionStart = data->SelectionEnd = data->CursorPos; } + var text = MemoryHelper.ReadString((IntPtr) data->Buf, data->BufTextLen); + if (text.StartsWith('/')) { + var command = text.Split(' ')[0]; + var cmd = this.Ui.Plugin.DataManager.GetExcelSheet()?.FirstOrDefault(cmd => cmd.Command.RawString == command + || cmd.Alias.RawString == command + || cmd.ShortCommand.RawString == command + || cmd.ShortAlias.RawString == command); + if (cmd != null) { + this._commandHelp = new CommandHelp(this, cmd); + goto PostCommandHelp; + } + } + + this._commandHelp = null; + + PostCommandHelp: if (data->EventFlag != ImGuiInputTextFlags.CallbackHistory) { return 0; } diff --git a/ChatTwo/Ui/CommandHelp.cs b/ChatTwo/Ui/CommandHelp.cs new file mode 100755 index 0000000..b3c3e62 --- /dev/null +++ b/ChatTwo/Ui/CommandHelp.cs @@ -0,0 +1,57 @@ +using System.Numerics; +using ChatTwo.Util; +using Dalamud.Interface; +using Dalamud.Utility; +using ImGuiNET; +using Lumina.Excel.GeneratedSheets; + +namespace ChatTwo.Ui; + +internal class CommandHelp { + private ChatLog Log { get; } + private TextCommand Command { get; } + + internal CommandHelp(ChatLog log, TextCommand command) { + this.Log = log; + this.Command = command; + } + + internal void Draw() { + var width = 350 * ImGuiHelpers.GlobalScale; + + var pos = this.Log.LastWindowPos; + switch (this.Log.Ui.Plugin.Config.CommandHelpSide) { + case CommandHelpSide.Right: + pos.X += this.Log.LastWindowSize.X; + break; + case CommandHelpSide.Left: + pos.X -= width; + break; + case CommandHelpSide.None: + default: + return; + } + + ImGui.SetNextWindowPos(pos); + + ImGui.SetNextWindowSizeConstraints( + new Vector2(width, 0), + new Vector2(width, this.Log.LastWindowSize.Y) + ); + + const ImGuiWindowFlags flags = ImGuiWindowFlags.NoSavedSettings + | ImGuiWindowFlags.NoTitleBar + | ImGuiWindowFlags.NoMove + | ImGuiWindowFlags.NoResize + | ImGuiWindowFlags.NoFocusOnAppearing + | ImGuiWindowFlags.AlwaysAutoResize; + if (!ImGui.Begin($"command help {this.Command.RowId}", flags)) { + ImGui.End(); + return; + } + + this.Log.DrawChunks(ChunkUtil.ToChunks(this.Command.Description.ToDalamudString(), null).ToList()); + + ImGui.End(); + } +} diff --git a/ChatTwo/Ui/SettingsTabs/Display.cs b/ChatTwo/Ui/SettingsTabs/Display.cs index a87be0c..44bddbc 100755 --- a/ChatTwo/Ui/SettingsTabs/Display.cs +++ b/ChatTwo/Ui/SettingsTabs/Display.cs @@ -60,6 +60,19 @@ internal sealed class Display : ISettingsTab { ImGuiUtil.OptionCheckbox(ref this.Mutable.ShowNoviceNetwork, Language.Options_ShowNoviceNetwork_Name, Language.Options_ShowNoviceNetwork_Description); ImGui.Spacing(); + if (ImGui.BeginCombo(Language.Options_CommandHelpSide_Name, this.Mutable.CommandHelpSide.Name())) { + foreach (var side in Enum.GetValues()) { + if (ImGui.Selectable(side.Name(), this.Mutable.CommandHelpSide == side)) { + this.Mutable.CommandHelpSide = side; + } + } + + ImGui.EndCombo(); + } + + ImGuiUtil.HelpText(Language.Options_CommandHelpSide_Description); + ImGui.Spacing(); + if (ImGui.DragFloat(Language.Options_WindowOpacity_Name, ref this.Mutable.WindowAlpha, .0025f, 0f, 1f, $"{this.Mutable.WindowAlpha * 100f:N2}%%")) { switch (this.Mutable.WindowAlpha) { case > 1f and <= 100f: