Penumbra/Penumbra/UI/MenuTabs/TabSettings.cs

323 lines
No EOL
13 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text.RegularExpressions;
using Dalamud.Interface;
using Dalamud.Logging;
using ImGuiNET;
using Penumbra.Interop;
using Penumbra.Mods;
using Penumbra.UI.Custom;
using Penumbra.Util;
namespace Penumbra.UI
{
public partial class SettingsInterface
{
private class TabSettings
{
private const string LabelTab = "Settings";
private const string LabelRootFolder = "Root Folder";
private const string LabelTempFolder = "Temporary Folder";
private const string LabelRediscoverButton = "Rediscover Mods";
private const string LabelOpenFolder = "Open Mods Folder";
private const string LabelOpenTempFolder = "Open Temporary Folder";
private const string LabelEnabled = "Enable Mods";
private const string LabelEnabledPlayerWatch = "Enable automatic Character Redraws";
private const string LabelWaitFrames = "Wait Frames";
private const string LabelSortFoldersFirst = "Sort Mod Folders Before Mods";
private const string LabelScaleModSelector = "Scale Mod Selector With Window Size";
private const string LabelShowAdvanced = "Show Advanced Settings";
private const string LabelLogLoadedFiles = "Log all loaded files";
private const string LabelDisableNotifications = "Disable filesystem change notifications";
private const string LabelEnableHttpApi = "Enable HTTP API";
private const string LabelReloadResource = "Reload Player Resource";
private readonly SettingsInterface _base;
private readonly Configuration _config;
private bool _configChanged;
private string _newModDirectory;
private string _newTempDirectory;
public TabSettings( SettingsInterface ui )
{
_base = ui;
_config = Penumbra.Config;
_configChanged = false;
_newModDirectory = _config.ModDirectory;
_newTempDirectory = _config.TempDirectory;
}
private static bool DrawPressEnterWarning( string old, float? width = null )
{
const uint red = 0xFF202080;
using var color = ImGuiRaii.PushColor( ImGuiCol.Button, red );
var w = Vector2.UnitX * ( width ?? ImGui.CalcItemWidth() );
return ImGui.Button( $"Press Enter or Click Here to Save (Current Directory: {old})", w );
}
private void DrawRootFolder()
{
var save = ImGui.InputText( LabelRootFolder, ref _newModDirectory, 255, ImGuiInputTextFlags.EnterReturnsTrue );
if( _config.ModDirectory == _newModDirectory || !_newModDirectory.Any() )
{
return;
}
if( save || DrawPressEnterWarning( _config.ModDirectory ) )
{
_base._menu.InstalledTab.Selector.ClearSelection();
_base._modManager.DiscoverMods( _newModDirectory );
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
_newModDirectory = _config.ModDirectory;
}
}
private void DrawTempFolder()
{
ImGui.SetNextItemWidth( 400 * ImGuiHelpers.GlobalScale );
ImGui.BeginGroup();
var save = ImGui.InputText( LabelTempFolder, ref _newTempDirectory, 255, ImGuiInputTextFlags.EnterReturnsTrue );
ImGuiCustom.HoverTooltip( "The folder used to store temporary meta manipulation files.\n"
+ "Leave this blank if you have no reason not to.\n"
+ "A folder 'penumbrametatmp' will be created as a subdirectory to the specified directory.\n"
+ "If none is specified (i.e. this is blank) this folder will be created in the root folder instead." );
ImGui.SameLine();
if( ImGui.Button( LabelOpenTempFolder ) )
{
if( !Directory.Exists( _base._modManager.TempPath.FullName ) || !_base._modManager.TempWritable )
{
return;
}
Process.Start( new ProcessStartInfo( _base._modManager.TempPath.FullName )
{
UseShellExecute = true,
} );
}
ImGui.EndGroup();
if( _newTempDirectory == _config.TempDirectory )
{
return;
}
if( save || DrawPressEnterWarning( _config.TempDirectory, 400 ) )
{
_base._modManager.SetTempDirectory( _newTempDirectory );
_newTempDirectory = _config.TempDirectory;
}
}
private void DrawRediscoverButton()
{
if( ImGui.Button( LabelRediscoverButton ) )
{
_base._menu.InstalledTab.Selector.ClearSelection();
_base._modManager.DiscoverMods();
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
}
}
private void DrawOpenModsButton()
{
if( ImGui.Button( LabelOpenFolder ) )
{
if( !Directory.Exists( _config.ModDirectory ) || !Service< ModManager >.Get().Valid )
{
return;
}
Process.Start( new ProcessStartInfo( _config.ModDirectory )
{
UseShellExecute = true,
} );
}
}
private void DrawEnabledBox()
{
var enabled = _config.IsEnabled;
if( ImGui.Checkbox( LabelEnabled, ref enabled ) )
{
_base._penumbra.SetEnabled( enabled );
}
}
private void DrawShowAdvancedBox()
{
var showAdvanced = _config.ShowAdvanced;
if( ImGui.Checkbox( LabelShowAdvanced, ref showAdvanced ) )
{
_config.ShowAdvanced = showAdvanced;
_configChanged = true;
}
}
private void DrawSortFoldersFirstBox()
{
var foldersFirst = _config.SortFoldersFirst;
if( ImGui.Checkbox( LabelSortFoldersFirst, ref foldersFirst ) )
{
_config.SortFoldersFirst = foldersFirst;
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
_configChanged = true;
}
}
private void DrawScaleModSelectorBox()
{
var scaleModSelector = _config.ScaleModSelector;
if( ImGui.Checkbox( LabelScaleModSelector, ref scaleModSelector ) )
{
_config.ScaleModSelector = scaleModSelector;
_configChanged = true;
}
}
private void DrawLogLoadedFilesBox()
{
ImGui.Checkbox( LabelLogLoadedFiles, ref _base._penumbra.ResourceLoader.LogAllFiles );
ImGui.SameLine();
var regex = _base._penumbra.ResourceLoader.LogFileFilter?.ToString() ?? string.Empty;
var tmp = regex;
if( ImGui.InputTextWithHint( "##LogFilter", "Matching this Regex...", ref tmp, 64 ) && tmp != regex )
{
try
{
var newRegex = tmp.Length > 0 ? new Regex( tmp, RegexOptions.Compiled ) : null;
_base._penumbra.ResourceLoader.LogFileFilter = newRegex;
}
catch( Exception e )
{
PluginLog.Debug( "Could not create regex:\n{Exception}", e );
}
}
}
private void DrawDisableNotificationsBox()
{
var fsWatch = _config.DisableFileSystemNotifications;
if( ImGui.Checkbox( LabelDisableNotifications, ref fsWatch ) )
{
_config.DisableFileSystemNotifications = fsWatch;
_configChanged = true;
}
}
private void DrawEnableHttpApiBox()
{
var http = _config.EnableHttpApi;
if( ImGui.Checkbox( LabelEnableHttpApi, ref http ) )
{
if( http )
{
_base._penumbra.CreateWebServer();
}
else
{
_base._penumbra.ShutdownWebServer();
}
_config.EnableHttpApi = http;
_configChanged = true;
}
}
private void DrawEnabledPlayerWatcher()
{
var enabled = _config.EnablePlayerWatch;
if( ImGui.Checkbox( LabelEnabledPlayerWatch, ref enabled ) )
{
_config.EnablePlayerWatch = enabled;
_configChanged = true;
Penumbra.PlayerWatcher.SetStatus( enabled );
}
ImGuiCustom.HoverTooltip(
"If this setting is enabled, penumbra will keep tabs on characters that have a corresponding collection setup in the Collections tab.\n"
+ "Penumbra will try to automatically redraw those characters using their collection when they first appear in an instance, or when they change their current equip." );
if( !_config.EnablePlayerWatch || !_config.ShowAdvanced )
{
return;
}
var waitFrames = _config.WaitFrames;
ImGui.SameLine();
ImGui.SetNextItemWidth( 50 );
if( ImGui.InputInt( LabelWaitFrames, ref waitFrames, 0, 0 )
&& waitFrames != _config.WaitFrames
&& waitFrames > 0
&& waitFrames < 3000 )
{
_base._penumbra.ObjectReloader.DefaultWaitFrames = waitFrames;
_config.WaitFrames = waitFrames;
_configChanged = true;
}
ImGuiCustom.HoverTooltip(
"The number of frames penumbra waits after some events (like zone changes) until it starts trying to redraw actors again, in a range of [1, 3001].\n"
+ "Keep this as low as possible while producing stable results." );
}
private static void DrawReloadResourceButton()
{
if( ImGui.Button( LabelReloadResource ) )
{
Service< ResidentResources >.Get().ReloadPlayerResources();
}
}
private void DrawAdvancedSettings()
{
DrawTempFolder();
DrawLogLoadedFilesBox();
DrawDisableNotificationsBox();
DrawEnableHttpApiBox();
DrawReloadResourceButton();
}
public void Draw()
{
if( !ImGui.BeginTabItem( LabelTab ) )
{
return;
}
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
DrawRootFolder();
DrawRediscoverButton();
ImGui.SameLine();
DrawOpenModsButton();
ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
DrawEnabledBox();
DrawEnabledPlayerWatcher();
ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
DrawScaleModSelectorBox();
DrawSortFoldersFirstBox();
DrawShowAdvancedBox();
if( _config.ShowAdvanced )
{
DrawAdvancedSettings();
}
if( _configChanged )
{
_config.Save();
_configChanged = false;
}
}
}
}
}