feat(sidebar): restore per-tab notification sound picker with preview

This commit is contained in:
2026-06-10 13:26:55 +02:00
parent ac7f74b227
commit 1f2c354471
4 changed files with 258 additions and 19 deletions
+100
View File
@@ -1,5 +1,9 @@
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using FFXIVClientStructs.FFXIV.Client.UI;
using HellionChat.Resources;
using HellionChat.Util;
namespace HellionChat.Ui.Components;
@@ -26,12 +30,108 @@ internal static class TabContextMenu
if (ImGui.InputText("##tab-name", ref name, 512) && ApplyTabRename(tab, name))
Plugin.Instance.SaveConfig();
// Per-tab notification sound (B3-3). The checkbox gates the picker so
// tabs that never want a sound keep the popup short.
if (
ImGui.Checkbox(
HellionStrings.Tabs_NotificationSound_Enable_Name,
ref tab.EnableNotificationSound
)
)
Plugin.Instance.SaveConfig();
ImGuiUtil.HelpMarker(HellionStrings.Tabs_NotificationSound_Description);
if (tab.EnableNotificationSound)
DrawSoundPicker(tab);
if (ImGui.MenuItem("Pop Out"))
pool.TryOpen(tab);
ImGui.EndPopup();
}
// Sound picker: 16 numbered game sounds, a separator, then the 3 bundled
// Hellion clips stored as ids 17-19 (1.5.6 parity order). The collapsed
// preview reuses the entry label scheme so the current pick reads the same
// open or closed.
private static void DrawSoundPicker(Tab tab)
{
var preview =
tab.NotificationSoundId <= 16
? $"{HellionStrings.Tabs_NotificationSound_Option} {tab.NotificationSoundId}"
: $"{HellionStrings.Tabs_NotificationSound_CustomOption} {tab.NotificationSoundId - 16}";
using (
var combo = ImGuiUtil.BeginComboVertical(
HellionStrings.Tabs_NotificationSound_Option,
preview
)
)
{
if (combo.Success)
{
for (uint s = 1; s <= 16; s++)
{
if (
ImGui.Selectable(
$"{HellionStrings.Tabs_NotificationSound_Option} {s}",
tab.NotificationSoundId == s
)
)
{
tab.NotificationSoundId = s;
Plugin.Instance.SaveConfig();
}
}
ImGui.Separator();
for (uint n = 1; n <= 3; n++)
{
var customId = 16 + n;
if (
ImGui.Selectable(
$"{HellionStrings.Tabs_NotificationSound_CustomOption} {n}",
tab.NotificationSoundId == customId
)
)
{
tab.NotificationSoundId = customId;
Plugin.Instance.SaveConfig();
}
}
}
}
if (
ImGuiUtil.IconButton(
FontAwesomeIcon.Play,
"tab-sound-preview",
HellionStrings.Tabs_NotificationSound_Preview
)
)
PreviewSound(tab.NotificationSoundId);
}
// Preview: 1-16 are game UI sounds (must hit the framework thread); 17+ are
// custom NAudio clips (own playback thread). Open range >= 17 (not 17-19); the
// 3-clip ceiling is guarded inside CustomAudioPlayer.
private static void PreviewSound(uint id)
{
if (id is >= 1 and <= 16)
{
Plugin.Framework.RunOnFrameworkThread(() =>
{
unsafe
{
UIGlobals.PlaySoundEffect(id);
}
});
}
else if (id >= 17)
{
Plugin.Instance.CustomAudioPlayer.Play((int)id - 16, Plugin.Config.CustomSoundVolume);
}
}
// Factored out so the SelfTest drives the real rename path, not a field poke.
// Returns true when the name actually changed (gates the SaveConfig write).
internal static bool ApplyTabRename(Tab tab, string newName)