mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Added option to move a mods priority via numerical input (right click) and to rename (and merge) a mod directory. Actually implemented Add Mod button.
This commit is contained in:
parent
6012b2c6ea
commit
6a1ae4f317
6 changed files with 387 additions and 89 deletions
|
|
@ -1,12 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Dalamud.Plugin;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Lumina.Data;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.Importer.Models;
|
||||
using Penumbra.Models;
|
||||
|
|
@ -155,7 +153,7 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
var newModFolder = CreateModFolder( _outDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine( newModFolder.FullName, "meta.json" ),
|
||||
|
|
@ -187,9 +185,9 @@ namespace Penumbra.Importer
|
|||
}
|
||||
}
|
||||
|
||||
private DirectoryInfo CreateModFolder( string modListName )
|
||||
public static DirectoryInfo CreateModFolder( DirectoryInfo outDirectory, string modListName )
|
||||
{
|
||||
var correctedPath = Path.Combine( _outDirectory.FullName,
|
||||
var correctedPath = Path.Combine( outDirectory.FullName,
|
||||
Path.GetFileName( modListName ).RemoveInvalidPathSymbols().RemoveNonAsciiSymbols() );
|
||||
var newModFolder = new DirectoryInfo( correctedPath );
|
||||
var i = 2;
|
||||
|
|
@ -224,7 +222,7 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( modList.Name ?? "New Mod" );
|
||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
|
||||
File.WriteAllText( Path.Combine( newModFolder.FullName, "meta.json" ),
|
||||
JsonConvert.SerializeObject( modMeta ) );
|
||||
|
|
@ -252,7 +250,7 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( modList.Name ?? "New Mod" );
|
||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
|
||||
if( modList.SimpleModsList != null )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,7 +55,9 @@ namespace Penumbra.Mods
|
|||
foreach( var modDir in _basePath.EnumerateDirectories() )
|
||||
{
|
||||
if( modDir.Name.ToLowerInvariant() == MetaManager.TmpDirectory )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var metaFile = modDir.EnumerateFiles().FirstOrDefault( f => f.Name == "meta.json" );
|
||||
|
||||
|
|
@ -115,30 +117,47 @@ namespace Penumbra.Mods
|
|||
}
|
||||
}
|
||||
|
||||
public void ReorderMod( ModInfo info, bool up )
|
||||
private int CleanPriority( int priority )
|
||||
=> priority < 0 ? 0 : priority >= ModSettings!.Count ? ModSettings.Count - 1 : priority;
|
||||
|
||||
public void ReorderMod( ModInfo info, int newPriority )
|
||||
{
|
||||
// todo: certified fucked tier
|
||||
|
||||
var prio = info.Priority;
|
||||
var swapPrio = up ? prio + 1 : prio - 1;
|
||||
var swapMeta = ModSettings.FirstOrDefault( x => x.Priority == swapPrio );
|
||||
|
||||
if( swapMeta == null )
|
||||
if( ModSettings == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
info.Priority = swapPrio;
|
||||
swapMeta.Priority = prio;
|
||||
var oldPriority = info.Priority;
|
||||
newPriority = CleanPriority( newPriority );
|
||||
if( oldPriority == newPriority )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
info.Priority = newPriority;
|
||||
if( newPriority < oldPriority )
|
||||
{
|
||||
for( var i = oldPriority - 1; i >= newPriority; --i )
|
||||
{
|
||||
++ModSettings![ i ].Priority;
|
||||
ModSettings.Swap( i, i + 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( var i = oldPriority + 1; i <= newPriority; ++i )
|
||||
{
|
||||
--ModSettings![ i ].Priority;
|
||||
ModSettings.Swap( i - 1, i );
|
||||
}
|
||||
}
|
||||
|
||||
// reorder mods list
|
||||
ModSettings = ModSettings.OrderBy( x => x.Priority ).ToList();
|
||||
EnabledMods = GetOrderedAndEnabledModList().ToArray();
|
||||
|
||||
// save new prios
|
||||
Save();
|
||||
}
|
||||
|
||||
public void ReorderMod( ModInfo info, bool up )
|
||||
=> ReorderMod( info, info.Priority + ( up ? 1 : -1 ) );
|
||||
|
||||
public ModInfo? FindModSettings( string name )
|
||||
{
|
||||
|
|
@ -157,7 +176,7 @@ namespace Penumbra.Mods
|
|||
{
|
||||
Priority = ModSettings?.Count ?? 0,
|
||||
FolderName = mod.ModBasePath.Name,
|
||||
Enabled = true
|
||||
Enabled = true,
|
||||
};
|
||||
entry.FixInvalidSettings();
|
||||
#if DEBUG
|
||||
|
|
@ -184,7 +203,8 @@ namespace Penumbra.Mods
|
|||
public IEnumerable< ModInfo > GetOrderedAndEnabledModSettings( bool invertOrder = false )
|
||||
{
|
||||
var query = ModSettings?
|
||||
.Where( x => x.Enabled ) ?? Enumerable.Empty< ModInfo >();
|
||||
.Where( x => x.Enabled )
|
||||
?? Enumerable.Empty< ModInfo >();
|
||||
|
||||
if( !invertOrder )
|
||||
{
|
||||
|
|
@ -197,13 +217,13 @@ namespace Penumbra.Mods
|
|||
public IEnumerable< ResourceMod > GetOrderedAndEnabledModList( bool invertOrder = false )
|
||||
{
|
||||
return GetOrderedAndEnabledModSettings( invertOrder )
|
||||
.Select( x => x.Mod );
|
||||
.Select( x => x.Mod );
|
||||
}
|
||||
|
||||
public IEnumerable< (ResourceMod, ModInfo) > GetOrderedAndEnabledModListWithSettings( bool invertOrder = false )
|
||||
{
|
||||
return GetOrderedAndEnabledModSettings( invertOrder )
|
||||
.Select( x => ( x.Mod, x ) );
|
||||
.Select( x => ( x.Mod, x ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Hooks;
|
||||
using Penumbra.Models;
|
||||
|
|
@ -117,7 +116,7 @@ namespace Penumbra.Mods
|
|||
}
|
||||
|
||||
private void AddFiles( IEnumerable< GamePath > gamePaths, FileInfo file, Dictionary< GamePath, string > registeredFiles,
|
||||
ResourceMod mod )
|
||||
ResourceMod mod )
|
||||
{
|
||||
foreach( var gamePath in gamePaths )
|
||||
{
|
||||
|
|
@ -147,6 +146,12 @@ namespace Penumbra.Mods
|
|||
}
|
||||
}
|
||||
|
||||
public void ChangeModPriority( ModInfo info, int newPriority )
|
||||
{
|
||||
Mods!.ReorderMod( info, newPriority );
|
||||
CalculateEffectiveFileList();
|
||||
}
|
||||
|
||||
public void ChangeModPriority( ModInfo info, bool up = false )
|
||||
{
|
||||
Mods!.ReorderMod( info, up );
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace Penumbra.UI
|
|||
private void SelectGroup( int idx )
|
||||
{
|
||||
// Not using the properties here because we need it to be not null forgiving in this case.
|
||||
var numGroups = _selector.Mod()?.Mod.Meta.Groups.Count ?? 0;
|
||||
var numGroups = _selector.Mod?.Mod.Meta.Groups.Count ?? 0;
|
||||
_selectedGroupIndex = idx;
|
||||
if( _selectedGroupIndex >= numGroups )
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ namespace Penumbra.UI
|
|||
|
||||
// This is only drawn when we have a mod selected, so we can forgive nulls.
|
||||
private ModInfo Mod
|
||||
=> _selector.Mod()!;
|
||||
=> _selector.Mod!;
|
||||
|
||||
private ModMeta Meta
|
||||
=> Mod.Mod.Meta;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
|
|
@ -12,25 +13,28 @@ namespace Penumbra.UI
|
|||
{
|
||||
private class ModPanel
|
||||
{
|
||||
private const string LabelModPanel = "selectedModInfo";
|
||||
private const string LabelEditName = "##editName";
|
||||
private const string LabelEditVersion = "##editVersion";
|
||||
private const string LabelEditAuthor = "##editAuthor";
|
||||
private const string LabelEditWebsite = "##editWebsite";
|
||||
private const string LabelModEnabled = "Enabled";
|
||||
private const string LabelEditingEnabled = "Enable Editing";
|
||||
private const string ButtonOpenWebsite = "Open Website";
|
||||
private const string ButtonOpenModFolder = "Open Mod Folder";
|
||||
private const string ButtonEditJson = "Edit JSON";
|
||||
private const string ButtonReloadJson = "Reload JSON";
|
||||
private const string ButtonDeduplicate = "Deduplicate";
|
||||
private const string TooltipOpenModFolder = "Open the directory containing this mod in your default file explorer.";
|
||||
private const string TooltipEditJson = "Open the JSON configuration file in your default application for .json.";
|
||||
private const string TooltipReloadJson = "Reload the configuration of all mods.";
|
||||
private const string LabelModPanel = "selectedModInfo";
|
||||
private const string LabelEditName = "##editName";
|
||||
private const string LabelEditVersion = "##editVersion";
|
||||
private const string LabelEditAuthor = "##editAuthor";
|
||||
private const string LabelEditWebsite = "##editWebsite";
|
||||
private const string LabelModEnabled = "Enabled";
|
||||
private const string LabelEditingEnabled = "Enable Editing";
|
||||
private const string ButtonOpenWebsite = "Open Website";
|
||||
private const string ButtonOpenModFolder = "Open Mod Folder";
|
||||
private const string ButtonRenameModFolder = "Rename Mod Folder";
|
||||
private const string ButtonEditJson = "Edit JSON";
|
||||
private const string ButtonReloadJson = "Reload JSON";
|
||||
private const string ButtonDeduplicate = "Deduplicate";
|
||||
private const string TooltipOpenModFolder = "Open the directory containing this mod in your default file explorer.";
|
||||
private const string TooltipRenameModFolder = "Rename the directory containing this mod without opening another application.";
|
||||
private const string TooltipEditJson = "Open the JSON configuration file in your default application for .json.";
|
||||
private const string TooltipReloadJson = "Reload the configuration of all mods.";
|
||||
private const string PopupRenameFolder = "Rename Folder";
|
||||
|
||||
private const string TooltipDeduplicate =
|
||||
"Try to find identical files and remove duplicate occurences to reduce the mods disk size.\n" +
|
||||
"Introduces an invisible single-option Group \"Duplicates\".";
|
||||
"Try to find identical files and remove duplicate occurences to reduce the mods disk size.\n"
|
||||
+ "Introduces an invisible single-option Group \"Duplicates\".";
|
||||
|
||||
private const float HeaderLineDistance = 10f;
|
||||
private static readonly Vector4 GreyColor = new( 1f, 1f, 1f, 0.66f );
|
||||
|
|
@ -51,14 +55,18 @@ namespace Penumbra.UI
|
|||
_currentWebsite = Meta?.Website ?? "";
|
||||
}
|
||||
|
||||
private ModInfo? Mod => _selector.Mod();
|
||||
private ModMeta? Meta => Mod?.Mod.Meta;
|
||||
private ModInfo? Mod
|
||||
=> _selector.Mod;
|
||||
|
||||
private ModMeta? Meta
|
||||
=> Mod?.Mod.Meta;
|
||||
|
||||
private void DrawName()
|
||||
{
|
||||
var name = Meta!.Name;
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 )
|
||||
&& name.Length > 0 && name != Meta.Name )
|
||||
&& name.Length > 0
|
||||
&& name != Meta.Name )
|
||||
{
|
||||
Meta.Name = name;
|
||||
_selector.SaveCurrentMod();
|
||||
|
|
@ -76,7 +84,7 @@ namespace Penumbra.UI
|
|||
ImGui.SameLine();
|
||||
var version = Meta!.Version;
|
||||
if( ImGuiCustom.ResizingTextInput( LabelEditVersion, ref version, 16 )
|
||||
&& version != Meta.Version )
|
||||
&& version != Meta.Version )
|
||||
{
|
||||
Meta.Version = version;
|
||||
_selector.SaveCurrentMod();
|
||||
|
|
@ -101,7 +109,7 @@ namespace Penumbra.UI
|
|||
ImGui.SameLine();
|
||||
var author = Meta!.Author;
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditAuthor, ref author, 64 )
|
||||
&& author != Meta.Author )
|
||||
&& author != Meta.Author )
|
||||
{
|
||||
Meta.Author = author;
|
||||
_selector.SaveCurrentMod();
|
||||
|
|
@ -119,7 +127,7 @@ namespace Penumbra.UI
|
|||
ImGui.SameLine();
|
||||
var website = Meta!.Website;
|
||||
if( ImGuiCustom.ResizingTextInput( LabelEditWebsite, ref website, 512 )
|
||||
&& website != Meta.Website )
|
||||
&& website != Meta.Website )
|
||||
{
|
||||
Meta.Website = website;
|
||||
_selector.SaveCurrentMod();
|
||||
|
|
@ -131,7 +139,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_currentWebsite = Meta.Website;
|
||||
_validWebsite = Uri.TryCreate( Meta.Website, UriKind.Absolute, out var uriResult )
|
||||
&& ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp );
|
||||
&& ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp );
|
||||
}
|
||||
|
||||
if( _validWebsite )
|
||||
|
|
@ -142,7 +150,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
var process = new ProcessStartInfo( Meta.Website )
|
||||
{
|
||||
UseShellExecute = true
|
||||
UseShellExecute = true,
|
||||
};
|
||||
Process.Start( process );
|
||||
}
|
||||
|
|
@ -209,6 +217,148 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private string _newName = "";
|
||||
private bool _keyboardFocus = true;
|
||||
|
||||
private void DrawRenameModFolderButton()
|
||||
{
|
||||
var _ = true;
|
||||
_keyboardFocus |= !ImGui.IsPopupOpen( PopupRenameFolder );
|
||||
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, new Vector2( 0.5f, 1f ) );
|
||||
if( ImGui.BeginPopupModal( PopupRenameFolder, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
{
|
||||
if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
var newName = Mod!.FolderName;
|
||||
|
||||
if( _keyboardFocus )
|
||||
{
|
||||
PluginLog.Log( "Fuck you" );
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
_keyboardFocus = false;
|
||||
}
|
||||
|
||||
if( ImGui.InputText( "New Folder Name##RenameFolderInput", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
_newName = newName.RemoveNonAsciiSymbols().RemoveInvalidPathSymbols();
|
||||
if( _newName.Length == 0 )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
else if( !string.Equals( _newName, Mod!.FolderName, StringComparison.InvariantCultureIgnoreCase ) )
|
||||
{
|
||||
DirectoryInfo dir = Mod!.Mod.ModBasePath;
|
||||
DirectoryInfo newDir = new( Path.Combine( dir.Parent!.FullName, _newName ) );
|
||||
if( newDir.Exists )
|
||||
{
|
||||
PluginLog.Error( "GOTT" );
|
||||
ImGui.OpenPopup( "OverwriteDir" );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
dir.MoveTo( newDir.FullName );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Error while renaming directory {dir.FullName} to {newDir.FullName}:\n{e}" );
|
||||
}
|
||||
|
||||
Mod!.FolderName = _newName;
|
||||
Mod!.Mod.ModBasePath = newDir;
|
||||
_selector.ReloadCurrentMod();
|
||||
Service< ModManager >.Get()!.Mods!.Save();
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.TextColored( GreyColor,
|
||||
"Please restrict yourself to ascii symbols that are valid in a windows path,\nother symbols will be replaced by underscores." );
|
||||
|
||||
var closeParent = false;
|
||||
_ = true;
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
|
||||
if( ImGui.BeginPopupModal( "OverwriteDir", ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
{
|
||||
DirectoryInfo dir = Mod!.Mod.ModBasePath;
|
||||
DirectoryInfo newDir = new( Path.Combine( dir.Parent!.FullName, _newName ) );
|
||||
ImGui.Text(
|
||||
$"The mod directory {newDir} already exists.\nDo you want to merge / overwrite both mods?\nThis may corrupt the resulting mod in irrecoverable ways." );
|
||||
var buttonSize = new Vector2( 120, 0 );
|
||||
if( ImGui.Button( "Yes", buttonSize ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach( var file in dir.EnumerateFiles( "*", SearchOption.AllDirectories ) )
|
||||
{
|
||||
var target = new FileInfo( Path.Combine( newDir.FullName,
|
||||
file.FullName.Substring( dir.FullName.Length ) ) );
|
||||
if( target.Exists )
|
||||
{
|
||||
target.Delete();
|
||||
}
|
||||
|
||||
target.Directory?.Create();
|
||||
file.MoveTo( target.FullName );
|
||||
}
|
||||
|
||||
dir.Delete( true );
|
||||
|
||||
var mod = Service< ModManager >.Get()!.Mods!.ModSettings!
|
||||
.RemoveAll( m => m.FolderName == _newName );
|
||||
|
||||
Mod!.FolderName = _newName;
|
||||
Mod!.Mod.ModBasePath = newDir;
|
||||
Service< ModManager >.Get()!.Mods!.Save();
|
||||
_base.ReloadMods();
|
||||
_selector.SelectModByDir( _newName );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Error while renaming directory {dir.FullName} to {newDir.FullName}:\n{e}" );
|
||||
}
|
||||
|
||||
closeParent = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if( ImGui.Button( "Cancel", buttonSize ) )
|
||||
{
|
||||
PluginLog.Error( "FUCKFUCK" );
|
||||
_keyboardFocus = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if( closeParent )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
if( ImGui.Button( ButtonRenameModFolder ) )
|
||||
{
|
||||
ImGui.OpenPopup( PopupRenameFolder );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipRenameModFolder );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEditJsonButton()
|
||||
{
|
||||
if( ImGui.Button( ButtonEditJson ) )
|
||||
|
|
@ -255,6 +405,8 @@ namespace Penumbra.UI
|
|||
{
|
||||
DrawOpenModFolderButton();
|
||||
ImGui.SameLine();
|
||||
DrawRenameModFolderButton();
|
||||
ImGui.SameLine();
|
||||
DrawEditJsonButton();
|
||||
ImGui.SameLine();
|
||||
DrawReloadJsonButton();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Models;
|
||||
using Penumbra.Mods;
|
||||
|
||||
|
|
@ -13,28 +16,34 @@ namespace Penumbra.UI
|
|||
{
|
||||
private class Selector
|
||||
{
|
||||
private const string LabelSelectorList = "##availableModList";
|
||||
private const string LabelModFilter = "##ModFilter";
|
||||
private const string TooltipModFilter = "Filter mods for those containing the given substring.";
|
||||
private const string TooltipMoveDown = "Move the selected mod down in priority";
|
||||
private const string TooltipMoveUp = "Move the selected mod up in priority";
|
||||
private const string TooltipDelete = "Delete the selected mod";
|
||||
private const string TooltipAdd = "Add an empty mod";
|
||||
private const string DialogDeleteMod = "PenumbraDeleteMod";
|
||||
private const string ButtonYesDelete = "Yes, delete it";
|
||||
private const string ButtonNoDelete = "No, keep it";
|
||||
private const float SelectorPanelWidth = 240f;
|
||||
private const uint DisabledModColor = 0xFF666666;
|
||||
private const uint ConflictingModColor = 0xFFAAAAFF;
|
||||
private const string LabelSelectorList = "##availableModList";
|
||||
private const string LabelModFilter = "##ModFilter";
|
||||
private const string LabelPriorityPopup = "Priority";
|
||||
private const string LabelAddModPopup = "AddMod";
|
||||
private const string TooltipModFilter = "Filter mods for those containing the given substring.";
|
||||
private const string TooltipMoveDown = "Move the selected mod down in priority";
|
||||
private const string TooltipMoveUp = "Move the selected mod up in priority";
|
||||
private const string TooltipDelete = "Delete the selected mod";
|
||||
private const string TooltipAdd = "Add an empty mod";
|
||||
private const string DialogDeleteMod = "PenumbraDeleteMod";
|
||||
private const string ButtonYesDelete = "Yes, delete it";
|
||||
private const string ButtonNoDelete = "No, keep it";
|
||||
private const string DescPriorityPopup = "New Priority:";
|
||||
|
||||
private const float SelectorPanelWidth = 240f;
|
||||
private const uint DisabledModColor = 0xFF666666;
|
||||
private const uint ConflictingModColor = 0xFFAAAAFF;
|
||||
|
||||
private static readonly Vector2 SelectorButtonSizes = new( 60, 0 );
|
||||
private static readonly string ArrowUpString = FontAwesomeIcon.ArrowUp.ToIconString();
|
||||
private static readonly string ArrowDownString = FontAwesomeIcon.ArrowDown.ToIconString();
|
||||
|
||||
private readonly SettingsInterface _base;
|
||||
private ModCollection? Mods => Service< ModManager >.Get().Mods;
|
||||
|
||||
private ModInfo? _mod;
|
||||
private static ModCollection? Mods
|
||||
=> Service< ModManager >.Get().Mods;
|
||||
|
||||
public ModInfo? Mod { get; private set; }
|
||||
private int _index;
|
||||
private int? _deleteIndex;
|
||||
private string _modFilter = "";
|
||||
|
|
@ -49,8 +58,9 @@ namespace Penumbra.UI
|
|||
|
||||
public void ResetModNamesLower()
|
||||
{
|
||||
_modNamesLower = Mods?.ModSettings?.Where(I => I.Mod != null)
|
||||
.Select( I => I.Mod!.Meta.Name.ToLowerInvariant() ).ToArray() ?? new string[]{};
|
||||
_modNamesLower = Mods?.ModSettings?.Where( I => I.Mod != null )
|
||||
.Select( I => I.Mod!.Meta.Name.ToLowerInvariant() ).ToArray()
|
||||
?? new string[] { };
|
||||
}
|
||||
|
||||
private void DrawPriorityChangeButton( string iconString, bool up, int unavailableWhen )
|
||||
|
|
@ -61,7 +71,7 @@ namespace Penumbra.UI
|
|||
if( ImGui.Button( iconString, SelectorButtonSizes ) )
|
||||
{
|
||||
SetSelection( _index );
|
||||
Service< ModManager >.Get().ChangeModPriority( _mod!, up );
|
||||
Service< ModManager >.Get().ChangeModPriority( Mod!, up );
|
||||
_modNamesLower!.Swap( _index, _index + ( up ? 1 : -1 ) );
|
||||
_index += up ? 1 : -1;
|
||||
}
|
||||
|
|
@ -100,13 +110,58 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private static void DrawModAddButton()
|
||||
private bool _keyboardFocus = true;
|
||||
|
||||
private void DrawModAddButton()
|
||||
{
|
||||
if( ImGui.BeginPopupContextItem( LabelAddModPopup ) )
|
||||
{
|
||||
if( _keyboardFocus )
|
||||
{
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
_keyboardFocus = false;
|
||||
}
|
||||
|
||||
var newName = "";
|
||||
if( ImGui.InputTextWithHint( "##AddMod", "New Mod Name...", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
var newDir = TexToolsImport.CreateModFolder( new DirectoryInfo( _base._plugin.Configuration!.CurrentCollection ),
|
||||
newName );
|
||||
var modMeta = new ModMeta
|
||||
{
|
||||
Author = "Unknown",
|
||||
Name = newName,
|
||||
Description = string.Empty,
|
||||
};
|
||||
var metaPath = Path.Combine( newDir.FullName, "meta.json" );
|
||||
File.WriteAllText( metaPath, JsonConvert.SerializeObject( modMeta, Formatting.Indented ) );
|
||||
_base.ReloadMods();
|
||||
SelectModByDir( newDir.Name );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not create directory for new Mod {newName}:\n{e}" );
|
||||
}
|
||||
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
|
||||
if( ImGui.Button( FontAwesomeIcon.Plus.ToIconString(), SelectorButtonSizes ) )
|
||||
{
|
||||
// Do nothing. YEAH. #TODO.
|
||||
_keyboardFocus = true;
|
||||
ImGui.OpenPopup( LabelAddModPopup );
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
|
|
@ -158,13 +213,15 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.OpenPopup( DialogDeleteMod );
|
||||
|
||||
var ret = ImGui.BeginPopupModal( DialogDeleteMod );
|
||||
var _ = true;
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
|
||||
var ret = ImGui.BeginPopupModal( DialogDeleteMod, ref _, ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoDecoration );
|
||||
if( !ret )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( _mod?.Mod == null )
|
||||
if( Mod?.Mod == null )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.EndPopup();
|
||||
|
|
@ -173,19 +230,22 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.Text( "Are you sure you want to delete the following mod:" );
|
||||
// todo: why the fuck does this become null??????
|
||||
ImGui.Text( _mod?.Mod?.Meta?.Name );
|
||||
ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() / 2 ) );
|
||||
ImGui.TextColored( new Vector4( 0.7f, 0.1f, 0.1f, 1 ), Mod?.Mod?.Meta?.Name ?? "Unknown" );
|
||||
ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() ) / 2 );
|
||||
|
||||
if( ImGui.Button( ButtonYesDelete ) )
|
||||
var buttonSize = new Vector2( 120, 0 );
|
||||
if( ImGui.Button( ButtonYesDelete, buttonSize ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
Service< ModManager >.Get().DeleteMod( _mod?.Mod );
|
||||
Service< ModManager >.Get().DeleteMod( Mod?.Mod );
|
||||
ClearSelection();
|
||||
_base.ReloadMods();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if( ImGui.Button( ButtonNoDelete ) )
|
||||
if( ImGui.Button( ButtonNoDelete, buttonSize ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
_deleteIndex = null;
|
||||
|
|
@ -194,6 +254,7 @@ namespace Penumbra.UI
|
|||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
private int _priorityPopupIdx = 0;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
|
|
@ -207,7 +268,6 @@ namespace Penumbra.UI
|
|||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
|
||||
DrawModsSelectorFilter();
|
||||
|
||||
// Inlay selector list
|
||||
ImGui.BeginChild( LabelSelectorList, new Vector2( SelectorPanelWidth, -ImGui.GetFrameHeightWithSpacing() ), true );
|
||||
|
||||
|
|
@ -242,6 +302,19 @@ namespace Penumbra.UI
|
|||
#else
|
||||
var selected = ImGui.Selectable( modName, modIndex == _index );
|
||||
#endif
|
||||
if( ImGui.IsItemClicked( ImGuiMouseButton.Right ) )
|
||||
{
|
||||
if( ImGui.IsPopupOpen( LabelPriorityPopup ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
_priorityPopupIdx = modIndex;
|
||||
_keyboardFocus = true;
|
||||
ImGui.OpenPopup( LabelPriorityPopup );
|
||||
}
|
||||
|
||||
ImGui.OpenPopupOnItemClick( LabelPriorityPopup, ImGuiPopupFlags.MouseButtonRight );
|
||||
|
||||
if( changedColour )
|
||||
{
|
||||
|
|
@ -261,13 +334,54 @@ namespace Penumbra.UI
|
|||
ImGui.EndGroup();
|
||||
|
||||
DrawDeleteModal();
|
||||
DrawPriorityPopup();
|
||||
}
|
||||
|
||||
private void DrawPriorityPopup()
|
||||
{
|
||||
if( !ImGui.BeginPopupContextItem( LabelPriorityPopup ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var size = ImGui.CalcTextSize( DescPriorityPopup ).X;
|
||||
//ImGui.Text( DescPriorityPopup );
|
||||
var newPriority = _priorityPopupIdx;
|
||||
|
||||
if( _keyboardFocus )
|
||||
{
|
||||
ImGui.SetKeyboardFocusHere( -1 );
|
||||
_keyboardFocus = false;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( size );
|
||||
if( ImGui.InputInt( "New Priority", ref newPriority, 0, 0,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue )
|
||||
&& newPriority != _priorityPopupIdx )
|
||||
{
|
||||
Service< ModManager >.Get().ChangeModPriority( Mods!.ModSettings![ _priorityPopupIdx ], newPriority );
|
||||
ResetModNamesLower();
|
||||
if( _priorityPopupIdx == _index )
|
||||
{
|
||||
_index = newPriority;
|
||||
SetSelection( _index );
|
||||
}
|
||||
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
public ModInfo? Mod() => _mod;
|
||||
|
||||
private void SetSelection( int idx, ModInfo? info )
|
||||
{
|
||||
_mod = info;
|
||||
Mod = info;
|
||||
if( idx != _index )
|
||||
{
|
||||
_base._menu.InstalledTab.ModPanel.Details.ResetState();
|
||||
|
|
@ -294,7 +408,8 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
public void ClearSelection() => SetSelection( -1 );
|
||||
public void ClearSelection()
|
||||
=> SetSelection( -1 );
|
||||
|
||||
public void SelectModByName( string name )
|
||||
{
|
||||
|
|
@ -302,32 +417,40 @@ namespace Penumbra.UI
|
|||
SetSelection( idx );
|
||||
}
|
||||
|
||||
public void SelectModByDir( string name )
|
||||
{
|
||||
var idx = Mods?.ModSettings?.FindIndex( mod => mod.FolderName == name ) ?? -1;
|
||||
SetSelection( idx );
|
||||
}
|
||||
|
||||
private string GetCurrentModMetaFile()
|
||||
=> _mod == null ? "" : Path.Combine( _mod.Mod.ModBasePath.FullName, "meta.json" );
|
||||
=> Mod == null ? "" : Path.Combine( Mod.Mod.ModBasePath.FullName, "meta.json" );
|
||||
|
||||
public void ReloadCurrentMod()
|
||||
{
|
||||
var metaPath = GetCurrentModMetaFile();
|
||||
if( metaPath.Length > 0 && File.Exists( metaPath ) )
|
||||
{
|
||||
_mod!.Mod.Meta = ModMeta.LoadFromFile( metaPath ) ?? _mod.Mod.Meta;
|
||||
Mod!.Mod.Meta = ModMeta.LoadFromFile( metaPath ) ?? Mod.Mod.Meta;
|
||||
_base._menu.InstalledTab.ModPanel.Details.ResetState();
|
||||
}
|
||||
|
||||
_mod!.Mod.RefreshModFiles();
|
||||
Mod!.Mod.RefreshModFiles();
|
||||
Service< ModManager >.Get().CalculateEffectiveFileList();
|
||||
ResetModNamesLower();
|
||||
}
|
||||
|
||||
public string SaveCurrentMod()
|
||||
{
|
||||
if( _mod == null )
|
||||
if( Mod == null )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var metaPath = GetCurrentModMetaFile();
|
||||
if( metaPath.Length > 0 )
|
||||
{
|
||||
File.WriteAllText( metaPath, JsonConvert.SerializeObject( _mod.Mod.Meta, Formatting.Indented ) );
|
||||
File.WriteAllText( metaPath, JsonConvert.SerializeObject( Mod.Mod.Meta, Formatting.Indented ) );
|
||||
}
|
||||
|
||||
_base._menu.InstalledTab.ModPanel.Details.ResetState();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue