Penumbra/Penumbra/UI/ConfigWindow.cs
2025-10-20 22:41:29 +02:00

170 lines
6.6 KiB
C#

using Dalamud.Plugin;
using Dalamud.Bindings.ImGui;
using ImSharp;
using Luna;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Text;
using Penumbra.Api.Enums;
using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.UI.Tabs;
using Penumbra.Util;
using Window = Dalamud.Interface.Windowing.Window;
namespace Penumbra.UI;
public sealed class ConfigWindow : Window, Luna.IUiService
{
private readonly IDalamudPluginInterface _pluginInterface;
private readonly Configuration _config;
private readonly ValidityChecker _validityChecker;
private Penumbra? _penumbra;
private ConfigTabBar _configTabs = null!;
private string? _lastException;
public ConfigWindow(IDalamudPluginInterface pi, Configuration config, ValidityChecker checker,
TutorialService tutorial)
: base(GetLabel(checker))
{
_pluginInterface = pi;
_config = config;
_validityChecker = checker;
RespectCloseHotkey = true;
tutorial.UpdateTutorialStep();
IsOpen = _config.OpenWindowAtStart;
}
public void OpenSettings()
{
_configTabs.SelectTab = TabType.Settings;
IsOpen = true;
}
public void Setup(Penumbra penumbra, ConfigTabBar configTabs)
{
_penumbra = penumbra;
_configTabs = configTabs;
_configTabs.SelectTab = _config.Ephemeral.SelectedTab;
}
public override bool DrawConditions()
=> _penumbra != null;
public override void PreDraw()
{
if (_config.Ephemeral.FixMainWindow)
Flags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove;
else
Flags &= ~(ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove);
SizeConstraints = new WindowSizeConstraints()
{
MinimumSize = _config.MinimumSize,
MaximumSize = new Vector2(4096, 2160),
};
}
public override void Draw()
{
UiHelpers.SetupCommonSizes();
try
{
if (_validityChecker.ImcExceptions.Count > 0)
{
DrawProblemWindow(
$"There were {_validityChecker.ImcExceptions.Count} errors while trying to load IMC files from the game data.\n"
+ "This usually means that your game installation was corrupted by updating the game while having TexTools mods still active.\n"
+ "It is recommended to not use TexTools and Penumbra (or other Lumina-based tools) at the same time.\n\n"
+ "Please use the Launcher's Repair Game Files function to repair your client installation.");
DrawImcExceptions();
}
else if (!_validityChecker.IsValidSourceRepo)
{
DrawProblemWindow(
$"You are loading a release version of Penumbra from the repository \"{_pluginInterface.SourceRepository}\" instead of the official repository.\n"
+ $"Please use the official repository at {ValidityChecker.Repository} or the suite repository at {ValidityChecker.SeaOfStars}.\n\n"
+ "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.");
}
else if (_validityChecker.IsNotInstalledPenumbra)
{
DrawProblemWindow(
$"You are loading a release version of Penumbra from \"{_pluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\" instead of the installedPlugins directory.\n\n"
+ "You should not install Penumbra manually, but rather add the plugin repository under settings and then install it via the plugin installer.\n\n"
+ "If you do not know how to do this, please take a look at the readme in Penumbras github repository or join us in discord.\n"
+ "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.");
}
else if (_validityChecker.DevPenumbraExists)
{
DrawProblemWindow(
$"You are loading a installed version of Penumbra from \"{_pluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\", "
+ "but also still have some remnants of a custom install of Penumbra in your devPlugins folder.\n\n"
+ "This can cause some issues, so please go to your \"%%appdata%%\\XIVLauncher\\devPlugins\" folder and delete the Penumbra folder from there.\n\n"
+ "If you are developing for Penumbra, try to avoid mixing versions. This warning will not appear if compiled in Debug mode.");
}
else
{
var type = _configTabs.Draw();
if (type != _config.Ephemeral.SelectedTab)
{
_config.Ephemeral.SelectedTab = type;
_config.Ephemeral.Save();
}
}
_lastException = null;
}
catch (Exception e)
{
if (_lastException != null)
{
var text = e.ToString();
if (text == _lastException)
return;
_lastException = text;
}
else
{
_lastException = e.ToString();
}
Penumbra.Log.Error($"Exception thrown during UI Render:\n{_lastException}");
}
}
private static string GetLabel(ValidityChecker checker)
=> checker.Version.Length == 0
? "Penumbra###PenumbraConfigWindow"
: $"Penumbra v{checker.Version}###PenumbraConfigWindow";
private void DrawProblemWindow(string text)
{
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
ImGui.NewLine();
ImGui.NewLine();
ImUtf8.TextWrapped(text);
color.Pop();
ImGui.NewLine();
ImGui.NewLine();
SupportButton.Discord(Penumbra.Messager, 0);
Im.Line.Same();
UiHelpers.DrawSupportButton(_penumbra!);
ImGui.NewLine();
ImGui.NewLine();
}
private void DrawImcExceptions()
{
ImGui.TextUnformatted("Exceptions");
ImGui.Separator();
using var box = ImRaii.ListBox("##Exceptions", new Vector2(-1, -1));
foreach (var exception in _validityChecker.ImcExceptions)
{
ImGuiUtil.TextWrapped(exception.ToString());
ImGui.Separator();
ImGui.NewLine();
}
}
}