Current State.

This commit is contained in:
Ottermandias 2024-12-27 17:51:17 +01:00
parent 98a89bb2b4
commit 282189ef6d
9 changed files with 115 additions and 56 deletions

View file

@ -742,7 +742,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
private void OnSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, Setting oldValue, int groupIdx, bool inherited)
{
if (collection != _collectionManager.Active.Current || mod != _mod)
if (collection != _collectionManager.Active.Current || mod != _mod || type is ModSettingChange.TemporarySetting)
return;
_swapData.LoadMod(_mod, _modSettings);

View file

@ -1,8 +1,9 @@
using ImGuiNET;
using OtterGui.Custom;
namespace Penumbra.UI.Classes;
public enum ColorId
public enum ColorId : short
{
EnabledMod,
DisabledMod,
@ -10,6 +11,7 @@ public enum ColorId
InheritedMod,
InheritedDisabledMod,
NewMod,
NewModTint,
ConflictingMod,
HandledConflictMod,
FolderExpanded,
@ -31,10 +33,8 @@ public enum ColorId
ResTreeNonNetworked,
PredefinedTagAdd,
PredefinedTagRemove,
TemporaryEnabledMod,
TemporaryDisabledMod,
TemporaryInheritedMod,
TemporaryInheritedDisabledMod,
TemporaryModSettingsTint,
NoTint,
}
public static class Colors
@ -52,6 +52,18 @@ public static class Colors
public const uint ReniColorHovered = CustomGui.ReniColorHovered;
public const uint ReniColorActive = CustomGui.ReniColorActive;
public static uint Tinted(this ColorId color, ColorId tint)
{
var tintValue = ImGui.ColorConvertU32ToFloat4(tint.Value());
var value = ImGui.ColorConvertU32ToFloat4(color.Value());
var negAlpha = 1 - tintValue.W;
var newAlpha = negAlpha * value.W + tintValue.W;
var newR = (negAlpha * value.W * value.X + tintValue.W * tintValue.X) / newAlpha;
var newG = (negAlpha * value.W * value.Y + tintValue.W * tintValue.Y) / newAlpha;
var newB = (negAlpha * value.W * value.Z + tintValue.W * tintValue.Z) / newAlpha;
return ImGui.ColorConvertFloat4ToU32(new Vector4(newR, newG, newB, newAlpha));
}
public static (uint DefaultColor, string Name, string Description) Data(this ColorId color)
=> color switch
{
@ -83,10 +95,9 @@ public static class Colors
ColorId.ResTreeNonNetworked => ( 0xFFC0C0FF, "On-Screen: Non-Players (Local)", "Non-player entities handled locally, in the On-Screen tab." ),
ColorId.PredefinedTagAdd => ( 0xFF44AA44, "Predefined Tags: Add Tag", "A predefined tag that is not present on the current mod and can be added." ),
ColorId.PredefinedTagRemove => ( 0xFF2222AA, "Predefined Tags: Remove Tag", "A predefined tag that is already present on the current mod and can be removed." ),
ColorId.TemporaryEnabledMod => ( 0xFFFFC0A0, "Mod Enabled By Temporary Settings", "A mod that is enabled by temporary settings in the currently selected collection." ),
ColorId.TemporaryDisabledMod => ( 0xFFB08070, "Mod Disabled By Temporary Settings", "A mod that is disabled by temporary settings in the currently selected collection." ),
ColorId.TemporaryInheritedMod => ( 0xFFE8FFB0, "Mod Enabled By Temporary Inheritance", "A mod that is forced to inherit by temporary settings in the currently selected collection." ),
ColorId.TemporaryInheritedDisabledMod => ( 0xFF90A080, "Mod Disabled By Temporary Inheritance", "A mod that is forced to inherit by temporary settings in the currently selected collection." ),
ColorId.TemporaryModSettingsTint => ( 0x30FF0000, "Mod with Temporary Settings", "A mod that has temporary settings. This color is used as a tint for the regular state colors." ),
ColorId.NewModTint => ( 0x8000FF00, "New Mod Tint", "A mod that was newly imported or created during this session and has not been enabled yet. This color is used as a tint for the regular state colors."),
ColorId.NoTint => ( 0x00000000, "No Tint", "The default tint for all mods."),
_ => throw new ArgumentOutOfRangeException( nameof( color ), color, null ),
// @formatter:on
};

View file

@ -62,6 +62,8 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
SubscribeRightClickFolder(f => SetQuickMove(f, 1, _config.QuickMoveFolder2, s => { _config.QuickMoveFolder2 = s; _config.Save(); }), 120);
SubscribeRightClickFolder(f => SetQuickMove(f, 2, _config.QuickMoveFolder3, s => { _config.QuickMoveFolder3 = s; _config.Save(); }), 130);
SubscribeRightClickLeaf(ToggleLeafFavorite);
SubscribeRightClickLeaf(RemoveTemporarySettings);
SubscribeRightClickLeaf(DisableTemporarily);
SubscribeRightClickLeaf(l => QuickMove(l, _config.QuickMoveFolder1, _config.QuickMoveFolder2, _config.QuickMoveFolder3));
SubscribeRightClickMain(ClearDefaultImportFolder, 100);
SubscribeRightClickMain(() => ClearQuickMove(0, _config.QuickMoveFolder1, () => {_config.QuickMoveFolder1 = string.Empty; _config.Save();}), 110);
@ -194,7 +196,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
protected override void DrawLeafName(FileSystem<Mod>.Leaf leaf, in ModState state, bool selected)
{
var flags = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
using var c = ImRaii.PushColor(ImGuiCol.Text, state.Color.Value())
using var c = ImRaii.PushColor(ImGuiCol.Text, state.Color.Tinted(state.Tint))
.Push(ImGuiCol.HeaderHovered, 0x4000FFFF, leaf.Value.Favorite);
using var id = ImRaii.PushId(leaf.Value.Index);
ImRaii.TreeNode(leaf.Value.Name, flags).Dispose();
@ -264,6 +266,23 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
_modManager.DataEditor.ChangeModFavorite(mod.Value, !mod.Value.Favorite);
}
private void RemoveTemporarySettings(FileSystem<Mod>.Leaf mod)
{
var tempSettings = _collectionManager.Active.Current.GetTempSettings(mod.Value.Index);
if (tempSettings is { Lock: 0 })
if (ImUtf8.MenuItem("Remove Temporary Settings"))
_collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value, null);
}
private void DisableTemporarily(FileSystem<Mod>.Leaf mod)
{
var tempSettings = _collectionManager.Active.Current.GetTempSettings(mod.Value.Index);
if (tempSettings == null || tempSettings.Lock == 0)
if (ImUtf8.MenuItem("Disable Temporarily"))
_collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value,
TemporaryModSettings.DefaultSettings(mod.Value, "User Context-Menu"));
}
private void SetDefaultImportFolder(ModFileSystem.Folder folder)
{
if (!ImGui.MenuItem("Set As Default Import Folder"))
@ -392,8 +411,6 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
ImGuiUtil.BulletTextColored(ColorId.InheritedMod.Value(), "enabled due to inheritance from another collection.");
ImGuiUtil.BulletTextColored(ColorId.InheritedDisabledMod.Value(), "disabled due to inheritance from another collection.");
ImGuiUtil.BulletTextColored(ColorId.UndefinedMod.Value(), "unconfigured in all inherited collections.");
ImGuiUtil.BulletTextColored(ColorId.NewMod.Value(),
"newly imported during this session. Will go away when first enabling a mod or when Penumbra is reloaded.");
ImGuiUtil.BulletTextColored(ColorId.HandledConflictMod.Value(),
"enabled and conflicting with another enabled Mod, but on different priorities (i.e. the conflict is solved).");
ImGuiUtil.BulletTextColored(ColorId.ConflictingMod.Value(),
@ -501,6 +518,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
public struct ModState
{
public ColorId Color;
public ColorId Tint;
public ModPriority Priority;
}
@ -571,31 +589,31 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
=> !_filter.IsVisible(leaf);
/// <summary> Only get the text color for a mod if no filters are set. </summary>
private ColorId GetTextColor(Mod mod, ModSettings? settings, ModCollection collection)
private (ColorId Color, ColorId Tint) GetTextColor(Mod mod, ModSettings? settings, ModCollection collection)
{
if (_modManager.IsNew(mod))
return ColorId.NewMod;
var tint = settings.IsTemporary()
? ColorId.TemporaryModSettingsTint
: _modManager.IsNew(mod)
? ColorId.NewModTint
: ColorId.NoTint;
if (settings.IsTemporary())
tint = ColorId.TemporaryModSettingsTint;
if (settings == null)
return ColorId.UndefinedMod;
return (ColorId.UndefinedMod, tint);
if (!settings.Enabled)
return collection != _collectionManager.Active.Current
? ColorId.InheritedDisabledMod
: settings is TemporaryModSettings
? ColorId.TemporaryDisabledMod
: ColorId.DisabledMod;
if (settings is TemporaryModSettings)
return ColorId.TemporaryEnabledMod;
return (collection != _collectionManager.Active.Current
? ColorId.InheritedDisabledMod
: ColorId.DisabledMod, tint);
var conflicts = _collectionManager.Active.Current.Conflicts(mod);
if (conflicts.Count == 0)
return collection != _collectionManager.Active.Current ? ColorId.InheritedMod : ColorId.EnabledMod;
return (collection != _collectionManager.Active.Current ? ColorId.InheritedMod : ColorId.EnabledMod, tint);
return conflicts.Any(c => !c.Solved)
return (conflicts.Any(c => !c.Solved)
? ColorId.ConflictingMod
: ColorId.HandledConflictMod;
: ColorId.HandledConflictMod, tint);
}
private bool CheckStateFilters(Mod mod, ModSettings? settings, ModCollection collection, ref ModState state)
@ -627,6 +645,15 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
return true;
}
// isNew color takes precedence before other colors.
if (settings.IsTemporary())
state.Tint = ColorId.TemporaryModSettingsTint;
else if (isNew)
state.Tint = ColorId.NewModTint;
else
state.Tint = ColorId.NoTint;
// Handle settings.
if (settings == null)
{
@ -640,9 +667,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
{
state.Color = collection != _collectionManager.Active.Current
? ColorId.InheritedDisabledMod
: settings is TemporaryModSettings
? ColorId.TemporaryDisabledMod
: ColorId.DisabledMod;
: ColorId.DisabledMod;
if (!_stateFilter.HasFlag(ModFilter.Disabled)
|| !_stateFilter.HasFlag(ModFilter.NoConflict))
return true;
@ -652,10 +677,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
if (!_stateFilter.HasFlag(ModFilter.Enabled))
return true;
if (settings is TemporaryModSettings)
state.Color = ColorId.TemporaryEnabledMod;
// Conflicts can only be relevant if the mod is enabled.
// Conflicts can only be relevant if the mod is enabled.
var conflicts = _collectionManager.Active.Current.Conflicts(mod);
if (conflicts.Count > 0)
{
@ -664,14 +686,14 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
if (!_stateFilter.HasFlag(ModFilter.UnsolvedConflict))
return true;
state.Color = settings is TemporaryModSettings ? ColorId.TemporaryEnabledMod : ColorId.ConflictingMod;
state.Color = ColorId.ConflictingMod;
}
else
{
if (!_stateFilter.HasFlag(ModFilter.SolvedConflict))
return true;
state.Color = settings is TemporaryModSettings ? ColorId.TemporaryEnabledMod : ColorId.HandledConflictMod;
state.Color = ColorId.HandledConflictMod;
}
}
else if (!_stateFilter.HasFlag(ModFilter.NoConflict))
@ -680,9 +702,6 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
}
}
// isNew color takes precedence before other colors.
if (isNew)
state.Color = ColorId.NewMod;
return false;
}
@ -704,7 +723,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
if (_stateFilter != ModFilterExtensions.UnfilteredStateMods)
return CheckStateFilters(mod, settings, collection, ref state);
state.Color = GetTextColor(mod, settings, collection);
(state.Color, state.Tint) = GetTextColor(mod, settings, collection);
return false;
}