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:
Ottermandias 2021-06-03 15:29:47 +02:00
parent 6012b2c6ea
commit 6a1ae4f317
6 changed files with 387 additions and 89 deletions

View file

@ -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 )
{

View file

@ -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 ) );
}
}
}

View file

@ -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 );

View file

@ -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;

View file

@ -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();

View file

@ -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();