- Implement independent hide condition for popouts (closes #124)
This commit is contained in:
@@ -240,6 +240,14 @@ internal class Tab
|
|||||||
public bool CanMove = true;
|
public bool CanMove = true;
|
||||||
public bool CanResize = true;
|
public bool CanResize = true;
|
||||||
|
|
||||||
|
public bool IndependentHide;
|
||||||
|
public bool HideDuringCutscenes = true;
|
||||||
|
public bool HideWhenNotLoggedIn = true;
|
||||||
|
public bool HideWhenUiHidden = true;
|
||||||
|
public bool HideInLoadingScreens;
|
||||||
|
public bool HideInBattle;
|
||||||
|
public bool HideWhenInactive;
|
||||||
|
|
||||||
[NonSerialized] public uint Unread;
|
[NonSerialized] public uint Unread;
|
||||||
[NonSerialized] public long LastActivity;
|
[NonSerialized] public long LastActivity;
|
||||||
[NonSerialized] public MessageList Messages = new();
|
[NonSerialized] public MessageList Messages = new();
|
||||||
@@ -285,6 +293,13 @@ internal class Tab
|
|||||||
CurrentChannel = CurrentChannel,
|
CurrentChannel = CurrentChannel,
|
||||||
CanMove = CanMove,
|
CanMove = CanMove,
|
||||||
CanResize = CanResize,
|
CanResize = CanResize,
|
||||||
|
IndependentHide = IndependentHide,
|
||||||
|
HideDuringCutscenes = HideDuringCutscenes,
|
||||||
|
HideWhenNotLoggedIn = HideWhenNotLoggedIn,
|
||||||
|
HideWhenUiHidden = HideWhenUiHidden,
|
||||||
|
HideInLoadingScreens = HideInLoadingScreens,
|
||||||
|
HideInBattle = HideInBattle,
|
||||||
|
HideWhenInactive = HideWhenInactive,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -561,4 +561,14 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
_ => playerName
|
_ => playerName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool CheckHideFlags()
|
||||||
|
{
|
||||||
|
// Only hide the chat in a cutscene when the vanilla chat would've
|
||||||
|
// also been hidden. This prevents Chat 2 from hiding for a split
|
||||||
|
// second before the cutscene actually starts, because the game sets
|
||||||
|
// the cutscene conditions before processing the skip.
|
||||||
|
var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
|
||||||
|
return raptureAtkUnitManager == null || raptureAtkUnitManager->UiFlags.HasFlag(UIModule.UiFlags.Chat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,4 +242,8 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
if (GameFunctions.GameFunctions.IsAddonInteractable(name))
|
if (GameFunctions.GameFunctions.IsAddonInteractable(name))
|
||||||
GameFunctions.GameFunctions.SetAddonInteractable(name, false);
|
GameFunctions.GameFunctions.SetAddonInteractable(name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool InBattle => Condition[ConditionFlag.InCombat];
|
||||||
|
public static bool GposeActive => Condition[ConditionFlag.WatchingCutscene];
|
||||||
|
public static bool CutsceneActive => Condition[ConditionFlag.OccupiedInCutSceneEvent] || Condition[ConditionFlag.WatchingCutscene78];
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+9
@@ -3236,6 +3236,15 @@ namespace ChatTwo.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Use different hide condition than main window.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Options_Tabs_IndependentHide {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Options_Tabs_IndependentHide", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Use different opacity than main window.
|
/// Looks up a localized string similar to Use different opacity than main window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -541,6 +541,9 @@
|
|||||||
<data name="Options_Tabs_Opacity">
|
<data name="Options_Tabs_Opacity">
|
||||||
<value>Opacity</value>
|
<value>Opacity</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Options_Tabs_IndependentHide">
|
||||||
|
<value>Use different hide condition than main window</value>
|
||||||
|
</data>
|
||||||
<data name="Options_FontsEnabled">
|
<data name="Options_FontsEnabled">
|
||||||
<value>Enable custom fonts</value>
|
<value>Enable custom fonts</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -369,10 +369,6 @@ public sealed class ChatLogWindow : Window
|
|||||||
Plugin.ServerCore.SendNewLogin();
|
Plugin.ServerCore.SendNewLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
private enum HideState
|
private enum HideState
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
@@ -385,30 +381,25 @@ public sealed class ChatLogWindow : Window
|
|||||||
private HideState CurrentHideState = HideState.None;
|
private HideState CurrentHideState = HideState.None;
|
||||||
|
|
||||||
public bool IsHidden;
|
public bool IsHidden;
|
||||||
public unsafe void HideStateCheck()
|
public void HideStateCheck()
|
||||||
{
|
{
|
||||||
// if the chat has no hide state set, and the player has entered battle, we hide chat if they have configured it
|
// if the chat has no hide state set, and the player has entered battle, we hide chat if they have configured it
|
||||||
if (Plugin.Config.HideInBattle && CurrentHideState == HideState.None && InBattle)
|
if (Plugin.Config.HideInBattle && CurrentHideState == HideState.None && Plugin.InBattle)
|
||||||
CurrentHideState = HideState.Battle;
|
CurrentHideState = HideState.Battle;
|
||||||
|
|
||||||
// If the chat is hidden because of battle, we reset it here
|
// If the chat is hidden because of battle, we reset it here
|
||||||
if (CurrentHideState is HideState.Battle && !InBattle)
|
if (CurrentHideState is HideState.Battle && !Plugin.InBattle)
|
||||||
CurrentHideState = HideState.None;
|
CurrentHideState = HideState.None;
|
||||||
|
|
||||||
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
|
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
|
||||||
if (Plugin.Config.HideDuringCutscenes && CurrentHideState == HideState.None && (CutsceneActive || GposeActive))
|
if (Plugin.Config.HideDuringCutscenes && CurrentHideState == HideState.None && (Plugin.CutsceneActive || Plugin.GposeActive))
|
||||||
{
|
{
|
||||||
// Only hide the chat in a cutscene when the vanilla chat would've
|
if (Plugin.Functions.Chat.CheckHideFlags())
|
||||||
// also been hidden. This prevents Chat 2 from hiding for a split
|
|
||||||
// second before the cutscene actually starts, because the game sets
|
|
||||||
// the cutscene conditions before processing the skip.
|
|
||||||
var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
|
|
||||||
if (raptureAtkUnitManager == null || raptureAtkUnitManager->UiFlags.HasFlag(UIModule.UiFlags.Chat))
|
|
||||||
CurrentHideState = HideState.Cutscene;
|
CurrentHideState = HideState.Cutscene;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
|
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
|
||||||
if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !CutsceneActive && !GposeActive)
|
if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !Plugin.CutsceneActive && !Plugin.GposeActive)
|
||||||
CurrentHideState = HideState.None;
|
CurrentHideState = HideState.None;
|
||||||
|
|
||||||
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
|
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
|
||||||
@@ -453,7 +444,7 @@ public sealed class ChatLogWindow : Window
|
|||||||
if (IsHidden)
|
if (IsHidden)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && InBattle) || Activate)
|
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && Plugin.InBattle) || Activate)
|
||||||
{
|
{
|
||||||
LastActivityTime = FrameTime;
|
LastActivityTime = FrameTime;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+45
-2
@@ -38,10 +38,10 @@ internal class Popout : Window
|
|||||||
public override bool DrawConditions()
|
public override bool DrawConditions()
|
||||||
{
|
{
|
||||||
FrameTime = Environment.TickCount64;
|
FrameTime = Environment.TickCount64;
|
||||||
if (ChatLogWindow.IsHidden)
|
if (Tab.IndependentHide ? HideStateCheck() : ChatLogWindow.IsHidden)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && ChatLogWindow.InBattle) || !Tab.UnhideOnActivity)
|
if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && Plugin.InBattle) || !Tab.UnhideOnActivity)
|
||||||
{
|
{
|
||||||
LastActivityTime = FrameTime;
|
LastActivityTime = FrameTime;
|
||||||
return true;
|
return true;
|
||||||
@@ -108,4 +108,47 @@ internal class Popout : Window
|
|||||||
Tab.PopOut = false;
|
Tab.PopOut = false;
|
||||||
ChatLogWindow.Plugin.SaveConfig();
|
ChatLogWindow.Plugin.SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum HideState
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Cutscene,
|
||||||
|
CutsceneOverride,
|
||||||
|
User,
|
||||||
|
Battle
|
||||||
|
}
|
||||||
|
|
||||||
|
private HideState CurrentHideState = HideState.None;
|
||||||
|
|
||||||
|
private bool HideStateCheck()
|
||||||
|
{
|
||||||
|
// if the chat has no hide state set, and the player has entered battle, we hide chat if they have configured it
|
||||||
|
if (Tab.HideInBattle && CurrentHideState == HideState.None && Plugin.InBattle)
|
||||||
|
CurrentHideState = HideState.Battle;
|
||||||
|
|
||||||
|
// If the chat is hidden because of battle, we reset it here
|
||||||
|
if (CurrentHideState is HideState.Battle && !Plugin.InBattle)
|
||||||
|
CurrentHideState = HideState.None;
|
||||||
|
|
||||||
|
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
|
||||||
|
if (Tab.HideDuringCutscenes && CurrentHideState == HideState.None && (Plugin.CutsceneActive || Plugin.GposeActive))
|
||||||
|
{
|
||||||
|
if (ChatLogWindow.Plugin.Functions.Chat.CheckHideFlags())
|
||||||
|
CurrentHideState = HideState.Cutscene;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
|
||||||
|
if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !Plugin.CutsceneActive && !Plugin.GposeActive)
|
||||||
|
CurrentHideState = HideState.None;
|
||||||
|
|
||||||
|
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
|
||||||
|
if (CurrentHideState == HideState.Cutscene && ChatLogWindow.Activate)
|
||||||
|
CurrentHideState = HideState.CutsceneOverride;
|
||||||
|
|
||||||
|
// if the user hid the chat and is now activating chat, reset the hide state
|
||||||
|
if (CurrentHideState == HideState.User && ChatLogWindow.Activate)
|
||||||
|
CurrentHideState = HideState.None;
|
||||||
|
|
||||||
|
return CurrentHideState is HideState.Cutscene or HideState.User or HideState.Battle || (Tab.HideWhenNotLoggedIn && !Plugin.ClientState.IsLoggedIn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,10 +88,31 @@ internal sealed class Tabs : ISettingsTab
|
|||||||
ImGui.Checkbox(Language.Options_Tabs_PopOut, ref tab.PopOut);
|
ImGui.Checkbox(Language.Options_Tabs_PopOut, ref tab.PopOut);
|
||||||
if (tab.PopOut)
|
if (tab.PopOut)
|
||||||
{
|
{
|
||||||
|
using var _ = ImRaii.PushIndent(10.0f);
|
||||||
ImGui.Checkbox(Language.Options_Tabs_IndependentOpacity, ref tab.IndependentOpacity);
|
ImGui.Checkbox(Language.Options_Tabs_IndependentOpacity, ref tab.IndependentOpacity);
|
||||||
if (tab.IndependentOpacity)
|
if (tab.IndependentOpacity)
|
||||||
ImGuiUtil.DragFloatVertical(Language.Options_Tabs_Opacity, ref tab.Opacity, 0.25f, 0f, 100f, $"{tab.Opacity:N2}%%", ImGuiSliderFlags.AlwaysClamp);
|
ImGuiUtil.DragFloatVertical(Language.Options_Tabs_Opacity, ref tab.Opacity, 0.25f, 0f, 100f, $"{tab.Opacity:N2}%%", ImGuiSliderFlags.AlwaysClamp);
|
||||||
|
|
||||||
|
ImGui.Checkbox(Language.Options_Tabs_IndependentHide, ref tab.IndependentHide);
|
||||||
|
if (tab.IndependentHide)
|
||||||
|
{
|
||||||
|
using var __ = ImRaii.PushIndent(10.0f);
|
||||||
|
ImGuiUtil.OptionCheckbox(ref tab.HideDuringCutscenes, Language.Options_HideDuringCutscenes_Name);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
ImGuiUtil.OptionCheckbox(ref tab.HideWhenNotLoggedIn, Language.Options_HideWhenNotLoggedIn_Name);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
ImGuiUtil.OptionCheckbox(ref tab.HideWhenUiHidden, Language.Options_HideWhenUiHidden_Name);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
ImGuiUtil.OptionCheckbox(ref tab.HideInLoadingScreens, Language.Options_HideInLoadingScreens_Name);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
ImGuiUtil.OptionCheckbox(ref tab.HideInBattle, Language.Options_HideInBattle_Name);
|
||||||
|
ImGui.Spacing();
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiUtil.OptionCheckbox(ref tab.CanMove, Language.Popout_CanMove_Name);
|
ImGuiUtil.OptionCheckbox(ref tab.CanMove, Language.Popout_CanMove_Name);
|
||||||
ImGui.Spacing();
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user