mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-30 12:23:41 +01:00
Add local data, favorites and tags.
This commit is contained in:
parent
b9662e39a9
commit
ccfc05f2b2
19 changed files with 481 additions and 94 deletions
|
|
@ -29,8 +29,9 @@ public partial class ModFileSystemSelector
|
|||
private void SetFilterTooltip()
|
||||
{
|
||||
FilterTooltip = "Filter mods for those where their full paths or names contain the given substring.\n"
|
||||
+ "Enter n:[string] to filter only for mod names and no paths.\n"
|
||||
+ "Enter c:[string] to filter for mods changing specific items.\n"
|
||||
+ "Enter t:[string] to filter for mods set to specific tags.\n"
|
||||
+ "Enter n:[string] to filter only for mod names and no paths.\n"
|
||||
+ "Enter a:[string] to filter for mods by specific authors.";
|
||||
}
|
||||
|
||||
|
|
@ -49,6 +50,8 @@ public partial class ModFileSystemSelector
|
|||
'A' => filterValue.Length == 2 ? ( LowerString.Empty, -1 ) : ( new LowerString( filterValue[ 2.. ] ), 2 ),
|
||||
'c' => filterValue.Length == 2 ? ( LowerString.Empty, -1 ) : ( new LowerString( filterValue[ 2.. ] ), 3 ),
|
||||
'C' => filterValue.Length == 2 ? ( LowerString.Empty, -1 ) : ( new LowerString( filterValue[ 2.. ] ), 3 ),
|
||||
't' => filterValue.Length == 2 ? ( LowerString.Empty, -1 ) : ( new LowerString( filterValue[ 2.. ] ), 4 ),
|
||||
'T' => filterValue.Length == 2 ? ( LowerString.Empty, -1 ) : ( new LowerString( filterValue[ 2.. ] ), 4 ),
|
||||
_ => ( new LowerString( filterValue ), 0 ),
|
||||
},
|
||||
_ => ( new LowerString( filterValue ), 0 ),
|
||||
|
|
@ -96,7 +99,8 @@ public partial class ModFileSystemSelector
|
|||
0 => !( leaf.FullName().Contains( _modFilter.Lower, IgnoreCase ) || mod.Name.Contains( _modFilter ) ),
|
||||
1 => !mod.Name.Contains( _modFilter ),
|
||||
2 => !mod.Author.Contains( _modFilter ),
|
||||
3 => !mod.LowerChangedItemsString.Contains( _modFilter.Lower, IgnoreCase ),
|
||||
3 => !mod.LowerChangedItemsString.Contains( _modFilter.Lower ),
|
||||
4 => !mod.AllTagsLower.Contains( _modFilter.Lower ),
|
||||
_ => false, // Should never happen
|
||||
};
|
||||
}
|
||||
|
|
@ -143,6 +147,13 @@ public partial class ModFileSystemSelector
|
|||
return true;
|
||||
}
|
||||
|
||||
// Handle Favoritism
|
||||
if( !_stateFilter.HasFlag( ModFilter.Favorite ) && mod.Favorite
|
||||
|| !_stateFilter.HasFlag( ModFilter.NotFavorite ) && !mod.Favorite )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle Inheritance
|
||||
if( collection == Penumbra.CollectionManager.Current )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
|
|||
Penumbra.CollectionManager.CollectionChanged += OnCollectionChange;
|
||||
Penumbra.CollectionManager.Current.ModSettingChanged += OnSettingChange;
|
||||
Penumbra.CollectionManager.Current.InheritanceChanged += OnInheritanceChange;
|
||||
Penumbra.ModManager.ModMetaChanged += OnModMetaChange;
|
||||
Penumbra.ModManager.ModDataChanged += OnModDataChange;
|
||||
Penumbra.ModManager.ModDiscoveryStarted += StoreCurrentSelection;
|
||||
Penumbra.ModManager.ModDiscoveryFinished += RestoreLastSelection;
|
||||
OnCollectionChange( CollectionType.Current, null, Penumbra.CollectionManager.Current, null );
|
||||
|
|
@ -54,7 +54,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
|
|||
base.Dispose();
|
||||
Penumbra.ModManager.ModDiscoveryStarted -= StoreCurrentSelection;
|
||||
Penumbra.ModManager.ModDiscoveryFinished -= RestoreLastSelection;
|
||||
Penumbra.ModManager.ModMetaChanged -= OnModMetaChange;
|
||||
Penumbra.ModManager.ModDataChanged -= OnModDataChange;
|
||||
Penumbra.CollectionManager.Current.ModSettingChanged -= OnSettingChange;
|
||||
Penumbra.CollectionManager.Current.InheritanceChanged -= OnInheritanceChange;
|
||||
Penumbra.CollectionManager.CollectionChanged -= OnCollectionChange;
|
||||
|
|
@ -120,7 +120,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
|
|||
var flags = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
|
||||
using var c = ImRaii.PushColor( ImGuiCol.Text, state.Color.Value() );
|
||||
using var id = ImRaii.PushId( leaf.Value.Index );
|
||||
using var _ = ImRaii.TreeNode( leaf.Value.Name, flags );
|
||||
ImRaii.TreeNode( leaf.Value.Name, flags ).Dispose();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -347,12 +347,15 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
|
|||
}
|
||||
}
|
||||
|
||||
private void OnModMetaChange( MetaChangeType type, Mod mod, string? oldName )
|
||||
private void OnModDataChange( ModDataChangeType type, Mod mod, string? oldName )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case MetaChangeType.Name:
|
||||
case MetaChangeType.Author:
|
||||
case ModDataChangeType.Name:
|
||||
case ModDataChangeType.Author:
|
||||
case ModDataChangeType.ModTags:
|
||||
case ModDataChangeType.LocalTags:
|
||||
case ModDataChangeType.Favorite:
|
||||
SetFilterDirty();
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,33 +7,37 @@ public enum ModFilter
|
|||
{
|
||||
Enabled = 1 << 0,
|
||||
Disabled = 1 << 1,
|
||||
NoConflict = 1 << 2,
|
||||
SolvedConflict = 1 << 3,
|
||||
UnsolvedConflict = 1 << 4,
|
||||
HasNoMetaManipulations = 1 << 5,
|
||||
HasMetaManipulations = 1 << 6,
|
||||
HasNoFileSwaps = 1 << 7,
|
||||
HasFileSwaps = 1 << 8,
|
||||
HasConfig = 1 << 9,
|
||||
HasNoConfig = 1 << 10,
|
||||
HasNoFiles = 1 << 11,
|
||||
HasFiles = 1 << 12,
|
||||
IsNew = 1 << 13,
|
||||
NotNew = 1 << 14,
|
||||
Inherited = 1 << 15,
|
||||
Uninherited = 1 << 16,
|
||||
Undefined = 1 << 17,
|
||||
Favorite = 1 << 2,
|
||||
NotFavorite = 1 << 3,
|
||||
NoConflict = 1 << 4,
|
||||
SolvedConflict = 1 << 5,
|
||||
UnsolvedConflict = 1 << 6,
|
||||
HasNoMetaManipulations = 1 << 7,
|
||||
HasMetaManipulations = 1 << 8,
|
||||
HasNoFileSwaps = 1 << 9,
|
||||
HasFileSwaps = 1 << 10,
|
||||
HasConfig = 1 << 11,
|
||||
HasNoConfig = 1 << 12,
|
||||
HasNoFiles = 1 << 13,
|
||||
HasFiles = 1 << 14,
|
||||
IsNew = 1 << 15,
|
||||
NotNew = 1 << 16,
|
||||
Inherited = 1 << 17,
|
||||
Uninherited = 1 << 18,
|
||||
Undefined = 1 << 19,
|
||||
};
|
||||
|
||||
public static class ModFilterExtensions
|
||||
{
|
||||
public const ModFilter UnfilteredStateMods = ( ModFilter )( ( 1 << 18 ) - 1 );
|
||||
public const ModFilter UnfilteredStateMods = ( ModFilter )( ( 1 << 20 ) - 1 );
|
||||
|
||||
public static string ToName( this ModFilter filter )
|
||||
=> filter switch
|
||||
{
|
||||
ModFilter.Enabled => "Enabled",
|
||||
ModFilter.Disabled => "Disabled",
|
||||
ModFilter.Favorite => "Favorite",
|
||||
ModFilter.NotFavorite => "No Favorite",
|
||||
ModFilter.NoConflict => "No Conflicts",
|
||||
ModFilter.SolvedConflict => "Solved Conflicts",
|
||||
ModFilter.UnsolvedConflict => "Unsolved Conflicts",
|
||||
|
|
|
|||
|
|
@ -22,12 +22,19 @@ public partial class ConfigWindow
|
|||
Add5_8_7( ret );
|
||||
Add5_9_0( ret );
|
||||
Add5_10_0( ret );
|
||||
Add5_11_0( ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void Add5_11_0( Changelog log )
|
||||
=> log.NextVersion( "Version 0.5.11.0" )
|
||||
.RegisterEntry(
|
||||
"Added local data storage for mods in the plugin config folder. This information is not exported together with your mod, but not dependent on collections." )
|
||||
.RegisterEntry( "Moved the import date from mod metadata to local data.", 1 )
|
||||
.RegisterEntry( "Added Favorites. You can declare mods as favorites and filter for them.", 1 )
|
||||
.RegisterEntry( "Added Local Tags. You can apply custom Tags to mods and filter for them.", 1 )
|
||||
.RegisterEntry( "Added Mod Tags. Mod Creators (and the Edit Mod tab) can set tags that are stored in the mod meta data and are thus exported." )
|
||||
.RegisterEntry( "Add backface and transparency toggles to .mtrl editing, as well as a info section." )
|
||||
.RegisterEntry( "Meta Manipulation editing now highlights if the selected ID is 0 or 1." )
|
||||
.RegisterEntry( "Fixed a bug when manually adding EQP or EQDP entries to Mods." )
|
||||
|
|
|
|||
|
|
@ -55,6 +55,13 @@ public partial class ConfigWindow
|
|||
}
|
||||
}
|
||||
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
var tagIdx = _modTags.Draw( "Mod Tags: ", "Edit tags by clicking them, or add new tags. Empty tags are removed.", _mod.ModTags, out var editedTag );
|
||||
if( tagIdx >= 0 )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModTag( _mod.Index, tagIdx, editedTag );
|
||||
}
|
||||
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
AddOptionGroup.Draw( _window, _mod );
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
|
|
@ -566,7 +573,7 @@ public partial class ConfigWindow
|
|||
|
||||
ImGui.TableNextColumn();
|
||||
var canAddGroup = mod.Groups[ groupIdx ].Type != GroupType.Multi || mod.Groups[ groupIdx ].Count < IModGroup.MaxMultiOptions;
|
||||
var validName = _newOptionName.Length > 0 && _newOptionNameIdx == groupIdx;
|
||||
var validName = _newOptionName.Length > 0 && _newOptionNameIdx == groupIdx;
|
||||
var tt = canAddGroup
|
||||
? validName ? "Add a new option to this group." : "Please enter a name for the new option."
|
||||
: $"Can not add more than {IModGroup.MaxMultiOptions} options to a multi group.";
|
||||
|
|
@ -642,7 +649,7 @@ public partial class ConfigWindow
|
|||
{
|
||||
GroupType.Single => "Single Group",
|
||||
GroupType.Multi => "Multi Group",
|
||||
_ => "Unknown",
|
||||
_ => "Unknown",
|
||||
};
|
||||
|
||||
ImGui.SetNextItemWidth( _window._inputTextWidth.X - 3 * _window._iconButtonSize.X - 12 * ImGuiHelpers.GlobalScale );
|
||||
|
|
|
|||
|
|
@ -58,16 +58,20 @@ public partial class ConfigWindow
|
|||
DrawPriorityInput();
|
||||
OpenTutorial( BasicTutorialSteps.Priority );
|
||||
DrawRemoveSettings();
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
for( var idx = 0; idx < _mod.Groups.Count; ++idx )
|
||||
{
|
||||
DrawSingleGroup( _mod.Groups[ idx ], idx );
|
||||
}
|
||||
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
for( var idx = 0; idx < _mod.Groups.Count; ++idx )
|
||||
if( _mod.Groups.Count > 0 )
|
||||
{
|
||||
DrawMultiGroup( _mod.Groups[ idx ], idx );
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
for( var idx = 0; idx < _mod.Groups.Count; ++idx )
|
||||
{
|
||||
DrawSingleGroup( _mod.Groups[ idx ], idx );
|
||||
}
|
||||
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
for( var idx = 0; idx < _mod.Groups.Count; ++idx )
|
||||
{
|
||||
DrawMultiGroup( _mod.Groups[ idx ], idx );
|
||||
}
|
||||
}
|
||||
|
||||
_window._penumbra.Api.InvokePostSettingsPanel( _mod.ModPath.Name );
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods;
|
||||
|
|
@ -36,10 +38,12 @@ public partial class ConfigWindow
|
|||
private static readonly Utf8String ChangedItemsTabHeader = Utf8String.FromStringUnsafe( "Changed Items", false );
|
||||
private static readonly Utf8String EditModTabHeader = Utf8String.FromStringUnsafe( "Edit Mod", false );
|
||||
|
||||
private readonly TagButtons _modTags = new();
|
||||
|
||||
private void DrawTabBar()
|
||||
{
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
using var tabBar = ImRaii.TabBar( "##ModTabs" );
|
||||
var tabBarHeight = ImGui.GetCursorPosY();
|
||||
using var tabBar = ImRaii.TabBar( "##ModTabs" );
|
||||
if( !tabBar )
|
||||
{
|
||||
return;
|
||||
|
|
@ -47,8 +51,8 @@ public partial class ConfigWindow
|
|||
|
||||
_availableTabs = Tabs.Settings
|
||||
| ( _mod.ChangedItems.Count > 0 ? Tabs.ChangedItems : 0 )
|
||||
| ( _mod.Description.Length > 0 ? Tabs.Description : 0 )
|
||||
| ( _conflicts.Count > 0 ? Tabs.Conflicts : 0 )
|
||||
| Tabs.Description
|
||||
| ( _conflicts.Count > 0 ? Tabs.Conflicts : 0 )
|
||||
| Tabs.Edit;
|
||||
|
||||
DrawSettingsTab();
|
||||
|
|
@ -56,6 +60,12 @@ public partial class ConfigWindow
|
|||
DrawChangedItemsTab();
|
||||
DrawConflictsTab();
|
||||
DrawEditModTab();
|
||||
DrawAdvancedEditingButton();
|
||||
DrawFavoriteButton( tabBarHeight );
|
||||
}
|
||||
|
||||
private void DrawAdvancedEditingButton()
|
||||
{
|
||||
if( ImGui.TabItemButton( "Advanced Editing", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip ) )
|
||||
{
|
||||
_window.ModEditPopup.ChangeMod( _mod );
|
||||
|
|
@ -73,6 +83,44 @@ public partial class ConfigWindow
|
|||
+ "\t\t- textures" );
|
||||
}
|
||||
|
||||
private void DrawFavoriteButton( float height )
|
||||
{
|
||||
var oldPos = ImGui.GetCursorPos();
|
||||
|
||||
using( var font = ImRaii.PushFont( UiBuilder.IconFont ) )
|
||||
{
|
||||
var size = ImGui.CalcTextSize( FontAwesomeIcon.Star.ToIconString() ) + ImGui.GetStyle().FramePadding * 2;
|
||||
var newPos = new Vector2( ImGui.GetWindowWidth() - size.X - ImGui.GetStyle().ItemSpacing.X, height );
|
||||
if( ImGui.GetScrollMaxX() > 0 )
|
||||
{
|
||||
newPos.X += ImGui.GetScrollX();
|
||||
}
|
||||
|
||||
var rectUpper = ImGui.GetWindowPos() + newPos;
|
||||
var color = ImGui.IsMouseHoveringRect( rectUpper, rectUpper + size ) ? ImGui.GetColorU32( ImGuiCol.Text ) :
|
||||
_mod.Favorite ? 0xFF00FFFF : ImGui.GetColorU32( ImGuiCol.TextDisabled );
|
||||
using var c = ImRaii.PushColor( ImGuiCol.Text, color )
|
||||
.Push( ImGuiCol.Button, 0 )
|
||||
.Push( ImGuiCol.ButtonHovered, 0 )
|
||||
.Push( ImGuiCol.ButtonActive, 0 );
|
||||
|
||||
ImGui.SetCursorPos( newPos );
|
||||
if( ImGui.Button( FontAwesomeIcon.Star.ToIconString() ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModFavorite( _mod.Index, !_mod.Favorite );
|
||||
}
|
||||
}
|
||||
|
||||
var hovered = ImGui.IsItemHovered();
|
||||
OpenTutorial( BasicTutorialSteps.Favorites );
|
||||
|
||||
if( hovered )
|
||||
{
|
||||
ImGui.SetTooltip( "Favorite" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Just a simple text box with the wrapped description, if it exists.
|
||||
private void DrawDescriptionTab()
|
||||
{
|
||||
|
|
@ -88,6 +136,26 @@ public partial class ConfigWindow
|
|||
return;
|
||||
}
|
||||
|
||||
ImGui.Dummy( ImGuiHelpers.ScaledVector2( 2 ) );
|
||||
|
||||
ImGui.Dummy( ImGuiHelpers.ScaledVector2( 2 ) );
|
||||
var tagIdx = _localTags.Draw( "Local Tags: ", "Custom tags you can set personally that will not be exported to the mod data but only set for you.\n"
|
||||
+ "If the mod already contains a local tag in its own tags, the local tag will be ignored.", _mod.LocalTags,
|
||||
out var editedTag );
|
||||
OpenTutorial( BasicTutorialSteps.Tags );
|
||||
if( tagIdx >= 0 )
|
||||
{
|
||||
Penumbra.ModManager.ChangeLocalTag( _mod.Index, tagIdx, editedTag );
|
||||
}
|
||||
if( _mod.ModTags.Count > 0 )
|
||||
{
|
||||
_modTags.Draw( "Mod Tags: ", "Tags assigned by the mod creator and saved with the mod data. To edit these, look at Edit Mod.", _mod.ModTags, out var _, false,
|
||||
ImGui.CalcTextSize( "Local " ).X - ImGui.CalcTextSize( "Mod " ).X );
|
||||
}
|
||||
|
||||
ImGui.Dummy( ImGuiHelpers.ScaledVector2( 2 ) );
|
||||
ImGui.Separator();
|
||||
|
||||
ImGuiUtil.TextWrapped( _mod.Description );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ using System;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
@ -198,9 +198,10 @@ public partial class ConfigWindow
|
|||
{
|
||||
private readonly ConfigWindow _window;
|
||||
|
||||
private bool _valid;
|
||||
private ModFileSystem.Leaf _leaf = null!;
|
||||
private Mod _mod = null!;
|
||||
private bool _valid;
|
||||
private ModFileSystem.Leaf _leaf = null!;
|
||||
private Mod _mod = null!;
|
||||
private readonly TagButtons _localTags = new();
|
||||
|
||||
public ModPanel( ConfigWindow window )
|
||||
=> _window = window;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ public partial class ConfigWindow
|
|||
Faq1,
|
||||
Faq2,
|
||||
Faq3,
|
||||
Favorites,
|
||||
Tags,
|
||||
}
|
||||
|
||||
public static readonly Tutorial Tutorial = new Tutorial()
|
||||
|
|
@ -159,5 +161,7 @@ public partial class ConfigWindow
|
|||
.Register( "FAQ 2",
|
||||
"It is advised to not use TexTools and Penumbra at the same time. Penumbra may refuse to work if TexTools broke your game indices." )
|
||||
.Register( "FAQ 3", "Penumbra can change the skin material a mod uses. This is under advanced editing." )
|
||||
.Register( "Favorites", "You can now toggle mods as favorites using this button. You can filter for favorited mods in the mod selector. Favorites are stored locally, not within the mod, but independently of collections." )
|
||||
.Register( "Tags", "Mods can now have two types of tags:\n\n- Local Tags are those that you can set for yourself. They are stored locally and are not saved in any way in the mod directory itself.\n- Mod Tags are stored in the mod metadata, are set by the mod creator and are exported together with the mod, they can only be edited in the Edit Mod tab.\n\nIf a mod has a tag in its Mod Tags, this overwrites any identical Local Tags.\n\nYou can filter for tags in the mod selector via 't:text'." )
|
||||
.EnsureSize( Enum.GetValues< BasicTutorialSteps >().Length );
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue