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: