- New option to limit minimum preview length
- New option only preview with parameters - Improve preview drawing modes - Prevent null ref on plugin load
This commit is contained in:
@@ -25,6 +25,8 @@ internal class Configuration : IPluginConfiguration
|
||||
public bool HideSameTimestamps;
|
||||
public bool ShowNoviceNetwork;
|
||||
public bool SidebarTabView;
|
||||
public bool OnlyPreviewIf;
|
||||
public int PreviewMinimum = 1;
|
||||
public PreviewPosition PreviewPosition = PreviewPosition.Inside;
|
||||
public CommandHelpSide CommandHelpSide = CommandHelpSide.None;
|
||||
public KeybindMode KeybindMode = KeybindMode.Strict;
|
||||
@@ -79,6 +81,8 @@ internal class Configuration : IPluginConfiguration
|
||||
HideSameTimestamps = other.HideSameTimestamps;
|
||||
ShowNoviceNetwork = other.ShowNoviceNetwork;
|
||||
SidebarTabView = other.SidebarTabView;
|
||||
OnlyPreviewIf = other.OnlyPreviewIf;
|
||||
PreviewMinimum = other.PreviewMinimum;
|
||||
PreviewPosition = other.PreviewPosition;
|
||||
CommandHelpSide = other.CommandHelpSide;
|
||||
KeybindMode = other.KeybindMode;
|
||||
|
||||
@@ -461,7 +461,7 @@ internal sealed unsafe class Chat : IDisposable
|
||||
|
||||
private byte ChatLogRefreshDetour(IntPtr log, ushort eventId, AtkValue* value)
|
||||
{
|
||||
if (Plugin.ChatLogWindow.CurrentTab is { InputDisabled: true })
|
||||
if (Plugin is { ChatLogWindow.CurrentTab.InputDisabled: true })
|
||||
return ChatLogRefreshHook!.Original(log, eventId, value);
|
||||
|
||||
if (eventId != 0x31 || value == null || value->UInt is not (0x05 or 0x0C))
|
||||
|
||||
@@ -152,6 +152,7 @@ public sealed class Plugin : IDalamudPlugin
|
||||
|
||||
WindowSystem?.RemoveAllWindows();
|
||||
ChatLogWindow?.Dispose();
|
||||
InputPreview?.Dispose();
|
||||
SettingsWindow?.Dispose();
|
||||
DebuggerWindow?.Dispose();
|
||||
SeStringDebugger?.Dispose();
|
||||
|
||||
Generated
+38
-2
@@ -2400,7 +2400,7 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A preview wih all emote, auto-translate encoded as they appear in chat.
|
||||
/// Looks up a localized string similar to Displays a preview with special parameter evaluated, like emotes and <item>.
|
||||
/// </summary>
|
||||
internal static string Options_Preview_Description {
|
||||
get {
|
||||
@@ -2427,7 +2427,7 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Input preview.
|
||||
/// Looks up a localized string similar to Text preview.
|
||||
/// </summary>
|
||||
internal static string Options_Preview_Name {
|
||||
get {
|
||||
@@ -2462,6 +2462,42 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show only if the text length is greater-than or equal.
|
||||
/// </summary>
|
||||
internal static string Options_PreviewMinimum_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_PreviewMinimum_Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Minimum input length.
|
||||
/// </summary>
|
||||
internal static string Options_PreviewMinimum_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_PreviewMinimum_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show only if the text contains special parameter.
|
||||
/// </summary>
|
||||
internal static string Options_PreviewOnlyIf_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_PreviewOnlyIf_Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Only with parameter.
|
||||
/// </summary>
|
||||
internal static string Options_PreviewOnlyIf_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_PreviewOnlyIf_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Replaces words with their emote version, currently supports BetterTTV.
|
||||
/// </summary>
|
||||
|
||||
@@ -1052,10 +1052,10 @@
|
||||
<value>Emotes available:</value>
|
||||
</data>
|
||||
<data name="Options_Preview_Description" xml:space="preserve">
|
||||
<value>A preview wih all emote, auto-translate encoded as they appear in chat</value>
|
||||
<value>Displays a preview with special parameter evaluated, like emotes and <item></value>
|
||||
</data>
|
||||
<data name="Options_Preview_Name" xml:space="preserve">
|
||||
<value>Input preview</value>
|
||||
<value>Text preview</value>
|
||||
</data>
|
||||
<data name="Options_Preview_None" xml:space="preserve">
|
||||
<value>None</value>
|
||||
@@ -1075,4 +1075,16 @@
|
||||
<data name="Options_Preview_Tooltip" xml:space="preserve">
|
||||
<value>Tooltip</value>
|
||||
</data>
|
||||
<data name="Options_PreviewOnlyIf_Name" xml:space="preserve">
|
||||
<value>Only with parameter</value>
|
||||
</data>
|
||||
<data name="Options_PreviewOnlyIf_Description" xml:space="preserve">
|
||||
<value>Show only if the text contains special parameter</value>
|
||||
</data>
|
||||
<data name="Options_PreviewMinimum_Name" xml:space="preserve">
|
||||
<value>Minimum input length</value>
|
||||
</data>
|
||||
<data name="Options_PreviewMinimum_Description" xml:space="preserve">
|
||||
<value>Show only if the text length is greater-than or equal</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -501,6 +501,7 @@ public sealed class ChatLogWindow : Window
|
||||
DrawAutoComplete();
|
||||
}
|
||||
|
||||
private static bool IsChatMode => Plugin.Config.PreviewPosition is PreviewPosition.Inside or PreviewPosition.Tooltip;
|
||||
private unsafe void DrawChatLog()
|
||||
{
|
||||
// Position change has applied, so we set it to null again
|
||||
@@ -517,7 +518,7 @@ public sealed class ChatLogWindow : Window
|
||||
LastViewport = ImGui.GetWindowViewport().NativePtr;
|
||||
WasDocked = ImGui.IsWindowDocked();
|
||||
|
||||
if (Plugin.Config.PreviewPosition is PreviewPosition.Inside or PreviewPosition.Tooltip)
|
||||
if (IsChatMode && Plugin.InputPreview.IsDrawable)
|
||||
Plugin.InputPreview.CalculatePreview();
|
||||
|
||||
var currentTab = Plugin.Config.SidebarTabView ? DrawTabSidebar() : DrawTabBar();
|
||||
@@ -526,7 +527,7 @@ public sealed class ChatLogWindow : Window
|
||||
if (currentTab > -1 && currentTab < Plugin.Config.Tabs.Count)
|
||||
activeTab = Plugin.Config.Tabs[currentTab];
|
||||
|
||||
if (Plugin.Config.PreviewPosition is PreviewPosition.Inside)
|
||||
if (Plugin.Config.PreviewPosition is PreviewPosition.Inside && Plugin.InputPreview.IsDrawable)
|
||||
Plugin.InputPreview.DrawPreview();
|
||||
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
|
||||
@@ -701,7 +702,8 @@ public sealed class ChatLogWindow : Window
|
||||
ImGui.InputTextWithHint("##chat2-input", isChatEnabled ? "": Language.ChatLog_DisabledInput, ref Chat, 500, flags, Callback);
|
||||
}
|
||||
|
||||
if (Plugin.Config.PreviewPosition is PreviewPosition.Tooltip && !string.IsNullOrEmpty(Chat) && ImGui.IsItemHovered())
|
||||
var tooltipDraw = Plugin.Config.PreviewPosition is PreviewPosition.Tooltip && Plugin.InputPreview.IsDrawable;
|
||||
if (tooltipDraw && ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetNextWindowSize(new Vector2(500 * ImGuiHelpers.GlobalScale, -1));
|
||||
using var tooltip = ImRaii.Tooltip();
|
||||
|
||||
+52
-34
@@ -9,6 +9,7 @@ using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Plugin.Services;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace ChatTwo.Ui;
|
||||
@@ -17,14 +18,17 @@ public class InputPreview : Window
|
||||
{
|
||||
private ChatLogWindow LogWindow { get; }
|
||||
|
||||
private bool Drawing;
|
||||
private bool HasEvaluation;
|
||||
internal float PreviewHeight;
|
||||
|
||||
private int LastLength;
|
||||
private Message? PreviewMessage;
|
||||
|
||||
private bool NextChunkIsAutoTranslate;
|
||||
private int CursorPosition;
|
||||
public int SelectedCursorPos = -1;
|
||||
private bool NextChunkIsAutoTranslate;
|
||||
|
||||
internal int SelectedCursorPos = -1;
|
||||
|
||||
internal InputPreview(ChatLogWindow logWindow) : base("##chat2-inputpreview")
|
||||
{
|
||||
@@ -36,6 +40,49 @@ public class InputPreview : Window
|
||||
RespectCloseHotkey = false;
|
||||
DisableWindowSounds = true;
|
||||
IsOpen = true;
|
||||
|
||||
Plugin.Framework.Update += UpdateConditionCheck;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Plugin.Framework.Update -= UpdateConditionCheck;
|
||||
}
|
||||
|
||||
private bool ValidDraw => !string.IsNullOrEmpty(LogWindow.Chat) && LogWindow.Chat.Length >= Plugin.Config.PreviewMinimum;
|
||||
private void UpdateConditionCheck(IFramework framework)
|
||||
{
|
||||
Drawing = ValidDraw;
|
||||
if (!Drawing)
|
||||
{
|
||||
LastLength = 0;
|
||||
PreviewHeight = 0;
|
||||
PreviewMessage = null;
|
||||
HasEvaluation = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (PreviewMessage == null || LastLength != LogWindow.Chat.Length)
|
||||
{
|
||||
LastLength = LogWindow.Chat.Length;
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(LogWindow.Chat.Trim());
|
||||
AutoTranslate.ReplaceWithPayload(ref bytes);
|
||||
|
||||
var chunks = ChunkUtil.ToChunks(SeString.Parse(bytes), ChunkSource.Content, ChatType.Say).ToList();
|
||||
PreviewMessage = Message.FakeMessage(chunks, new ChatCode((ushort)XivChatType.Say));
|
||||
PreviewMessage.DecodeTextParam();
|
||||
}
|
||||
HasEvaluation = !Plugin.Config.OnlyPreviewIf || PreviewMessage.Content.Count > 1;
|
||||
}
|
||||
|
||||
internal bool IsDrawable => ValidDraw && HasEvaluation;
|
||||
|
||||
private static bool IsWindowMode => Plugin.Config.PreviewPosition is PreviewPosition.Top or PreviewPosition.Bottom;
|
||||
public override bool DrawConditions()
|
||||
{
|
||||
return IsWindowMode && IsDrawable;
|
||||
}
|
||||
|
||||
public override void PreDraw()
|
||||
@@ -56,11 +103,6 @@ public class InputPreview : Window
|
||||
PositionCondition = ImGuiCond.Always;
|
||||
}
|
||||
|
||||
public override bool DrawConditions()
|
||||
{
|
||||
return Plugin.Config.PreviewPosition is PreviewPosition.Top or PreviewPosition.Bottom && !string.IsNullOrEmpty(LogWindow.Chat);
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
CalculatePreview();
|
||||
@@ -71,19 +113,6 @@ public class InputPreview : Window
|
||||
{
|
||||
// We Pre-draw this once to get the actual height :HideThePain:
|
||||
PreviewHeight = 0;
|
||||
if (!string.IsNullOrEmpty(LogWindow.Chat))
|
||||
{
|
||||
if (PreviewMessage == null || LastLength != LogWindow.Chat.Length)
|
||||
{
|
||||
LastLength = LogWindow.Chat.Length;
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(LogWindow.Chat.Trim());
|
||||
AutoTranslate.ReplaceWithPayload(ref bytes);
|
||||
|
||||
var chunks = ChunkUtil.ToChunks(SeString.Parse(bytes), ChunkSource.Content, ChatType.Say).ToList();
|
||||
PreviewMessage = Message.FakeMessage(chunks, new ChatCode((ushort)XivChatType.Say));
|
||||
PreviewMessage.DecodeTextParam();
|
||||
}
|
||||
|
||||
var pos = ImGui.GetCursorPos();
|
||||
ImGui.SetCursorPos(new Vector2(-500, -500));
|
||||
@@ -91,34 +120,23 @@ public class InputPreview : Window
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
|
||||
{
|
||||
ImGui.TextUnformatted(Language.Options_Preview_Header);
|
||||
DrawChunksPreview(PreviewMessage.Content);
|
||||
DrawChunksPreview(PreviewMessage!.Content);
|
||||
}
|
||||
var after = ImGui.GetCursorPosY();
|
||||
ImGui.SetCursorPos(pos);
|
||||
|
||||
PreviewHeight = after - before;
|
||||
PreviewHeight += Plugin.Config.PreviewPosition is not PreviewPosition.Inside
|
||||
? ImGui.GetStyle().WindowPadding.Y * 2
|
||||
: 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LastLength = 0;
|
||||
PreviewMessage = null;
|
||||
}
|
||||
PreviewHeight += IsWindowMode ? ImGui.GetStyle().WindowPadding.Y * 2 : 0;
|
||||
}
|
||||
|
||||
internal void DrawPreview()
|
||||
{
|
||||
if (PreviewMessage == null)
|
||||
return;
|
||||
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
|
||||
{
|
||||
ImGui.TextUnformatted(Language.Options_Preview_Header);
|
||||
|
||||
var handler = LogWindow.HandlerLender.Borrow();
|
||||
DrawChunksPreview(PreviewMessage.Content, handler, unique: 10000);
|
||||
DrawChunksPreview(PreviewMessage!.Content, handler, unique: 10000);
|
||||
handler.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ internal sealed class Miscellaneous(Configuration mutable) : ISettingsTab
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(string.Format(Language.Options_Language_Description, Plugin.PluginName));
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
using (var combo = ImGuiUtil.BeginComboVertical(Language.Options_Preview_Name, Mutable.PreviewPosition.Name()))
|
||||
@@ -33,10 +36,21 @@ internal sealed class Miscellaneous(Configuration mutable) : ISettingsTab
|
||||
Mutable.PreviewPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpText(Language.Options_Preview_Description);
|
||||
ImGui.Spacing();
|
||||
|
||||
if (Mutable.PreviewPosition is not PreviewPosition.None)
|
||||
{
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.OnlyPreviewIf, Language.Options_PreviewOnlyIf_Name, Language.Options_PreviewOnlyIf_Description);
|
||||
ImGui.Spacing();
|
||||
if (ImGuiUtil.InputIntVertical(Language.Options_PreviewMinimum_Name, Language.Options_PreviewMinimum_Description, ref Mutable.PreviewMinimum))
|
||||
Mutable.PreviewMinimum = Math.Clamp(Mutable.PreviewMinimum, 1, 250);
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
using (var combo = ImGuiUtil.BeginComboVertical(Language.Options_CommandHelpSide_Name, Mutable.CommandHelpSide.Name()))
|
||||
{
|
||||
if (combo)
|
||||
|
||||
Reference in New Issue
Block a user