Merge pull request #90 from deansheather/dean/autohide-improvements
feat: autohide improvements
This commit is contained in:
+20
-20
@@ -3,6 +3,7 @@ using ChatTwo.Code;
|
||||
using ChatTwo.GameFunctions.Types;
|
||||
using ChatTwo.Resources;
|
||||
using ChatTwo.Ui;
|
||||
using ChatTwo.Util;
|
||||
using Dalamud.Configuration;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using ImGuiNET;
|
||||
@@ -43,6 +44,10 @@ internal class Configuration : IPluginConfiguration
|
||||
public bool HideInBattle;
|
||||
public bool HideWhenInactive;
|
||||
public int InactivityHideTimeout = 10;
|
||||
public bool InactivityHideActiveDuringBattle = true;
|
||||
public Dictionary<ChatType, ChatSource> InactivityHideChannels = TabsUtil.AllChannels();
|
||||
public bool InactivityHideExtraChatAll = true;
|
||||
public HashSet<Guid> InactivityHideExtraChatChannels = [];
|
||||
public bool ShowHideButton = true;
|
||||
public bool NativeItemTooltips = true;
|
||||
public bool PrettierTimestamps = true;
|
||||
@@ -106,6 +111,10 @@ internal class Configuration : IPluginConfiguration
|
||||
HideInBattle = other.HideInBattle;
|
||||
HideWhenInactive = other.HideWhenInactive;
|
||||
InactivityHideTimeout = other.InactivityHideTimeout;
|
||||
InactivityHideActiveDuringBattle = other.InactivityHideActiveDuringBattle;
|
||||
InactivityHideChannels = other.InactivityHideChannels.ToDictionary(entry => entry.Key, entry => entry.Value);
|
||||
InactivityHideExtraChatAll = other.InactivityHideExtraChatAll;
|
||||
InactivityHideExtraChatChannels = other.InactivityHideExtraChatChannels.ToHashSet();
|
||||
ShowHideButton = other.ShowHideButton;
|
||||
NativeItemTooltips = other.NativeItemTooltips;
|
||||
PrettierTimestamps = other.PrettierTimestamps;
|
||||
@@ -188,6 +197,7 @@ internal class Tab
|
||||
public HashSet<Guid> ExtraChatChannels = [];
|
||||
|
||||
public UnreadMode UnreadMode = UnreadMode.Unseen;
|
||||
public bool UnhideOnActivity;
|
||||
public bool DisplayTimestamp = true;
|
||||
public InputChannel? Channel;
|
||||
public bool PopOut;
|
||||
@@ -199,7 +209,7 @@ internal class Tab
|
||||
public uint Unread;
|
||||
|
||||
[NonSerialized]
|
||||
public long LastMessageTime;
|
||||
public long LastActivity;
|
||||
|
||||
[NonSerialized]
|
||||
public MessageList Messages = new();
|
||||
@@ -210,31 +220,20 @@ internal class Tab
|
||||
[NonSerialized]
|
||||
public Guid Identifier = Guid.NewGuid();
|
||||
|
||||
internal bool Matches(Message message)
|
||||
{
|
||||
if (message.ExtraChatChannel != Guid.Empty)
|
||||
return ExtraChatAll || ExtraChatChannels.Contains(message.ExtraChatChannel);
|
||||
|
||||
return message.Code.Type.IsGm()
|
||||
|| ChatCodes.TryGetValue(message.Code.Type, out var sources)
|
||||
&& (message.Code.Source is 0 or (ChatSource) 1
|
||||
|| sources.HasFlag(message.Code.Source));
|
||||
}
|
||||
internal bool Matches(Message message) => message.Matches(ChatCodes, ExtraChatAll, ExtraChatChannels);
|
||||
|
||||
internal void AddMessage(Message message, bool unread = true)
|
||||
{
|
||||
Messages.AddPrune(message, MessageManager.MessageDisplayLimit);
|
||||
if (unread)
|
||||
{
|
||||
Unread += 1;
|
||||
LastMessageTime = Environment.TickCount64;
|
||||
}
|
||||
if (!unread)
|
||||
return;
|
||||
Unread += 1;
|
||||
|
||||
if (message.Matches(Plugin.Config.InactivityHideChannels, Plugin.Config.InactivityHideExtraChatAll, Plugin.Config.InactivityHideExtraChatChannels))
|
||||
LastActivity = Environment.TickCount64;
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
Messages.Clear();
|
||||
}
|
||||
internal void Clear() => Messages.Clear();
|
||||
|
||||
internal Tab Clone()
|
||||
{
|
||||
@@ -245,6 +244,7 @@ internal class Tab
|
||||
ExtraChatAll = ExtraChatAll,
|
||||
ExtraChatChannels = ExtraChatChannels.ToHashSet(),
|
||||
UnreadMode = UnreadMode,
|
||||
UnhideOnActivity = UnhideOnActivity,
|
||||
DisplayTimestamp = DisplayTimestamp,
|
||||
Channel = Channel,
|
||||
PopOut = PopOut,
|
||||
|
||||
@@ -10,8 +10,6 @@ using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using ImGuiNET;
|
||||
using ModifierFlag = ChatTwo.GameFunctions.Types.ModifierFlag;
|
||||
|
||||
using ModifierFlag = ChatTwo.GameFunctions.Types.ModifierFlag;
|
||||
|
||||
namespace ChatTwo.GameFunctions;
|
||||
|
||||
internal enum KeyboardSource {
|
||||
@@ -95,8 +93,8 @@ internal unsafe class KeybindManager : IDisposable {
|
||||
|
||||
// List of keys that can be used as a part of keybinds while the chat is
|
||||
// focused WITHOUT modifiers. All other keys can only be used if their
|
||||
// configured keybind contains modifiers. This allows for using e.g. F11 to
|
||||
// change chat channel while typing.
|
||||
// configured keybind contains modifiers (except only SHIFT). This allows
|
||||
// for using e.g. F11 to change chat channel while typing.
|
||||
private static readonly IReadOnlyCollection<VirtualKey> ModifierlessChatKeys = new[]
|
||||
{
|
||||
// VirtualKey.NO_KEY,
|
||||
|
||||
@@ -124,6 +124,17 @@ internal partial class Message
|
||||
return new Message(0, 0, code, [], content, new SeString(), new SeString());
|
||||
}
|
||||
|
||||
internal bool Matches(Dictionary<ChatType, ChatSource> channels, bool allExtraChatChannels, HashSet<Guid> extraChatChannels)
|
||||
{
|
||||
if (ExtraChatChannel != Guid.Empty)
|
||||
return allExtraChatChannels || extraChatChannels.Contains(ExtraChatChannel);
|
||||
|
||||
return Code.Type.IsGm()
|
||||
|| channels.TryGetValue(Code.Type, out var sources)
|
||||
&& (Code.Source is 0 or (ChatSource) 1
|
||||
|| sources.HasFlag(Code.Source));
|
||||
}
|
||||
|
||||
private int GenerateHash()
|
||||
{
|
||||
return SortCode.GetHashCode()
|
||||
|
||||
Generated
+73
-1
@@ -2481,7 +2481,7 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Hide the chat after a configurable period of inactivity. The current tab and any tabs with unread indicators enabled are considered for activity..
|
||||
/// Looks up a localized string similar to Hide the chat after a configurable period of inactivity. The current tab and any other tabs with the setting enabled are considered for activity..
|
||||
/// </summary>
|
||||
internal static string Options_HideWhenInactive_Description {
|
||||
get {
|
||||
@@ -2534,6 +2534,69 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to When disabled, the chat log will stay active during battle..
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideActiveDuringBattle_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideActiveDuringBattle_Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Enable inactivity hide during battle.
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideActiveDuringBattle_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideActiveDuringBattle_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Select All.
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideChannels_All_Label {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideChannels_All_Label", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Hold Ctrl+Shift to click..
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideChannels_Button_Tooltip {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideChannels_Button_Tooltip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Which chat channels should be considered for activity. Other channels will not restore the chat regardless of which tab they occur in..
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideChannels_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideChannels_Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Chat channels considered for activity.
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideChannels_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideChannels_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unselect All.
|
||||
/// </summary>
|
||||
internal static string Options_InactivityHideChannels_None_Label {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_InactivityHideChannels_None_Label", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to How long to wait (in seconds) before considering the chat log inactive..
|
||||
/// </summary>
|
||||
@@ -3137,6 +3200,15 @@ namespace ChatTwo.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unhide the chat window on activity.
|
||||
/// </summary>
|
||||
internal static string Options_Tabs_InactivityBehaviour {
|
||||
get {
|
||||
return ResourceManager.GetString("Options_Tabs_InactivityBehaviour", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Use different opacity than main window.
|
||||
/// </summary>
|
||||
|
||||
@@ -220,6 +220,9 @@
|
||||
<data name="Options_Tabs_UnreadMode">
|
||||
<value>Unread mode</value>
|
||||
</data>
|
||||
<data name="Options_Tabs_InactivityBehaviour">
|
||||
<value>Unhide the chat window on activity</value>
|
||||
</data>
|
||||
<data name="Options_Tabs_NoInputChannel">
|
||||
<value><None></value>
|
||||
</data>
|
||||
@@ -410,7 +413,7 @@
|
||||
<value>Hide when inactive</value>
|
||||
</data>
|
||||
<data name="Options_HideWhenInactive_Description">
|
||||
<value>Hide the chat after a configurable period of inactivity. The current tab and any tabs with unread indicators enabled are considered for activity.</value>
|
||||
<value>Hide the chat after a configurable period of inactivity. The current tab and any other tabs with the setting enabled are considered for activity.</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideTimeout_Name">
|
||||
<value>Inactivity timeout</value>
|
||||
@@ -418,6 +421,27 @@
|
||||
<data name="Options_InactivityHideTimeout_Description">
|
||||
<value>How long to wait (in seconds) before considering the chat log inactive.</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideActiveDuringBattle_Name" xml:space="preserve">
|
||||
<value>Enable inactivity hide during battle</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideActiveDuringBattle_Description" xml:space="preserve">
|
||||
<value>When disabled, the chat log will stay active during battle.</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideChannels_Name">
|
||||
<value>Chat channels considered for activity</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideChannels_Description">
|
||||
<value>Which chat channels should be considered for activity. Other channels will not restore the chat regardless of which tab they occur in.</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideChannels_All_Label">
|
||||
<value>Select All</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideChannels_None_Label">
|
||||
<value>Unselect All</value>
|
||||
</data>
|
||||
<data name="Options_InactivityHideChannels_Button_Tooltip">
|
||||
<value>Hold Ctrl+Shift to click.</value>
|
||||
</data>
|
||||
<data name="Options_KeybindMode_Name">
|
||||
<value>Keybind mode</value>
|
||||
</data>
|
||||
|
||||
@@ -87,7 +87,7 @@ public sealed class ChatLogWindow : Window
|
||||
private bool PlayedClosingSound = true;
|
||||
|
||||
private long FrameTime; // set every frame
|
||||
private long LastActivityTime = Environment.TickCount64;
|
||||
internal long LastActivityTime = Environment.TickCount64;
|
||||
|
||||
private readonly ExcelSheet<World> WorldSheet;
|
||||
private readonly ExcelSheet<LogFilter> LogFilterSheet;
|
||||
@@ -348,7 +348,10 @@ public sealed class ChatLogWindow : Window
|
||||
return height;
|
||||
}
|
||||
|
||||
internal void ChangeTab(int index) => WantedTab = index;
|
||||
internal void ChangeTab(int index) {
|
||||
WantedTab = index;
|
||||
LastActivityTime = FrameTime;
|
||||
}
|
||||
|
||||
internal void ChangeTabDelta(int offset)
|
||||
{
|
||||
@@ -373,7 +376,7 @@ public sealed class ChatLogWindow : Window
|
||||
SetChannel(tab.Channel ?? tab.PreviousChannel);
|
||||
}
|
||||
|
||||
private static bool InBattle => Plugin.Condition[ConditionFlag.InCombat];
|
||||
internal static bool InBattle => Plugin.Condition[ConditionFlag.InCombat];
|
||||
private static bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
|
||||
private static bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78];
|
||||
|
||||
@@ -448,7 +451,8 @@ public sealed class ChatLogWindow : Window
|
||||
FrameTime = Environment.TickCount64;
|
||||
if (IsHidden)
|
||||
return false;
|
||||
if (!Plugin.Config.HideWhenInactive || Activate)
|
||||
|
||||
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && InBattle) || Activate)
|
||||
{
|
||||
LastActivityTime = FrameTime;
|
||||
return true;
|
||||
@@ -456,11 +460,10 @@ public sealed class ChatLogWindow : Window
|
||||
|
||||
var currentTab = CurrentTab; // local to avoid calling the getter repeatedly
|
||||
var lastActivityTime = Plugin.Config.Tabs
|
||||
.Where(tab => tab.UnreadMode is not UnreadMode.None || tab == currentTab)
|
||||
.Select(tab => tab.LastMessageTime)
|
||||
.DefaultIfEmpty(0)
|
||||
.Where(tab => !tab.PopOut && (tab.UnhideOnActivity || tab == currentTab))
|
||||
.Select(tab => tab.LastActivity)
|
||||
.Append(LastActivityTime)
|
||||
.Max();
|
||||
lastActivityTime = Math.Max(lastActivityTime, LastActivityTime);
|
||||
return FrameTime - lastActivityTime <= 1000 * Plugin.Config.InactivityHideTimeout;
|
||||
}
|
||||
|
||||
|
||||
+20
-1
@@ -12,6 +12,9 @@ internal class Popout : Window
|
||||
private readonly Tab Tab;
|
||||
private readonly int Idx;
|
||||
|
||||
private long FrameTime; // set every frame
|
||||
private long LastActivityTime = Environment.TickCount64;
|
||||
|
||||
public Popout(ChatLogWindow chatLogWindow, Tab tab, int idx) : base($"{tab.Name}##popout")
|
||||
{
|
||||
ChatLogWindow = chatLogWindow;
|
||||
@@ -34,7 +37,20 @@ internal class Popout : Window
|
||||
|
||||
public override bool DrawConditions()
|
||||
{
|
||||
return !ChatLogWindow.IsHidden;
|
||||
FrameTime = Environment.TickCount64;
|
||||
if (ChatLogWindow.IsHidden)
|
||||
return false;
|
||||
|
||||
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && ChatLogWindow.InBattle) || !Tab.UnhideOnActivity)
|
||||
{
|
||||
LastActivityTime = FrameTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Activity in the tab, this popout window, or the main chat log window.
|
||||
var lastActivityTime = Math.Max(Tab.LastActivity, LastActivityTime);
|
||||
lastActivityTime = Math.Max(lastActivityTime, ChatLogWindow.LastActivityTime);
|
||||
return FrameTime - lastActivityTime <= 1000 * Plugin.Config.InactivityHideTimeout;
|
||||
}
|
||||
|
||||
public override void PreDraw()
|
||||
@@ -65,6 +81,9 @@ internal class Popout : Window
|
||||
|
||||
var handler = ChatLogWindow.HandlerLender.Borrow();
|
||||
ChatLogWindow.DrawMessageLog(Tab, handler, ImGui.GetContentRegionAvail().Y, false);
|
||||
|
||||
if (ImGui.IsWindowHovered(ImGuiHoveredFlags.ChildWindows))
|
||||
LastActivityTime = FrameTime;
|
||||
}
|
||||
|
||||
public override void PostDraw()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using ChatTwo.Resources;
|
||||
using ChatTwo.Util;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace ChatTwo.Ui.SettingsTabs;
|
||||
@@ -37,27 +38,70 @@ internal sealed class Display : ISettingsTab
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.HideInBattle, Language.Options_HideInBattle_Name, Language.Options_HideInBattle_Description);
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.HideWhenInactive, Language.Options_HideWhenInactive_Name, Language.Options_HideWhenInactive_Description);
|
||||
ImGui.Spacing();
|
||||
|
||||
if (Mutable.HideWhenInactive)
|
||||
{
|
||||
using var _ = ImRaii.PushIndent();
|
||||
ImGuiUtil.InputIntVertical(Language.Options_InactivityHideTimeout_Name,
|
||||
Language.Options_InactivityHideTimeout_Description, ref Mutable.InactivityHideTimeout, 1, 10);
|
||||
// Enforce a minimum of 2 seconds to avoid people soft locking
|
||||
// themselves.
|
||||
Mutable.InactivityHideTimeout = Math.Max(2, Mutable.InactivityHideTimeout);
|
||||
ImGui.Spacing();
|
||||
|
||||
// This setting conflicts with HideInBattle, so it's disabled.
|
||||
using (ImRaii.Disabled(Mutable.HideInBattle))
|
||||
{
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.InactivityHideActiveDuringBattle,
|
||||
Language.Options_InactivityHideActiveDuringBattle_Name,
|
||||
Language.Options_InactivityHideActiveDuringBattle_Description);
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
using var channelTree = ImRaii.TreeNode(Language.Options_InactivityHideChannels_Name);
|
||||
if (channelTree.Success)
|
||||
{
|
||||
if (ImGuiUtil.CtrlShiftButton(Language.Options_InactivityHideChannels_All_Label,
|
||||
Language.Options_InactivityHideChannels_Button_Tooltip))
|
||||
{
|
||||
Mutable.InactivityHideChannels = TabsUtil.AllChannels();
|
||||
Mutable.InactivityHideExtraChatAll = true;
|
||||
Mutable.InactivityHideExtraChatChannels = [];
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.CtrlShiftButton(Language.Options_InactivityHideChannels_None_Label,
|
||||
Language.Options_InactivityHideChannels_Button_Tooltip))
|
||||
{
|
||||
Mutable.InactivityHideChannels = new();
|
||||
Mutable.InactivityHideExtraChatAll = false;
|
||||
Mutable.InactivityHideExtraChatChannels = [];
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.ChannelSelector(Language.Options_Tabs_Channels, Mutable.InactivityHideChannels);
|
||||
ImGuiUtil.ExtraChatSelector(Language.Options_Tabs_ExtraChatChannels,
|
||||
ref Mutable.InactivityHideExtraChatAll, Mutable.InactivityHideExtraChatChannels);
|
||||
}
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.PrettierTimestamps, Language.Options_PrettierTimestamps_Name, Language.Options_PrettierTimestamps_Description);
|
||||
|
||||
if (Mutable.PrettierTimestamps)
|
||||
{
|
||||
ImGui.TreePush();
|
||||
using var _ = ImRaii.PushIndent();
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.MoreCompactPretty, Language.Options_MoreCompactPretty_Name, Language.Options_MoreCompactPretty_Description);
|
||||
ImGuiUtil.OptionCheckbox(ref Mutable.HideSameTimestamps, Language.Options_HideSameTimestamps_Name, Language.Options_HideSameTimestamps_Description);
|
||||
ImGui.TreePop();
|
||||
}
|
||||
ImGui.Spacing();
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ internal sealed class Tabs : ISettingsTab
|
||||
}
|
||||
}
|
||||
|
||||
if (Mutable.HideWhenInactive)
|
||||
ImGui.Checkbox(Language.Options_Tabs_InactivityBehaviour, ref tab.UnhideOnActivity);
|
||||
|
||||
ImGui.Checkbox(Language.Options_Tabs_NoInput, ref tab.InputDisabled);
|
||||
if (!tab.InputDisabled)
|
||||
{
|
||||
@@ -124,81 +127,8 @@ internal sealed class Tabs : ISettingsTab
|
||||
}
|
||||
}
|
||||
|
||||
using (var channelNode = ImRaii.TreeNode(Language.Options_Tabs_Channels))
|
||||
{
|
||||
if (channelNode)
|
||||
{
|
||||
foreach (var (header, types) in ChatTypeExt.SortOrder)
|
||||
{
|
||||
using var headerNode = ImRaii.TreeNode(header + $"##{i}");
|
||||
if (!headerNode.Success)
|
||||
continue;
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type.IsGm())
|
||||
continue;
|
||||
|
||||
var enabled = tab.ChatCodes.ContainsKey(type);
|
||||
if (ImGui.Checkbox($"##{type.Name()}-{i}", ref enabled))
|
||||
{
|
||||
if (enabled)
|
||||
tab.ChatCodes[type] = ChatSourceExt.All;
|
||||
else
|
||||
tab.ChatCodes.Remove(type);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (!type.HasSource())
|
||||
{
|
||||
ImGui.TextUnformatted(type.Name());
|
||||
continue;
|
||||
}
|
||||
|
||||
using var typeNode = ImRaii.TreeNode($"{type.Name()}##{i}");
|
||||
if (!typeNode.Success)
|
||||
continue;
|
||||
|
||||
tab.ChatCodes.TryGetValue(type, out var sourcesEnum);
|
||||
var sources = (uint) sourcesEnum;
|
||||
|
||||
foreach (var source in Enum.GetValues<ChatSource>())
|
||||
if (ImGui.CheckboxFlags(source.Name(), ref sources, (uint) source))
|
||||
tab.ChatCodes[type] = (ChatSource) sources;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Plugin.ExtraChat.ChannelNames.Count <= 0)
|
||||
continue;
|
||||
|
||||
using var extraTree = ImRaii.TreeNode(Language.Options_Tabs_ExtraChatChannels);
|
||||
if (!extraTree.Success)
|
||||
continue;
|
||||
|
||||
ImGui.Checkbox(Language.Options_Tabs_ExtraChatAll, ref tab.ExtraChatAll);
|
||||
ImGui.Separator();
|
||||
|
||||
if (tab.ExtraChatAll)
|
||||
ImGui.BeginDisabled();
|
||||
|
||||
foreach (var (id, name) in Plugin.ExtraChat.ChannelNames)
|
||||
{
|
||||
var enabled = tab.ExtraChatChannels.Contains(id);
|
||||
if (!ImGui.Checkbox($"{name}##ec-{id}", ref enabled))
|
||||
continue;
|
||||
|
||||
if (enabled)
|
||||
tab.ExtraChatChannels.Add(id);
|
||||
else
|
||||
tab.ExtraChatChannels.Remove(id);
|
||||
}
|
||||
|
||||
if (tab.ExtraChatAll)
|
||||
ImGui.EndDisabled();
|
||||
ImGuiUtil.ChannelSelector(Language.Options_Tabs_Channels, tab.ChatCodes);
|
||||
ImGuiUtil.ExtraChatSelector(Language.Options_Tabs_ExtraChatChannels, ref tab.ExtraChatAll, tab.ExtraChatChannels);
|
||||
}
|
||||
|
||||
if (toRemove > -1)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using ChatTwo.Code;
|
||||
using ChatTwo.GameFunctions.Types;
|
||||
using ChatTwo.Resources;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
@@ -549,6 +550,80 @@ internal static class ImGuiUtil
|
||||
return new EndUnconditionally(ImGui.PopTextWrapPos, true);
|
||||
}
|
||||
|
||||
public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes)
|
||||
{
|
||||
using var channelNode = ImRaii.TreeNode(headerText);
|
||||
if (!channelNode)
|
||||
return;
|
||||
|
||||
foreach (var (header, types) in ChatTypeExt.SortOrder)
|
||||
{
|
||||
using var headerNode = ImRaii.TreeNode(header);
|
||||
if (!headerNode.Success)
|
||||
continue;
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type.IsGm())
|
||||
continue;
|
||||
|
||||
var enabled = chatCodes.ContainsKey(type);
|
||||
if (ImGui.Checkbox($"##{type.Name()}", ref enabled))
|
||||
{
|
||||
if (enabled)
|
||||
chatCodes[type] = ChatSourceExt.All;
|
||||
else
|
||||
chatCodes.Remove(type);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (!type.HasSource())
|
||||
{
|
||||
ImGui.TextUnformatted(type.Name());
|
||||
continue;
|
||||
}
|
||||
|
||||
using var typeNode = ImRaii.TreeNode($"{type.Name()}");
|
||||
if (!typeNode.Success)
|
||||
continue;
|
||||
|
||||
chatCodes.TryGetValue(type, out var sourcesEnum);
|
||||
var sources = (uint)sourcesEnum;
|
||||
|
||||
foreach (var source in Enum.GetValues<ChatSource>())
|
||||
if (ImGui.CheckboxFlags(source.Name(), ref sources, (uint)source))
|
||||
chatCodes[type] = (ChatSource)sources;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExtraChatSelector(string headerText, ref bool all, HashSet<Guid> extraChatChannels)
|
||||
{
|
||||
if (Plugin.ExtraChat.ChannelNames.Count <= 0)
|
||||
return;
|
||||
|
||||
using var extraTree = ImRaii.TreeNode(headerText);
|
||||
if (!extraTree.Success)
|
||||
return;
|
||||
|
||||
ImGui.Checkbox(Language.Options_Tabs_ExtraChatAll, ref all);
|
||||
ImGui.Separator();
|
||||
|
||||
using var _ = ImRaii.Disabled(all);
|
||||
foreach (var (id, name) in Plugin.ExtraChat.ChannelNames)
|
||||
{
|
||||
var enabled = extraChatChannels.Contains(id);
|
||||
if (!ImGui.Checkbox($"{name}##ec-{id}", ref enabled))
|
||||
continue;
|
||||
|
||||
if (enabled)
|
||||
extraChatChannels.Add(id);
|
||||
else
|
||||
extraChatChannels.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to avoid pops if condition is false for Push.
|
||||
private static void Nop() { }
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@ using ChatTwo.Resources;
|
||||
namespace ChatTwo.Util;
|
||||
|
||||
internal static class TabsUtil {
|
||||
internal static Dictionary<ChatType, ChatSource> AllChannels()
|
||||
{
|
||||
var channels = new Dictionary<ChatType, ChatSource>();
|
||||
foreach (var chatType in Enum.GetValues<ChatType>())
|
||||
channels[chatType] = ChatSourceExt.All;
|
||||
return channels;
|
||||
}
|
||||
|
||||
internal static Tab VanillaGeneral => new() {
|
||||
Name = Language.Tabs_Presets_General,
|
||||
ChatCodes = new Dictionary<ChatType, ChatSource> {
|
||||
|
||||
Reference in New Issue
Block a user