use imraii in chatlogwindow 1/2

This commit is contained in:
Infi
2024-04-21 20:19:02 +02:00
parent c152f3dfde
commit 2044306c3f
+139 -167
View File
@@ -15,10 +15,13 @@ using Dalamud.Interface;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;
using Dalamud.Interface.Utility; using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Utility.Table;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Memory; using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using ImGuiNET; using ImGuiNET;
using Lumina.Excel;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
namespace ChatTwo.Ui; namespace ChatTwo.Ui;
@@ -28,10 +31,13 @@ public sealed class ChatLogWindow : Window
private const string ChatChannelPicker = "chat-channel-picker"; private const string ChatChannelPicker = "chat-channel-picker";
private const string AutoCompleteId = "##chat2-autocomplete"; private const string AutoCompleteId = "##chat2-autocomplete";
private const ImGuiInputTextFlags InputFlags = ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackCharFilter |
ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory;
internal Plugin Plugin { get; } internal Plugin Plugin { get; }
internal bool ScreenshotMode; internal bool ScreenshotMode;
internal string Salt { get; } private string Salt { get; }
internal Vector4 DefaultText { get; set; } internal Vector4 DefaultText { get; set; }
@@ -40,9 +46,7 @@ public sealed class ChatLogWindow : Window
get get
{ {
var i = LastTab; var i = LastTab;
if (i > -1 && i < Plugin.Config.Tabs.Count) return i > -1 && i < Plugin.Config.Tabs.Count ? Plugin.Config.Tabs[i] : null;
return Plugin.Config.Tabs[i];
return null;
} }
} }
@@ -50,9 +54,9 @@ public sealed class ChatLogWindow : Window
private int _activatePos = -1; private int _activatePos = -1;
internal string Chat = string.Empty; internal string Chat = string.Empty;
private readonly IDalamudTextureWrap? _fontIcon; private readonly IDalamudTextureWrap? _fontIcon;
private readonly List<string> _inputBacklog = new(); private readonly List<string> _inputBacklog = [];
private int _inputBacklogIdx = -1; private int _inputBacklogIdx = -1;
internal int LastTab { get; private set; } private int LastTab { get; set; }
private InputChannel? _tempChannel; private InputChannel? _tempChannel;
private TellTarget? _tellTarget; private TellTarget? _tellTarget;
private readonly Stopwatch _lastResize = new(); private readonly Stopwatch _lastResize = new();
@@ -69,15 +73,18 @@ public sealed class ChatLogWindow : Window
public unsafe ImGuiViewport* LastViewport; public unsafe ImGuiViewport* LastViewport;
private bool _wasDocked; private bool _wasDocked;
internal PayloadHandler PayloadHandler { get; } private PayloadHandler PayloadHandler { get; }
internal Lender<PayloadHandler> HandlerLender { get; } internal Lender<PayloadHandler> HandlerLender { get; }
private Dictionary<string, ChatType> TextCommandChannels { get; } = new(); private Dictionary<string, ChatType> TextCommandChannels { get; } = new();
private HashSet<string> AllCommands { get; } = new(); private HashSet<string> AllCommands { get; } = [];
private uint ChatOpenSfx = 35u; private uint ChatOpenSfx = 35u;
private uint ChatCloseSfx = 3u; private uint ChatCloseSfx = 3u;
private bool PlayedClosingSound = true; private bool PlayedClosingSound = true;
private ExcelSheet<World> WorldSheet;
private ExcelSheet<LogFilter> LogFilterSheet;
internal ChatLogWindow(Plugin plugin) : base($"{Plugin.PluginName}###chat2") internal ChatLogWindow(Plugin plugin) : base($"{Plugin.PluginName}###chat2")
{ {
Plugin = plugin; Plugin = plugin;
@@ -99,6 +106,8 @@ public sealed class ChatLogWindow : Window
Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += ClearLog; Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += ClearLog;
Plugin.Commands.Register("/chat2").Execute += ToggleChat; Plugin.Commands.Register("/chat2").Execute += ToggleChat;
WorldSheet = Plugin.DataManager.GetExcelSheet<World>()!;
LogFilterSheet = Plugin.DataManager.GetExcelSheet<LogFilter>()!;
_fontIcon = Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex"); _fontIcon = Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
Plugin.Functions.Chat.Activated += Activated; Plugin.Functions.Chat.Activated += Activated;
@@ -142,7 +151,8 @@ public sealed class ChatLogWindow : Window
Plugin.MessageManager.FilterAllTabs(false); Plugin.MessageManager.FilterAllTabs(false);
} }
private void Activated(ChatActivatedArgs args) { private void Activated(ChatActivatedArgs args)
{
Activate = true; Activate = true;
if (args.AddIfNotPresent != null && !Chat.Contains(args.AddIfNotPresent)) if (args.AddIfNotPresent != null && !Chat.Contains(args.AddIfNotPresent))
Chat += args.AddIfNotPresent; Chat += args.AddIfNotPresent;
@@ -155,7 +165,6 @@ public sealed class ChatLogWindow : Window
if (info.Channel != null) if (info.Channel != null)
{ {
var prevTemp = _tempChannel; var prevTemp = _tempChannel;
if (info.Permanent) if (info.Permanent)
SetChannel(info.Channel.Value); SetChannel(info.Channel.Value);
else else
@@ -176,7 +185,6 @@ public sealed class ChatLogWindow : Window
else else
{ {
_tellTarget = null; _tellTarget = null;
if (target != null) if (target != null)
_tellTarget = target; _tellTarget = target;
} }
@@ -255,7 +263,6 @@ public sealed class ChatLogWindow : Window
HideState.None => HideState.User, HideState.None => HideState.User,
_ => _hideState, _ => _hideState,
}; };
break; break;
} }
} }
@@ -322,10 +329,7 @@ public sealed class ChatLogWindow : Window
private static float GetRemainingHeightForMessageLog() private static float GetRemainingHeightForMessageLog()
{ {
var lineHeight = ImGui.CalcTextSize("A").Y; var lineHeight = ImGui.CalcTextSize("A").Y;
return ImGui.GetContentRegionAvail().Y return ImGui.GetContentRegionAvail().Y - lineHeight * 2 - ImGui.GetStyle().ItemSpacing.Y - ImGui.GetStyle().FramePadding.Y * 2;
- lineHeight * 2
- ImGui.GetStyle().ItemSpacing.Y
- ImGui.GetStyle().FramePadding.Y * 2;
} }
private void HandleKeybinds(bool modifiersOnly = false) private void HandleKeybinds(bool modifiersOnly = false)
@@ -402,9 +406,8 @@ public sealed class ChatLogWindow : Window
SetChannel(tab.Channel ?? tab.PreviousChannel); SetChannel(tab.Channel ?? tab.PreviousChannel);
} }
private bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78]; private static bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
private static bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78];
private bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
private enum HideState private enum HideState
{ {
@@ -472,7 +475,7 @@ public sealed class ChatLogWindow : Window
{ {
DrawChatLog(); DrawChatLog();
DrawPopOuts(); AddPopOutsToDraw();
DrawAutoComplete(); DrawAutoComplete();
} }
@@ -494,19 +497,14 @@ public sealed class ChatLogWindow : Window
if (currentTab > -1 && currentTab < Plugin.Config.Tabs.Count) if (currentTab > -1 && currentTab < Plugin.Config.Tabs.Count)
activeTab = Plugin.Config.Tabs[currentTab]; activeTab = Plugin.Config.Tabs[currentTab];
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
try
{ {
if (_tellTarget != null) if (_tellTarget != null)
{ {
var playerName = _tellTarget.Name; var playerName = _tellTarget.Name;
if (ScreenshotMode) if (ScreenshotMode)
playerName = HashPlayer(_tellTarget.Name, _tellTarget.World); playerName = HashPlayer(_tellTarget.Name, _tellTarget.World);
var world = WorldSheet.GetRow(_tellTarget.World)?.Name?.RawString ?? "???";
var world = Plugin.DataManager.GetExcelSheet<World>()
?.GetRow(_tellTarget.World)
?.Name
?.RawString ?? "???";
DrawChunks(new Chunk[] DrawChunks(new Chunk[]
{ {
@@ -543,10 +541,7 @@ public sealed class ChatLogWindow : Window
// //
// We don't call channel.ToChatType().Name() as it has the // We don't call channel.ToChatType().Name() as it has the
// long name as used in the settings window. // long name as used in the settings window.
if (channel.IsExtraChatLinkshell()) ImGui.TextUnformatted(channel.IsExtraChatLinkshell() ? $"ECLS [{channel.LinkshellIndex() + 1}]" : channel.ToChatType().Name());
ImGui.TextUnformatted($"ECLS [{channel.LinkshellIndex() + 1}]");
else
ImGui.TextUnformatted(channel.ToChatType().Name());
} }
else if (Plugin.ExtraChat.ChannelOverride is var (overrideName, _)) else if (Plugin.ExtraChat.ChannelOverride is var (overrideName, _))
{ {
@@ -557,12 +552,10 @@ public sealed class ChatLogWindow : Window
if (!string.IsNullOrWhiteSpace(tellPlayerName) && tellWorldId != 0) if (!string.IsNullOrWhiteSpace(tellPlayerName) && tellWorldId != 0)
{ {
var playerName = HashPlayer(tellPlayerName, tellWorldId); var playerName = HashPlayer(tellPlayerName, tellWorldId);
var world = Plugin.DataManager.GetExcelSheet<World>() var world = WorldSheet.GetRow(tellWorldId)?.Name?.RawString ?? "???";
?.GetRow(tellWorldId)
?.Name
?.RawString ?? "???";
DrawChunks(new Chunk[] { DrawChunks(new Chunk[]
{
new TextChunk(ChunkSource.None, null, "Tell "), new TextChunk(ChunkSource.None, null, "Tell "),
new TextChunk(ChunkSource.None, null, playerName), new TextChunk(ChunkSource.None, null, playerName),
new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld), new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld),
@@ -581,28 +574,21 @@ public sealed class ChatLogWindow : Window
DrawChunks(Plugin.Functions.Chat.Channel.name); DrawChunks(Plugin.Functions.Chat.Channel.name);
} }
} }
finally
{
ImGui.PopStyleVar();
}
var beforeIcon = ImGui.GetCursorPos(); var beforeIcon = ImGui.GetCursorPos();
if (ImGuiUtil.IconButton(FontAwesomeIcon.Comment) && activeTab is not { Channel: not null })
if (ImGuiUtil.IconButton(FontAwesomeIcon.Comment) && activeTab is not { Channel: { } })
ImGui.OpenPopup(ChatChannelPicker); ImGui.OpenPopup(ChatChannelPicker);
if (activeTab is { Channel: { } } && ImGui.IsItemHovered()) if (activeTab is { Channel: not null } && ImGui.IsItemHovered())
ImGui.SetTooltip(Language.ChatLog_SwitcherDisabled); ImGui.SetTooltip(Language.ChatLog_SwitcherDisabled);
if (ImGui.BeginPopup(ChatChannelPicker)) using (var popup = ImRaii.Popup(ChatChannelPicker))
{
if (popup)
{ {
foreach (var channel in Enum.GetValues<InputChannel>()) foreach (var channel in Enum.GetValues<InputChannel>())
{ {
var name = Plugin.DataManager.GetExcelSheet<LogFilter>()! var name = LogFilterSheet.FirstOrDefault(row => row.LogKind == (byte) channel.ToChatType())?.Name?.RawString ?? channel.ToChatType().Name();
.FirstOrDefault(row => row.LogKind == (byte) channel.ToChatType())
?.Name
?.RawString ?? channel.ToChatType().Name();
if (channel.IsLinkshell()) if (channel.IsLinkshell())
{ {
var lsName = Plugin.Functions.Chat.GetLinkshellName(channel.LinkshellIndex()); var lsName = Plugin.Functions.Chat.GetLinkshellName(channel.LinkshellIndex());
@@ -633,8 +619,7 @@ public sealed class ChatLogWindow : Window
if (ImGui.Selectable(name)) if (ImGui.Selectable(name))
SetChannel(channel); SetChannel(channel);
} }
}
ImGui.EndPopup();
} }
ImGui.SameLine(); ImGui.SameLine();
@@ -656,11 +641,8 @@ public sealed class ChatLogWindow : Window
inputType = ChatType.Error; inputType = ChatType.Error;
} }
var normalColour = *ImGui.GetStyleColorVec4(ImGuiCol.Text); var normalColor = ImGui.GetColorU32(ImGuiCol.Text);
var inputColour = Plugin.Config.ChatColours.TryGetValue(inputType, out var inputCol) ? inputCol : inputType.DefaultColour();
var inputColour = Plugin.Config.ChatColours.TryGetValue(inputType, out var inputCol)
? inputCol
: inputType.DefaultColour();
if (!isCommand && Plugin.ExtraChat.ChannelOverride is var (_, overrideColour)) if (!isCommand && Plugin.ExtraChat.ChannelOverride is var (_, overrideColour))
inputColour = overrideColour; inputColour = overrideColour;
@@ -668,17 +650,15 @@ public sealed class ChatLogWindow : Window
if (isCommand && Plugin.ExtraChat.ChannelCommandColours.TryGetValue(Chat.Split(' ')[0], out var ecColour)) if (isCommand && Plugin.ExtraChat.ChannelCommandColours.TryGetValue(Chat.Split(' ')[0], out var ecColour))
inputColour = ecColour; inputColour = ecColour;
if (inputColour != null) var push = inputColour != null;
ImGui.PushStyleColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(inputColour.Value)); using (ImRaii.PushColor(ImGuiCol.Text, push ? ColourUtil.RgbaToAbgr(inputColour!.Value) : 0, push))
{
if (Activate) if (Activate)
ImGui.SetKeyboardFocusHere(); ImGui.SetKeyboardFocusHere();
var chatCopy = Chat; var chatCopy = Chat;
ImGui.SetNextItemWidth(inputWidth); ImGui.SetNextItemWidth(inputWidth);
const ImGuiInputTextFlags inputFlags = ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackCharFilter | ImGui.InputText("##chat2-input", ref Chat, 500, InputFlags, Callback);
ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory;
ImGui.InputText("##chat2-input", ref Chat, 500, inputFlags, Callback);
if (ImGui.IsItemDeactivated()) if (ImGui.IsItemDeactivated())
{ {
@@ -693,8 +673,7 @@ public sealed class ChatLogWindow : Window
} }
} }
var enter = ImGui.IsKeyDown(ImGuiKey.Enter) || ImGui.IsKeyDown(ImGuiKey.KeypadEnter); if (ImGui.IsKeyDown(ImGuiKey.Enter) || ImGui.IsKeyDown(ImGuiKey.KeypadEnter))
if (enter)
{ {
Plugin.CommandHelpWindow.IsOpen = false; Plugin.CommandHelpWindow.IsOpen = false;
SendChatBox(activeTab); SendChatBox(activeTab);
@@ -730,39 +709,30 @@ public sealed class ChatLogWindow : Window
} }
} }
if (ImGui.BeginPopupContextItem()) using (var context = ImRaii.ContextPopupItem("ChatInputContext"))
{ {
ImGui.PushStyleColor(ImGuiCol.Text, normalColour); if (context)
try
{ {
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, normalColor);
if (ImGui.Selectable(Language.ChatLog_HideChat)) if (ImGui.Selectable(Language.ChatLog_HideChat))
UserHide(); UserHide();
} }
finally
{
ImGui.PopStyleColor();
} }
ImGui.EndPopup();
} }
if (inputColour != null)
ImGui.PopStyleColor();
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog)) if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog))
Plugin.SettingsWindow.Toggle(); Plugin.SettingsWindow.Toggle();
if (showNovice) if (!showNovice)
{ return;
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiUtil.IconButton(FontAwesomeIcon.Leaf)) if (ImGuiUtil.IconButton(FontAwesomeIcon.Leaf))
Plugin.Functions.ClickNoviceNetworkButton(); Plugin.Functions.ClickNoviceNetworkButton();
} }
}
internal void SetChannel(InputChannel? channel) internal void SetChannel(InputChannel? channel)
{ {
@@ -804,7 +774,7 @@ public sealed class ChatLogWindow : Window
{ {
var target = _tellTarget; var target = _tellTarget;
var reason = target.Reason; var reason = target.Reason;
var world = Plugin.DataManager.GetExcelSheet<World>()?.GetRow(target.World); var world = WorldSheet.GetRow(target.World);
if (world is { IsPublic: true }) if (world is { IsPublic: true })
{ {
if (reason == TellReason.Reply && Plugin.Common.Functions.FriendList.List.Any(friend => friend.ContentId == target.ContentId)) if (reason == TellReason.Reply && Plugin.Common.Functions.FriendList.List.Any(friend => friend.ContentId == target.ContentId))
@@ -819,7 +789,8 @@ public sealed class ChatLogWindow : Window
if (_tempChannel is InputChannel.Tell) if (_tempChannel is InputChannel.Tell)
_tellTarget = null; _tellTarget = null;
goto Skip; Chat = string.Empty;
return;
} }
@@ -835,7 +806,6 @@ public sealed class ChatLogWindow : Window
Plugin.Common.Functions.Chat.SendMessageUnsafe(bytes); Plugin.Common.Functions.Chat.SendMessageUnsafe(bytes);
} }
Skip:
Chat = string.Empty; Chat = string.Empty;
} }
@@ -846,32 +816,63 @@ public sealed class ChatLogWindow : Window
internal void DrawMessageLog(Tab tab, PayloadHandler handler, float childHeight, bool switchedTab) internal void DrawMessageLog(Tab tab, PayloadHandler handler, float childHeight, bool switchedTab)
{ {
if (ImGui.BeginChild("##chat2-messages", new Vector2(-1, childHeight))) using var child = ImRaii.Child("##chat2-messages", new Vector2(-1, childHeight));
{ if (!child.Success)
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
var table = tab.DisplayTimestamp && Plugin.Config.PrettierTimestamps;
var oldCellPaddingY = ImGui.GetStyle().CellPadding.Y;
if (Plugin.Config is { PrettierTimestamps: true, MoreCompactPretty: true })
{
var padding = ImGui.GetStyle().CellPadding;
padding.Y = 0;
ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, padding);
}
if (table)
{
if (!ImGui.BeginTable("timestamp-table", 2, ImGuiTableFlags.PreciseWidths))
{
ImGui.EndChild();
return; return;
var useTable = tab.DisplayTimestamp && Plugin.Config.PrettierTimestamps;
if (useTable)
DrawLogTableStyle(tab, handler, switchedTab);
else
DrawLogNormalStyle(tab, handler, switchedTab);
} }
private void DrawLogNormalStyle(Tab tab, PayloadHandler handler, bool switchedTab)
{
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
{
DrawMessages(tab, handler, false);
}
if (switchedTab || ImGui.GetScrollY() >= ImGui.GetScrollMaxY())
ImGui.SetScrollHereY(1f);
handler.Draw();
}
private void DrawLogTableStyle(Tab tab, PayloadHandler handler, bool switchedTab)
{
var oldItemSpacing = ImGui.GetStyle().ItemSpacing;
var oldCellPadding = ImGui.GetStyle().CellPadding;
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
using (ImRaii.PushStyle(ImGuiStyleVar.CellPadding, oldCellPadding with { Y = 0 }, Plugin.Config.MoreCompactPretty))
{
using var table = ImRaii.Table("timestamp-table", 2, ImGuiTableFlags.PreciseWidths);
if (!table.Success)
return;
ImGui.TableSetupColumn("timestamps", ImGuiTableColumnFlags.WidthFixed); ImGui.TableSetupColumn("timestamps", ImGuiTableColumnFlags.WidthFixed);
ImGui.TableSetupColumn("messages", ImGuiTableColumnFlags.WidthStretch); ImGui.TableSetupColumn("messages", ImGuiTableColumnFlags.WidthStretch);
DrawMessages(tab, handler, true, Plugin.Config.MoreCompactPretty, oldCellPadding.Y);
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, oldItemSpacing))
using (ImRaii.PushStyle(ImGuiStyleVar.CellPadding, oldCellPadding))
{
if (switchedTab || ImGui.GetScrollY() >= ImGui.GetScrollMaxY())
{
Plugin.Log.Information($"Setting Scroll {ImGui.GetScrollY() >= ImGui.GetScrollMaxY()} {ImGui.GetScrollY()} {ImGui.GetScrollMaxY()}");
ImGui.SetScrollHereY(1f);
} }
handler.Draw();
}
}
}
private void DrawMessages(Tab tab, PayloadHandler handler, bool isTable, bool moreCompact = false, float oldCellPaddingY = 0)
{
try try
{ {
tab.MessagesMutex.Wait(); tab.MessagesMutex.Wait();
@@ -889,13 +890,11 @@ public sealed class ChatLogWindow : Window
int? lastMessageHash = null; int? lastMessageHash = null;
var sameCount = 0; var sameCount = 0;
int maxLines = Plugin.Config.MaxLinesToRender; var maxLines = Plugin.Config.MaxLinesToRender;
int startLine = tab.Messages.Count > maxLines ? tab.Messages.Count - maxLines : 0; var startLine = tab.Messages.Count > maxLines ? tab.Messages.Count - maxLines : 0;
for (var i = startLine; i < tab.Messages.Count; i++)
for (int i = startLine; i < tab.Messages.Count; i++)
{ {
var message = tab.Messages[i]; var message = tab.Messages[i];
if (reset) if (reset)
{ {
message.Height = null; message.Height = null;
@@ -909,7 +908,6 @@ public sealed class ChatLogWindow : Window
if (same) if (same)
{ {
sameCount += 1; sameCount += 1;
if (i != tab.Messages.Count - 1) if (i != tab.Messages.Count - 1)
continue; continue;
} }
@@ -927,13 +925,12 @@ public sealed class ChatLogWindow : Window
} }
lastMessageHash = messageHash; lastMessageHash = messageHash;
if (same && i == tab.Messages.Count - 1) if (same && i == tab.Messages.Count - 1)
continue; continue;
} }
// go to next row // go to next row
if (table) if (isTable)
ImGui.TableNextColumn(); ImGui.TableNextColumn();
// message has rendered once // message has rendered once
@@ -943,7 +940,7 @@ public sealed class ChatLogWindow : Window
var beforeDummy = ImGui.GetCursorPos(); var beforeDummy = ImGui.GetCursorPos();
// skip to the message column for vis test // skip to the message column for vis test
if (table) if (isTable)
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.Dummy(new Vector2(10f, message.Height.Value)); ImGui.Dummy(new Vector2(10f, message.Height.Value));
@@ -951,7 +948,7 @@ public sealed class ChatLogWindow : Window
if (message.IsVisible) if (message.IsVisible)
{ {
if (table) if (isTable)
ImGui.TableSetColumnIndex(0); ImGui.TableSetColumnIndex(0);
ImGui.SetCursorPos(beforeDummy); ImGui.SetCursorPos(beforeDummy);
@@ -966,7 +963,7 @@ public sealed class ChatLogWindow : Window
if (tab.DisplayTimestamp) if (tab.DisplayTimestamp)
{ {
var timestamp = message.Date.ToLocalTime().ToString("t"); var timestamp = message.Date.ToLocalTime().ToString("t");
if (table) if (isTable)
{ {
if (!Plugin.Config.HideSameTimestamps || timestamp != lastTimestamp) if (!Plugin.Config.HideSameTimestamps || timestamp != lastTimestamp)
{ {
@@ -981,11 +978,10 @@ public sealed class ChatLogWindow : Window
} }
} }
if (table) if (isTable)
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var lineWidth = ImGui.GetContentRegionAvail().X; var lineWidth = ImGui.GetContentRegionAvail().X;
var beforeDraw = ImGui.GetCursorScreenPos(); var beforeDraw = ImGui.GetCursorScreenPos();
if (message.Sender.Count > 0) if (message.Sender.Count > 0)
{ {
@@ -999,41 +995,30 @@ public sealed class ChatLogWindow : Window
DrawChunks(message.Content, true, handler, lineWidth); DrawChunks(message.Content, true, handler, lineWidth);
var afterDraw = ImGui.GetCursorScreenPos(); var afterDraw = ImGui.GetCursorScreenPos();
message.Height = ImGui.GetCursorPosY() - lastPos; message.Height = ImGui.GetCursorPosY() - lastPos;
if (Plugin.Config is { PrettierTimestamps: true, MoreCompactPretty: false }) if (moreCompact)
{ {
message.Height -= oldCellPaddingY * 2; message.Height -= oldCellPaddingY * 2;
beforeDraw.Y += oldCellPaddingY; beforeDraw.Y += oldCellPaddingY;
afterDraw.Y -= oldCellPaddingY; afterDraw.Y -= oldCellPaddingY;
} }
message.IsVisible = ImGui.IsRectVisible(beforeDraw, afterDraw);
lastPos = ImGui.GetCursorPosY(); lastPos = ImGui.GetCursorPosY();
message.IsVisible = ImGui.IsRectVisible(beforeDraw, afterDraw);
} }
} }
finally finally
{ {
tab.MessagesMutex.Release(); tab.MessagesMutex.Release();
ImGui.PopStyleVar(Plugin.Config is { PrettierTimestamps: true, MoreCompactPretty: true } ? 2 : 1);
} }
if (switchedTab || ImGui.GetScrollY() >= ImGui.GetScrollMaxY())
ImGui.SetScrollHereY(1f);
handler.Draw();
if (table)
ImGui.EndTable();
}
ImGui.EndChild();
} }
private int DrawTabBar() private int DrawTabBar()
{ {
var currentTab = -1; var currentTab = -1;
if (!ImGui.BeginTabBar("##chat2-tabs")) using var tabBar = ImRaii.TabBar("##chat2-tabs");
if (!tabBar.Success)
return currentTab; return currentTab;
for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++) for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++)
@@ -1043,10 +1028,10 @@ public sealed class ChatLogWindow : Window
continue; continue;
var unread = tabI == LastTab || tab.UnreadMode == UnreadMode.None || tab.Unread == 0 ? "" : $" ({tab.Unread})"; var unread = tabI == LastTab || tab.UnreadMode == UnreadMode.None || tab.Unread == 0 ? "" : $" ({tab.Unread})";
var draw = ImGui.BeginTabItem($"{tab.Name}{unread}###log-tab-{tabI}"); using var tabItem = ImRaii.TabItem($"{tab.Name}{unread}###log-tab-{tabI}");
DrawTabContextMenu(tab, tabI); DrawTabContextMenu(tab, tabI);
if (!draw) if (!tabItem.Success)
continue; continue;
currentTab = tabI; currentTab = tabI;
@@ -1057,12 +1042,8 @@ public sealed class ChatLogWindow : Window
tab.Unread = 0; tab.Unread = 0;
DrawMessageLog(tab, PayloadHandler, GetRemainingHeightForMessageLog(), switchedTab); DrawMessageLog(tab, PayloadHandler, GetRemainingHeightForMessageLog(), switchedTab);
ImGui.EndTabItem();
} }
ImGui.EndTabBar();
return currentTab; return currentTab;
} }
@@ -1070,8 +1051,9 @@ public sealed class ChatLogWindow : Window
{ {
var currentTab = -1; var currentTab = -1;
if (!ImGui.BeginTable("tabs-table", 2, ImGuiTableFlags.BordersInnerV | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.Resizable)) using var tabTable = ImRaii.Table("tabs-table", 2, ImGuiTableFlags.BordersInnerV | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.Resizable);
return -1; if (!tabTable.Success)
return currentTab;
ImGui.TableSetupColumn("tabs", ImGuiTableColumnFlags.None, 1); ImGui.TableSetupColumn("tabs", ImGuiTableColumnFlags.None, 1);
ImGui.TableSetupColumn("chat", ImGuiTableColumnFlags.None, 4); ImGui.TableSetupColumn("chat", ImGuiTableColumnFlags.None, 4);
@@ -1080,7 +1062,9 @@ public sealed class ChatLogWindow : Window
var switchedTab = false; var switchedTab = false;
var childHeight = GetRemainingHeightForMessageLog(); var childHeight = GetRemainingHeightForMessageLog();
if (ImGui.BeginChild("##chat2-tab-sidebar", new Vector2(-1, childHeight))) using (var child = ImRaii.Child("##chat2-tab-sidebar", new Vector2(-1, childHeight)))
{
if (child)
{ {
for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++) for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++)
{ {
@@ -1102,8 +1086,7 @@ public sealed class ChatLogWindow : Window
LastTab = tabI; LastTab = tabI;
} }
} }
}
ImGui.EndChild();
ImGui.TableNextColumn(); ImGui.TableNextColumn();
@@ -1116,20 +1099,17 @@ public sealed class ChatLogWindow : Window
if (currentTab > -1) if (currentTab > -1)
DrawMessageLog(Plugin.Config.Tabs[currentTab], PayloadHandler, childHeight, switchedTab); DrawMessageLog(Plugin.Config.Tabs[currentTab], PayloadHandler, childHeight, switchedTab);
ImGui.EndTable();
return currentTab; return currentTab;
} }
private void DrawTabContextMenu(Tab tab, int i) private void DrawTabContextMenu(Tab tab, int i)
{ {
if (!ImGui.BeginPopupContextItem()) using var contextMenu = ImRaii.ContextPopupItem($"tab-context-menu-{i}");
if (!contextMenu.Success)
return; return;
var tabs = Plugin.Config.Tabs;
var anyChanged = false; var anyChanged = false;
var tabs = Plugin.Config.Tabs;
ImGui.PushID($"tab-context-menu-{i}");
ImGui.SetNextItemWidth(250f * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(250f * ImGuiHelpers.GlobalScale);
if (ImGui.InputText("##tab-name", ref tab.Name, 128)) if (ImGui.InputText("##tab-name", ref tab.Name, 128))
@@ -1174,14 +1154,11 @@ public sealed class ChatLogWindow : Window
if (anyChanged) if (anyChanged)
Plugin.SaveConfig(); Plugin.SaveConfig();
ImGui.PopID();
ImGui.EndPopup();
} }
internal readonly List<bool> PopOutDocked = new(); internal readonly List<bool> PopOutDocked = [];
internal Dictionary<string, Window> PopOutWindows = new(); internal readonly Dictionary<string, Window> PopOutWindows = new();
private void DrawPopOuts() private void AddPopOutsToDraw()
{ {
HandlerLender.ResetCounter(); HandlerLender.ResetCounter();
@@ -1213,7 +1190,6 @@ public sealed class ChatLogWindow : Window
return; return;
_autoCompleteList ??= AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Plugin.Config.SortAutoTranslate); _autoCompleteList ??= AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Plugin.Config.SortAutoTranslate);
if (_autoCompleteOpen) if (_autoCompleteOpen)
{ {
ImGui.OpenPopup(AutoCompleteId); ImGui.OpenPopup(AutoCompleteId);
@@ -1221,7 +1197,8 @@ public sealed class ChatLogWindow : Window
} }
ImGui.SetNextWindowSize(new Vector2(400, 300) * ImGuiHelpers.GlobalScale); ImGui.SetNextWindowSize(new Vector2(400, 300) * ImGuiHelpers.GlobalScale);
if (!ImGui.BeginPopup(AutoCompleteId)) using var popup = ImRaii.Popup(AutoCompleteId);
if (!popup.Success)
{ {
if (_activatePos == -1) if (_activatePos == -1)
_activatePos = _autoCompleteInfo.EndPos; _activatePos = _autoCompleteInfo.EndPos;
@@ -1258,7 +1235,7 @@ public sealed class ChatLogWindow : Window
if (ImGui.IsKeyDown(ImGuiKey.Escape)) if (ImGui.IsKeyDown(ImGuiKey.Escape))
{ {
ImGui.CloseCurrentPopup(); ImGui.CloseCurrentPopup();
goto End; return;
} }
var enter = ImGui.IsKeyDown(ImGuiKey.Enter) || ImGui.IsKeyDown(ImGuiKey.KeypadEnter); var enter = ImGui.IsKeyDown(ImGuiKey.Enter) || ImGui.IsKeyDown(ImGuiKey.KeypadEnter);
@@ -1272,8 +1249,10 @@ public sealed class ChatLogWindow : Window
ImGui.SetKeyboardFocusHere(-1); ImGui.SetKeyboardFocusHere(-1);
} }
if (ImGui.BeginChild("##auto-complete-list", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar)) using var child = ImRaii.Child("##auto-complete-list", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar);
{ if (!child.Success)
return;
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper()); var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
clipper.Begin(_autoCompleteList.Count); clipper.Begin(_autoCompleteList.Count);
@@ -1285,7 +1264,6 @@ public sealed class ChatLogWindow : Window
var highlight = _autoCompleteSelection == i; var highlight = _autoCompleteSelection == i;
var clicked = ImGui.Selectable($"{entry.String}##{entry.Group}/{entry.Row}", highlight) || selected == i; var clicked = ImGui.Selectable($"{entry.String}##{entry.Group}/{entry.Row}", highlight) || selected == i;
if (i < 10) if (i < 10)
{ {
var button = (i + 1) % 10; var button = (i + 1) % 10;
@@ -1310,20 +1288,14 @@ public sealed class ChatLogWindow : Window
} }
} }
if (_autoCompleteShouldScroll) if (!_autoCompleteShouldScroll)
{ return;
_autoCompleteShouldScroll = false; _autoCompleteShouldScroll = false;
var selectedPos = clipper.StartPosY + clipper.ItemsHeight * (_autoCompleteSelection * 1f); var selectedPos = clipper.StartPosY + clipper.ItemsHeight * (_autoCompleteSelection * 1f);
ImGui.SetScrollFromPosY(selectedPos - ImGui.GetWindowPos().Y); ImGui.SetScrollFromPosY(selectedPos - ImGui.GetWindowPos().Y);
} }
ImGui.EndChild();
}
End:
ImGui.EndPopup();
}
private unsafe int AutoCompleteCallback(ImGuiInputTextCallbackData* data) private unsafe int AutoCompleteCallback(ImGuiInputTextCallbackData* data)
{ {
if (_fixCursor && _autoCompleteInfo != null) if (_fixCursor && _autoCompleteInfo != null)