diff --git a/Dalamud/Game/Gui/Internal/DalamudIME.cs b/Dalamud/Game/Gui/Internal/DalamudIME.cs index 6e9616b8c..4aafa5f3b 100644 --- a/Dalamud/Game/Gui/Internal/DalamudIME.cs +++ b/Dalamud/Game/Gui/Internal/DalamudIME.cs @@ -37,13 +37,18 @@ namespace Dalamud.Game.Gui.Internal /// internal bool IsEnabled { get; private set; } + /// + /// Gets the index of the first imm candidate in relation to the full list. + /// + internal CandidateList ImmCandNative { get; private set; } = default; + /// /// Gets the imm candidates. /// internal List ImmCand { get; private set; } = new(); /// - /// Gets the imm component. + /// Gets the selected imm component. /// internal string ImmComp { get; private set; } = string.Empty; @@ -110,45 +115,47 @@ namespace Dalamud.Game.Gui.Internal return 0; var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0); - if (size > 0) + if (size == 0) + break; + + var candlistPtr = Marshal.AllocHGlobal((int)size); + size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size); + + var candlist = this.ImmCandNative = Marshal.PtrToStructure(candlistPtr); + var pageSize = candlist.PageSize; + var candCount = candlist.Count; + + if (pageSize > 0 && candCount > 1) { - var candlistPtr = Marshal.AllocHGlobal((int)size); - size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size); - - var candlist = Marshal.PtrToStructure(candlistPtr); - var pageSize = candlist.PageSize; - var candCount = candlist.Count; - if (pageSize > 0 && candCount > 1) + var dwOffsets = new int[candCount]; + for (var i = 0; i < candCount; i++) { - var dwOffsets = new int[candCount]; - for (var i = 0; i < candCount; i++) - dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int))); + dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int))); + } - var pageStart = candlist.PageStart; - // var pageEnd = pageStart + pageSize; + var pageStart = candlist.PageStart; - var cand = new string[pageSize]; - this.ImmCand.Clear(); + var cand = new string[pageSize]; + this.ImmCand.Clear(); - for (var i = 0; i < pageSize; i++) + for (var i = 0; i < pageSize; i++) + { + var offStart = dwOffsets[i + pageStart]; + var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size; + + var pStrStart = candlistPtr + (int)offStart; + var pStrEnd = candlistPtr + (int)offEnd; + + var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64()); + if (len > 0) { - var offStart = dwOffsets[i + pageStart]; - var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size; + var candBytes = new byte[len]; + Marshal.Copy(pStrStart, candBytes, 0, len); - var pStrStart = candlistPtr + (int)offStart; - var pStrEnd = candlistPtr + (int)offEnd; + var candStr = Encoding.Unicode.GetString(candBytes); + cand[i] = candStr; - var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64()); - if (len > 0) - { - var candBytes = new byte[len]; - Marshal.Copy(pStrStart, candBytes, 0, len); - - var candStr = Encoding.Unicode.GetString(candBytes); - cand[i] = candStr; - - this.ImmCand.Add(candStr); - } + this.ImmCand.Add(candStr); } } @@ -158,12 +165,16 @@ namespace Dalamud.Game.Gui.Internal break; case IMECommand.OpenCandidate: this.ToggleWindow(true); + this.ImmCandNative = default; this.ImmCand.Clear(); break; + case IMECommand.CloseCandidate: this.ToggleWindow(false); + this.ImmCandNative = default; this.ImmCand.Clear(); break; + default: break; } @@ -188,6 +199,7 @@ namespace Dalamud.Game.Gui.Internal io.AddInputCharactersUTF8(lpstr); this.ImmComp = string.Empty; + this.ImmCandNative = default; this.ImmCand.Clear(); this.ToggleWindow(false); } diff --git a/Dalamud/Interface/Internal/Windows/IMEWindow.cs b/Dalamud/Interface/Internal/Windows/IMEWindow.cs index 8887bbd68..5c936d4e9 100644 --- a/Dalamud/Interface/Internal/Windows/IMEWindow.cs +++ b/Dalamud/Interface/Internal/Windows/IMEWindow.cs @@ -1,6 +1,7 @@ using System.Numerics; using Dalamud.Game.Gui.Internal; +using Dalamud.Interface.Colors; using Dalamud.Interface.Windowing; using ImGuiNET; @@ -11,11 +12,13 @@ namespace Dalamud.Interface.Internal.Windows /// internal class IMEWindow : Window { + private const int ImePageSize = 9; + /// /// Initializes a new instance of the class. /// public IMEWindow() - : base("Dalamud IME", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoFocusOnAppearing) + : base("Dalamud IME", ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysAutoResize) { this.Size = new Vector2(100, 200); this.SizeCondition = ImGuiCond.FirstUseEver; @@ -37,10 +40,30 @@ namespace Dalamud.Interface.Internal.Windows ImGui.Text(ime.ImmComp); ImGui.Separator(); + + var native = ime.ImmCandNative; for (var i = 0; i < ime.ImmCand.Count; i++) { + var selected = i == (native.Selection % ImePageSize); + + if (selected) + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen); + ImGui.Text($"{i + 1}. {ime.ImmCand[i]}"); + + if (selected) + ImGui.PopStyleColor(); } + + var totalIndex = native.Selection + 1; + var totalSize = native.Count; + + var pageStart = native.PageStart; + var pageIndex = (pageStart / ImePageSize) + 1; + var pageCount = (totalSize / ImePageSize) + 1; + + ImGui.Separator(); + ImGui.Text($"{totalIndex}/{totalSize} ({pageIndex}/{pageCount})"); } } }