forked from liza/Questionable
Restructure config window
This commit is contained in:
parent
097c67ed5d
commit
3820647827
@ -26,6 +26,7 @@ using Questionable.Functions;
|
||||
using Questionable.Validation;
|
||||
using Questionable.Validation.Validators;
|
||||
using Questionable.Windows;
|
||||
using Questionable.Windows.ConfigComponents;
|
||||
using Questionable.Windows.JournalComponents;
|
||||
using Questionable.Windows.QuestComponents;
|
||||
using Action = Questionable.Controller.Steps.Interactions.Action;
|
||||
@ -298,6 +299,11 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
||||
serviceCollection.AddSingleton<QuestValidationWindow>();
|
||||
serviceCollection.AddSingleton<JournalProgressWindow>();
|
||||
serviceCollection.AddSingleton<PriorityWindow>();
|
||||
|
||||
serviceCollection.AddSingleton<GeneralConfigComponent>();
|
||||
serviceCollection.AddSingleton<DutyConfigComponent>();
|
||||
serviceCollection.AddSingleton<NotificationConfigComponent>();
|
||||
serviceCollection.AddSingleton<DebugConfigComponent>();
|
||||
}
|
||||
|
||||
private static void AddQuestValidators(ServiceCollection serviceCollection)
|
||||
|
64
Questionable/Windows/ConfigComponents/ConfigComponent.cs
Normal file
64
Questionable/Windows/ConfigComponents/ConfigComponent.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System.Text;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Questionable.Windows.ConfigComponents;
|
||||
|
||||
internal abstract class ConfigComponent
|
||||
{
|
||||
protected const string DutyClipboardSeparator = ";";
|
||||
protected const string DutyWhitelistPrefix = "+";
|
||||
protected const string DutyBlacklistPrefix = "-";
|
||||
|
||||
protected readonly string[] SupportedCfcOptions =
|
||||
[
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled (Default)",
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled",
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled"
|
||||
];
|
||||
|
||||
protected readonly string[] UnsupportedCfcOptions =
|
||||
[
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled (Default)",
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled",
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled"
|
||||
];
|
||||
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
|
||||
protected ConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
protected Configuration Configuration { get; }
|
||||
|
||||
public abstract void DrawTab();
|
||||
|
||||
protected void Save() => _pluginInterface.SavePluginConfig(Configuration);
|
||||
|
||||
protected static string FormatLevel(int level)
|
||||
{
|
||||
if (level == 0)
|
||||
return string.Empty;
|
||||
|
||||
return $"{FormatLevel(level / 10)}{(SeIconChar.Number0 + level % 10).ToIconChar()}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default implementation for <see cref="ImGui.GetClipboardText"/> throws an NullReferenceException if the clipboard is empty, maybe also if it doesn't contain text.
|
||||
/// </summary>
|
||||
protected unsafe string? GetClipboardText()
|
||||
{
|
||||
byte* ptr = ImGuiNative.igGetClipboardText();
|
||||
if (ptr == null)
|
||||
return null;
|
||||
|
||||
int byteCount = 0;
|
||||
while (ptr[byteCount] != 0)
|
||||
++byteCount;
|
||||
return Encoding.UTF8.GetString(ptr, byteCount);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Questionable.Windows.ConfigComponents;
|
||||
|
||||
internal sealed class DebugConfigComponent : ConfigComponent
|
||||
{
|
||||
public DebugConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration)
|
||||
: base(pluginInterface, configuration)
|
||||
{
|
||||
}
|
||||
|
||||
public override void DrawTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Advanced");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed,
|
||||
"Enabling any option here may cause unexpected behavior. Use at your own risk.");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
bool debugOverlay = Configuration.Advanced.DebugOverlay;
|
||||
if (ImGui.Checkbox("Enable debug overlay", ref debugOverlay))
|
||||
{
|
||||
Configuration.Advanced.DebugOverlay = debugOverlay;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool neverFly = Configuration.Advanced.NeverFly;
|
||||
if (ImGui.Checkbox("Disable flying (even if unlocked for the zone)", ref neverFly))
|
||||
{
|
||||
Configuration.Advanced.NeverFly = neverFly;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool additionalStatusInformation = Configuration.Advanced.AdditionalStatusInformation;
|
||||
if (ImGui.Checkbox("Draw additional status information", ref additionalStatusInformation))
|
||||
{
|
||||
Configuration.Advanced.AdditionalStatusInformation = additionalStatusInformation;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
249
Questionable/Windows/ConfigComponents/DutyConfigComponent.cs
Normal file
249
Questionable/Windows/ConfigComponents/DutyConfigComponent.cs
Normal file
@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.Sheets;
|
||||
using Questionable.Controller;
|
||||
using Questionable.Data;
|
||||
using Questionable.External;
|
||||
using Questionable.Model;
|
||||
|
||||
namespace Questionable.Windows.ConfigComponents;
|
||||
|
||||
internal sealed class DutyConfigComponent : ConfigComponent
|
||||
{
|
||||
private const string DutyClipboardPrefix = "qst:duty:";
|
||||
|
||||
private readonly QuestRegistry _questRegistry;
|
||||
private readonly AutoDutyIpc _autoDutyIpc;
|
||||
private readonly Dictionary<EExpansionVersion, List<DutyInfo>> _contentFinderConditionNames;
|
||||
|
||||
public DutyConfigComponent(
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
Configuration configuration,
|
||||
IDataManager dataManager,
|
||||
QuestRegistry questRegistry,
|
||||
AutoDutyIpc autoDutyIpc,
|
||||
TerritoryData territoryData)
|
||||
: base(pluginInterface, configuration)
|
||||
{
|
||||
_questRegistry = questRegistry;
|
||||
_autoDutyIpc = autoDutyIpc;
|
||||
|
||||
_contentFinderConditionNames = dataManager.GetExcelSheet<DawnContent>()
|
||||
.Where(x => x is { RowId: > 0, Unknown16: false })
|
||||
.OrderBy(x => x.Unknown15) // SortKey for the support UI
|
||||
.Select(x => x.Content.ValueNullable)
|
||||
.Where(x => x != null)
|
||||
.Select(x => x!.Value)
|
||||
.Select(x => new
|
||||
{
|
||||
Expansion = (EExpansionVersion)x.TerritoryType.Value.ExVersion.RowId,
|
||||
CfcId = x.RowId,
|
||||
Name = territoryData.GetContentFinderCondition(x.RowId)?.Name ?? "?",
|
||||
TerritoryId = x.TerritoryType.RowId,
|
||||
ContentType = x.ContentType.RowId,
|
||||
Level = x.ClassJobLevelRequired,
|
||||
x.SortKey
|
||||
})
|
||||
.GroupBy(x => x.Expansion)
|
||||
.ToDictionary(x => x.Key,
|
||||
x => x
|
||||
.Select(y => new DutyInfo(y.CfcId, y.TerritoryId,
|
||||
$"{SeIconChar.LevelEn.ToIconChar()}{FormatLevel(y.Level)} {y.Name}"))
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public override void DrawTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Duties");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
bool runInstancedContentWithAutoDuty = Configuration.Duties.RunInstancedContentWithAutoDuty;
|
||||
if (ImGui.Checkbox("Run instanced content with AutoDuty and BossMod", ref runInstancedContentWithAutoDuty))
|
||||
{
|
||||
Configuration.Duties.RunInstancedContentWithAutoDuty = runInstancedContentWithAutoDuty;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(
|
||||
"The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration.");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
using (ImRaii.Disabled(!runInstancedContentWithAutoDuty))
|
||||
{
|
||||
ImGui.Text(
|
||||
"Questionable includes a default list of duties that work if AutoDuty and BossMod are installed.");
|
||||
|
||||
ImGui.Text(
|
||||
"The included list of duties can change with each update, and is based on the following spreadsheet:");
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.GlobeEurope, "Open AutoDuty spreadsheet"))
|
||||
Util.OpenLink(
|
||||
"https://docs.google.com/spreadsheets/d/151RlpqRcCpiD_VbQn6Duf-u-S71EP7d0mx3j1PDNoNA/edit?pli=1#gid=0");
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("You can override the dungeon settings for each individual dungeon/trial:");
|
||||
|
||||
DrawConfigTable(runInstancedContentWithAutoDuty);
|
||||
DrawClipboardButtons();
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
using (var unused = ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl)))
|
||||
{
|
||||
if (ImGui.Button("Reset to default"))
|
||||
{
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Clear();
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Clear();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
ImGui.SetTooltip("Hold CTRL to enable this button.");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawConfigTable(bool runInstancedContentWithAutoDuty)
|
||||
{
|
||||
using var child = ImRaii.Child("DutyConfiguration", new Vector2(-1, 400), true);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
foreach (EExpansionVersion expansion in Enum.GetValues<EExpansionVersion>())
|
||||
{
|
||||
if (ImGui.CollapsingHeader(expansion.ToString()))
|
||||
{
|
||||
using var table = ImRaii.Table($"Duties{expansion}", 2, ImGuiTableFlags.SizingFixedFit);
|
||||
if (table)
|
||||
{
|
||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableSetupColumn("Options", ImGuiTableColumnFlags.WidthFixed, 200f);
|
||||
|
||||
if (_contentFinderConditionNames.TryGetValue(expansion, out var cfcNames))
|
||||
{
|
||||
foreach (var (cfcId, territoryId, name) in cfcNames)
|
||||
{
|
||||
if (_questRegistry.TryGetDutyByContentFinderConditionId(cfcId,
|
||||
out bool autoDutyEnabledByDefault))
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
|
||||
string[] labels = autoDutyEnabledByDefault
|
||||
? SupportedCfcOptions
|
||||
: UnsupportedCfcOptions;
|
||||
int value = 0;
|
||||
if (Configuration.Duties.WhitelistedDutyCfcIds.Contains(cfcId))
|
||||
value = 1;
|
||||
if (Configuration.Duties.BlacklistedDutyCfcIds.Contains(cfcId))
|
||||
value = 2;
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted(name);
|
||||
if (ImGui.IsItemHovered() &&
|
||||
Configuration.Advanced.AdditionalStatusInformation)
|
||||
{
|
||||
using var tooltip = ImRaii.Tooltip();
|
||||
if (tooltip)
|
||||
{
|
||||
ImGui.TextUnformatted(name);
|
||||
ImGui.Separator();
|
||||
ImGui.BulletText($"TerritoryId: {territoryId}");
|
||||
ImGui.BulletText($"ContentFinderConditionId: {cfcId}");
|
||||
}
|
||||
}
|
||||
|
||||
if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(cfcId))
|
||||
ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty",
|
||||
FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
|
||||
}
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
{
|
||||
using var _ = ImRaii.PushId($"##Dungeon{cfcId}");
|
||||
ImGui.SetNextItemWidth(200);
|
||||
if (ImGui.Combo(string.Empty, ref value, labels, labels.Length))
|
||||
{
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Remove(cfcId);
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Remove(cfcId);
|
||||
|
||||
if (value == 1)
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Add(cfcId);
|
||||
else if (value == 2)
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Add(cfcId);
|
||||
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawClipboardButtons()
|
||||
{
|
||||
using (ImRaii.Disabled(Configuration.Duties.WhitelistedDutyCfcIds.Count +
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Count == 0))
|
||||
{
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard"))
|
||||
{
|
||||
var whitelisted =
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Select(x => $"{DutyWhitelistPrefix}{x}");
|
||||
var blacklisted =
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Select(x => $"{DutyBlacklistPrefix}{x}");
|
||||
string text = DutyClipboardPrefix + Convert.ToBase64String(Encoding.UTF8.GetBytes(
|
||||
string.Join(DutyClipboardSeparator, whitelisted.Concat(blacklisted))));
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
string? clipboardText = GetClipboardText();
|
||||
using (ImRaii.Disabled(clipboardText == null ||
|
||||
!clipboardText.StartsWith(DutyClipboardPrefix, StringComparison.InvariantCulture)))
|
||||
{
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Paste, "Import from Clipboard"))
|
||||
{
|
||||
clipboardText = clipboardText!.Substring(DutyClipboardPrefix.Length);
|
||||
string text = Encoding.UTF8.GetString(Convert.FromBase64String(clipboardText));
|
||||
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Clear();
|
||||
Configuration.Duties.BlacklistedDutyCfcIds.Clear();
|
||||
foreach (string part in text.Split(DutyClipboardSeparator))
|
||||
{
|
||||
if (part.StartsWith(DutyWhitelistPrefix, StringComparison.InvariantCulture) &&
|
||||
uint.TryParse(part.AsSpan(DutyWhitelistPrefix.Length), CultureInfo.InvariantCulture,
|
||||
out uint whitelistedCfcId))
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Add(whitelistedCfcId);
|
||||
|
||||
if (part.StartsWith(DutyBlacklistPrefix, StringComparison.InvariantCulture) &&
|
||||
uint.TryParse(part.AsSpan(DutyBlacklistPrefix.Length), CultureInfo.InvariantCulture,
|
||||
out uint blacklistedCfcId))
|
||||
Configuration.Duties.WhitelistedDutyCfcIds.Add(blacklistedCfcId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed record DutyInfo(uint CfcId, uint TerritoryId, string Name);
|
||||
}
|
114
Questionable/Windows/ConfigComponents/GeneralConfigComponent.cs
Normal file
114
Questionable/Windows/ConfigComponents/GeneralConfigComponent.cs
Normal file
@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.Sheets;
|
||||
using Questionable.Controller;
|
||||
using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
|
||||
|
||||
namespace Questionable.Windows.ConfigComponents;
|
||||
|
||||
internal sealed class GeneralConfigComponent : ConfigComponent
|
||||
{
|
||||
private static readonly List<(uint Id, string Name)> DefaultMounts = [(0, "Mount Roulette")];
|
||||
|
||||
private readonly CombatController _combatController;
|
||||
|
||||
private readonly uint[] _mountIds;
|
||||
private readonly string[] _mountNames;
|
||||
private readonly string[] _combatModuleNames = ["None", "Boss Mod (VBM)", "Wrath Combo", "Rotation Solver Reborn"];
|
||||
|
||||
private readonly string[] _grandCompanyNames =
|
||||
["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
|
||||
|
||||
public GeneralConfigComponent(
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
Configuration configuration,
|
||||
CombatController combatController,
|
||||
IDataManager dataManager)
|
||||
: base(pluginInterface, configuration)
|
||||
{
|
||||
_combatController = combatController;
|
||||
|
||||
var mounts = dataManager.GetExcelSheet<Mount>()
|
||||
.Where(x => x is { RowId: > 0, Icon: > 0 })
|
||||
.Select(x => (MountId: x.RowId, Name: x.Singular.ToString()))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList();
|
||||
_mountIds = DefaultMounts.Select(x => x.Id).Concat(mounts.Select(x => x.MountId)).ToArray();
|
||||
_mountNames = DefaultMounts.Select(x => x.Name).Concat(mounts.Select(x => x.Name)).ToArray();
|
||||
}
|
||||
|
||||
public override void DrawTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("General");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
using (ImRaii.Disabled(_combatController.IsRunning))
|
||||
{
|
||||
int selectedCombatModule = (int)Configuration.General.CombatModule;
|
||||
if (ImGui.Combo("Preferred Combat Module", ref selectedCombatModule, _combatModuleNames,
|
||||
_combatModuleNames.Length))
|
||||
{
|
||||
Configuration.General.CombatModule = (Configuration.ECombatModule)selectedCombatModule;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
int selectedMount = Array.FindIndex(_mountIds, x => x == Configuration.General.MountId);
|
||||
if (selectedMount == -1)
|
||||
{
|
||||
selectedMount = 0;
|
||||
Configuration.General.MountId = _mountIds[selectedMount];
|
||||
Save();
|
||||
}
|
||||
|
||||
if (ImGui.Combo("Preferred Mount", ref selectedMount, _mountNames, _mountNames.Length))
|
||||
{
|
||||
Configuration.General.MountId = _mountIds[selectedMount];
|
||||
Save();
|
||||
}
|
||||
|
||||
int grandCompany = (int)Configuration.General.GrandCompany;
|
||||
if (ImGui.Combo("Preferred Grand Company", ref grandCompany, _grandCompanyNames,
|
||||
_grandCompanyNames.Length))
|
||||
{
|
||||
Configuration.General.GrandCompany = (GrandCompany)grandCompany;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool hideInAllInstances = Configuration.General.HideInAllInstances;
|
||||
if (ImGui.Checkbox("Hide quest window in all instanced duties", ref hideInAllInstances))
|
||||
{
|
||||
Configuration.General.HideInAllInstances = hideInAllInstances;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool useEscToCancelQuesting = Configuration.General.UseEscToCancelQuesting;
|
||||
if (ImGui.Checkbox("Use ESC to cancel questing/movement", ref useEscToCancelQuesting))
|
||||
{
|
||||
Configuration.General.UseEscToCancelQuesting = useEscToCancelQuesting;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool showIncompleteSeasonalEvents = Configuration.General.ShowIncompleteSeasonalEvents;
|
||||
if (ImGui.Checkbox("Show details for incomplete seasonal events", ref showIncompleteSeasonalEvents))
|
||||
{
|
||||
Configuration.General.ShowIncompleteSeasonalEvents = showIncompleteSeasonalEvents;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool configureTextAdvance = Configuration.General.ConfigureTextAdvance;
|
||||
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings",
|
||||
ref configureTextAdvance))
|
||||
{
|
||||
Configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using Questionable.External;
|
||||
|
||||
namespace Questionable.Windows.ConfigComponents;
|
||||
|
||||
internal sealed class NotificationConfigComponent : ConfigComponent
|
||||
{
|
||||
private readonly NotificationMasterIpc _notificationMasterIpc;
|
||||
|
||||
public NotificationConfigComponent(
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
Configuration configuration,
|
||||
NotificationMasterIpc notificationMasterIpc)
|
||||
: base(pluginInterface, configuration)
|
||||
{
|
||||
_notificationMasterIpc = notificationMasterIpc;
|
||||
}
|
||||
|
||||
public override void DrawTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Notifications");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
bool enabled = Configuration.Notifications.Enabled;
|
||||
if (ImGui.Checkbox("Enable notifications when manual interaction is required", ref enabled))
|
||||
{
|
||||
Configuration.Notifications.Enabled = enabled;
|
||||
Save();
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(!Configuration.Notifications.Enabled))
|
||||
{
|
||||
using (ImRaii.PushIndent())
|
||||
{
|
||||
var xivChatTypes = Enum.GetValues<XivChatType>()
|
||||
.Where(x => x != XivChatType.StandardEmote)
|
||||
.ToArray();
|
||||
var selectedChatType = Array.IndexOf(xivChatTypes, Configuration.Notifications.ChatType);
|
||||
string[] chatTypeNames = xivChatTypes
|
||||
.Select(t => t.GetAttribute<XivChatTypeInfoAttribute>()?.FancyName ?? t.ToString())
|
||||
.ToArray();
|
||||
if (ImGui.Combo("Chat channel", ref selectedChatType, chatTypeNames,
|
||||
chatTypeNames.Length))
|
||||
{
|
||||
Configuration.Notifications.ChatType = xivChatTypes[selectedChatType];
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("NotificationMaster settings");
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker("Requires the plugin 'NotificationMaster' to be installed.");
|
||||
using (ImRaii.Disabled(!_notificationMasterIpc.Enabled))
|
||||
{
|
||||
bool showTrayMessage = Configuration.Notifications.ShowTrayMessage;
|
||||
if (ImGui.Checkbox("Show tray notification", ref showTrayMessage))
|
||||
{
|
||||
Configuration.Notifications.ShowTrayMessage = showTrayMessage;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool flashTaskbar = Configuration.Notifications.FlashTaskbar;
|
||||
if (ImGui.Checkbox("Flash taskbar icon", ref flashTaskbar))
|
||||
{
|
||||
Configuration.Notifications.FlashTaskbar = flashTaskbar;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,485 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using LLib.ImGui;
|
||||
using Lumina.Excel.Sheets;
|
||||
using Questionable.Controller;
|
||||
using Questionable.Data;
|
||||
using Questionable.External;
|
||||
using Questionable.Model;
|
||||
using GrandCompany = FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany;
|
||||
using Questionable.Windows.ConfigComponents;
|
||||
|
||||
namespace Questionable.Windows;
|
||||
|
||||
internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
||||
{
|
||||
private const string DutyClipboardPrefix = "qst:duty:";
|
||||
private const string DutyClipboardSeparator = ";";
|
||||
private const string DutyWhitelistPrefix = "+";
|
||||
private const string DutyBlacklistPrefix = "-";
|
||||
|
||||
private static readonly List<(uint Id, string Name)> DefaultMounts = [(0, "Mount Roulette")];
|
||||
|
||||
private readonly IDalamudPluginInterface _pluginInterface;
|
||||
private readonly NotificationMasterIpc _notificationMasterIpc;
|
||||
private readonly GeneralConfigComponent _generalConfigComponent;
|
||||
private readonly DutyConfigComponent _dutyConfigComponent;
|
||||
private readonly NotificationConfigComponent _notificationConfigComponent;
|
||||
private readonly DebugConfigComponent _debugConfigComponent;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly CombatController _combatController;
|
||||
private readonly QuestRegistry _questRegistry;
|
||||
private readonly AutoDutyIpc _autoDutyIpc;
|
||||
|
||||
private readonly uint[] _mountIds;
|
||||
private readonly string[] _mountNames;
|
||||
|
||||
private readonly string[] _combatModuleNames = ["None", "Boss Mod (VBM)", "Wrath Combo", "Rotation Solver Reborn"];
|
||||
|
||||
private readonly string[] _grandCompanyNames =
|
||||
["None (manually pick quest)", "Maelstrom", "Twin Adder", "Immortal Flames"];
|
||||
|
||||
private readonly string[] _supportedCfcOptions =
|
||||
[
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled (Default)",
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled",
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled"
|
||||
];
|
||||
|
||||
private readonly string[] _unsupportedCfcOptions =
|
||||
[
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled (Default)",
|
||||
$"{SeIconChar.Circle.ToIconChar()} Enabled",
|
||||
$"{SeIconChar.Cross.ToIconChar()} Disabled"
|
||||
];
|
||||
|
||||
private readonly Dictionary<EExpansionVersion, List<DutyInfo>> _contentFinderConditionNames;
|
||||
|
||||
public ConfigWindow(IDalamudPluginInterface pluginInterface,
|
||||
NotificationMasterIpc notificationMasterIpc,
|
||||
Configuration configuration,
|
||||
IDataManager dataManager,
|
||||
CombatController combatController,
|
||||
TerritoryData territoryData,
|
||||
QuestRegistry questRegistry,
|
||||
AutoDutyIpc autoDutyIpc)
|
||||
public ConfigWindow(
|
||||
IDalamudPluginInterface pluginInterface,
|
||||
GeneralConfigComponent generalConfigComponent,
|
||||
DutyConfigComponent dutyConfigComponent,
|
||||
NotificationConfigComponent notificationConfigComponent,
|
||||
DebugConfigComponent debugConfigComponent,
|
||||
Configuration configuration)
|
||||
: base("Config - Questionable###QuestionableConfig", ImGuiWindowFlags.AlwaysAutoResize)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
_notificationMasterIpc = notificationMasterIpc;
|
||||
_generalConfigComponent = generalConfigComponent;
|
||||
_dutyConfigComponent = dutyConfigComponent;
|
||||
_notificationConfigComponent = notificationConfigComponent;
|
||||
_debugConfigComponent = debugConfigComponent;
|
||||
_configuration = configuration;
|
||||
_combatController = combatController;
|
||||
_questRegistry = questRegistry;
|
||||
_autoDutyIpc = autoDutyIpc;
|
||||
|
||||
var mounts = dataManager.GetExcelSheet<Mount>()
|
||||
.Where(x => x is { RowId: > 0, Icon: > 0 })
|
||||
.Select(x => (MountId: x.RowId, Name: x.Singular.ToString()))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList();
|
||||
_mountIds = DefaultMounts.Select(x => x.Id).Concat(mounts.Select(x => x.MountId)).ToArray();
|
||||
_mountNames = DefaultMounts.Select(x => x.Name).Concat(mounts.Select(x => x.Name)).ToArray();
|
||||
|
||||
_contentFinderConditionNames = dataManager.GetExcelSheet<DawnContent>()
|
||||
.Where(x => x is { RowId: > 0, Unknown16: false })
|
||||
.OrderBy(x => x.Unknown15) // SortKey for the support UI
|
||||
.Select(x => x.Content.ValueNullable)
|
||||
.Where(x => x != null)
|
||||
.Select(x => x!.Value)
|
||||
.Select(x => new
|
||||
{
|
||||
Expansion = (EExpansionVersion)x.TerritoryType.Value.ExVersion.RowId,
|
||||
CfcId = x.RowId,
|
||||
Name = territoryData.GetContentFinderCondition(x.RowId)?.Name ?? "?",
|
||||
TerritoryId = x.TerritoryType.RowId,
|
||||
ContentType = x.ContentType.RowId,
|
||||
Level = x.ClassJobLevelRequired,
|
||||
x.SortKey
|
||||
})
|
||||
.GroupBy(x => x.Expansion)
|
||||
.ToDictionary(x => x.Key,
|
||||
x => x
|
||||
.Select(y => new DutyInfo(y.CfcId, y.TerritoryId, $"{SeIconChar.LevelEn.ToIconChar()}{FormatLevel(y.Level)} {y.Name}"))
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public WindowConfig WindowConfig => _configuration.ConfigWindowConfig;
|
||||
|
||||
private static string FormatLevel(int level)
|
||||
{
|
||||
if (level == 0)
|
||||
return string.Empty;
|
||||
|
||||
return $"{FormatLevel(level / 10)}{(SeIconChar.Number0 + level % 10).ToIconChar()}";
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
using var tabBar = ImRaii.TabBar("QuestionableConfigTabs");
|
||||
if (!tabBar)
|
||||
return;
|
||||
|
||||
DrawGeneralTab();
|
||||
DrawDutiesTab();
|
||||
DrawNotificationsTab();
|
||||
DrawAdvancedTab();
|
||||
_generalConfigComponent.DrawTab();
|
||||
_dutyConfigComponent.DrawTab();
|
||||
_notificationConfigComponent.DrawTab();
|
||||
_debugConfigComponent.DrawTab();
|
||||
}
|
||||
|
||||
private void DrawGeneralTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("General");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
using (ImRaii.Disabled(_combatController.IsRunning))
|
||||
{
|
||||
int selectedCombatModule = (int)_configuration.General.CombatModule;
|
||||
if (ImGui.Combo("Preferred Combat Module", ref selectedCombatModule, _combatModuleNames,
|
||||
_combatModuleNames.Length))
|
||||
{
|
||||
_configuration.General.CombatModule = (Configuration.ECombatModule)selectedCombatModule;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
int selectedMount = Array.FindIndex(_mountIds, x => x == _configuration.General.MountId);
|
||||
if (selectedMount == -1)
|
||||
{
|
||||
selectedMount = 0;
|
||||
_configuration.General.MountId = _mountIds[selectedMount];
|
||||
Save();
|
||||
}
|
||||
|
||||
if (ImGui.Combo("Preferred Mount", ref selectedMount, _mountNames, _mountNames.Length))
|
||||
{
|
||||
_configuration.General.MountId = _mountIds[selectedMount];
|
||||
Save();
|
||||
}
|
||||
|
||||
int grandCompany = (int)_configuration.General.GrandCompany;
|
||||
if (ImGui.Combo("Preferred Grand Company", ref grandCompany, _grandCompanyNames,
|
||||
_grandCompanyNames.Length))
|
||||
{
|
||||
_configuration.General.GrandCompany = (GrandCompany)grandCompany;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool hideInAllInstances = _configuration.General.HideInAllInstances;
|
||||
if (ImGui.Checkbox("Hide quest window in all instanced duties", ref hideInAllInstances))
|
||||
{
|
||||
_configuration.General.HideInAllInstances = hideInAllInstances;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool useEscToCancelQuesting = _configuration.General.UseEscToCancelQuesting;
|
||||
if (ImGui.Checkbox("Use ESC to cancel questing/movement", ref useEscToCancelQuesting))
|
||||
{
|
||||
_configuration.General.UseEscToCancelQuesting = useEscToCancelQuesting;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool showIncompleteSeasonalEvents = _configuration.General.ShowIncompleteSeasonalEvents;
|
||||
if (ImGui.Checkbox("Show details for incomplete seasonal events", ref showIncompleteSeasonalEvents))
|
||||
{
|
||||
_configuration.General.ShowIncompleteSeasonalEvents = showIncompleteSeasonalEvents;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool configureTextAdvance = _configuration.General.ConfigureTextAdvance;
|
||||
if (ImGui.Checkbox("Automatically configure TextAdvance with the recommended settings",
|
||||
ref configureTextAdvance))
|
||||
{
|
||||
_configuration.General.ConfigureTextAdvance = configureTextAdvance;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDutiesTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Duties");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
bool runInstancedContentWithAutoDuty = _configuration.Duties.RunInstancedContentWithAutoDuty;
|
||||
if (ImGui.Checkbox("Run instanced content with AutoDuty and BossMod", ref runInstancedContentWithAutoDuty))
|
||||
{
|
||||
_configuration.Duties.RunInstancedContentWithAutoDuty = runInstancedContentWithAutoDuty;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(
|
||||
"The combat module used for this is configured by AutoDuty, ignoring whichever selection you've made in Questionable's \"General\" configuration.");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
using (ImRaii.Disabled(!runInstancedContentWithAutoDuty))
|
||||
{
|
||||
ImGui.Text(
|
||||
"Questionable includes a default list of duties that work if AutoDuty and BossMod are installed.");
|
||||
|
||||
ImGui.Text("The included list of duties can change with each update, and is based on the following spreadsheet:");
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.GlobeEurope, "Open AutoDuty spreadsheet"))
|
||||
Util.OpenLink(
|
||||
"https://docs.google.com/spreadsheets/d/151RlpqRcCpiD_VbQn6Duf-u-S71EP7d0mx3j1PDNoNA/edit?pli=1#gid=0");
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("You can override the dungeon settings for each individual dungeon/trial:");
|
||||
|
||||
using (var child = ImRaii.Child("DutyConfiguration", new Vector2(-1, 400), true))
|
||||
{
|
||||
if (child)
|
||||
{
|
||||
foreach (EExpansionVersion expansion in Enum.GetValues<EExpansionVersion>())
|
||||
{
|
||||
if (ImGui.CollapsingHeader(expansion.ToString()))
|
||||
{
|
||||
using var table = ImRaii.Table($"Duties{expansion}", 2, ImGuiTableFlags.SizingFixedFit);
|
||||
if (table)
|
||||
{
|
||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableSetupColumn("Options", ImGuiTableColumnFlags.WidthFixed, 200f);
|
||||
|
||||
if (_contentFinderConditionNames.TryGetValue(expansion, out var cfcNames))
|
||||
{
|
||||
foreach (var (cfcId, territoryId, name) in cfcNames)
|
||||
{
|
||||
if (_questRegistry.TryGetDutyByContentFinderConditionId(cfcId,
|
||||
out bool autoDutyEnabledByDefault))
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
|
||||
string[] labels = autoDutyEnabledByDefault
|
||||
? _supportedCfcOptions
|
||||
: _unsupportedCfcOptions;
|
||||
int value = 0;
|
||||
if (_configuration.Duties.WhitelistedDutyCfcIds.Contains(cfcId))
|
||||
value = 1;
|
||||
if (_configuration.Duties.BlacklistedDutyCfcIds.Contains(cfcId))
|
||||
value = 2;
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted(name);
|
||||
if (ImGui.IsItemHovered() && _configuration.Advanced.AdditionalStatusInformation)
|
||||
{
|
||||
using var tooltip = ImRaii.Tooltip();
|
||||
if (tooltip)
|
||||
{
|
||||
ImGui.TextUnformatted(name);
|
||||
ImGui.Separator();
|
||||
ImGui.BulletText($"TerritoryId: {territoryId}");
|
||||
ImGui.BulletText($"ContentFinderConditionId: {cfcId}");
|
||||
}
|
||||
}
|
||||
|
||||
if (runInstancedContentWithAutoDuty && !_autoDutyIpc.HasPath(cfcId))
|
||||
ImGuiComponents.HelpMarker("This duty is not supported by AutoDuty", FontAwesomeIcon.Times, ImGuiColors.DalamudRed);
|
||||
}
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
{
|
||||
using var _ = ImRaii.PushId($"##Dungeon{cfcId}");
|
||||
ImGui.SetNextItemWidth(200);
|
||||
if (ImGui.Combo(string.Empty, ref value, labels, labels.Length))
|
||||
{
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Remove(cfcId);
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Remove(cfcId);
|
||||
|
||||
if (value == 1)
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Add(cfcId);
|
||||
else if (value == 2)
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Add(cfcId);
|
||||
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(_configuration.Duties.WhitelistedDutyCfcIds.Count +
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Count == 0))
|
||||
{
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Copy, "Export to clipboard"))
|
||||
{
|
||||
var whitelisted =
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Select(x => $"{DutyWhitelistPrefix}{x}");
|
||||
var blacklisted =
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Select(x => $"{DutyBlacklistPrefix}{x}");
|
||||
string text = DutyClipboardPrefix + Convert.ToBase64String(Encoding.UTF8.GetBytes(
|
||||
string.Join(DutyClipboardSeparator, whitelisted.Concat(blacklisted))));
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
string? clipboardText = GetClipboardText();
|
||||
using (ImRaii.Disabled(clipboardText == null || !clipboardText.StartsWith(DutyClipboardPrefix, StringComparison.InvariantCulture)))
|
||||
{
|
||||
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Paste, "Import from Clipboard"))
|
||||
{
|
||||
clipboardText = clipboardText!.Substring(DutyClipboardPrefix.Length);
|
||||
string text = Encoding.UTF8.GetString(Convert.FromBase64String(clipboardText));
|
||||
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Clear();
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Clear();
|
||||
foreach (string part in text.Split(DutyClipboardSeparator))
|
||||
{
|
||||
if (part.StartsWith(DutyWhitelistPrefix, StringComparison.InvariantCulture) &&
|
||||
uint.TryParse(part.AsSpan(DutyWhitelistPrefix.Length), CultureInfo.InvariantCulture,
|
||||
out uint whitelistedCfcId))
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Add(whitelistedCfcId);
|
||||
|
||||
if (part.StartsWith(DutyBlacklistPrefix, StringComparison.InvariantCulture) &&
|
||||
uint.TryParse(part.AsSpan(DutyBlacklistPrefix.Length), CultureInfo.InvariantCulture,
|
||||
out uint blacklistedCfcId))
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Add(blacklistedCfcId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
using (var unused = ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl)))
|
||||
{
|
||||
if (ImGui.Button("Reset to default"))
|
||||
{
|
||||
_configuration.Duties.WhitelistedDutyCfcIds.Clear();
|
||||
_configuration.Duties.BlacklistedDutyCfcIds.Clear();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
ImGui.SetTooltip("Hold CTRL to enable this button.");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNotificationsTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Notifications");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
bool enabled = _configuration.Notifications.Enabled;
|
||||
if (ImGui.Checkbox("Enable notifications when manual interaction is required", ref enabled))
|
||||
{
|
||||
_configuration.Notifications.Enabled = enabled;
|
||||
Save();
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(!_configuration.Notifications.Enabled))
|
||||
{
|
||||
using (ImRaii.PushIndent())
|
||||
{
|
||||
var xivChatTypes = Enum.GetValues<XivChatType>()
|
||||
.Where(x => x != XivChatType.StandardEmote)
|
||||
.ToArray();
|
||||
var selectedChatType = Array.IndexOf(xivChatTypes, _configuration.Notifications.ChatType);
|
||||
string[] chatTypeNames = xivChatTypes
|
||||
.Select(t => t.GetAttribute<XivChatTypeInfoAttribute>()?.FancyName ?? t.ToString())
|
||||
.ToArray();
|
||||
if (ImGui.Combo("Chat channel", ref selectedChatType, chatTypeNames,
|
||||
chatTypeNames.Length))
|
||||
{
|
||||
_configuration.Notifications.ChatType = xivChatTypes[selectedChatType];
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("NotificationMaster settings");
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker("Requires the plugin 'NotificationMaster' to be installed.");
|
||||
using (ImRaii.Disabled(!_notificationMasterIpc.Enabled))
|
||||
{
|
||||
bool showTrayMessage = _configuration.Notifications.ShowTrayMessage;
|
||||
if (ImGui.Checkbox("Show tray notification", ref showTrayMessage))
|
||||
{
|
||||
_configuration.Notifications.ShowTrayMessage = showTrayMessage;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool flashTaskbar = _configuration.Notifications.FlashTaskbar;
|
||||
if (ImGui.Checkbox("Flash taskbar icon", ref flashTaskbar))
|
||||
{
|
||||
_configuration.Notifications.FlashTaskbar = flashTaskbar;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAdvancedTab()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Advanced");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed,
|
||||
"Enabling any option here may cause unexpected behavior. Use at your own risk.");
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
bool debugOverlay = _configuration.Advanced.DebugOverlay;
|
||||
if (ImGui.Checkbox("Enable debug overlay", ref debugOverlay))
|
||||
{
|
||||
_configuration.Advanced.DebugOverlay = debugOverlay;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool neverFly = _configuration.Advanced.NeverFly;
|
||||
if (ImGui.Checkbox("Disable flying (even if unlocked for the zone)", ref neverFly))
|
||||
{
|
||||
_configuration.Advanced.NeverFly = neverFly;
|
||||
Save();
|
||||
}
|
||||
|
||||
bool additionalStatusInformation = _configuration.Advanced.AdditionalStatusInformation;
|
||||
if (ImGui.Checkbox("Draw additional status information", ref additionalStatusInformation))
|
||||
{
|
||||
_configuration.Advanced.AdditionalStatusInformation = additionalStatusInformation;
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
private void Save() => _pluginInterface.SavePluginConfig(_configuration);
|
||||
|
||||
public void SaveWindowConfig() => Save();
|
||||
|
||||
/// <summary>
|
||||
/// The default implementation for <see cref="ImGui.GetClipboardText"/> throws an NullReferenceException if the clipboard is empty, maybe also if it doesn't contain text.
|
||||
/// </summary>
|
||||
private unsafe string? GetClipboardText()
|
||||
{
|
||||
byte* ptr = ImGuiNative.igGetClipboardText();
|
||||
if (ptr == null)
|
||||
return null;
|
||||
|
||||
int byteCount = 0;
|
||||
while (ptr[byteCount] != 0)
|
||||
++byteCount;
|
||||
return Encoding.UTF8.GetString(ptr, byteCount);
|
||||
}
|
||||
|
||||
private sealed record DutyInfo(uint CfcId, uint TerritoryId, string Name);
|
||||
public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user