- Fixed hotkey behaviour in vanilla inputs
- Changed behaviour of tab switching
This commit is contained in:
@@ -17,10 +17,40 @@
|
|||||||
<ProjectReference Include="..\ChatTwo\ChatTwo.csproj" />
|
<ProjectReference Include="..\ChatTwo\ChatTwo.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<PropertyGroup>
|
||||||
<Reference Include="Dalamud">
|
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev</DalamudLibPath>
|
||||||
<HintPath>..\..\AppData\Roaming\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
|
</PropertyGroup>
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
|
||||||
|
<DalamudLibPath>$(DALAMUD_HOME)</DalamudLibPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(IsCI)' == 'true'">
|
||||||
|
<DalamudLibPath>$(HOME)/dalamud</DalamudLibPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Dalamud">
|
||||||
|
<HintPath>$(DalamudLibPath)\Dalamud.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="FFXIVClientStructs">
|
||||||
|
<HintPath>$(DalamudLibPath)\FFXIVClientStructs.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ImGui.NET">
|
||||||
|
<HintPath>$(DalamudLibPath)\ImGui.NET.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Lumina">
|
||||||
|
<HintPath>$(DalamudLibPath)\Lumina.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Lumina.Excel">
|
||||||
|
<HintPath>$(DalamudLibPath)\Lumina.Excel.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -198,6 +198,9 @@ internal class Tab
|
|||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
public HashSet<Guid> TrackedMessageIds = new();
|
public HashSet<Guid> TrackedMessageIds = new();
|
||||||
|
|
||||||
|
[NonSerialized]
|
||||||
|
public InputChannel? PreviousChannel;
|
||||||
|
|
||||||
~Tab() { MessagesMutex.Dispose(); }
|
~Tab() { MessagesMutex.Dispose(); }
|
||||||
|
|
||||||
internal bool Contains(Message message) {
|
internal bool Contains(Message message) {
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
internal bool UsesTellTempChannel { get; set; }
|
internal bool UsesTellTempChannel { get; set; }
|
||||||
internal InputChannel? PreviousChannel { get; private set; }
|
internal InputChannel? PreviousChannel { get; private set; }
|
||||||
|
|
||||||
|
private bool DirectChat;
|
||||||
private long LastRefresh;
|
private long LastRefresh;
|
||||||
|
|
||||||
internal Chat(Plugin plugin)
|
internal Chat(Plugin plugin)
|
||||||
@@ -372,10 +373,10 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (LastRefresh + 5 * 1000 < Environment.TickCount64)
|
if (LastRefresh + 5 * 1000 < Environment.TickCount64)
|
||||||
{
|
{
|
||||||
UpdateKeybinds();
|
UpdateKeybinds();
|
||||||
|
DirectChat = Plugin.GameConfig.TryGet(UiControlOption.DirectChat, out bool option) && option;
|
||||||
LastRefresh = Environment.TickCount64;
|
LastRefresh = Environment.TickCount64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var modifierState = (ModifierFlag) 0;
|
var modifierState = (ModifierFlag) 0;
|
||||||
foreach (var modifier in Enum.GetValues<ModifierFlag>())
|
foreach (var modifier in Enum.GetValues<ModifierFlag>())
|
||||||
{
|
{
|
||||||
@@ -390,6 +391,18 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (!Keybinds.TryGetValue(toIntercept, out var keybind))
|
if (!Keybinds.TryGetValue(toIntercept, out var keybind))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Vanilla input has focus, so we ignore Ready Chat and Ready Command keybind
|
||||||
|
if (toIntercept is "CMD_CHAT" or "CMD_COMMAND")
|
||||||
|
{
|
||||||
|
// Vanilla text input has focus
|
||||||
|
if (RaptureAtkModule.Instance()->AtkModule.IsTextInputActive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Direct chat option is selected
|
||||||
|
if (DirectChat)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
void Intercept(VirtualKey key, ModifierFlag modifier)
|
void Intercept(VirtualKey key, ModifierFlag modifier)
|
||||||
{
|
{
|
||||||
if (!Plugin.KeyState.IsVirtualKeyValid(key))
|
if (!Plugin.KeyState.IsVirtualKeyValid(key))
|
||||||
@@ -450,38 +463,32 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (eventId != 0x31 || value == null || value->UInt is not (0x05 or 0x0C))
|
if (eventId != 0x31 || value == null || value->UInt is not (0x05 or 0x0C))
|
||||||
return ChatLogRefreshHook!.Original(log, eventId, value);
|
return ChatLogRefreshHook!.Original(log, eventId, value);
|
||||||
|
|
||||||
if (Plugin.GameConfig.TryGet(UiControlOption.DirectChat, out bool option) && option)
|
if (DirectChat && CurrentCharacter != null)
|
||||||
{
|
{
|
||||||
if (CurrentCharacter != null)
|
// FIXME: this whole system sucks
|
||||||
|
// FIXME v2: I hate everything about this, but it works
|
||||||
|
Plugin.Framework.RunOnTick(() =>
|
||||||
{
|
{
|
||||||
// FIXME: this whole system sucks
|
string? input = null;
|
||||||
// FIXME v2: I hate everything about this, but it works
|
|
||||||
Plugin.Framework.RunOnTick(() =>
|
var utf8Bytes = MemoryHelper.ReadRaw((nint) CurrentCharacter, 2);
|
||||||
|
var chars = Encoding.UTF8.GetString(utf8Bytes).ToCharArray();
|
||||||
|
if (chars.Length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var c = chars[0];
|
||||||
|
if (c != '\0' && !char.IsControl(c))
|
||||||
|
input = c.ToString();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
string? input = null;
|
Activated?.Invoke(new ChatActivatedArgs(new ChannelSwitchInfo(null)) { Input = input, });
|
||||||
|
}
|
||||||
var utf8Bytes = MemoryHelper.ReadRaw((nint) CurrentCharacter, 2);
|
catch (Exception ex)
|
||||||
var chars = Encoding.UTF8.GetString(utf8Bytes).ToCharArray();
|
{
|
||||||
if (chars.Length == 0)
|
Plugin.Log.Error(ex, "Error in chat Activated event");
|
||||||
return;
|
}
|
||||||
|
});
|
||||||
var c = chars[0];
|
|
||||||
if (c != '\0' && !char.IsControl(c))
|
|
||||||
input = c.ToString();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var args = new ChatActivatedArgs(new ChannelSwitchInfo(null)) {
|
|
||||||
Input = input,
|
|
||||||
};
|
|
||||||
Activated?.Invoke(args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Plugin.Log.Error(ex, "Error in chat Activated event");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string? addIfNotPresent = null;
|
string? addIfNotPresent = null;
|
||||||
@@ -496,10 +503,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var args = new ChatActivatedArgs(new ChannelSwitchInfo(null)) {
|
Activated?.Invoke(new ChatActivatedArgs(new ChannelSwitchInfo(null)) { AddIfNotPresent = addIfNotPresent, });
|
||||||
AddIfNotPresent = addIfNotPresent,
|
|
||||||
};
|
|
||||||
Activated?.Invoke(args);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -387,6 +387,21 @@ public sealed class ChatLogWindow : Window, IUiComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TabChannelSwitch(Tab tab)
|
||||||
|
{
|
||||||
|
// Save the previous channel to restore it later
|
||||||
|
var current = CurrentTab;
|
||||||
|
if (current is { Channel: null })
|
||||||
|
current.PreviousChannel = Plugin.Functions.Chat.Channel.channel;
|
||||||
|
|
||||||
|
// Channel will be null if PreviousChannel is used
|
||||||
|
var channel = tab.Channel ?? tab.PreviousChannel;
|
||||||
|
|
||||||
|
// Channel being null it doesn't have a default, and we never selected this channel before
|
||||||
|
if (channel != null)
|
||||||
|
SetChannel(tab.Channel ?? tab.PreviousChannel);
|
||||||
|
}
|
||||||
|
|
||||||
private bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78];
|
private bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78];
|
||||||
|
|
||||||
private bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
|
private bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
|
||||||
@@ -1036,12 +1051,11 @@ public sealed class ChatLogWindow : Window, IUiComponent
|
|||||||
|
|
||||||
currentTab = tabI;
|
currentTab = tabI;
|
||||||
var switchedTab = LastTab != tabI;
|
var switchedTab = LastTab != tabI;
|
||||||
|
if (switchedTab)
|
||||||
|
TabChannelSwitch(tab);
|
||||||
LastTab = tabI;
|
LastTab = tabI;
|
||||||
tab.Unread = 0;
|
tab.Unread = 0;
|
||||||
|
|
||||||
if (switchedTab && tab.Channel.HasValue)
|
|
||||||
SetChannel(tab.Channel.Value);
|
|
||||||
|
|
||||||
DrawMessageLog(tab, PayloadHandler, GetRemainingHeightForMessageLog(), switchedTab);
|
DrawMessageLog(tab, PayloadHandler, GetRemainingHeightForMessageLog(), switchedTab);
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
@@ -1083,10 +1097,9 @@ public sealed class ChatLogWindow : Window, IUiComponent
|
|||||||
|
|
||||||
currentTab = tabI;
|
currentTab = tabI;
|
||||||
switchedTab = LastTab != tabI;
|
switchedTab = LastTab != tabI;
|
||||||
|
if (switchedTab)
|
||||||
|
TabChannelSwitch(tab);
|
||||||
LastTab = tabI;
|
LastTab = tabI;
|
||||||
|
|
||||||
if (switchedTab && tab.Channel.HasValue)
|
|
||||||
SetChannel(tab.Channel.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user