Switch to dalamud window system
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.19.4</Version>
|
<Version>1.20.0</Version>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
Executable → Regular
+8
-63
@@ -1,5 +1,4 @@
|
|||||||
using System.Numerics;
|
using ChatTwo.Ui;
|
||||||
using ChatTwo.Ui;
|
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.GameFonts;
|
using Dalamud.Interface.GameFonts;
|
||||||
using Dalamud.Interface.ManagedFontAtlas;
|
using Dalamud.Interface.ManagedFontAtlas;
|
||||||
@@ -8,32 +7,15 @@ using ImGuiNET;
|
|||||||
|
|
||||||
namespace ChatTwo;
|
namespace ChatTwo;
|
||||||
|
|
||||||
internal sealed class PluginUi : IDisposable {
|
public class FontManager
|
||||||
internal Plugin Plugin { get; }
|
{
|
||||||
|
private readonly Plugin Plugin;
|
||||||
internal bool SettingsVisible;
|
|
||||||
internal bool ScreenshotMode;
|
|
||||||
internal string Salt { get; }
|
|
||||||
|
|
||||||
internal IFontHandle Axis { get; private set; }
|
internal IFontHandle Axis { get; private set; }
|
||||||
internal IFontHandle AxisItalic { get; private set; }
|
internal IFontHandle AxisItalic { get; private set; }
|
||||||
|
|
||||||
internal IFontHandle RegularFont { get; private set; }
|
internal IFontHandle RegularFont { get; private set; }
|
||||||
internal IFontHandle? ItalicFont { get; private set; }
|
internal IFontHandle? ItalicFont { get; private set; }
|
||||||
internal Vector4 DefaultText { get; private set; }
|
|
||||||
|
|
||||||
internal Tab? CurrentTab {
|
|
||||||
get {
|
|
||||||
var i = ChatLog.LastTab;
|
|
||||||
if (i > -1 && i < Plugin.Config.Tabs.Count) {
|
|
||||||
return Plugin.Config.Tabs[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<IUiComponent> Components { get; }
|
|
||||||
|
|
||||||
private FaceData _regularFont;
|
private FaceData _regularFont;
|
||||||
private FaceData? _italicFont;
|
private FaceData? _italicFont;
|
||||||
@@ -44,17 +26,9 @@ internal sealed class PluginUi : IDisposable {
|
|||||||
private ushort[] _jpRange;
|
private ushort[] _jpRange;
|
||||||
private ushort[] _symRange = [0xE020, 0xE0DB, 0];
|
private ushort[] _symRange = [0xE020, 0xE0DB, 0];
|
||||||
|
|
||||||
public readonly ChatLog ChatLog;
|
public FontManager(Plugin plugin)
|
||||||
|
{
|
||||||
internal PluginUi(Plugin plugin) {
|
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
Salt = new Random().Next().ToString();
|
|
||||||
|
|
||||||
ChatLog = new ChatLog(this);
|
|
||||||
Components = new List<IUiComponent> {
|
|
||||||
new Settings(this),
|
|
||||||
ChatLog,
|
|
||||||
};
|
|
||||||
|
|
||||||
var gameSym = new HttpClient().GetAsync("https://img.finalfantasyxiv.com/lds/pc/global/fonts/FFXIV_Lodestone_SSF.ttf")
|
var gameSym = new HttpClient().GetAsync("https://img.finalfantasyxiv.com/lds/pc/global/fonts/FFXIV_Lodestone_SSF.ttf")
|
||||||
.Result
|
.Result
|
||||||
@@ -62,38 +36,9 @@ internal sealed class PluginUi : IDisposable {
|
|||||||
.ReadAsByteArrayAsync()
|
.ReadAsByteArrayAsync()
|
||||||
.Result;
|
.Result;
|
||||||
_gameSymFont = new FaceData(gameSym);
|
_gameSymFont = new FaceData(gameSym);
|
||||||
|
|
||||||
Plugin.Interface.UiBuilder.DisableCutsceneUiHide = true;
|
|
||||||
Plugin.Interface.UiBuilder.DisableGposeUiHide = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
private byte[] GetResource(string name) {
|
||||||
foreach (var component in Components) {
|
|
||||||
component.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw() {
|
|
||||||
if (Plugin.Config.DatabaseMigration != Configuration.LatestDbVersion) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugin.Interface.UiBuilder.DisableUserUiHide = !Plugin.Config.HideWhenUiHidden;
|
|
||||||
DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text];
|
|
||||||
|
|
||||||
using ((Plugin.Config.FontsEnabled ? RegularFont : Axis).Push())
|
|
||||||
{
|
|
||||||
foreach (var component in Components) {
|
|
||||||
try {
|
|
||||||
component.Draw();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Plugin.Log.Error(ex, "Error drawing component");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] GetResource(string name) {
|
|
||||||
var stream = GetType().Assembly.GetManifestResourceStream(name)!;
|
var stream = GetType().Assembly.GetManifestResourceStream(name)!;
|
||||||
var memory = new MemoryStream();
|
var memory = new MemoryStream();
|
||||||
stream.CopyTo(memory);
|
stream.CopyTo(memory);
|
||||||
@@ -257,4 +202,4 @@ internal sealed class PluginUi : IDisposable {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+55
-57
@@ -22,11 +22,10 @@ using ChatTwoPartyFinderPayload = ChatTwo.Util.PartyFinderPayload;
|
|||||||
|
|
||||||
namespace ChatTwo;
|
namespace ChatTwo;
|
||||||
|
|
||||||
internal sealed class PayloadHandler {
|
public sealed class PayloadHandler {
|
||||||
private const string PopupId = "chat2-context-popup";
|
private const string PopupId = "chat2-context-popup";
|
||||||
|
|
||||||
private PluginUi Ui { get; }
|
private ChatLogWindow LogWindow { get; }
|
||||||
private ChatLog Log { get; }
|
|
||||||
|
|
||||||
private (Chunk, Payload?)? Popup { get; set; }
|
private (Chunk, Payload?)? Popup { get; set; }
|
||||||
|
|
||||||
@@ -35,9 +34,8 @@ internal sealed class PayloadHandler {
|
|||||||
private uint _hoverCounter;
|
private uint _hoverCounter;
|
||||||
private uint _lastHoverCounter;
|
private uint _lastHoverCounter;
|
||||||
|
|
||||||
internal PayloadHandler(PluginUi ui, ChatLog log) {
|
internal PayloadHandler(ChatLogWindow logWindow) {
|
||||||
Ui = ui;
|
LogWindow = logWindow;
|
||||||
Log = log;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Draw() {
|
internal void Draw() {
|
||||||
@@ -87,7 +85,7 @@ internal sealed class PayloadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Integrations(Chunk chunk, Payload? payload) {
|
private void Integrations(Chunk chunk, Payload? payload) {
|
||||||
var registered = Ui.Plugin.Ipc.Registered;
|
var registered = LogWindow.Plugin.Ipc.Registered;
|
||||||
if (registered.Count == 0) {
|
if (registered.Count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -102,7 +100,7 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
foreach (var id in registered) {
|
foreach (var id in registered) {
|
||||||
try {
|
try {
|
||||||
Ui.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource);
|
LogWindow.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Plugin.Log.Error(ex, "Error executing integration");
|
Plugin.Log.Error(ex, "Error executing integration");
|
||||||
}
|
}
|
||||||
@@ -127,10 +125,10 @@ internal sealed class PayloadHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Checkbox(Language.Context_ScreenshotMode, ref Ui.ScreenshotMode);
|
ImGui.Checkbox(Language.Context_ScreenshotMode, ref LogWindow.ScreenshotMode);
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_HideChat)) {
|
if (ImGui.Selectable(Language.Context_HideChat)) {
|
||||||
Log.UserHide();
|
LogWindow.UserHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk.Message is { } message) {
|
if (chunk.Message is { } message) {
|
||||||
@@ -186,7 +184,7 @@ internal sealed class PayloadHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemPayload item: {
|
case ItemPayload item: {
|
||||||
if (Ui.Plugin.Config.NativeItemTooltips) {
|
if (LogWindow.Plugin.Config.NativeItemTooltips) {
|
||||||
GameFunctions.GameFunctions.OpenItemTooltip(item.RawItemId);
|
GameFunctions.GameFunctions.OpenItemTooltip(item.RawItemId);
|
||||||
|
|
||||||
_handleTooltips = true;
|
_handleTooltips = true;
|
||||||
@@ -214,7 +212,7 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
ImGui.BeginTooltip();
|
ImGui.BeginTooltip();
|
||||||
ImGui.PushTextWrapPos();
|
ImGui.PushTextWrapPos();
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, Ui.DefaultText);
|
ImGui.PushStyleColor(ImGuiCol.Text, LogWindow.DefaultText);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -237,7 +235,7 @@ internal sealed class PayloadHandler {
|
|||||||
if (!Plugin.GameConfig.TryGet(UiControlOption.DetailTrackingType, out uint selected) || selected != 0)
|
if (!Plugin.GameConfig.TryGet(UiControlOption.DetailTrackingType, out uint selected) || selected != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Log.LastViewport != ImGuiHelpers.MainViewport.NativePtr)
|
if (LogWindow.LastViewport != ImGuiHelpers.MainViewport.NativePtr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var atk = (AtkUnitBase*) args.Addon;
|
var atk = (AtkUnitBase*) args.Addon;
|
||||||
@@ -246,11 +244,11 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
var atkSize = (X: atk->GetScaledWidth(true), Y: atk->GetScaledHeight(true));
|
var atkSize = (X: atk->GetScaledWidth(true), Y: atk->GetScaledHeight(true));
|
||||||
var viewportSize = ImGuiHelpers.MainViewport.Size;
|
var viewportSize = ImGuiHelpers.MainViewport.Size;
|
||||||
var window = Log.LastWindowPos + Log.LastWindowSize;
|
var window = LogWindow.LastWindowPos + LogWindow.LastWindowSize;
|
||||||
var isLeft = window.X < viewportSize.X / 2;
|
var isLeft = window.X < viewportSize.X / 2;
|
||||||
var isTop = window.Y < viewportSize.Y / 2;
|
var isTop = window.Y < viewportSize.Y / 2;
|
||||||
|
|
||||||
var x = isLeft ? window.X : Log.LastWindowPos.X - atkSize.X;
|
var x = isLeft ? window.X : LogWindow.LastWindowPos.X - atkSize.X;
|
||||||
var y = Math.Clamp(window.Y - atkSize.Y, 0, float.MaxValue);
|
var y = Math.Clamp(window.Y - atkSize.Y, 0, float.MaxValue);
|
||||||
y -= isTop ? 0 : 10; // small offset to prevent cut-off on the bottom
|
y -= isTop ? 0 : 10; // small offset to prevent cut-off on the bottom
|
||||||
atk->SetPosition((short) x, (short) y);
|
atk->SetPosition((short) x, (short) y);
|
||||||
@@ -267,16 +265,16 @@ internal sealed class PayloadHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void HoverStatus(StatusPayload status) {
|
private void HoverStatus(StatusPayload status) {
|
||||||
if (Ui.Plugin.TextureCache.GetStatus(status.Status) is { } icon) {
|
if (LogWindow.Plugin.TextureCache.GetStatus(status.Status) is { } icon) {
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = ChunkUtil.ToChunks(status.Status.Name.ToDalamudString(), ChunkSource.None, null);
|
var name = ChunkUtil.ToChunks(status.Status.Name.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(name.ToList());
|
LogWindow.DrawChunks(name.ToList());
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var desc = ChunkUtil.ToChunks(status.Status.Description.ToDalamudString(), ChunkSource.None, null);
|
var desc = ChunkUtil.ToChunks(status.Status.Description.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(desc.ToList());
|
LogWindow.DrawChunks(desc.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HoverItem(ItemPayload item) {
|
private void HoverItem(ItemPayload item) {
|
||||||
@@ -289,16 +287,16 @@ internal sealed class PayloadHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ui.Plugin.TextureCache.GetItem(item.Item, item.IsHQ) is { } icon) {
|
if (LogWindow.Plugin.TextureCache.GetItem(item.Item, item.IsHQ) is { } icon) {
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = ChunkUtil.ToChunks(item.Item.Name.ToDalamudString(), ChunkSource.None, null);
|
var name = ChunkUtil.ToChunks(item.Item.Name.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(name.ToList());
|
LogWindow.DrawChunks(name.ToList());
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var desc = ChunkUtil.ToChunks(item.Item.Description.ToDalamudString(), ChunkSource.None, null);
|
var desc = ChunkUtil.ToChunks(item.Item.Description.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(desc.ToList());
|
LogWindow.DrawChunks(desc.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HoverEventItem(ItemPayload payload) {
|
private void HoverEventItem(ItemPayload payload) {
|
||||||
@@ -307,18 +305,18 @@ internal sealed class PayloadHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ui.Plugin.TextureCache.GetEventItem(item) is { } icon) {
|
if (LogWindow.Plugin.TextureCache.GetEventItem(item) is { } icon) {
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = ChunkUtil.ToChunks(item.Name.ToDalamudString(), ChunkSource.None, null);
|
var name = ChunkUtil.ToChunks(item.Name.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(name.ToList());
|
LogWindow.DrawChunks(name.ToList());
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var help = Plugin.DataManager.GetExcelSheet<EventItemHelp>()?.GetRow(payload.RawItemId);
|
var help = Plugin.DataManager.GetExcelSheet<EventItemHelp>()?.GetRow(payload.RawItemId);
|
||||||
if (help != null) {
|
if (help != null) {
|
||||||
var desc = ChunkUtil.ToChunks(help.Description.ToDalamudString(), ChunkSource.None, null);
|
var desc = ChunkUtil.ToChunks(help.Description.ToDalamudString(), ChunkSource.None, null);
|
||||||
Log.DrawChunks(desc.ToList());
|
LogWindow.DrawChunks(desc.ToList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +327,7 @@ internal sealed class PayloadHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuestPayload quest: {
|
case QuestPayload quest: {
|
||||||
Ui.Plugin.Common.Functions.Journal.OpenQuest(quest.Quest);
|
LogWindow.Plugin.Common.Functions.Journal.OpenQuest(quest.Quest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DalamudLinkPayload link: {
|
case DalamudLinkPayload link: {
|
||||||
@@ -340,17 +338,17 @@ internal sealed class PayloadHandler {
|
|||||||
if (pf.LinkType == DalamudPartyFinderPayload.PartyFinderLinkType.PartyFinderNotification) {
|
if (pf.LinkType == DalamudPartyFinderPayload.PartyFinderLinkType.PartyFinderNotification) {
|
||||||
GameFunctions.GameFunctions.OpenPartyFinder();
|
GameFunctions.GameFunctions.OpenPartyFinder();
|
||||||
} else {
|
} else {
|
||||||
Ui.Plugin.Functions.OpenPartyFinder(pf.ListingId);
|
LogWindow.Plugin.Functions.OpenPartyFinder(pf.ListingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ChatTwoPartyFinderPayload pf: {
|
case ChatTwoPartyFinderPayload pf: {
|
||||||
Ui.Plugin.Functions.OpenPartyFinder(pf.Id);
|
LogWindow.Plugin.Functions.OpenPartyFinder(pf.Id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AchievementPayload achievement: {
|
case AchievementPayload achievement: {
|
||||||
Ui.Plugin.Functions.OpenAchievement(achievement.Id);
|
LogWindow.Plugin.Functions.OpenAchievement(achievement.Id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RawPayload raw: {
|
case RawPayload raw: {
|
||||||
@@ -408,7 +406,7 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
var hq = payload.Kind == ItemPayload.ItemKind.Hq;
|
var hq = payload.Kind == ItemPayload.ItemKind.Hq;
|
||||||
|
|
||||||
if (Ui.Plugin.TextureCache.GetItem(item, hq) is { } icon) {
|
if (LogWindow.Plugin.TextureCache.GetItem(item, hq) is { } icon) {
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,32 +418,32 @@ internal sealed class PayloadHandler {
|
|||||||
name.Payloads.Add(new TextPayload(" "));
|
name.Payloads.Add(new TextPayload(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.DrawChunks(ChunkUtil.ToChunks(name, ChunkSource.None, null).ToList(), false);
|
LogWindow.DrawChunks(ChunkUtil.ToChunks(name, ChunkSource.None, null).ToList(), false);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var realItemId = payload.RawItemId;
|
var realItemId = payload.RawItemId;
|
||||||
if (item.EquipSlotCategory.Row != 0) {
|
if (item.EquipSlotCategory.Row != 0) {
|
||||||
if (ImGui.Selectable(Language.Context_TryOn)) {
|
if (ImGui.Selectable(Language.Context_TryOn)) {
|
||||||
Ui.Plugin.Functions.Context.TryOn(realItemId, 0);
|
LogWindow.Plugin.Functions.Context.TryOn(realItemId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_ItemComparison)) {
|
if (ImGui.Selectable(Language.Context_ItemComparison)) {
|
||||||
Ui.Plugin.Functions.Context.OpenItemComparison(realItemId);
|
LogWindow.Plugin.Functions.Context.OpenItemComparison(realItemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.ItemSearchCategory.Value?.Category == 3) {
|
if (item.ItemSearchCategory.Value?.Category == 3) {
|
||||||
if (ImGui.Selectable(Language.Context_SearchRecipes)) {
|
if (ImGui.Selectable(Language.Context_SearchRecipes)) {
|
||||||
Ui.Plugin.Functions.Context.SearchForRecipesUsingItem(payload.ItemId);
|
LogWindow.Plugin.Functions.Context.SearchForRecipesUsingItem(payload.ItemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_SearchForItem)) {
|
if (ImGui.Selectable(Language.Context_SearchForItem)) {
|
||||||
Ui.Plugin.Functions.Context.SearchForItem(realItemId);
|
LogWindow.Plugin.Functions.Context.SearchForItem(realItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_Link)) {
|
if (ImGui.Selectable(Language.Context_Link)) {
|
||||||
Ui.Plugin.Functions.Context.LinkItem(realItemId);
|
LogWindow.Plugin.Functions.Context.LinkItem(realItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_CopyItemName)) {
|
if (ImGui.Selectable(Language.Context_CopyItemName)) {
|
||||||
@@ -463,17 +461,17 @@ internal sealed class PayloadHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ui.Plugin.TextureCache.GetEventItem(item) is { } icon) {
|
if (LogWindow.Plugin.TextureCache.GetEventItem(item) is { } icon) {
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = item.Name.ToDalamudString();
|
var name = item.Name.ToDalamudString();
|
||||||
Log.DrawChunks(ChunkUtil.ToChunks(name, ChunkSource.None, null).ToList(), false);
|
LogWindow.DrawChunks(ChunkUtil.ToChunks(name, ChunkSource.None, null).ToList(), false);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var realItemId = payload.RawItemId;
|
var realItemId = payload.RawItemId;
|
||||||
if (ImGui.Selectable(Language.Context_Link)) {
|
if (ImGui.Selectable(Language.Context_Link)) {
|
||||||
Ui.Plugin.Functions.Context.LinkItem(realItemId);
|
LogWindow.Plugin.Functions.Context.LinkItem(realItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_CopyItemName)) {
|
if (ImGui.Selectable(Language.Context_CopyItemName)) {
|
||||||
@@ -502,17 +500,17 @@ internal sealed class PayloadHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.DrawChunks(name, false);
|
LogWindow.DrawChunks(name, false);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_SendTell)) {
|
if (ImGui.Selectable(Language.Context_SendTell)) {
|
||||||
Log.Chat = $"/tell {player.PlayerName}";
|
LogWindow.Chat = $"/tell {player.PlayerName}";
|
||||||
if (world.IsPublic) {
|
if (world.IsPublic) {
|
||||||
Log.Chat += $"@{world.Name}";
|
LogWindow.Chat += $"@{world.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Chat += " ";
|
LogWindow.Chat += " ";
|
||||||
Log.Activate = true;
|
LogWindow.Activate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var validContentId = chunk.Message?.ContentId is not (null or 0);
|
var validContentId = chunk.Message?.ContentId is not (null or 0);
|
||||||
@@ -522,21 +520,21 @@ internal sealed class PayloadHandler {
|
|||||||
var isLeader = party.Length == 0 || Plugin.ClientState.LocalContentId == leader;
|
var isLeader = party.Length == 0 || Plugin.ClientState.LocalContentId == leader;
|
||||||
var member = party.FirstOrDefault(member => member.Name.TextValue == player.PlayerName && member.World.Id == world.RowId);
|
var member = party.FirstOrDefault(member => member.Name.TextValue == player.PlayerName && member.World.Id == world.RowId);
|
||||||
var isInParty = member != default;
|
var isInParty = member != default;
|
||||||
var inInstance = Ui.Plugin.Functions.IsInInstance();
|
var inInstance = LogWindow.Plugin.Functions.IsInInstance();
|
||||||
var inPartyInstance = Plugin.DataManager.GetExcelSheet<TerritoryType>()!.GetRow(Plugin.ClientState.TerritoryType)?.TerritoryIntendedUse is (41 or 47 or 48 or 52 or 53);
|
var inPartyInstance = Plugin.DataManager.GetExcelSheet<TerritoryType>()!.GetRow(Plugin.ClientState.TerritoryType)?.TerritoryIntendedUse is (41 or 47 or 48 or 52 or 53);
|
||||||
if (isLeader) {
|
if (isLeader) {
|
||||||
if (!isInParty) {
|
if (!isInParty) {
|
||||||
if (inInstance && inPartyInstance) {
|
if (inInstance && inPartyInstance) {
|
||||||
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty)) {
|
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty)) {
|
||||||
Ui.Plugin.Functions.Party.InviteInInstance(chunk.Message!.ContentId);
|
LogWindow.Plugin.Functions.Party.InviteInInstance(chunk.Message!.ContentId);
|
||||||
}
|
}
|
||||||
} else if (!inInstance && ImGui.BeginMenu(Language.Context_InviteToParty)) {
|
} else if (!inInstance && ImGui.BeginMenu(Language.Context_InviteToParty)) {
|
||||||
if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld)) {
|
if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld)) {
|
||||||
Ui.Plugin.Functions.Party.InviteSameWorld(player.PlayerName, (ushort) world.RowId, chunk.Message?.ContentId ?? 0);
|
LogWindow.Plugin.Functions.Party.InviteSameWorld(player.PlayerName, (ushort) world.RowId, chunk.Message?.ContentId ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty_DifferentWorld)) {
|
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty_DifferentWorld)) {
|
||||||
Ui.Plugin.Functions.Party.InviteOtherWorld(chunk.Message!.ContentId);
|
LogWindow.Plugin.Functions.Party.InviteOtherWorld(chunk.Message!.ContentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
@@ -545,33 +543,33 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
if (isInParty && member != null && (!inInstance || (inInstance && inPartyInstance))) {
|
if (isInParty && member != null && (!inInstance || (inInstance && inPartyInstance))) {
|
||||||
if (ImGui.Selectable(Language.Context_Promote)) {
|
if (ImGui.Selectable(Language.Context_Promote)) {
|
||||||
Ui.Plugin.Functions.Party.Promote(player.PlayerName, (ulong) member.ContentId);
|
LogWindow.Plugin.Functions.Party.Promote(player.PlayerName, (ulong) member.ContentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_KickFromParty)) {
|
if (ImGui.Selectable(Language.Context_KickFromParty)) {
|
||||||
Ui.Plugin.Functions.Party.Kick(player.PlayerName, (ulong) member.ContentId);
|
LogWindow.Plugin.Functions.Party.Kick(player.PlayerName, (ulong) member.ContentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isFriend = Ui.Plugin.Common.Functions.FriendList.List.Any(friend => friend.Name.TextValue == player.PlayerName && friend.HomeWorld == world.RowId);
|
var isFriend = LogWindow.Plugin.Common.Functions.FriendList.List.Any(friend => friend.Name.TextValue == player.PlayerName && friend.HomeWorld == world.RowId);
|
||||||
if (!isFriend && ImGui.Selectable(Language.Context_SendFriendRequest)) {
|
if (!isFriend && ImGui.Selectable(Language.Context_SendFriendRequest)) {
|
||||||
Ui.Plugin.Functions.SendFriendRequest(player.PlayerName, (ushort) world.RowId);
|
LogWindow.Plugin.Functions.SendFriendRequest(player.PlayerName, (ushort) world.RowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_AddToBlacklist)) {
|
if (ImGui.Selectable(Language.Context_AddToBlacklist)) {
|
||||||
Ui.Plugin.Functions.AddToBlacklist(player.PlayerName, (ushort) world.RowId);
|
LogWindow.Plugin.Functions.AddToBlacklist(player.PlayerName, (ushort) world.RowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ui.Plugin.Functions.IsMentor() && ImGui.Selectable(Language.Context_InviteToNoviceNetwork)) {
|
if (LogWindow.Plugin.Functions.IsMentor() && ImGui.Selectable(Language.Context_InviteToNoviceNetwork)) {
|
||||||
Ui.Plugin.Functions.Context.InviteToNoviceNetwork(player.PlayerName, (ushort) world.RowId);
|
LogWindow.Plugin.Functions.Context.InviteToNoviceNetwork(player.PlayerName, (ushort) world.RowId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputChannel = chunk.Message?.Code.Type.ToInputChannel();
|
var inputChannel = chunk.Message?.Code.Type.ToInputChannel();
|
||||||
if (inputChannel != null && ImGui.Selectable(Language.Context_ReplyInSelectedChatMode)) {
|
if (inputChannel != null && ImGui.Selectable(Language.Context_ReplyInSelectedChatMode)) {
|
||||||
Ui.Plugin.Functions.Chat.SetChannel(inputChannel.Value);
|
LogWindow.Plugin.Functions.Chat.SetChannel(inputChannel.Value);
|
||||||
Log.Activate = true;
|
LogWindow.Activate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(Language.Context_Target) && FindCharacterForPayload(player) is { } obj) {
|
if (ImGui.Selectable(Language.Context_Target) && FindCharacterForPayload(player) is { } obj) {
|
||||||
@@ -580,7 +578,7 @@ internal sealed class PayloadHandler {
|
|||||||
|
|
||||||
if (validContentId && ImGui.Selectable(Language.Context_AdventurerPlate))
|
if (validContentId && ImGui.Selectable(Language.Context_AdventurerPlate))
|
||||||
{
|
{
|
||||||
if (!Ui.Plugin.Functions.TryOpenAdventurerPlate(chunk.Message!.ContentId))
|
if (!LogWindow.Plugin.Functions.TryOpenAdventurerPlate(chunk.Message!.ContentId))
|
||||||
WrapperUtil.AddNotification(Language.Context_AdventurerPlateError, NotificationType.Warning);
|
WrapperUtil.AddNotification(Language.Context_AdventurerPlateError, NotificationType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+65
-36
@@ -2,12 +2,14 @@ using System.Diagnostics;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using ChatTwo.Ipc;
|
using ChatTwo.Ipc;
|
||||||
using ChatTwo.Resources;
|
using ChatTwo.Resources;
|
||||||
|
using ChatTwo.Ui;
|
||||||
using ChatTwo.Util;
|
using ChatTwo.Util;
|
||||||
using Dalamud.Game.Addon.Lifecycle;
|
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using ImGuiNET;
|
||||||
using XivCommon;
|
using XivCommon;
|
||||||
|
|
||||||
namespace ChatTwo;
|
namespace ChatTwo;
|
||||||
@@ -35,6 +37,12 @@ public sealed class Plugin : IDalamudPlugin {
|
|||||||
[PluginService] internal static INotificationManager Notification { get; private set; } = null!;
|
[PluginService] internal static INotificationManager Notification { get; private set; } = null!;
|
||||||
[PluginService] internal static IAddonLifecycle AddonLifecycle { get; private set; } = null!;
|
[PluginService] internal static IAddonLifecycle AddonLifecycle { get; private set; } = null!;
|
||||||
|
|
||||||
|
public readonly WindowSystem WindowSystem = new(PluginName);
|
||||||
|
|
||||||
|
public SettingsWindow SettingsWindow { get; }
|
||||||
|
public ChatLogWindow ChatLogWindow { get; }
|
||||||
|
public CommandHelpWindow CommandHelpWindow { get; }
|
||||||
|
|
||||||
internal Configuration Config { get; }
|
internal Configuration Config { get; }
|
||||||
internal Commands Commands { get; }
|
internal Commands Commands { get; }
|
||||||
internal XivCommonBase Common { get; }
|
internal XivCommonBase Common { get; }
|
||||||
@@ -43,7 +51,7 @@ public sealed class Plugin : IDalamudPlugin {
|
|||||||
internal Store Store { get; }
|
internal Store Store { get; }
|
||||||
internal IpcManager Ipc { get; }
|
internal IpcManager Ipc { get; }
|
||||||
internal ExtraChat ExtraChat { get; }
|
internal ExtraChat ExtraChat { get; }
|
||||||
internal PluginUi Ui { get; }
|
internal FontManager FontManager { get; }
|
||||||
|
|
||||||
internal int DeferredSaveFrames = -1;
|
internal int DeferredSaveFrames = -1;
|
||||||
|
|
||||||
@@ -51,69 +59,90 @@ public sealed class Plugin : IDalamudPlugin {
|
|||||||
|
|
||||||
#pragma warning disable CS8618
|
#pragma warning disable CS8618
|
||||||
public Plugin() {
|
public Plugin() {
|
||||||
this.GameStarted = Process.GetCurrentProcess().StartTime.ToUniversalTime();
|
GameStarted = Process.GetCurrentProcess().StartTime.ToUniversalTime();
|
||||||
|
|
||||||
this.Config = Interface.GetPluginConfig() as Configuration ?? new Configuration();
|
Config = Interface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||||
this.Config.Migrate();
|
Config.Migrate();
|
||||||
|
|
||||||
if (this.Config.Tabs.Count == 0) {
|
if (Config.Tabs.Count == 0) {
|
||||||
this.Config.Tabs.Add(TabsUtil.VanillaGeneral);
|
Config.Tabs.Add(TabsUtil.VanillaGeneral);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.LanguageChanged(Interface.UiLanguage);
|
LanguageChanged(Interface.UiLanguage);
|
||||||
|
|
||||||
this.Commands = new Commands(this);
|
Commands = new Commands(this);
|
||||||
this.Common = new XivCommonBase(Interface);
|
Common = new XivCommonBase(Interface);
|
||||||
this.TextureCache = new TextureCache(TextureProvider);
|
TextureCache = new TextureCache(TextureProvider);
|
||||||
this.Functions = new GameFunctions.GameFunctions(this);
|
Functions = new GameFunctions.GameFunctions(this);
|
||||||
this.Ipc = new IpcManager(Interface);
|
Ipc = new IpcManager(Interface);
|
||||||
this.ExtraChat = new ExtraChat(this);
|
ExtraChat = new ExtraChat(this);
|
||||||
this.Ui = new PluginUi(this);
|
FontManager = new FontManager(this);
|
||||||
Ui.BuildFonts();
|
|
||||||
|
|
||||||
this.Store = new Store(this); // requires Ui
|
ChatLogWindow = new ChatLogWindow(this);
|
||||||
|
SettingsWindow = new SettingsWindow(this);
|
||||||
|
CommandHelpWindow = new CommandHelpWindow(ChatLogWindow);
|
||||||
|
|
||||||
|
WindowSystem.AddWindow(ChatLogWindow);
|
||||||
|
WindowSystem.AddWindow(SettingsWindow);
|
||||||
|
WindowSystem.AddWindow(CommandHelpWindow);
|
||||||
|
FontManager.BuildFonts();
|
||||||
|
|
||||||
|
Interface.UiBuilder.DisableCutsceneUiHide = true;
|
||||||
|
Interface.UiBuilder.DisableGposeUiHide = true;
|
||||||
|
|
||||||
|
Store = new Store(this); // requires Ui
|
||||||
|
|
||||||
// let all the other components register, then initialise commands
|
// let all the other components register, then initialise commands
|
||||||
this.Commands.Initialise();
|
Commands.Initialise();
|
||||||
|
|
||||||
if (Interface.Reason is not PluginLoadReason.Boot) {
|
if (Interface.Reason is not PluginLoadReason.Boot) {
|
||||||
this.Store.FilterAllTabs(false);
|
Store.FilterAllTabs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Framework.Update += FrameworkUpdate;
|
Framework.Update += FrameworkUpdate;
|
||||||
Interface.UiBuilder.Draw += Ui.Draw;
|
Interface.UiBuilder.Draw += Draw;
|
||||||
Interface.LanguageChanged += LanguageChanged;
|
Interface.LanguageChanged += LanguageChanged;
|
||||||
|
|
||||||
AddonLifecycle.RegisterListener(AddonEvent.PostRequestedUpdate, "ItemDetail", Ui.ChatLog.PayloadHandler.MoveTooltip);
|
|
||||||
}
|
}
|
||||||
#pragma warning restore CS8618
|
#pragma warning restore CS8618
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
AddonLifecycle.UnregisterListener(AddonEvent.PostRequestedUpdate, "ItemDetail", Ui.ChatLog.PayloadHandler.MoveTooltip);
|
|
||||||
|
|
||||||
Interface.LanguageChanged -= LanguageChanged;
|
Interface.LanguageChanged -= LanguageChanged;
|
||||||
Interface.UiBuilder.Draw -= Ui.Draw;
|
Interface.UiBuilder.Draw -= Draw;
|
||||||
Framework.Update -= FrameworkUpdate;
|
Framework.Update -= FrameworkUpdate;
|
||||||
GameFunctions.GameFunctions.SetChatInteractable(true);
|
GameFunctions.GameFunctions.SetChatInteractable(true);
|
||||||
|
|
||||||
this.Ui.Dispose();
|
WindowSystem.RemoveAllWindows();
|
||||||
this.ExtraChat.Dispose();
|
ChatLogWindow.Dispose();
|
||||||
this.Ipc.Dispose();
|
SettingsWindow.Dispose();
|
||||||
this.Store.Dispose();
|
|
||||||
this.Functions.Dispose();
|
ExtraChat.Dispose();
|
||||||
this.TextureCache.Dispose();
|
Ipc.Dispose();
|
||||||
this.Common.Dispose();
|
Store.Dispose();
|
||||||
this.Commands.Dispose();
|
Functions.Dispose();
|
||||||
|
TextureCache.Dispose();
|
||||||
|
Common.Dispose();
|
||||||
|
Commands.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Draw()
|
||||||
|
{
|
||||||
|
Interface.UiBuilder.DisableUserUiHide = !Config.HideWhenUiHidden;
|
||||||
|
ChatLogWindow.DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text];
|
||||||
|
|
||||||
|
using ((Config.FontsEnabled ? FontManager.RegularFont : FontManager.Axis).Push())
|
||||||
|
{
|
||||||
|
WindowSystem.Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SaveConfig() {
|
internal void SaveConfig() {
|
||||||
Interface.SavePluginConfig(this.Config);
|
Interface.SavePluginConfig(Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LanguageChanged(string langCode) {
|
internal void LanguageChanged(string langCode) {
|
||||||
var info = this.Config.LanguageOverride is LanguageOverride.None
|
var info = Config.LanguageOverride is LanguageOverride.None
|
||||||
? new CultureInfo(langCode)
|
? new CultureInfo(langCode)
|
||||||
: new CultureInfo(this.Config.LanguageOverride.Code());
|
: new CultureInfo(Config.LanguageOverride.Code());
|
||||||
|
|
||||||
Language.Culture = info;
|
Language.Culture = info;
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-132
@@ -1,13 +1,10 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
|
||||||
using ChatTwo.Code;
|
using ChatTwo.Code;
|
||||||
using ChatTwo.Resources;
|
|
||||||
using ChatTwo.Util;
|
using ChatTwo.Util;
|
||||||
using Dalamud.Game.Text;
|
using Dalamud.Game.Text;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using ImGuiNET;
|
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
@@ -21,7 +18,7 @@ internal class Store : IDisposable {
|
|||||||
private ConcurrentQueue<(uint, Message)> Pending { get; } = new();
|
private ConcurrentQueue<(uint, Message)> Pending { get; } = new();
|
||||||
private Stopwatch CheckpointTimer { get; } = new();
|
private Stopwatch CheckpointTimer { get; } = new();
|
||||||
internal ILiteDatabase Database { get; private set; }
|
internal ILiteDatabase Database { get; private set; }
|
||||||
private ILiteCollection<Message> Messages => this.Database.GetCollection<Message>("messages");
|
private ILiteCollection<Message> Messages => Database.GetCollection<Message>("messages");
|
||||||
|
|
||||||
private Dictionary<ChatType, NameFormatting> Formats { get; } = new();
|
private Dictionary<ChatType, NameFormatting> Formats { get; } = new();
|
||||||
private ulong LastContentId { get; set; }
|
private ulong LastContentId { get; set; }
|
||||||
@@ -29,13 +26,13 @@ internal class Store : IDisposable {
|
|||||||
private ulong CurrentContentId {
|
private ulong CurrentContentId {
|
||||||
get {
|
get {
|
||||||
var contentId = Plugin.ClientState.LocalContentId;
|
var contentId = Plugin.ClientState.LocalContentId;
|
||||||
return contentId == 0 ? this.LastContentId : contentId;
|
return contentId == 0 ? LastContentId : contentId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Store(Plugin plugin) {
|
internal Store(Plugin plugin) {
|
||||||
this.Plugin = plugin;
|
Plugin = plugin;
|
||||||
this.CheckpointTimer.Start();
|
CheckpointTimer.Start();
|
||||||
|
|
||||||
BsonMapper.Global = new BsonMapper {
|
BsonMapper.Global = new BsonMapper {
|
||||||
IncludeNonPublic = true,
|
IncludeNonPublic = true,
|
||||||
@@ -43,7 +40,7 @@ internal class Store : IDisposable {
|
|||||||
// EnumAsInteger = true,
|
// EnumAsInteger = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.Plugin.Config.DatabaseMigration == 0) {
|
if (Plugin.Config.DatabaseMigration == 0) {
|
||||||
BsonMapper.Global.Entity<Message>()
|
BsonMapper.Global.Entity<Message>()
|
||||||
.Id(msg => msg.Id)
|
.Id(msg => msg.Id)
|
||||||
.Ctor(doc => new Message(
|
.Ctor(doc => new Message(
|
||||||
@@ -136,26 +133,24 @@ internal class Store : IDisposable {
|
|||||||
dateTime => dateTime.Subtract(DateTime.UnixEpoch).TotalMilliseconds,
|
dateTime => dateTime.Subtract(DateTime.UnixEpoch).TotalMilliseconds,
|
||||||
bson => DateTime.UnixEpoch.AddMilliseconds(bson.AsInt64)
|
bson => DateTime.UnixEpoch.AddMilliseconds(bson.AsInt64)
|
||||||
);
|
);
|
||||||
this.Database = this.Connect();
|
Database = Connect();
|
||||||
this.Messages.EnsureIndex(msg => msg.Date);
|
Messages.EnsureIndex(msg => msg.Date);
|
||||||
this.Messages.EnsureIndex(msg => msg.SortCode);
|
Messages.EnsureIndex(msg => msg.SortCode);
|
||||||
this.Messages.EnsureIndex(msg => msg.ExtraChatChannel);
|
Messages.EnsureIndex(msg => msg.ExtraChatChannel);
|
||||||
|
|
||||||
this.MigrateWrapper();
|
Plugin.ChatGui.ChatMessageUnhandled += ChatMessage;
|
||||||
|
Plugin.Framework.Update += GetMessageInfo;
|
||||||
Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage;
|
Plugin.Framework.Update += UpdateReceiver;
|
||||||
Plugin.Framework.Update += this.GetMessageInfo;
|
Plugin.ClientState.Logout += Logout;
|
||||||
Plugin.Framework.Update += this.UpdateReceiver;
|
|
||||||
Plugin.ClientState.Logout += this.Logout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
Plugin.ClientState.Logout -= this.Logout;
|
Plugin.ClientState.Logout -= Logout;
|
||||||
Plugin.Framework.Update -= this.UpdateReceiver;
|
Plugin.Framework.Update -= UpdateReceiver;
|
||||||
Plugin.Framework.Update -= this.GetMessageInfo;
|
Plugin.Framework.Update -= GetMessageInfo;
|
||||||
Plugin.ChatGui.ChatMessageUnhandled -= this.ChatMessage;
|
Plugin.ChatGui.ChatMessageUnhandled -= ChatMessage;
|
||||||
|
|
||||||
this.Database.Dispose();
|
Database.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILiteDatabase Connect() {
|
private ILiteDatabase Connect() {
|
||||||
@@ -163,7 +158,7 @@ internal class Store : IDisposable {
|
|||||||
dir.Create();
|
dir.Create();
|
||||||
|
|
||||||
var dbPath = Path.Join(dir.FullName, "chat.db");
|
var dbPath = Path.Join(dir.FullName, "chat.db");
|
||||||
var connection = this.Plugin.Config.SharedMode ? "shared" : "direct";
|
var connection = Plugin.Config.SharedMode ? "shared" : "direct";
|
||||||
var connString = $"Filename='{dbPath}';Connection={connection}";
|
var connString = $"Filename='{dbPath}';Connection={connection}";
|
||||||
return new LiteDatabase(connString, BsonMapper.Global) {
|
return new LiteDatabase(connString, BsonMapper.Global) {
|
||||||
CheckpointSize = 1_000,
|
CheckpointSize = 1_000,
|
||||||
@@ -172,127 +167,46 @@ internal class Store : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void Reconnect() {
|
internal void Reconnect() {
|
||||||
this.Database.Dispose();
|
Database.Dispose();
|
||||||
this.Database = this.Connect();
|
Database = Connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Logout() {
|
private void Logout() {
|
||||||
this.LastContentId = 0;
|
LastContentId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateReceiver(IFramework framework) {
|
private void UpdateReceiver(IFramework framework) {
|
||||||
var contentId = Plugin.ClientState.LocalContentId;
|
var contentId = Plugin.ClientState.LocalContentId;
|
||||||
if (contentId != 0) {
|
if (contentId != 0) {
|
||||||
this.LastContentId = contentId;
|
LastContentId = contentId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetMessageInfo(IFramework framework) {
|
private void GetMessageInfo(IFramework framework) {
|
||||||
if (this.CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) {
|
if (CheckpointTimer.Elapsed > TimeSpan.FromMinutes(5)) {
|
||||||
this.CheckpointTimer.Restart();
|
CheckpointTimer.Restart();
|
||||||
new Thread(() => this.Database.Checkpoint()).Start();
|
new Thread(() => Database.Checkpoint()).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Pending.TryDequeue(out var entry)) {
|
if (!Pending.TryDequeue(out var entry)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentId = this.Plugin.Functions.Chat.GetContentIdForEntry(entry.Item1);
|
var contentId = Plugin.Functions.Chat.GetContentIdForEntry(entry.Item1);
|
||||||
entry.Item2.ContentId = contentId ?? 0;
|
entry.Item2.ContentId = contentId ?? 0;
|
||||||
if (this.Plugin.Config.DatabaseBattleMessages || !entry.Item2.Code.IsBattle()) {
|
if (Plugin.Config.DatabaseBattleMessages || !entry.Item2.Code.IsBattle()) {
|
||||||
this.Messages.Update(entry.Item2);
|
Messages.Update(entry.Item2);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long _migrateCurrent;
|
|
||||||
private long _migrateMax;
|
|
||||||
|
|
||||||
private void MigrateDraw() {
|
|
||||||
ImGui.SetNextWindowSizeConstraints(new Vector2(450, 0), new Vector2(450, float.MaxValue));
|
|
||||||
if (!ImGui.Begin($"{Plugin.PluginName}##migration-window", ImGuiWindowFlags.AlwaysAutoResize)) {
|
|
||||||
ImGui.End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PushTextWrapPos();
|
|
||||||
ImGui.TextUnformatted(string.Format(Language.Migration_Line1, Plugin.PluginName));
|
|
||||||
ImGui.TextUnformatted(string.Format(Language.Migration_Line2, Plugin.PluginName));
|
|
||||||
ImGui.TextUnformatted(Language.Migration_Line3);
|
|
||||||
ImGui.TextUnformatted(Language.Migration_Line4);
|
|
||||||
ImGui.PopTextWrapPos();
|
|
||||||
|
|
||||||
ImGui.Spacing();
|
|
||||||
ImGui.ProgressBar((float) this._migrateCurrent / this._migrateMax, new Vector2(-1, 0), $"{this._migrateCurrent} / {this._migrateMax}");
|
|
||||||
|
|
||||||
ImGui.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void MigrateWrapper() {
|
|
||||||
if (this.Plugin.Config.DatabaseMigration < Configuration.LatestDbVersion) {
|
|
||||||
Plugin.Interface.UiBuilder.Draw += this.MigrateDraw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.Migrate();
|
|
||||||
} finally {
|
|
||||||
Plugin.Interface.UiBuilder.Draw -= this.MigrateDraw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Migrate() {
|
|
||||||
// re-save all messages, which will add the ExtraChat channel
|
|
||||||
if (this.Plugin.Config.DatabaseMigration == 0) {
|
|
||||||
var total = (float) this.Messages.LongCount() / 10_000.0;
|
|
||||||
var rounds = (long) Math.Ceiling(total);
|
|
||||||
this._migrateMax = rounds;
|
|
||||||
|
|
||||||
var lastId = ObjectId.Empty;
|
|
||||||
for (var i = 0; i < rounds; i++) {
|
|
||||||
this._migrateCurrent = i + 1;
|
|
||||||
Plugin.Log.Info($"Update round {i + 1}/{rounds}");
|
|
||||||
var messages = this.Messages.Query()
|
|
||||||
.OrderBy(msg => msg.Id)
|
|
||||||
.Where(msg => msg.Id > lastId)
|
|
||||||
.Limit(10_000)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var message in messages) {
|
|
||||||
this.Messages.Update(message);
|
|
||||||
lastId = message.Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Database.Checkpoint();
|
|
||||||
|
|
||||||
BsonMapper.Global.Entity<Message>()
|
|
||||||
.Id(msg => msg.Id)
|
|
||||||
.Ctor(doc => new Message(
|
|
||||||
doc["_id"].AsObjectId,
|
|
||||||
(ulong) doc["Receiver"].AsInt64,
|
|
||||||
(ulong) doc["ContentId"].AsInt64,
|
|
||||||
DateTime.UnixEpoch.AddMilliseconds(doc["Date"].AsInt64),
|
|
||||||
doc["Code"].AsDocument,
|
|
||||||
doc["Sender"].AsArray,
|
|
||||||
doc["Content"].AsArray,
|
|
||||||
doc["SenderSource"],
|
|
||||||
doc["ContentSource"],
|
|
||||||
doc["SortCode"].AsDocument,
|
|
||||||
doc["ExtraChatChannel"]
|
|
||||||
));
|
|
||||||
|
|
||||||
this.Plugin.Config.DatabaseMigration = 1;
|
|
||||||
this.Plugin.SaveConfig();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddMessage(Message message, Tab? currentTab) {
|
internal void AddMessage(Message message, Tab? currentTab) {
|
||||||
if (this.Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) {
|
if (Plugin.Config.DatabaseBattleMessages || !message.Code.IsBattle()) {
|
||||||
this.Messages.Insert(message);
|
Messages.Insert(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentMatches = currentTab?.Matches(message) ?? false;
|
var currentMatches = currentTab?.Matches(message) ?? false;
|
||||||
|
|
||||||
foreach (var tab in this.Plugin.Config.Tabs) {
|
foreach (var tab in Plugin.Config.Tabs) {
|
||||||
var unread = !(tab.UnreadMode == UnreadMode.Unseen && currentTab != tab && currentMatches);
|
var unread = !(tab.UnreadMode == UnreadMode.Unseen && currentTab != tab && currentMatches);
|
||||||
|
|
||||||
if (tab.Matches(message)) {
|
if (tab.Matches(message)) {
|
||||||
@@ -302,8 +216,8 @@ internal class Store : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void FilterAllTabs(bool unread = true) {
|
internal void FilterAllTabs(bool unread = true) {
|
||||||
foreach (var tab in this.Plugin.Config.Tabs) {
|
foreach (var tab in Plugin.Config.Tabs) {
|
||||||
this.FilterTab(tab, unread);
|
FilterTab(tab, unread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,13 +236,13 @@ internal class Store : IDisposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var query = this.Messages
|
var query = Messages
|
||||||
.Query()
|
.Query()
|
||||||
.OrderByDescending(msg => msg.Date)
|
.OrderByDescending(msg => msg.Date)
|
||||||
.Where(msg => sortCodes.Contains(msg.SortCode) || msg.ExtraChatChannel != Guid.Empty)
|
.Where(msg => sortCodes.Contains(msg.SortCode) || msg.ExtraChatChannel != Guid.Empty)
|
||||||
.Where(msg => msg.Receiver == this.CurrentContentId);
|
.Where(msg => msg.Receiver == CurrentContentId);
|
||||||
if (!this.Plugin.Config.FilterIncludePreviousSessions) {
|
if (!Plugin.Config.FilterIncludePreviousSessions) {
|
||||||
query = query.Where(msg => msg.Date >= this.Plugin.GameStarted);
|
query = query.Where(msg => msg.Date >= Plugin.GameStarted);
|
||||||
}
|
}
|
||||||
|
|
||||||
var messages = query
|
var messages = query
|
||||||
@@ -348,7 +262,7 @@ internal class Store : IDisposable {
|
|||||||
|
|
||||||
NameFormatting? formatting = null;
|
NameFormatting? formatting = null;
|
||||||
if (sender.Payloads.Count > 0) {
|
if (sender.Payloads.Count > 0) {
|
||||||
formatting = this.FormatFor(chatCode.Type);
|
formatting = FormatFor(chatCode.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
var senderChunks = new List<Chunk>();
|
var senderChunks = new List<Chunk>();
|
||||||
@@ -364,12 +278,12 @@ internal class Store : IDisposable {
|
|||||||
|
|
||||||
var messageChunks = ChunkUtil.ToChunks(message, ChunkSource.Content, chatCode.Type).ToList();
|
var messageChunks = ChunkUtil.ToChunks(message, ChunkSource.Content, chatCode.Type).ToList();
|
||||||
|
|
||||||
var msg = new Message(this.CurrentContentId, chatCode, senderChunks, messageChunks, sender, message);
|
var msg = new Message(CurrentContentId, chatCode, senderChunks, messageChunks, sender, message);
|
||||||
this.AddMessage(msg, this.Plugin.Ui.CurrentTab ?? null);
|
AddMessage(msg, Plugin.ChatLogWindow.CurrentTab ?? null);
|
||||||
|
|
||||||
var idx = this.Plugin.Functions.GetCurrentChatLogEntryIndex();
|
var idx = Plugin.Functions.GetCurrentChatLogEntryIndex();
|
||||||
if (idx != null) {
|
if (idx != null) {
|
||||||
this.Pending.Enqueue((idx.Value - 1, msg));
|
Pending.Enqueue((idx.Value - 1, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,7 +307,7 @@ internal class Store : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NameFormatting? FormatFor(ChatType type) {
|
private NameFormatting? FormatFor(ChatType type) {
|
||||||
if (this.Formats.TryGetValue(type, out var cached)) {
|
if (Formats.TryGetValue(type, out var cached)) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +348,7 @@ internal class Store : IDisposable {
|
|||||||
string.Join("", after)
|
string.Join("", after)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.Formats[type] = nameFormatting;
|
Formats[type] = nameFormatting;
|
||||||
|
|
||||||
return nameFormatting;
|
return nameFormatting;
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+178
-194
@@ -6,6 +6,7 @@ using ChatTwo.Code;
|
|||||||
using ChatTwo.GameFunctions.Types;
|
using ChatTwo.GameFunctions.Types;
|
||||||
using ChatTwo.Resources;
|
using ChatTwo.Resources;
|
||||||
using ChatTwo.Util;
|
using ChatTwo.Util;
|
||||||
|
using Dalamud.Game.Addon.Lifecycle;
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Keys;
|
using Dalamud.Game.ClientState.Keys;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
@@ -13,17 +14,34 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Internal;
|
using Dalamud.Interface.Internal;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
namespace ChatTwo.Ui;
|
namespace ChatTwo.Ui;
|
||||||
|
|
||||||
internal sealed class ChatLog : IUiComponent {
|
public sealed class ChatLogWindow : Window, IUiComponent {
|
||||||
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";
|
||||||
|
|
||||||
internal PluginUi Ui { get; }
|
internal Plugin Plugin { get; }
|
||||||
|
|
||||||
|
internal bool ScreenshotMode;
|
||||||
|
internal string Salt { get; }
|
||||||
|
|
||||||
|
internal Vector4 DefaultText { get; set; }
|
||||||
|
|
||||||
|
internal Tab? CurrentTab {
|
||||||
|
get {
|
||||||
|
var i = LastTab;
|
||||||
|
if (i > -1 && i < Plugin.Config.Tabs.Count) {
|
||||||
|
return Plugin.Config.Tabs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal bool Activate;
|
internal bool Activate;
|
||||||
private int _activatePos = -1;
|
private int _activatePos = -1;
|
||||||
@@ -35,7 +53,6 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
private InputChannel? _tempChannel;
|
private InputChannel? _tempChannel;
|
||||||
private TellTarget? _tellTarget;
|
private TellTarget? _tellTarget;
|
||||||
private readonly Stopwatch _lastResize = new();
|
private readonly Stopwatch _lastResize = new();
|
||||||
private CommandHelp? _commandHelp;
|
|
||||||
private AutoCompleteInfo? _autoCompleteInfo;
|
private AutoCompleteInfo? _autoCompleteInfo;
|
||||||
private bool _autoCompleteOpen;
|
private bool _autoCompleteOpen;
|
||||||
private List<AutoTranslateEntry>? _autoCompleteList;
|
private List<AutoTranslateEntry>? _autoCompleteList;
|
||||||
@@ -49,46 +66,59 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
public unsafe ImGuiViewport* LastViewport;
|
public unsafe ImGuiViewport* LastViewport;
|
||||||
private bool _wasDocked;
|
private bool _wasDocked;
|
||||||
|
|
||||||
public PayloadHandler PayloadHandler { get; }
|
internal PayloadHandler PayloadHandler { get; }
|
||||||
private 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; } = new();
|
||||||
|
|
||||||
internal ChatLog(PluginUi ui) {
|
internal ChatLogWindow(Plugin plugin) : base($"{Plugin.PluginName}###chat2") {
|
||||||
Ui = ui;
|
Plugin = plugin;
|
||||||
PayloadHandler = new PayloadHandler(Ui, this);
|
Salt = new Random().Next().ToString();
|
||||||
HandlerLender = new Lender<PayloadHandler>(() => new PayloadHandler(Ui, this));
|
|
||||||
|
SizeCondition = ImGuiCond.FirstUseEver;
|
||||||
|
SizeConstraints = new WindowSizeConstraints
|
||||||
|
{
|
||||||
|
MinimumSize = new Vector2(500, 250),
|
||||||
|
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
||||||
|
};
|
||||||
|
|
||||||
|
PayloadHandler = new PayloadHandler(this);
|
||||||
|
HandlerLender = new Lender<PayloadHandler>(() => new PayloadHandler(this));
|
||||||
|
|
||||||
SetUpTextCommandChannels();
|
SetUpTextCommandChannels();
|
||||||
SetUpAllCommands();
|
SetUpAllCommands();
|
||||||
|
|
||||||
Ui.Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += ClearLog;
|
Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += ClearLog;
|
||||||
Ui.Plugin.Commands.Register("/chat2").Execute += ToggleChat;
|
Plugin.Commands.Register("/chat2").Execute += ToggleChat;
|
||||||
|
|
||||||
_fontIcon = Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
|
_fontIcon = Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
|
||||||
|
|
||||||
Ui.Plugin.Functions.Chat.Activated += Activated;
|
Plugin.Functions.Chat.Activated += Activated;
|
||||||
Plugin.ClientState.Login += Login;
|
Plugin.ClientState.Login += Login;
|
||||||
Plugin.ClientState.Logout += Logout;
|
Plugin.ClientState.Logout += Logout;
|
||||||
|
|
||||||
|
Plugin.AddonLifecycle.RegisterListener(AddonEvent.PostRequestedUpdate, "ItemDetail", PayloadHandler.MoveTooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
|
Plugin.AddonLifecycle.UnregisterListener(AddonEvent.PostRequestedUpdate, "ItemDetail", PayloadHandler.MoveTooltip);
|
||||||
|
|
||||||
Plugin.ClientState.Logout -= Logout;
|
Plugin.ClientState.Logout -= Logout;
|
||||||
Plugin.ClientState.Login -= Login;
|
Plugin.ClientState.Login -= Login;
|
||||||
Ui.Plugin.Functions.Chat.Activated -= Activated;
|
Plugin.Functions.Chat.Activated -= Activated;
|
||||||
_fontIcon?.Dispose();
|
_fontIcon?.Dispose();
|
||||||
Ui.Plugin.Commands.Register("/chat2").Execute -= ToggleChat;
|
Plugin.Commands.Register("/chat2").Execute -= ToggleChat;
|
||||||
Ui.Plugin.Commands.Register("/clearlog2").Execute -= ClearLog;
|
Plugin.Commands.Register("/clearlog2").Execute -= ClearLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Logout() {
|
private void Logout() {
|
||||||
foreach (var tab in Ui.Plugin.Config.Tabs) {
|
foreach (var tab in Plugin.Config.Tabs) {
|
||||||
tab.Clear();
|
tab.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Login() {
|
private void Login() {
|
||||||
Ui.Plugin.Store.FilterAllTabs(false);
|
Plugin.Store.FilterAllTabs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Activated(ChatActivatedArgs args) {
|
private void Activated(ChatActivatedArgs args) {
|
||||||
@@ -107,7 +137,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var prevTemp = _tempChannel;
|
var prevTemp = _tempChannel;
|
||||||
|
|
||||||
if (info.Permanent) {
|
if (info.Permanent) {
|
||||||
Ui.Plugin.Functions.Chat.SetChannel(info.Channel.Value);
|
Plugin.Functions.Chat.SetChannel(info.Channel.Value);
|
||||||
} else {
|
} else {
|
||||||
_tempChannel = info.Channel.Value;
|
_tempChannel = info.Channel.Value;
|
||||||
}
|
}
|
||||||
@@ -120,7 +150,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
? -1
|
? -1
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
var tellInfo = Ui.Plugin.Functions.Chat.GetTellHistoryInfo(idx);
|
var tellInfo = Plugin.Functions.Chat.GetTellHistoryInfo(idx);
|
||||||
if (tellInfo != null && reason != null) {
|
if (tellInfo != null && reason != null) {
|
||||||
_tellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
|
_tellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
|
||||||
}
|
}
|
||||||
@@ -140,10 +170,10 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
: info.Rotate;
|
: info.Rotate;
|
||||||
|
|
||||||
if (info.Channel is InputChannel.Linkshell1 && info.Rotate != RotateMode.None) {
|
if (info.Channel is InputChannel.Linkshell1 && info.Rotate != RotateMode.None) {
|
||||||
var idx = Ui.Plugin.Functions.Chat.RotateLinkshellHistory(mode);
|
var idx = Plugin.Functions.Chat.RotateLinkshellHistory(mode);
|
||||||
_tempChannel = info.Channel.Value + (uint) idx;
|
_tempChannel = info.Channel.Value + (uint) idx;
|
||||||
} else if (info.Channel is InputChannel.CrossLinkshell1 && info.Rotate != RotateMode.None) {
|
} else if (info.Channel is InputChannel.CrossLinkshell1 && info.Rotate != RotateMode.None) {
|
||||||
var idx = Ui.Plugin.Functions.Chat.RotateCrossLinkshellHistory(mode);
|
var idx = Plugin.Functions.Chat.RotateCrossLinkshellHistory(mode);
|
||||||
_tempChannel = info.Channel.Value + (uint) idx;
|
_tempChannel = info.Channel.Value + (uint) idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +191,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
private void ClearLog(string command, string arguments) {
|
private void ClearLog(string command, string arguments) {
|
||||||
switch (arguments) {
|
switch (arguments) {
|
||||||
case "all":
|
case "all":
|
||||||
foreach (var tab in Ui.Plugin.Config.Tabs) {
|
foreach (var tab in Plugin.Config.Tabs) {
|
||||||
tab.Clear();
|
tab.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +203,8 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (LastTab > -1 && LastTab < Ui.Plugin.Config.Tabs.Count) {
|
if (LastTab > -1 && LastTab < Plugin.Config.Tabs.Count) {
|
||||||
Ui.Plugin.Config.Tabs[LastTab].Clear();
|
Plugin.Config.Tabs[LastTab].Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -287,7 +317,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var turnedOff = new Dictionary<VirtualKey, (uint, string)>();
|
var turnedOff = new Dictionary<VirtualKey, (uint, string)>();
|
||||||
foreach (var (toIntercept, keybind) in Ui.Plugin.Functions.Chat.Keybinds) {
|
foreach (var (toIntercept, keybind) in Plugin.Functions.Chat.Keybinds) {
|
||||||
if (toIntercept is "CMD_CHAT" or "CMD_COMMAND") {
|
if (toIntercept is "CMD_CHAT" or "CMD_COMMAND") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -297,7 +327,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var modifierPressed = Ui.Plugin.Config.KeybindMode switch {
|
var modifierPressed = Plugin.Config.KeybindMode switch {
|
||||||
KeybindMode.Strict => modifier == modifierState,
|
KeybindMode.Strict => modifier == modifierState,
|
||||||
KeybindMode.Flexible => modifierState.HasFlag(modifier),
|
KeybindMode.Flexible => modifierState.HasFlag(modifier),
|
||||||
_ => false,
|
_ => false,
|
||||||
@@ -354,90 +384,80 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
private HideState _hideState = HideState.None;
|
private HideState _hideState = HideState.None;
|
||||||
|
|
||||||
public void Draw() {
|
public override unsafe void PreOpenCheck()
|
||||||
if (!DrawChatLog()) {
|
{
|
||||||
|
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
|
||||||
|
if (Plugin.Config.HideDuringCutscenes && _hideState == HideState.None && (CutsceneActive || GposeActive))
|
||||||
|
_hideState = HideState.Cutscene;
|
||||||
|
|
||||||
|
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
|
||||||
|
if (_hideState is HideState.Cutscene or HideState.CutsceneOverride && !CutsceneActive && !GposeActive)
|
||||||
|
_hideState = HideState.None;
|
||||||
|
|
||||||
|
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
|
||||||
|
if (_hideState == HideState.Cutscene && Activate)
|
||||||
|
_hideState = HideState.CutsceneOverride;
|
||||||
|
|
||||||
|
// if the user hid the chat and is now activating chat, reset the hide state
|
||||||
|
if (_hideState == HideState.User && Activate)
|
||||||
|
_hideState = HideState.None;
|
||||||
|
|
||||||
|
if (_hideState is HideState.Cutscene or HideState.User)
|
||||||
|
{
|
||||||
|
IsOpen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandHelp?.Draw();
|
if (Plugin.Config.HideWhenNotLoggedIn && !Plugin.ClientState.IsLoggedIn) {
|
||||||
|
IsOpen = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsOpen = true;
|
||||||
|
|
||||||
|
Flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
|
||||||
|
if (Plugin.Config.CanMove)
|
||||||
|
Flags |= ImGuiWindowFlags.NoMove;
|
||||||
|
|
||||||
|
if (Plugin.Config.CanResize)
|
||||||
|
Flags |= ImGuiWindowFlags.NoResize;
|
||||||
|
|
||||||
|
if (!Plugin.Config.ShowTitleBar)
|
||||||
|
Flags |= ImGuiWindowFlags.NoTitleBar;
|
||||||
|
|
||||||
|
if (LastViewport == ImGuiHelpers.MainViewport.NativePtr && !_wasDocked)
|
||||||
|
BgAlpha = Plugin.Config.WindowAlpha / 100f;
|
||||||
|
|
||||||
|
LastViewport = ImGui.GetWindowViewport().NativePtr;
|
||||||
|
_wasDocked = ImGui.IsWindowDocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
DrawChatLog();
|
||||||
|
|
||||||
DrawPopOuts();
|
DrawPopOuts();
|
||||||
DrawAutoComplete();
|
DrawAutoComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>true if window was rendered</returns>
|
/// <returns>true if window was rendered</returns>
|
||||||
private unsafe bool DrawChatLog() {
|
private unsafe void DrawChatLog()
|
||||||
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
|
{
|
||||||
if (Ui.Plugin.Config.HideDuringCutscenes && _hideState == HideState.None && (CutsceneActive || GposeActive)) {
|
|
||||||
_hideState = HideState.Cutscene;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
|
|
||||||
if (_hideState is HideState.Cutscene or HideState.CutsceneOverride && !CutsceneActive && !GposeActive) {
|
|
||||||
_hideState = HideState.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
|
|
||||||
if (_hideState == HideState.Cutscene && Activate) {
|
|
||||||
_hideState = HideState.CutsceneOverride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the user hid the chat and is now activating chat, reset the hide state
|
|
||||||
if (_hideState == HideState.User && Activate) {
|
|
||||||
_hideState = HideState.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_hideState is HideState.Cutscene or HideState.User) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Ui.Plugin.Config.HideWhenNotLoggedIn && !Plugin.ClientState.IsLoggedIn) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
|
|
||||||
if (!Ui.Plugin.Config.CanMove) {
|
|
||||||
flags |= ImGuiWindowFlags.NoMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Ui.Plugin.Config.CanResize) {
|
|
||||||
flags |= ImGuiWindowFlags.NoResize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Ui.Plugin.Config.ShowTitleBar) {
|
|
||||||
flags |= ImGuiWindowFlags.NoTitleBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LastViewport == ImGuiHelpers.MainViewport.NativePtr && !_wasDocked) {
|
|
||||||
ImGui.SetNextWindowBgAlpha(Ui.Plugin.Config.WindowAlpha / 100f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SetNextWindowSize(new Vector2(500, 250) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
|
|
||||||
|
|
||||||
if (!ImGui.Begin($"{Plugin.PluginName}###chat2", flags)) {
|
|
||||||
LastViewport = ImGui.GetWindowViewport().NativePtr;
|
|
||||||
_wasDocked = ImGui.IsWindowDocked();
|
|
||||||
ImGui.End();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resized = LastWindowSize != ImGui.GetWindowSize();
|
var resized = LastWindowSize != ImGui.GetWindowSize();
|
||||||
LastWindowSize = ImGui.GetWindowSize();
|
LastWindowSize = ImGui.GetWindowSize();
|
||||||
LastWindowPos = ImGui.GetWindowPos();
|
LastWindowPos = ImGui.GetWindowPos();
|
||||||
|
|
||||||
if (resized) {
|
if (resized)
|
||||||
_lastResize.Restart();
|
_lastResize.Restart();
|
||||||
}
|
|
||||||
|
|
||||||
LastViewport = ImGui.GetWindowViewport().NativePtr;
|
LastViewport = ImGui.GetWindowViewport().NativePtr;
|
||||||
_wasDocked = ImGui.IsWindowDocked();
|
_wasDocked = ImGui.IsWindowDocked();
|
||||||
|
|
||||||
var currentTab = Ui.Plugin.Config.SidebarTabView
|
var currentTab = Plugin.Config.SidebarTabView ? DrawTabSidebar() : DrawTabBar();
|
||||||
? DrawTabSidebar()
|
|
||||||
: DrawTabBar();
|
|
||||||
|
|
||||||
Tab? activeTab = null;
|
Tab? activeTab = null;
|
||||||
if (currentTab > -1 && currentTab < Ui.Plugin.Config.Tabs.Count) {
|
if (currentTab > -1 && currentTab < Plugin.Config.Tabs.Count) {
|
||||||
activeTab = Ui.Plugin.Config.Tabs[currentTab];
|
activeTab = Plugin.Config.Tabs[currentTab];
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||||
@@ -457,23 +477,25 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
} else if (_tempChannel != null) {
|
} else if (_tempChannel != null) {
|
||||||
if (_tempChannel.Value.IsLinkshell()) {
|
if (_tempChannel.Value.IsLinkshell()) {
|
||||||
var idx = (uint) _tempChannel.Value - (uint) InputChannel.Linkshell1;
|
var idx = (uint) _tempChannel.Value - (uint) InputChannel.Linkshell1;
|
||||||
var lsName = Ui.Plugin.Functions.Chat.GetLinkshellName(idx);
|
var lsName = Plugin.Functions.Chat.GetLinkshellName(idx);
|
||||||
ImGui.TextUnformatted($"LS #{idx + 1}: {lsName}");
|
ImGui.TextUnformatted($"LS #{idx + 1}: {lsName}");
|
||||||
} else if (_tempChannel.Value.IsCrossLinkshell()) {
|
} else if (_tempChannel.Value.IsCrossLinkshell()) {
|
||||||
var idx = (uint) _tempChannel.Value - (uint) InputChannel.CrossLinkshell1;
|
var idx = (uint) _tempChannel.Value - (uint) InputChannel.CrossLinkshell1;
|
||||||
var cwlsName = Ui.Plugin.Functions.Chat.GetCrossLinkshellName(idx);
|
var cwlsName = Plugin.Functions.Chat.GetCrossLinkshellName(idx);
|
||||||
ImGui.TextUnformatted($"CWLS [{idx + 1}]: {cwlsName}");
|
ImGui.TextUnformatted($"CWLS [{idx + 1}]: {cwlsName}");
|
||||||
} else {
|
} else {
|
||||||
ImGui.TextUnformatted(_tempChannel.Value.ToChatType().Name());
|
ImGui.TextUnformatted(_tempChannel.Value.ToChatType().Name());
|
||||||
}
|
}
|
||||||
} else if (activeTab is { Channel: { } channel }) {
|
} else if (activeTab is { Channel: { } channel }) {
|
||||||
ImGui.TextUnformatted(channel.ToChatType().Name());
|
ImGui.TextUnformatted(channel.ToChatType().Name());
|
||||||
} else if (Ui.Plugin.ExtraChat.ChannelOverride is var (overrideName, _)) {
|
} else if (Plugin.ExtraChat.ChannelOverride is var (overrideName, _)) {
|
||||||
ImGui.TextUnformatted(overrideName);
|
ImGui.TextUnformatted(overrideName);
|
||||||
} else {
|
} else {
|
||||||
DrawChunks(Ui.Plugin.Functions.Chat.Channel.name);
|
DrawChunks(Plugin.Functions.Chat.Channel.name);
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
ImGui.PopStyleVar();
|
ImGui.PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,7 +519,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
?.RawString ?? channel.ToString();
|
?.RawString ?? channel.ToString();
|
||||||
|
|
||||||
if (channel.IsLinkshell()) {
|
if (channel.IsLinkshell()) {
|
||||||
var lsName = Ui.Plugin.Functions.Chat.GetLinkshellName(channel.LinkshellIndex());
|
var lsName = Plugin.Functions.Chat.GetLinkshellName(channel.LinkshellIndex());
|
||||||
if (string.IsNullOrWhiteSpace(lsName)) {
|
if (string.IsNullOrWhiteSpace(lsName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -506,7 +528,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (channel.IsCrossLinkshell()) {
|
if (channel.IsCrossLinkshell()) {
|
||||||
var lsName = Ui.Plugin.Functions.Chat.GetCrossLinkshellName(channel.LinkshellIndex());
|
var lsName = Plugin.Functions.Chat.GetCrossLinkshellName(channel.LinkshellIndex());
|
||||||
if (string.IsNullOrWhiteSpace(lsName)) {
|
if (string.IsNullOrWhiteSpace(lsName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -515,7 +537,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Selectable(name)) {
|
if (ImGui.Selectable(name)) {
|
||||||
Ui.Plugin.Functions.Chat.SetChannel(channel);
|
Plugin.Functions.Chat.SetChannel(channel);
|
||||||
_tellTarget = null;
|
_tellTarget = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -527,10 +549,10 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var afterIcon = ImGui.GetCursorPos();
|
var afterIcon = ImGui.GetCursorPos();
|
||||||
|
|
||||||
var buttonWidth = afterIcon.X - beforeIcon.X;
|
var buttonWidth = afterIcon.X - beforeIcon.X;
|
||||||
var showNovice = Ui.Plugin.Config.ShowNoviceNetwork && Ui.Plugin.Functions.IsMentor();
|
var showNovice = Plugin.Config.ShowNoviceNetwork && Plugin.Functions.IsMentor();
|
||||||
var inputWidth = ImGui.GetContentRegionAvail().X - buttonWidth * (showNovice ? 2 : 1);
|
var inputWidth = ImGui.GetContentRegionAvail().X - buttonWidth * (showNovice ? 2 : 1);
|
||||||
|
|
||||||
var inputType = _tempChannel?.ToChatType() ?? activeTab?.Channel?.ToChatType() ?? Ui.Plugin.Functions.Chat.Channel.channel.ToChatType();
|
var inputType = _tempChannel?.ToChatType() ?? activeTab?.Channel?.ToChatType() ?? Plugin.Functions.Chat.Channel.channel.ToChatType();
|
||||||
var isCommand = Chat.Trim().StartsWith('/');
|
var isCommand = Chat.Trim().StartsWith('/');
|
||||||
if (isCommand) {
|
if (isCommand) {
|
||||||
var command = Chat.Split(' ')[0];
|
var command = Chat.Split(' ')[0];
|
||||||
@@ -545,15 +567,15 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
var normalColour = *ImGui.GetStyleColorVec4(ImGuiCol.Text);
|
var normalColour = *ImGui.GetStyleColorVec4(ImGuiCol.Text);
|
||||||
|
|
||||||
var inputColour = Ui.Plugin.Config.ChatColours.TryGetValue(inputType, out var inputCol)
|
var inputColour = Plugin.Config.ChatColours.TryGetValue(inputType, out var inputCol)
|
||||||
? inputCol
|
? inputCol
|
||||||
: inputType.DefaultColour();
|
: inputType.DefaultColour();
|
||||||
|
|
||||||
if (!isCommand && Ui.Plugin.ExtraChat.ChannelOverride is var (_, overrideColour)) {
|
if (!isCommand && Plugin.ExtraChat.ChannelOverride is var (_, overrideColour)) {
|
||||||
inputColour = overrideColour;
|
inputColour = overrideColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCommand && Ui.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,10 +589,8 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
var chatCopy = Chat;
|
var chatCopy = Chat;
|
||||||
ImGui.SetNextItemWidth(inputWidth);
|
ImGui.SetNextItemWidth(inputWidth);
|
||||||
const ImGuiInputTextFlags inputFlags = ImGuiInputTextFlags.CallbackAlways
|
const ImGuiInputTextFlags inputFlags = ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackCharFilter |
|
||||||
| ImGuiInputTextFlags.CallbackCharFilter
|
ImGuiInputTextFlags.CallbackCompletion | ImGuiInputTextFlags.CallbackHistory;
|
||||||
| ImGuiInputTextFlags.CallbackCompletion
|
|
||||||
| ImGuiInputTextFlags.CallbackHistory;
|
|
||||||
ImGui.InputText("##chat2-input", ref Chat, 500, inputFlags, Callback);
|
ImGui.InputText("##chat2-input", ref Chat, 500, inputFlags, Callback);
|
||||||
|
|
||||||
if (ImGui.IsItemDeactivated()) {
|
if (ImGui.IsItemDeactivated()) {
|
||||||
@@ -618,20 +638,16 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog)) {
|
if (ImGuiUtil.IconButton(FontAwesomeIcon.Cog)) {
|
||||||
Ui.SettingsVisible ^= true;
|
Plugin.SettingsWindow.IsOpen ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showNovice) {
|
if (showNovice) {
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
if (ImGuiUtil.IconButton(FontAwesomeIcon.Leaf)) {
|
if (ImGuiUtil.IconButton(FontAwesomeIcon.Leaf)) {
|
||||||
Ui.Plugin.Functions.ClickNoviceNetworkButton();
|
Plugin.Functions.ClickNoviceNetworkButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.End();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendChatBox(Tab? activeTab) {
|
private void SendChatBox(Tab? activeTab) {
|
||||||
@@ -646,11 +662,11 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var reason = target.Reason;
|
var reason = target.Reason;
|
||||||
var world = Plugin.DataManager.GetExcelSheet<World>()?.GetRow(target.World);
|
var world = Plugin.DataManager.GetExcelSheet<World>()?.GetRow(target.World);
|
||||||
if (world is { IsPublic: true }) {
|
if (world is { IsPublic: true }) {
|
||||||
if (reason == TellReason.Reply && Ui.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)) {
|
||||||
reason = TellReason.Friend;
|
reason = TellReason.Friend;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui.Plugin.Functions.Chat.SendTell(reason, target.ContentId, target.Name, (ushort) world.RowId, trimmed);
|
Plugin.Functions.Chat.SendTell(reason, target.ContentId, target.Name, (ushort) world.RowId, trimmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tempChannel is InputChannel.Tell) {
|
if (_tempChannel is InputChannel.Tell) {
|
||||||
@@ -671,7 +687,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var bytes = Encoding.UTF8.GetBytes(trimmed);
|
var bytes = Encoding.UTF8.GetBytes(trimmed);
|
||||||
AutoTranslate.ReplaceWithPayload(Plugin.DataManager, ref bytes);
|
AutoTranslate.ReplaceWithPayload(Plugin.DataManager, ref bytes);
|
||||||
|
|
||||||
Ui.Plugin.Common.Functions.Chat.SendMessageUnsafe(bytes);
|
Plugin.Common.Functions.Chat.SendMessageUnsafe(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Skip:
|
Skip:
|
||||||
@@ -682,13 +698,13 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
_hideState = HideState.User;
|
_hideState = HideState.User;
|
||||||
}
|
}
|
||||||
|
|
||||||
private 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))) {
|
if (ImGui.BeginChild("##chat2-messages", new Vector2(-1, childHeight))) {
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||||
var table = tab.DisplayTimestamp && Ui.Plugin.Config.PrettierTimestamps;
|
var table = tab.DisplayTimestamp && Plugin.Config.PrettierTimestamps;
|
||||||
|
|
||||||
var oldCellPaddingY = ImGui.GetStyle().CellPadding.Y;
|
var oldCellPaddingY = ImGui.GetStyle().CellPadding.Y;
|
||||||
if (Ui.Plugin.Config.PrettierTimestamps && Ui.Plugin.Config.MoreCompactPretty) {
|
if (Plugin.Config.PrettierTimestamps && Plugin.Config.MoreCompactPretty) {
|
||||||
var padding = ImGui.GetStyle().CellPadding;
|
var padding = ImGui.GetStyle().CellPadding;
|
||||||
padding.Y = 0;
|
padding.Y = 0;
|
||||||
|
|
||||||
@@ -726,7 +742,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
message.IsVisible = false;
|
message.IsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ui.Plugin.Config.CollapseDuplicateMessages) {
|
if (Plugin.Config.CollapseDuplicateMessages) {
|
||||||
var messageHash = message.Hash;
|
var messageHash = message.Hash;
|
||||||
var same = lastMessageHash == messageHash;
|
var same = lastMessageHash == messageHash;
|
||||||
if (same) {
|
if (same) {
|
||||||
@@ -794,7 +810,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
if (tab.DisplayTimestamp) {
|
if (tab.DisplayTimestamp) {
|
||||||
var timestamp = message.Date.ToLocalTime().ToString("t");
|
var timestamp = message.Date.ToLocalTime().ToString("t");
|
||||||
if (table) {
|
if (table) {
|
||||||
if (!Ui.Plugin.Config.HideSameTimestamps || timestamp != lastTimestamp) {
|
if (!Plugin.Config.HideSameTimestamps || timestamp != lastTimestamp) {
|
||||||
ImGui.TextUnformatted(timestamp);
|
ImGui.TextUnformatted(timestamp);
|
||||||
lastTimestamp = timestamp;
|
lastTimestamp = timestamp;
|
||||||
}
|
}
|
||||||
@@ -827,7 +843,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var afterDraw = ImGui.GetCursorScreenPos();
|
var afterDraw = ImGui.GetCursorScreenPos();
|
||||||
|
|
||||||
message.Height = ImGui.GetCursorPosY() - lastPos;
|
message.Height = ImGui.GetCursorPosY() - lastPos;
|
||||||
if (Ui.Plugin.Config.PrettierTimestamps && !Ui.Plugin.Config.MoreCompactPretty) {
|
if (Plugin.Config.PrettierTimestamps && !Plugin.Config.MoreCompactPretty) {
|
||||||
message.Height -= oldCellPaddingY * 2;
|
message.Height -= oldCellPaddingY * 2;
|
||||||
beforeDraw.Y += oldCellPaddingY;
|
beforeDraw.Y += oldCellPaddingY;
|
||||||
afterDraw.Y -= oldCellPaddingY;
|
afterDraw.Y -= oldCellPaddingY;
|
||||||
@@ -840,7 +856,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
tab.MessagesMutex.Release();
|
tab.MessagesMutex.Release();
|
||||||
ImGui.PopStyleVar(Ui.Plugin.Config.PrettierTimestamps && Ui.Plugin.Config.MoreCompactPretty ? 2 : 1);
|
ImGui.PopStyleVar(Plugin.Config.PrettierTimestamps && Plugin.Config.MoreCompactPretty ? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switchedTab || ImGui.GetScrollY() >= ImGui.GetScrollMaxY()) {
|
if (switchedTab || ImGui.GetScrollY() >= ImGui.GetScrollMaxY()) {
|
||||||
@@ -865,8 +881,8 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
return currentTab;
|
return currentTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var tabI = 0; tabI < Ui.Plugin.Config.Tabs.Count; tabI++) {
|
for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++) {
|
||||||
var tab = Ui.Plugin.Config.Tabs[tabI];
|
var tab = Plugin.Config.Tabs[tabI];
|
||||||
if (tab.PopOut) {
|
if (tab.PopOut) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -909,8 +925,8 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var switchedTab = false;
|
var switchedTab = false;
|
||||||
var childHeight = GetRemainingHeightForMessageLog();
|
var childHeight = GetRemainingHeightForMessageLog();
|
||||||
if (ImGui.BeginChild("##chat2-tab-sidebar", new Vector2(-1, childHeight))) {
|
if (ImGui.BeginChild("##chat2-tab-sidebar", new Vector2(-1, childHeight))) {
|
||||||
for (var tabI = 0; tabI < Ui.Plugin.Config.Tabs.Count; tabI++) {
|
for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++) {
|
||||||
var tab = Ui.Plugin.Config.Tabs[tabI];
|
var tab = Plugin.Config.Tabs[tabI];
|
||||||
if (tab.PopOut) {
|
if (tab.PopOut) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -933,13 +949,13 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
if (currentTab == -1 && LastTab < Ui.Plugin.Config.Tabs.Count) {
|
if (currentTab == -1 && LastTab < Plugin.Config.Tabs.Count) {
|
||||||
currentTab = LastTab;
|
currentTab = LastTab;
|
||||||
Ui.Plugin.Config.Tabs[currentTab].Unread = 0;
|
Plugin.Config.Tabs[currentTab].Unread = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTab > -1) {
|
if (currentTab > -1) {
|
||||||
DrawMessageLog(Ui.Plugin.Config.Tabs[currentTab], PayloadHandler, childHeight, switchedTab);
|
DrawMessageLog(Plugin.Config.Tabs[currentTab], PayloadHandler, childHeight, switchedTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
@@ -952,7 +968,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabs = Ui.Plugin.Config.Tabs;
|
var tabs = Plugin.Config.Tabs;
|
||||||
var anyChanged = false;
|
var anyChanged = false;
|
||||||
|
|
||||||
ImGui.PushID($"tab-context-menu-{i}");
|
ImGui.PushID($"tab-context-menu-{i}");
|
||||||
@@ -969,7 +985,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
var (leftIcon, leftTooltip) = Ui.Plugin.Config.SidebarTabView
|
var (leftIcon, leftTooltip) = Plugin.Config.SidebarTabView
|
||||||
? (FontAwesomeIcon.ArrowUp, Language.ChatLog_Tabs_MoveUp)
|
? (FontAwesomeIcon.ArrowUp, Language.ChatLog_Tabs_MoveUp)
|
||||||
: (FontAwesomeIcon.ArrowLeft, Language.ChatLog_Tabs_MoveLeft);
|
: (FontAwesomeIcon.ArrowLeft, Language.ChatLog_Tabs_MoveLeft);
|
||||||
if (ImGuiUtil.IconButton(leftIcon, tooltip: leftTooltip) && i > 0) {
|
if (ImGuiUtil.IconButton(leftIcon, tooltip: leftTooltip) && i > 0) {
|
||||||
@@ -980,7 +996,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
var (rightIcon, rightTooltip) = Ui.Plugin.Config.SidebarTabView
|
var (rightIcon, rightTooltip) = Plugin.Config.SidebarTabView
|
||||||
? (FontAwesomeIcon.ArrowDown, Language.ChatLog_Tabs_MoveDown)
|
? (FontAwesomeIcon.ArrowDown, Language.ChatLog_Tabs_MoveDown)
|
||||||
: (FontAwesomeIcon.ArrowRight, Language.ChatLog_Tabs_MoveRight);
|
: (FontAwesomeIcon.ArrowRight, Language.ChatLog_Tabs_MoveRight);
|
||||||
if (ImGuiUtil.IconButton(rightIcon, tooltip: rightTooltip) && i < tabs.Count - 1) {
|
if (ImGuiUtil.IconButton(rightIcon, tooltip: rightTooltip) && i < tabs.Count - 1) {
|
||||||
@@ -996,67 +1012,35 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (anyChanged) {
|
if (anyChanged) {
|
||||||
Ui.Plugin.SaveConfig();
|
Plugin.SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<bool> _popOutDocked = new();
|
internal readonly List<bool> PopOutDocked = new();
|
||||||
|
internal Dictionary<string, Window> PopOutWindows = new();
|
||||||
private void DrawPopOuts() {
|
private void DrawPopOuts() {
|
||||||
HandlerLender.ResetCounter();
|
HandlerLender.ResetCounter();
|
||||||
|
|
||||||
if (_popOutDocked.Count != Ui.Plugin.Config.Tabs.Count) {
|
if (PopOutDocked.Count != Plugin.Config.Tabs.Count) {
|
||||||
_popOutDocked.Clear();
|
PopOutDocked.Clear();
|
||||||
_popOutDocked.AddRange(Enumerable.Repeat(false, Ui.Plugin.Config.Tabs.Count));
|
PopOutDocked.AddRange(Enumerable.Repeat(false, Plugin.Config.Tabs.Count));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < Ui.Plugin.Config.Tabs.Count; i++) {
|
for (var i = 0; i < Plugin.Config.Tabs.Count; i++) {
|
||||||
var tab = Ui.Plugin.Config.Tabs[i];
|
var tab = Plugin.Config.Tabs[i];
|
||||||
if (!tab.PopOut) {
|
if (!tab.PopOut)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
DrawPopOut(tab, i);
|
if (PopOutWindows.ContainsKey($"{tab.Name}{i}"))
|
||||||
}
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawPopOut(Tab tab, int idx) {
|
var window = new Popout(this, tab, i) { IsOpen = true };
|
||||||
var flags = ImGuiWindowFlags.None;
|
|
||||||
if (!Ui.Plugin.Config.ShowPopOutTitleBar) {
|
|
||||||
flags |= ImGuiWindowFlags.NoTitleBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_popOutDocked[idx]) {
|
Plugin.WindowSystem.AddWindow(window);
|
||||||
var alpha = tab.IndependentOpacity ? tab.Opacity : Ui.Plugin.Config.WindowAlpha;
|
PopOutWindows.Add($"{tab.Name}{i}", window);
|
||||||
ImGui.SetNextWindowBgAlpha(alpha / 100f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SetNextWindowSize(new Vector2(350, 350) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
|
|
||||||
if (!ImGui.Begin($"{tab.Name}##popout", ref tab.PopOut, flags)) {
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PushID($"popout-{tab.Name}");
|
|
||||||
|
|
||||||
if (!Ui.Plugin.Config.ShowPopOutTitleBar) {
|
|
||||||
ImGui.TextUnformatted(tab.Name);
|
|
||||||
ImGui.Separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
var handler = HandlerLender.Borrow();
|
|
||||||
DrawMessageLog(tab, handler, ImGui.GetContentRegionAvail().Y, false);
|
|
||||||
|
|
||||||
ImGui.PopID();
|
|
||||||
|
|
||||||
End:
|
|
||||||
_popOutDocked[idx] = ImGui.IsWindowDocked();
|
|
||||||
ImGui.End();
|
|
||||||
|
|
||||||
if (!tab.PopOut) {
|
|
||||||
Ui.Plugin.SaveConfig();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1065,7 +1049,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_autoCompleteList ??= AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Ui.Plugin.Config.SortAutoTranslate);
|
_autoCompleteList ??= AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Plugin.Config.SortAutoTranslate);
|
||||||
|
|
||||||
if (_autoCompleteOpen) {
|
if (_autoCompleteOpen) {
|
||||||
ImGui.OpenPopup(AutoCompleteId);
|
ImGui.OpenPopup(AutoCompleteId);
|
||||||
@@ -1086,7 +1070,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|
|
||||||
ImGui.SetNextItemWidth(-1);
|
ImGui.SetNextItemWidth(-1);
|
||||||
if (ImGui.InputTextWithHint("##auto-complete-filter", Language.AutoTranslate_Search_Hint, ref _autoCompleteInfo.ToComplete, 256, ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackHistory, AutoCompleteCallback)) {
|
if (ImGui.InputTextWithHint("##auto-complete-filter", Language.AutoTranslate_Search_Hint, ref _autoCompleteInfo.ToComplete, 256, ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackHistory, AutoCompleteCallback)) {
|
||||||
_autoCompleteList = AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Ui.Plugin.Config.SortAutoTranslate);
|
_autoCompleteList = AutoTranslate.Matching(Plugin.DataManager, _autoCompleteInfo.ToComplete, Plugin.Config.SortAutoTranslate);
|
||||||
_autoCompleteSelection = 0;
|
_autoCompleteSelection = 0;
|
||||||
_autoCompleteShouldScroll = true;
|
_autoCompleteShouldScroll = true;
|
||||||
}
|
}
|
||||||
@@ -1242,7 +1226,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data->EventFlag == ImGuiInputTextFlags.CallbackCharFilter) {
|
if (data->EventFlag == ImGuiInputTextFlags.CallbackCharFilter) {
|
||||||
var valid = Ui.Plugin.Functions.Chat.IsCharValid((char) ptr.EventChar);
|
var valid = Plugin.Functions.Chat.IsCharValid((char) ptr.EventChar);
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1263,12 +1247,12 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
|| cmd.ShortCommand.RawString == command
|
|| cmd.ShortCommand.RawString == command
|
||||||
|| cmd.ShortAlias.RawString == command);
|
|| cmd.ShortAlias.RawString == command);
|
||||||
if (cmd != null) {
|
if (cmd != null) {
|
||||||
_commandHelp = new CommandHelp(this, cmd);
|
Plugin.CommandHelpWindow.UpdateContent(cmd);
|
||||||
|
Plugin.CommandHelpWindow.IsOpen = true;
|
||||||
goto PostCommandHelp;
|
goto PostCommandHelp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Plugin.CommandHelpWindow.IsOpen = false;
|
||||||
_commandHelp = null;
|
|
||||||
|
|
||||||
PostCommandHelp:
|
PostCommandHelp:
|
||||||
if (data->EventFlag != ImGuiInputTextFlags.CallbackHistory) {
|
if (data->EventFlag != ImGuiInputTextFlags.CallbackHistory) {
|
||||||
@@ -1344,7 +1328,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
if (bounds != null) {
|
if (bounds != null) {
|
||||||
var texSize = new Vector2(_fontIcon.Width, _fontIcon.Height);
|
var texSize = new Vector2(_fontIcon.Width, _fontIcon.Height);
|
||||||
|
|
||||||
var sizeRatio = Ui.Plugin.Config.FontSize / bounds.Value.W;
|
var sizeRatio = Plugin.Config.FontSize / bounds.Value.W;
|
||||||
var size = new Vector2(bounds.Value.Z, bounds.Value.W) * sizeRatio * ImGuiHelpers.GlobalScale;
|
var size = new Vector2(bounds.Value.Z, bounds.Value.W) * sizeRatio * ImGuiHelpers.GlobalScale;
|
||||||
|
|
||||||
var uv0 = new Vector2(bounds.Value.X, bounds.Value.Y - 2) / texSize;
|
var uv0 = new Vector2(bounds.Value.X, bounds.Value.Y - 2) / texSize;
|
||||||
@@ -1363,7 +1347,7 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var colour = text.Foreground;
|
var colour = text.Foreground;
|
||||||
if (colour == null && text.FallbackColour != null) {
|
if (colour == null && text.FallbackColour != null) {
|
||||||
var type = text.FallbackColour.Value;
|
var type = text.FallbackColour.Value;
|
||||||
colour = Ui.Plugin.Config.ChatColours.TryGetValue(type, out var col)
|
colour = Plugin.Config.ChatColours.TryGetValue(type, out var col)
|
||||||
? col
|
? col
|
||||||
: type.DefaultColour();
|
: type.DefaultColour();
|
||||||
}
|
}
|
||||||
@@ -1376,29 +1360,29 @@ internal sealed class ChatLog : IUiComponent {
|
|||||||
var pushed = false;
|
var pushed = false;
|
||||||
if (text.Italic) {
|
if (text.Italic) {
|
||||||
pushed = true;
|
pushed = true;
|
||||||
(Ui.Plugin.Config.FontsEnabled && Ui.ItalicFont != null ? Ui.ItalicFont : Ui.AxisItalic).Push();
|
(Plugin.Config.FontsEnabled && Plugin.FontManager.ItalicFont != null ? Plugin.FontManager.ItalicFont : Plugin.FontManager.AxisItalic).Push();
|
||||||
}
|
}
|
||||||
|
|
||||||
var content = text.Content;
|
var content = text.Content;
|
||||||
if (Ui.ScreenshotMode) {
|
if (ScreenshotMode) {
|
||||||
if (chunk.Link is PlayerPayload playerPayload) {
|
if (chunk.Link is PlayerPayload playerPayload) {
|
||||||
var hashCode = $"{Ui.Salt}{playerPayload.PlayerName}{playerPayload.World.RowId}".GetHashCode();
|
var hashCode = $"{Salt}{playerPayload.PlayerName}{playerPayload.World.RowId}".GetHashCode();
|
||||||
content = $"Player {hashCode:X8}";
|
content = $"Player {hashCode:X8}";
|
||||||
} else if (Plugin.ClientState.LocalPlayer is { } player && content.Contains(player.Name.TextValue)) {
|
} else if (Plugin.ClientState.LocalPlayer is { } player && content.Contains(player.Name.TextValue)) {
|
||||||
var hashCode = $"{Ui.Salt}{player.Name.TextValue}{player.HomeWorld.Id}".GetHashCode();
|
var hashCode = $"{Salt}{player.Name.TextValue}{player.HomeWorld.Id}".GetHashCode();
|
||||||
content = content.Replace(player.Name.TextValue, $"Player {hashCode:X8}");
|
content = content.Replace(player.Name.TextValue, $"Player {hashCode:X8}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
ImGuiUtil.WrapText(content, chunk, handler, Ui.DefaultText, lineWidth);
|
ImGuiUtil.WrapText(content, chunk, handler, DefaultText, lineWidth);
|
||||||
} else {
|
} else {
|
||||||
ImGui.TextUnformatted(content);
|
ImGui.TextUnformatted(content);
|
||||||
ImGuiUtil.PostPayload(chunk, handler);
|
ImGuiUtil.PostPayload(chunk, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
(Ui.Plugin.Config.FontsEnabled && Ui.ItalicFont != null ? Ui.ItalicFont : Ui.AxisItalic).Pop();
|
(Plugin.Config.FontsEnabled && Plugin.FontManager.ItalicFont != null ? Plugin.FontManager.ItalicFont : Plugin.FontManager.AxisItalic).Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colour != null) {
|
if (colour != null) {
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using ChatTwo.Util;
|
|
||||||
using Dalamud.Interface.Utility;
|
|
||||||
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(), ChunkSource.None, null).ToList());
|
|
||||||
|
|
||||||
ImGui.End();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using ChatTwo.Util;
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
|
namespace ChatTwo.Ui;
|
||||||
|
|
||||||
|
public class CommandHelpWindow : Window {
|
||||||
|
private ChatLogWindow LogWindow { get; }
|
||||||
|
private TextCommand? Command { get; set; }
|
||||||
|
|
||||||
|
internal CommandHelpWindow(ChatLogWindow logWindow) : base($"command help##chat2-commandhelp")
|
||||||
|
{
|
||||||
|
LogWindow = logWindow;
|
||||||
|
|
||||||
|
Flags = ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoMove |
|
||||||
|
ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysAutoResize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateContent(TextCommand command)
|
||||||
|
{
|
||||||
|
Command = command;
|
||||||
|
|
||||||
|
var width = 350;
|
||||||
|
var scaledWidth = width * ImGuiHelpers.GlobalScale;
|
||||||
|
var pos = LogWindow.LastWindowPos;
|
||||||
|
switch (LogWindow.Plugin.Config.CommandHelpSide) {
|
||||||
|
case CommandHelpSide.Right:
|
||||||
|
pos.X += LogWindow.LastWindowSize.X;
|
||||||
|
break;
|
||||||
|
case CommandHelpSide.Left:
|
||||||
|
pos.X -= scaledWidth;
|
||||||
|
break;
|
||||||
|
case CommandHelpSide.None:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = pos;
|
||||||
|
SizeConstraints = new WindowSizeConstraints
|
||||||
|
{
|
||||||
|
MinimumSize = new Vector2(width, 0),
|
||||||
|
MaximumSize = LogWindow.LastWindowSize with { X = width }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
if (Command == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogWindow.DrawChunks(ChunkUtil.ToChunks(Command.Description.ToDalamudString(), ChunkSource.None, null).ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace ChatTwo.Ui;
|
||||||
|
|
||||||
|
internal class Popout : Window
|
||||||
|
{
|
||||||
|
private readonly ChatLogWindow ChatLogWindow;
|
||||||
|
private readonly Tab Tab;
|
||||||
|
private readonly int Idx;
|
||||||
|
|
||||||
|
public Popout(ChatLogWindow chatLogWindow, Tab tab, int idx) : base($"{tab.Name}##popout")
|
||||||
|
{
|
||||||
|
ChatLogWindow = chatLogWindow;
|
||||||
|
Tab = tab;
|
||||||
|
Idx = idx;
|
||||||
|
|
||||||
|
SizeCondition = ImGuiCond.FirstUseEver;
|
||||||
|
SizeConstraints = new WindowSizeConstraints
|
||||||
|
{
|
||||||
|
MinimumSize = new Vector2(350, 350),
|
||||||
|
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PreDraw()
|
||||||
|
{
|
||||||
|
Flags = ImGuiWindowFlags.None;
|
||||||
|
if (!ChatLogWindow.Plugin.Config.ShowPopOutTitleBar)
|
||||||
|
Flags |= ImGuiWindowFlags.NoTitleBar;
|
||||||
|
|
||||||
|
if (!ChatLogWindow.PopOutDocked[Idx]) {
|
||||||
|
var alpha = Tab.IndependentOpacity ? Tab.Opacity : ChatLogWindow.Plugin.Config.WindowAlpha;
|
||||||
|
BgAlpha = alpha / 100f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
ImGui.PushID($"popout-{Tab.Name}");
|
||||||
|
|
||||||
|
if (!ChatLogWindow.Plugin.Config.ShowPopOutTitleBar) {
|
||||||
|
ImGui.TextUnformatted(Tab.Name);
|
||||||
|
ImGui.Separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = ChatLogWindow.HandlerLender.Borrow();
|
||||||
|
ChatLogWindow.DrawMessageLog(Tab, handler, ImGui.GetContentRegionAvail().Y, false);
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostDraw()
|
||||||
|
{
|
||||||
|
ChatLogWindow.PopOutDocked[Idx] = ImGui.IsWindowDocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnClose()
|
||||||
|
{
|
||||||
|
ChatLogWindow.PopOutWindows.Remove($"{Tab.Name}{Idx}");
|
||||||
|
ChatLogWindow.Plugin.WindowSystem.RemoveWindow(this);
|
||||||
|
|
||||||
|
Tab.PopOut = false;
|
||||||
|
ChatLogWindow.Plugin.SaveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
-70
@@ -1,75 +1,69 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using ChatTwo.Resources;
|
using ChatTwo.Resources;
|
||||||
using ChatTwo.Ui.SettingsTabs;
|
using ChatTwo.Ui.SettingsTabs;
|
||||||
using ChatTwo.Util;
|
using ChatTwo.Util;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Windowing;
|
||||||
|
using Dalamud.Utility;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
namespace ChatTwo.Ui;
|
namespace ChatTwo.Ui;
|
||||||
|
|
||||||
internal sealed class Settings : IUiComponent {
|
public sealed class SettingsWindow : Window, IUiComponent
|
||||||
private PluginUi Ui { get; }
|
{
|
||||||
|
private readonly Plugin Plugin;
|
||||||
|
|
||||||
private Configuration Mutable { get; }
|
private Configuration Mutable { get; }
|
||||||
private List<ISettingsTab> Tabs { get; }
|
private List<ISettingsTab> Tabs { get; }
|
||||||
private int _currentTab;
|
private int CurrentTab;
|
||||||
|
|
||||||
internal Settings(PluginUi ui) {
|
internal SettingsWindow(Plugin plugin) : base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
|
||||||
this.Ui = ui;
|
{
|
||||||
this.Mutable = new Configuration();
|
Flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
|
||||||
|
|
||||||
this.Tabs = new List<ISettingsTab> {
|
SizeCondition = ImGuiCond.FirstUseEver;
|
||||||
new Display(this.Mutable),
|
SizeConstraints = new WindowSizeConstraints
|
||||||
new Ui.SettingsTabs.Fonts(this.Mutable),
|
{
|
||||||
new ChatColours(this.Mutable, this.Ui.Plugin),
|
MinimumSize = new Vector2(475, 600),
|
||||||
new Tabs(this.Ui.Plugin, this.Mutable),
|
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
||||||
new Database(this.Mutable, this.Ui.Plugin.Store),
|
};
|
||||||
new Miscellaneous(this.Mutable),
|
|
||||||
|
Plugin = plugin;
|
||||||
|
Mutable = new Configuration();
|
||||||
|
|
||||||
|
Tabs = new List<ISettingsTab> {
|
||||||
|
new Display(Mutable),
|
||||||
|
new Ui.SettingsTabs.Fonts(Mutable),
|
||||||
|
new ChatColours(Mutable, Plugin),
|
||||||
|
new Tabs(Plugin, Mutable),
|
||||||
|
new Database(Mutable, Plugin.Store),
|
||||||
|
new Miscellaneous(Mutable),
|
||||||
new About(),
|
new About(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Initialise();
|
Initialise();
|
||||||
|
|
||||||
this.Ui.Plugin.Commands.Register("/chat2", "Perform various actions with Chat 2.").Execute += this.Command;
|
Plugin.Commands.Register("/chat2", "Perform various actions with Chat 2.").Execute += Command;
|
||||||
Plugin.Interface.UiBuilder.OpenConfigUi += this.Toggle;
|
Plugin.Interface.UiBuilder.OpenConfigUi += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
Plugin.Interface.UiBuilder.OpenConfigUi -= this.Toggle;
|
Plugin.Interface.UiBuilder.OpenConfigUi -= Toggle;
|
||||||
this.Ui.Plugin.Commands.Register("/chat2").Execute -= this.Command;
|
Plugin.Commands.Register("/chat2").Execute -= Command;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Command(string command, string args) {
|
private void Command(string command, string args) {
|
||||||
if (string.IsNullOrWhiteSpace(args)) {
|
if (string.IsNullOrWhiteSpace(args))
|
||||||
this.Toggle();
|
Toggle();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Toggle() {
|
|
||||||
this.Ui.SettingsVisible ^= true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialise() {
|
private void Initialise() {
|
||||||
this.Mutable.UpdateFrom(this.Ui.Plugin.Config);
|
Mutable.UpdateFrom(Plugin.Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw() {
|
public override void Draw()
|
||||||
if (!this.Ui.SettingsVisible) {
|
{
|
||||||
return;
|
if (ImGui.IsWindowAppearing())
|
||||||
}
|
Initialise();
|
||||||
|
|
||||||
ImGui.SetNextWindowSize(new Vector2(475, 600) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
|
|
||||||
|
|
||||||
var name = string.Format(Language.Settings_Title, Plugin.PluginName);
|
|
||||||
if (!ImGui.Begin($"{name}###chat2-settings", ref this.Ui.SettingsVisible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) {
|
|
||||||
ImGui.End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.IsWindowAppearing()) {
|
|
||||||
this.Initialise();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginTable("##chat2-settings-table", 2)) {
|
if (ImGui.BeginTable("##chat2-settings-table", 2)) {
|
||||||
ImGui.TableSetupColumn("tab", ImGuiTableColumnFlags.WidthFixed);
|
ImGui.TableSetupColumn("tab", ImGuiTableColumnFlags.WidthFixed);
|
||||||
@@ -78,9 +72,9 @@ internal sealed class Settings : IUiComponent {
|
|||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
var changed = false;
|
var changed = false;
|
||||||
for (var i = 0; i < this.Tabs.Count; i++) {
|
for (var i = 0; i < Tabs.Count; i++) {
|
||||||
if (ImGui.Selectable($"{this.Tabs[i].Name}###tab-{i}", this._currentTab == i)) {
|
if (ImGui.Selectable($"{Tabs[i].Name}###tab-{i}", CurrentTab == i)) {
|
||||||
this._currentTab = i;
|
CurrentTab = i;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +87,7 @@ internal sealed class Settings : IUiComponent {
|
|||||||
- ImGui.GetStyle().ItemInnerSpacing.Y * 2
|
- ImGui.GetStyle().ItemInnerSpacing.Y * 2
|
||||||
- ImGui.CalcTextSize("A").Y;
|
- ImGui.CalcTextSize("A").Y;
|
||||||
if (ImGui.BeginChild("##chat2-settings", new Vector2(-1, height))) {
|
if (ImGui.BeginChild("##chat2-settings", new Vector2(-1, height))) {
|
||||||
this.Tabs[this._currentTab].Draw(changed);
|
Tabs[CurrentTab].Draw(changed);
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,13 +102,13 @@ internal sealed class Settings : IUiComponent {
|
|||||||
|
|
||||||
if (ImGui.Button(Language.Settings_SaveAndClose)) {
|
if (ImGui.Button(Language.Settings_SaveAndClose)) {
|
||||||
save = true;
|
save = true;
|
||||||
this.Ui.SettingsVisible = false;
|
IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
if (ImGui.Button(Language.Settings_Discard)) {
|
if (ImGui.Button(Language.Settings_Discard)) {
|
||||||
this.Ui.SettingsVisible = false;
|
IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var buttonLabel = "Anna's Ko-fi";
|
var buttonLabel = "Anna's Ko-fi";
|
||||||
@@ -143,46 +137,44 @@ internal sealed class Settings : IUiComponent {
|
|||||||
ImGui.PopStyleColor(4);
|
ImGui.PopStyleColor(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.End();
|
|
||||||
|
|
||||||
if (save) {
|
if (save) {
|
||||||
var config = this.Ui.Plugin.Config;
|
var config = Plugin.Config;
|
||||||
|
|
||||||
var hideChatChanged = this.Mutable.HideChat != this.Ui.Plugin.Config.HideChat;
|
var hideChatChanged = Mutable.HideChat != Plugin.Config.HideChat;
|
||||||
var fontChanged = this.Mutable.GlobalFont != this.Ui.Plugin.Config.GlobalFont
|
var fontChanged = Mutable.GlobalFont != Plugin.Config.GlobalFont
|
||||||
|| this.Mutable.JapaneseFont != this.Ui.Plugin.Config.JapaneseFont
|
|| Mutable.JapaneseFont != Plugin.Config.JapaneseFont
|
||||||
|| this.Mutable.ExtraGlyphRanges != this.Ui.Plugin.Config.ExtraGlyphRanges;
|
|| Mutable.ExtraGlyphRanges != Plugin.Config.ExtraGlyphRanges;
|
||||||
var fontSizeChanged = Math.Abs(this.Mutable.FontSize - this.Ui.Plugin.Config.FontSize) > 0.001
|
var fontSizeChanged = Math.Abs(Mutable.FontSize - Plugin.Config.FontSize) > 0.001
|
||||||
|| Math.Abs(this.Mutable.JapaneseFontSize - this.Ui.Plugin.Config.JapaneseFontSize) > 0.001
|
|| Math.Abs(Mutable.JapaneseFontSize - Plugin.Config.JapaneseFontSize) > 0.001
|
||||||
|| Math.Abs(this.Mutable.SymbolsFontSize - this.Ui.Plugin.Config.SymbolsFontSize) > 0.001;
|
|| Math.Abs(Mutable.SymbolsFontSize - Plugin.Config.SymbolsFontSize) > 0.001;
|
||||||
var langChanged = this.Mutable.LanguageOverride != this.Ui.Plugin.Config.LanguageOverride;
|
var langChanged = Mutable.LanguageOverride != Plugin.Config.LanguageOverride;
|
||||||
var sharedChanged = this.Mutable.SharedMode != this.Ui.Plugin.Config.SharedMode;
|
var sharedChanged = Mutable.SharedMode != Plugin.Config.SharedMode;
|
||||||
|
|
||||||
config.UpdateFrom(this.Mutable);
|
config.UpdateFrom(Mutable);
|
||||||
|
|
||||||
// save after 60 frames have passed, which should hopefully not
|
// save after 60 frames have passed, which should hopefully not
|
||||||
// commit any changes that cause a crash
|
// commit any changes that cause a crash
|
||||||
this.Ui.Plugin.DeferredSaveFrames = 60;
|
Plugin.DeferredSaveFrames = 60;
|
||||||
|
|
||||||
this.Ui.Plugin.Store.FilterAllTabs(false);
|
Plugin.Store.FilterAllTabs(false);
|
||||||
|
|
||||||
if (fontChanged || fontSizeChanged) {
|
if (fontChanged || fontSizeChanged) {
|
||||||
this.Ui.BuildFonts();
|
Plugin.FontManager.BuildFonts();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (langChanged) {
|
if (langChanged) {
|
||||||
this.Ui.Plugin.LanguageChanged(Plugin.Interface.UiLanguage);
|
Plugin.LanguageChanged(Plugin.Interface.UiLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedChanged) {
|
if (sharedChanged) {
|
||||||
this.Ui.Plugin.Store.Reconnect();
|
Plugin.Store.Reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Mutable.HideChat && hideChatChanged) {
|
if (!Mutable.HideChat && hideChatChanged) {
|
||||||
GameFunctions.GameFunctions.SetChatInteractable(true);
|
GameFunctions.GameFunctions.SetChatInteractable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Initialise();
|
Initialise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user