mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Current state.
This commit is contained in:
parent
924c9b9f7e
commit
a805e9c56d
15 changed files with 345 additions and 314 deletions
2
Luna
2
Luna
|
|
@ -1 +1 @@
|
||||||
Subproject commit 15636cda90725e6af7071512cf9873dd273570fc
|
Subproject commit 0e9fdb2bbfb02d76468a3f968b07289664d90808
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit dd14131793e5ae47cc8e9232f46469216017b5aa
|
Subproject commit 648b6fc2ce600a95ab2b2ced27e1639af2b04502
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Luna;
|
using Luna;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
|
using Penumbra.UI.CollectionTab;
|
||||||
|
|
||||||
namespace Penumbra.Communication;
|
namespace Penumbra.Communication;
|
||||||
|
|
||||||
|
|
@ -41,7 +42,10 @@ public sealed class CollectionChange(Logger log)
|
||||||
ModFileSystemSelector = 0,
|
ModFileSystemSelector = 0,
|
||||||
|
|
||||||
/// <seealso cref="Mods.ModSelection.OnCollectionChange"/>
|
/// <seealso cref="Mods.ModSelection.OnCollectionChange"/>
|
||||||
ModSelection = 10,
|
ModSelection = 10,
|
||||||
|
|
||||||
|
/// <seealso cref="CollectionCombo.OnCollectionChanged"/>
|
||||||
|
CollectionCombo = 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> The arguments for a collection change event. </summary>
|
/// <summary> The arguments for a collection change event. </summary>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ using Newtonsoft.Json;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.Communication;
|
using Penumbra.Communication;
|
||||||
using Penumbra.Enums;
|
using Penumbra.Enums;
|
||||||
using Penumbra.Mods;
|
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
||||||
public class ModCacheManager : IDisposable, Luna.IService
|
public class ModCacheManager : IDisposable, Luna.IRequiredService
|
||||||
{
|
{
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Bindings.ImGui;
|
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -17,6 +16,7 @@ using OtterGui.Tasks;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
|
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
using ImSharp;
|
||||||
using Lumina.Excel.Sheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Luna;
|
using Luna;
|
||||||
using Penumbra.Communication;
|
using Penumbra.Communication;
|
||||||
|
|
@ -24,9 +24,9 @@ using Penumbra.GameData.Data;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Interop.Hooks;
|
using Penumbra.Interop.Hooks;
|
||||||
using Penumbra.Interop.Hooks.PostProcessing;
|
using Penumbra.Interop.Hooks.PostProcessing;
|
||||||
using Penumbra.Interop.Hooks.ResourceLoading;
|
|
||||||
using DynamisIpc = OtterGui.Services.DynamisIpc;
|
using DynamisIpc = OtterGui.Services.DynamisIpc;
|
||||||
using MessageService = Penumbra.Services.MessageService;
|
using MessageService = Penumbra.Services.MessageService;
|
||||||
|
using MouseButton = Penumbra.Api.Enums.MouseButton;
|
||||||
|
|
||||||
namespace Penumbra;
|
namespace Penumbra;
|
||||||
|
|
||||||
|
|
@ -72,20 +72,17 @@ public class Penumbra : IDalamudPlugin
|
||||||
: "Unknown";
|
: "Unknown";
|
||||||
Log.Information(
|
Log.Information(
|
||||||
$"Loading Penumbra Version {_validityChecker.Version}, Commit #{_validityChecker.CommitHash} with Waiting For Plugins: {startup}...");
|
$"Loading Penumbra Version {_validityChecker.Version}, Commit #{_validityChecker.CommitHash} with Waiting For Plugins: {startup}...");
|
||||||
_services.GetService<BackupService>(); // Initialize because not required anywhere else.
|
_services.GetService<BackupService>(); // Initialize early to create backups.
|
||||||
_config = _services.GetService<Configuration>();
|
_config = _services.GetService<Configuration>();
|
||||||
_characterUtility = _services.GetService<CharacterUtility>();
|
_characterUtility = _services.GetService<CharacterUtility>();
|
||||||
_tempMods = _services.GetService<TempModManager>();
|
_tempMods = _services.GetService<TempModManager>();
|
||||||
_residentResources = _services.GetService<ResidentResourceManager>();
|
_residentResources = _services.GetService<ResidentResourceManager>();
|
||||||
_services.GetService<ResourceManagerService>(); // Initialize because not required anywhere else.
|
|
||||||
_modManager = _services.GetService<ModManager>();
|
_modManager = _services.GetService<ModManager>();
|
||||||
_collectionManager = _services.GetService<CollectionManager>();
|
_collectionManager = _services.GetService<CollectionManager>();
|
||||||
_tempCollections = _services.GetService<TempCollectionManager>();
|
_tempCollections = _services.GetService<TempCollectionManager>();
|
||||||
_redrawService = _services.GetService<RedrawService>();
|
_redrawService = _services.GetService<RedrawService>();
|
||||||
_communicatorService = _services.GetService<CommunicatorService>();
|
_communicatorService = _services.GetService<CommunicatorService>();
|
||||||
_gameData = _services.GetService<IDataManager>();
|
_gameData = _services.GetService<IDataManager>();
|
||||||
_services.GetService<ResourceService>(); // Initialize because not required anywhere else.
|
|
||||||
_services.GetService<ModCacheManager>(); // Initialize because not required anywhere else.
|
|
||||||
_collectionManager.Caches.CreateNecessaryCaches();
|
_collectionManager.Caches.CreateNecessaryCaches();
|
||||||
_services.GetService<PathResolver>();
|
_services.GetService<PathResolver>();
|
||||||
|
|
||||||
|
|
@ -118,13 +115,13 @@ public class Penumbra : IDalamudPlugin
|
||||||
{
|
{
|
||||||
_services.GetService<IpcProviders>();
|
_services.GetService<IpcProviders>();
|
||||||
var itemSheet = _services.GetService<IDataManager>().GetExcelSheet<Item>();
|
var itemSheet = _services.GetService<IDataManager>().GetExcelSheet<Item>();
|
||||||
_communicatorService.ChangedItemHover.Subscribe((in ChangedItemHover.Arguments args) =>
|
_communicatorService.ChangedItemHover.Subscribe((in args) =>
|
||||||
{
|
{
|
||||||
if (args.Data is IdentifiedItem { Item.Id.IsItem: true })
|
if (args.Data is IdentifiedItem { Item.Id.IsItem: true })
|
||||||
ImGui.TextUnformatted("Left Click to create an item link in chat.");
|
Im.Text("Left Click to create an item link in chat."u8);
|
||||||
}, ChangedItemHover.Priority.Link);
|
}, ChangedItemHover.Priority.Link);
|
||||||
|
|
||||||
_communicatorService.ChangedItemClick.Subscribe((in ChangedItemClick.Arguments args) =>
|
_communicatorService.ChangedItemClick.Subscribe((in args) =>
|
||||||
{
|
{
|
||||||
if (args is { Button: MouseButton.Left, Data: IdentifiedItem item } && itemSheet.GetRow(item.Item.ItemId.Id) is { } i)
|
if (args is { Button: MouseButton.Left, Data: IdentifiedItem item } && itemSheet.GetRow(item.Item.ItemId.Id) is { } i)
|
||||||
Messager.LinkItem(i);
|
Messager.LinkItem(i);
|
||||||
|
|
@ -255,10 +252,6 @@ public class Penumbra : IDalamudPlugin
|
||||||
sb.Append(
|
sb.Append(
|
||||||
$"> **`#Temp Mods: `** {_tempMods.Mods.Sum(kvp => kvp.Value.Count) + _tempMods.ModsForAllCollections.Count}\n");
|
$"> **`#Temp Mods: `** {_tempMods.Mods.Sum(kvp => kvp.Value.Count) + _tempMods.ModsForAllCollections.Count}\n");
|
||||||
|
|
||||||
void PrintCollection(ModCollection c, CollectionCache _)
|
|
||||||
=> sb.Append(
|
|
||||||
$"> **`Collection {c.Identity.AnonymizedName + ':',-18}`** Inheritances: `{c.Inheritance.DirectlyInheritsFrom.Count,3}`, Enabled Mods: `{c.ActualSettings.Count(s => s is { Enabled: true }),4}`, Conflicts: `{c.AllConflicts.SelectMany(x => x).Sum(x => x is { HasPriority: true, Solved: true } ? x.Conflicts.Count : 0),5}/{c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority ? x.Conflicts.Count : 0),5}`\n");
|
|
||||||
|
|
||||||
sb.AppendLine("**Collections**");
|
sb.AppendLine("**Collections**");
|
||||||
sb.Append($"> **`#Collections: `** {_collectionManager.Storage.Count - 1}\n");
|
sb.Append($"> **`#Collections: `** {_collectionManager.Storage.Count - 1}\n");
|
||||||
sb.Append($"> **`#Temp Collections: `** {_tempCollections.Count}\n");
|
sb.Append($"> **`#Temp Collections: `** {_tempCollections.Count}\n");
|
||||||
|
|
@ -280,6 +273,10 @@ public class Penumbra : IDalamudPlugin
|
||||||
PrintCollection(collection, collection._cache!);
|
PrintCollection(collection, collection._cache!);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
|
||||||
|
void PrintCollection(ModCollection c, CollectionCache _)
|
||||||
|
=> sb.Append(
|
||||||
|
$"> **`Collection {c.Identity.AnonymizedName + ':',-18}`** Inheritances: `{c.Inheritance.DirectlyInheritsFrom.Count,3}`, Enabled Mods: `{c.ActualSettings.Count(s => s is { Enabled: true }),4}`, Conflicts: `{c.AllConflicts.SelectMany(x => x).Sum(x => x is { HasPriority: true, Solved: true } ? x.Conflicts.Count : 0),5}/{c.AllConflicts.SelectMany(x => x).Sum(x => x.HasPriority ? x.Conflicts.Count : 0),5}`\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CollectLocaleEnvironmentVariables()
|
private static string CollectLocaleEnvironmentVariables()
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ public partial class ModEditWindow
|
||||||
registry.CurrentUsage == registry.SubModUsage.Count ? ColorId.NewMod : ColorId.InheritedMod;
|
registry.CurrentUsage == registry.SubModUsage.Count ? ColorId.NewMod : ColorId.InheritedMod;
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, color.Value()))
|
using (ImRaii.PushColor(ImGuiCol.Text, color.Value()))
|
||||||
{
|
{
|
||||||
if (UiHelpers.Selectable(registry.RelPath.Path, selected))
|
if (Im.Selectable(registry.RelPath.Path.Span, selected))
|
||||||
{
|
{
|
||||||
if (selected)
|
if (selected)
|
||||||
_selectedFiles.Remove(registry);
|
_selectedFiles.Remove(registry);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using ImSharp;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -11,25 +12,16 @@ using Penumbra.UI.CollectionTab;
|
||||||
|
|
||||||
namespace Penumbra.UI.Classes;
|
namespace Penumbra.UI.Classes;
|
||||||
|
|
||||||
public class CollectionSelectHeader : Luna.IUiService
|
public class CollectionSelectHeader(
|
||||||
|
CollectionManager collectionManager,
|
||||||
|
TutorialService tutorial,
|
||||||
|
ModSelection selection,
|
||||||
|
CollectionResolver resolver,
|
||||||
|
Configuration config,
|
||||||
|
CollectionCombo combo)
|
||||||
|
: Luna.IUiService
|
||||||
{
|
{
|
||||||
private readonly CollectionCombo _collectionCombo;
|
private readonly ActiveCollections _activeCollections = collectionManager.Active;
|
||||||
private readonly ActiveCollections _activeCollections;
|
|
||||||
private readonly TutorialService _tutorial;
|
|
||||||
private readonly ModSelection _selection;
|
|
||||||
private readonly CollectionResolver _resolver;
|
|
||||||
private readonly Configuration _config;
|
|
||||||
|
|
||||||
public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModSelection selection,
|
|
||||||
CollectionResolver resolver, Configuration config)
|
|
||||||
{
|
|
||||||
_tutorial = tutorial;
|
|
||||||
_selection = selection;
|
|
||||||
_resolver = resolver;
|
|
||||||
_config = config;
|
|
||||||
_activeCollections = collectionManager.Active;
|
|
||||||
_collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Identity.Name).ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Draw the header line that can quick switch between collections. </summary>
|
/// <summary> Draw the header line that can quick switch between collections. </summary>
|
||||||
public void Draw(bool spacing)
|
public void Draw(bool spacing)
|
||||||
|
|
@ -47,10 +39,10 @@ public class CollectionSelectHeader : Luna.IUiService
|
||||||
DrawCollectionButton(buttonSize, GetPlayerCollectionInfo(), 3);
|
DrawCollectionButton(buttonSize, GetPlayerCollectionInfo(), 3);
|
||||||
DrawCollectionButton(buttonSize, GetInheritedCollectionInfo(), 4);
|
DrawCollectionButton(buttonSize, GetInheritedCollectionInfo(), 4);
|
||||||
|
|
||||||
_collectionCombo.Draw("##collectionSelector", comboWidth, ColorId.SelectedCollection.Value());
|
combo.Draw("##collectionSelector"u8, comboWidth, ColorId.SelectedCollection.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.CollectionSelectors);
|
tutorial.OpenTutorial(BasicTutorialSteps.CollectionSelectors);
|
||||||
|
|
||||||
if (!_activeCollections.CurrentCollectionInUse)
|
if (!_activeCollections.CurrentCollectionInUse)
|
||||||
ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg);
|
ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg);
|
||||||
|
|
@ -58,26 +50,26 @@ public class CollectionSelectHeader : Luna.IUiService
|
||||||
|
|
||||||
private void DrawTemporaryCheckbox()
|
private void DrawTemporaryCheckbox()
|
||||||
{
|
{
|
||||||
var hold = _config.IncognitoModifier.IsActive();
|
var hold = config.IncognitoModifier.IsActive();
|
||||||
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImUtf8.GlobalScale))
|
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImUtf8.GlobalScale))
|
||||||
{
|
{
|
||||||
var tint = _config.DefaultTemporaryMode
|
var tint = config.DefaultTemporaryMode
|
||||||
? ImGuiCol.Text.Tinted(ColorId.TemporaryModSettingsTint)
|
? ImGuiCol.Text.Tinted(ColorId.TemporaryModSettingsTint)
|
||||||
: ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
: ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.ButtonHovered, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
|
using var color = ImRaii.PushColor(ImGuiCol.ButtonHovered, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
|
||||||
.Push(ImGuiCol.ButtonActive, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
|
.Push(ImGuiCol.ButtonActive, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
|
||||||
.Push(ImGuiCol.Border, tint, _config.DefaultTemporaryMode);
|
.Push(ImGuiCol.Border, tint, config.DefaultTemporaryMode);
|
||||||
if (ImUtf8.IconButton(FontAwesomeIcon.Stopwatch, ""u8, default, false, tint, ImGui.GetColorU32(ImGuiCol.FrameBg)) && hold)
|
if (ImUtf8.IconButton(FontAwesomeIcon.Stopwatch, ""u8, default, false, tint, ImGui.GetColorU32(ImGuiCol.FrameBg)) && hold)
|
||||||
{
|
{
|
||||||
_config.DefaultTemporaryMode = !_config.DefaultTemporaryMode;
|
config.DefaultTemporaryMode = !config.DefaultTemporaryMode;
|
||||||
_config.Save();
|
config.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled,
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled,
|
||||||
"Toggle the temporary settings mode, where all changes you do create temporary settings first and need to be made permanent if desired."u8);
|
"Toggle the temporary settings mode, where all changes you do create temporary settings first and need to be made permanent if desired."u8);
|
||||||
if (!hold)
|
if (!hold)
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"\nHold {_config.IncognitoModifier} while clicking to toggle.");
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"\nHold {config.IncognitoModifier} while clicking to toggle.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum CollectionState
|
private enum CollectionState
|
||||||
|
|
@ -116,7 +108,7 @@ public class CollectionSelectHeader : Luna.IUiService
|
||||||
|
|
||||||
private (ModCollection?, string, string, bool) GetPlayerCollectionInfo()
|
private (ModCollection?, string, string, bool) GetPlayerCollectionInfo()
|
||||||
{
|
{
|
||||||
var collection = _resolver.PlayerCollection();
|
var collection = resolver.PlayerCollection();
|
||||||
return CheckCollection(collection) switch
|
return CheckCollection(collection) switch
|
||||||
{
|
{
|
||||||
CollectionState.Empty => (collection, "None", "The loaded player character is configured to use no mods.", true),
|
CollectionState.Empty => (collection, "None", "The loaded player character is configured to use no mods.", true),
|
||||||
|
|
@ -145,7 +137,7 @@ public class CollectionSelectHeader : Luna.IUiService
|
||||||
|
|
||||||
private (ModCollection?, string, string, bool) GetInheritedCollectionInfo()
|
private (ModCollection?, string, string, bool) GetInheritedCollectionInfo()
|
||||||
{
|
{
|
||||||
var collection = _selection.Mod == null ? null : _selection.Collection;
|
var collection = selection.Mod == null ? null : selection.Collection;
|
||||||
return CheckCollection(collection, true) switch
|
return CheckCollection(collection, true) switch
|
||||||
{
|
{
|
||||||
CollectionState.Unavailable => (null, "Not Inherited",
|
CollectionState.Unavailable => (null, "Not Inherited",
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,64 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
using OtterGui.Raii;
|
using Penumbra.Collections;
|
||||||
using OtterGui.Text;
|
using Penumbra.Collections.Manager;
|
||||||
using OtterGui.Widgets;
|
using Penumbra.Communication;
|
||||||
using Penumbra.Collections;
|
|
||||||
using Penumbra.Collections.Manager;
|
namespace Penumbra.UI.CollectionTab;
|
||||||
|
|
||||||
namespace Penumbra.UI.CollectionTab;
|
public sealed class CollectionCombo : SimpleFilterCombo<ModCollection>, IDisposable, IUiService
|
||||||
|
{
|
||||||
public sealed class CollectionCombo(CollectionManager manager, Func<IReadOnlyList<ModCollection>> items)
|
private readonly Im.ColorDisposable _color = new();
|
||||||
: FilterComboCache<ModCollection>(items, MouseWheelType.Control, Penumbra.Log)
|
private readonly Im.StyleDisposable _style = new();
|
||||||
{
|
private readonly CollectionManager _manager;
|
||||||
private readonly ImRaii.Color _color = new();
|
private readonly CollectionChange _event;
|
||||||
|
|
||||||
protected override void DrawFilter(int currentSelected, float width)
|
public CollectionCombo(CollectionManager manager, CollectionChange @event)
|
||||||
{
|
: base(SimpleFilterType.Text)
|
||||||
_color.Dispose();
|
{
|
||||||
base.DrawFilter(currentSelected, width);
|
_manager = manager;
|
||||||
}
|
_event = @event;
|
||||||
|
Current = _manager.Active.Current;
|
||||||
public void Draw(string label, float width, uint color)
|
_event.Subscribe(OnCollectionChanged, CollectionChange.Priority.CollectionCombo);
|
||||||
{
|
ClearFilterOnSelection = true;
|
||||||
var current = manager.Active.Current;
|
ClearFilterOnCacheDisposal = true;
|
||||||
if (current != CurrentSelection)
|
}
|
||||||
{
|
|
||||||
CurrentSelectionIdx = Items.IndexOf(current);
|
private void OnCollectionChanged(in CollectionChange.Arguments arguments)
|
||||||
UpdateSelection(current);
|
{
|
||||||
}
|
if (arguments.Type is not CollectionType.Current)
|
||||||
|
return;
|
||||||
_color.Push(ImGuiCol.FrameBg, color).Push(ImGuiCol.FrameBgHovered, color);
|
|
||||||
if (Draw(label, current.Identity.Name, string.Empty, width, ImGui.GetTextLineHeightWithSpacing()) && CurrentSelection != null)
|
Current = _manager.Active.Current;
|
||||||
manager.Active.SetCollection(CurrentSelection, CollectionType.Current);
|
}
|
||||||
_color.Dispose();
|
|
||||||
}
|
public override StringU8 DisplayString(in ModCollection value)
|
||||||
|
=> new(value.Identity.Name);
|
||||||
protected override string ToString(ModCollection obj)
|
|
||||||
=> obj.Identity.Name;
|
public override string FilterString(in ModCollection value)
|
||||||
|
=> value.Identity.Name;
|
||||||
protected override void DrawCombo(string label, string preview, string tooltip, int currentSelected, float previewWidth, float itemHeight,
|
|
||||||
ImGuiComboFlags flags)
|
public override IEnumerable<ModCollection> GetBaseItems()
|
||||||
{
|
=> _manager.Storage.OrderBy(c => c.Identity.Name);
|
||||||
base.DrawCombo(label, preview, tooltip, currentSelected, previewWidth, itemHeight, flags);
|
|
||||||
ImUtf8.HoverTooltip("Control and mouse wheel to scroll."u8);
|
public void Draw(Utf8StringHandler<LabelStringHandlerBuffer> label, float width, Rgba32 color)
|
||||||
}
|
{
|
||||||
}
|
_color.Push(ImGuiColor.FrameBackground, color)
|
||||||
|
.Push(ImGuiColor.FrameBackgroundHovered, color);
|
||||||
|
if (Draw(label, Current!, "Control and mouse wheel to scroll."u8, width, out var collection))
|
||||||
|
_manager.Active.SetCollection(collection, CollectionType.Current);
|
||||||
|
|
||||||
|
_color.Dispose();
|
||||||
|
_style.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
=> _event.Unsubscribe(OnCollectionChanged);
|
||||||
|
|
||||||
|
protected override void PreDrawFilter()
|
||||||
|
{
|
||||||
|
_color.Dispose();
|
||||||
|
_style.PushDefault(ImStyleDouble.ItemSpacing);
|
||||||
|
base.PreDrawFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,32 @@
|
||||||
using Dalamud.Interface;
|
using ImSharp;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Luna;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
using OtterGui.Raii;
|
|
||||||
using OtterGui.Text;
|
namespace Penumbra.UI;
|
||||||
|
|
||||||
namespace Penumbra.UI;
|
public class IncognitoService(TutorialService tutorial, Configuration config) : IUiService
|
||||||
|
{
|
||||||
public class IncognitoService(TutorialService tutorial, Configuration config) : Luna.IService
|
public bool IncognitoMode
|
||||||
{
|
=> config.Ephemeral.IncognitoMode;
|
||||||
public bool IncognitoMode
|
|
||||||
=> config.Ephemeral.IncognitoMode;
|
public void DrawToggle(float width)
|
||||||
|
{
|
||||||
public void DrawToggle(float width)
|
var hold = config.IncognitoModifier.IsActive();
|
||||||
{
|
var color = ColorId.FolderExpanded.Value();
|
||||||
var hold = config.IncognitoModifier.IsActive();
|
using (new Im.ColorStyleDisposable().PushBorder(ImStyleBorder.Frame, color))
|
||||||
var color = ColorId.FolderExpanded.Value();
|
{
|
||||||
using (ImRaii.PushFrameBorder(ImUtf8.GlobalScale, color))
|
var tt = IncognitoMode ? "Toggle incognito mode off."u8 : "Toggle incognito mode on."u8;
|
||||||
{
|
var icon = IncognitoMode ? LunaStyle.IncognitoOn : LunaStyle.IncognitoOff;
|
||||||
var tt = IncognitoMode ? "Toggle incognito mode off."u8 : "Toggle incognito mode on."u8;
|
if (ImEx.Icon.Button(icon, tt, size: new Vector2(width, Im.Style.FrameHeight), textColor: color) && hold)
|
||||||
var icon = IncognitoMode ? FontAwesomeIcon.EyeSlash : FontAwesomeIcon.Eye;
|
{
|
||||||
if (ImUtf8.IconButton(icon, tt, new Vector2(width, ImUtf8.FrameHeight), false, color) && hold)
|
config.Ephemeral.IncognitoMode = !IncognitoMode;
|
||||||
{
|
config.Ephemeral.Save();
|
||||||
config.Ephemeral.IncognitoMode = !IncognitoMode;
|
}
|
||||||
config.Ephemeral.Save();
|
|
||||||
}
|
if (!hold)
|
||||||
|
Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"\nHold {config.IncognitoModifier} while clicking to toggle.");
|
||||||
if (!hold)
|
}
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"\nHold {config.IncognitoModifier} while clicking to toggle.");
|
|
||||||
}
|
tutorial.OpenTutorial(BasicTutorialSteps.Incognito);
|
||||||
|
}
|
||||||
tutorial.OpenTutorial(BasicTutorialSteps.Incognito);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
|
using ImSharp;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -102,50 +103,50 @@ public sealed class ResourceWatcher : IDisposable, ITab, Luna.IUiService
|
||||||
|
|
||||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetTextLineHeightWithSpacing() / 2);
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetTextLineHeightWithSpacing() / 2);
|
||||||
var isEnabled = _ephemeral.EnableResourceWatcher;
|
var isEnabled = _ephemeral.EnableResourceWatcher;
|
||||||
if (ImGui.Checkbox("Enable", ref isEnabled))
|
if (Im.Checkbox("Enable"u8, ref isEnabled))
|
||||||
{
|
{
|
||||||
_ephemeral.EnableResourceWatcher = isEnabled;
|
_ephemeral.EnableResourceWatcher = isEnabled;
|
||||||
_ephemeral.Save();
|
_ephemeral.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
Im.Line.Same();
|
||||||
DrawMaxEntries();
|
DrawMaxEntries();
|
||||||
ImGui.SameLine();
|
Im.Line.Same();
|
||||||
if (ImGui.Button("Clear"))
|
if (Im.Button("Clear"u8))
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var onlyMatching = _ephemeral.OnlyAddMatchingResources;
|
var onlyMatching = _ephemeral.OnlyAddMatchingResources;
|
||||||
if (ImGui.Checkbox("Store Only Matching", ref onlyMatching))
|
if (Im.Checkbox("Store Only Matching"u8, ref onlyMatching))
|
||||||
{
|
{
|
||||||
_ephemeral.OnlyAddMatchingResources = onlyMatching;
|
_ephemeral.OnlyAddMatchingResources = onlyMatching;
|
||||||
_ephemeral.Save();
|
_ephemeral.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
Im.Line.Same();
|
||||||
var writeToLog = _ephemeral.EnableResourceLogging;
|
var writeToLog = _ephemeral.EnableResourceLogging;
|
||||||
if (ImGui.Checkbox("Write to Log", ref writeToLog))
|
if (Im.Checkbox("Write to Log"u8, ref writeToLog))
|
||||||
{
|
{
|
||||||
_ephemeral.EnableResourceLogging = writeToLog;
|
_ephemeral.EnableResourceLogging = writeToLog;
|
||||||
_ephemeral.Save();
|
_ephemeral.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
Im.Line.Same();
|
||||||
DrawFilterInput();
|
DrawFilterInput();
|
||||||
|
|
||||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetTextLineHeightWithSpacing() / 2);
|
Im.Cursor.Y += Im.Style.TextHeightWithSpacing / 2;
|
||||||
|
|
||||||
_table.Draw(ImGui.GetTextLineHeightWithSpacing());
|
_table.Draw(Im.Style.TextHeightWithSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawFilterInput()
|
private void DrawFilterInput()
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
Im.Item.SetNextWidth(Im.ContentRegion.Available.X);
|
||||||
var tmp = _logFilter;
|
var tmp = _logFilter;
|
||||||
var invalidRegex = _logRegex == null && _logFilter.Length > 0;
|
var invalidRegex = _logRegex is null && _logFilter.Length > 0;
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, invalidRegex);
|
using var color =
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, UiHelpers.Scale, invalidRegex);
|
new Im.ColorStyleDisposable().PushBorder(ImStyleBorder.Frame, Colors.RegexWarningBorder, Im.Style.GlobalScale, invalidRegex);
|
||||||
if (ImGui.InputTextWithHint("##logFilter", "If path matches this Regex...", ref tmp, 256))
|
if (Im.Input.Text("##logFilter"u8, ref tmp, "If path matches this Regex..."u8))
|
||||||
UpdateFilter(tmp, true);
|
UpdateFilter(tmp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,8 +181,8 @@ public sealed class ResourceWatcher : IDisposable, ITab, Luna.IUiService
|
||||||
|
|
||||||
private void DrawMaxEntries()
|
private void DrawMaxEntries()
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(80 * UiHelpers.Scale);
|
Im.Item.SetNextWidth(80 * Im.Style.GlobalScale);
|
||||||
ImGui.InputInt("Max. Entries", ref _newMaxEntries, 0, 0);
|
Im.Input.Scalar("Max. Entries"u8, ref _newMaxEntries);
|
||||||
var change = ImGui.IsItemDeactivatedAfterEdit();
|
var change = ImGui.IsItemDeactivatedAfterEdit();
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right) && ImGui.GetIO().KeyCtrl)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -789,6 +789,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
Im.Text("Exists"u8);
|
Im.Text("Exists"u8);
|
||||||
Im.Text("File Size"u8);
|
Im.Text("File Size"u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
Im.Line.SameInner();
|
Im.Line.SameInner();
|
||||||
using (Im.Group())
|
using (Im.Group())
|
||||||
{
|
{
|
||||||
|
|
@ -1102,8 +1103,8 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
Penumbra.Dynamis.DrawPointer((nint)imc);
|
Penumbra.Dynamis.DrawPointer((nint)imc);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (imc != null)
|
if (imc is not null)
|
||||||
UiHelpers.Text(imc);
|
Im.Text(imc->FileName().Span);
|
||||||
|
|
||||||
var mdl = (RenderModel*)model->Models[i];
|
var mdl = (RenderModel*)model->Models[i];
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -1112,9 +1113,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
{
|
Im.Text(mdl->ResourceHandle->FileName().Span);
|
||||||
UiHelpers.Text(mdl->ResourceHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1209,14 +1208,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.TextUnformatted(r->RefCount.ToString());
|
ImGui.TextUnformatted(r->RefCount.ToString());
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ref var name = ref r->FileName;
|
Im.Text(r->FileName.AsSpan());
|
||||||
if (name.Capacity > 15)
|
|
||||||
UiHelpers.Text(name.BufferPtr, (int)name.Length);
|
|
||||||
else
|
|
||||||
fixed (byte* ptr = name.Buffer)
|
|
||||||
{
|
|
||||||
UiHelpers.Text(ptr, (int)name.Length);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||||
using FFXIVClientStructs.Interop;
|
|
||||||
using FFXIVClientStructs.STD;
|
using FFXIVClientStructs.STD;
|
||||||
|
using ImSharp;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
@ -52,7 +52,7 @@ public class ResourceTab(Configuration config, ResourceManagerService resourceMa
|
||||||
private string _resourceManagerFilter = string.Empty;
|
private string _resourceManagerFilter = string.Empty;
|
||||||
|
|
||||||
/// <summary> Draw a single resource map. </summary>
|
/// <summary> Draw a single resource map. </summary>
|
||||||
private unsafe void DrawResourceMap(ResourceCategory category, uint ext, StdMap<uint, Pointer<ResourceHandle>>* map)
|
private unsafe void DrawResourceMap(ResourceCategory category, uint ext, StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>* map)
|
||||||
{
|
{
|
||||||
if (map == null)
|
if (map == null)
|
||||||
return;
|
return;
|
||||||
|
|
@ -86,7 +86,7 @@ public class ResourceTab(Configuration config, ResourceManagerService resourceMa
|
||||||
|
|
||||||
var resource = (Interop.Structs.ResourceHandle*)r;
|
var resource = (Interop.Structs.ResourceHandle*)r;
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
UiHelpers.Text(resource);
|
Im.Text(resource->FileName().Span);
|
||||||
if (ImGui.IsItemClicked())
|
if (ImGui.IsItemClicked())
|
||||||
{
|
{
|
||||||
var data = resource->CsHandle.GetData();
|
var data = resource->CsHandle.GetData();
|
||||||
|
|
@ -106,7 +106,7 @@ public class ResourceTab(Configuration config, ResourceManagerService resourceMa
|
||||||
|
|
||||||
/// <summary> Draw a full category for the resource manager. </summary>
|
/// <summary> Draw a full category for the resource manager. </summary>
|
||||||
private unsafe void DrawCategoryContainer(ResourceCategory category,
|
private unsafe void DrawCategoryContainer(ResourceCategory category,
|
||||||
StdMap<uint, Pointer<StdMap<uint, Pointer<ResourceHandle>>>>* map, int idx)
|
StdMap<uint, FFXIVClientStructs.Interop.Pointer<StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>>>* map, int idx)
|
||||||
{
|
{
|
||||||
if (map == null)
|
if (map == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -104,30 +104,104 @@ public class SettingsTab : ITab, IUiService
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.Faq2);
|
_tutorial.OpenTutorial(BasicTutorialSteps.Faq2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly TwoPanelLayout _test = new();
|
public sealed class TestFlattened : IFlattenedTreeNode
|
||||||
|
{
|
||||||
|
public int ParentIndex { get; set; }
|
||||||
|
public int StartsLineTo { get; set; }
|
||||||
|
public int IndentationDepth { get; set; }
|
||||||
|
|
||||||
|
public void Draw()
|
||||||
|
{
|
||||||
|
Im.Tree.Node("",
|
||||||
|
TreeNodeFlags.DefaultOpen
|
||||||
|
| TreeNodeFlags.NoTreePushOnOpen); //Im.Selectable($"{ParentIndex} {StartsLineTo} {IndentationDepth}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly List<TestFlattened> List =
|
||||||
|
[
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 0,
|
||||||
|
ParentIndex = -1,
|
||||||
|
StartsLineTo = 2,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 1,
|
||||||
|
ParentIndex = 0,
|
||||||
|
StartsLineTo = -1,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 1,
|
||||||
|
ParentIndex = 0,
|
||||||
|
StartsLineTo = -1,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 0,
|
||||||
|
ParentIndex = -1,
|
||||||
|
StartsLineTo = 8,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 1,
|
||||||
|
ParentIndex = 3,
|
||||||
|
StartsLineTo = 6,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 2,
|
||||||
|
ParentIndex = 4,
|
||||||
|
StartsLineTo = -1,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 2,
|
||||||
|
ParentIndex = 4,
|
||||||
|
StartsLineTo = 7,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 3,
|
||||||
|
ParentIndex = 6,
|
||||||
|
StartsLineTo = -1,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IndentationDepth = 1,
|
||||||
|
ParentIndex = 3,
|
||||||
|
StartsLineTo = -1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
public void DrawContent()
|
public void DrawContent()
|
||||||
{
|
{
|
||||||
using var child = ImRaii.Child("##SettingsTab", -Vector2.One, false);
|
using var child = ImRaii.Child("##SettingsTab", -Vector2.One, false);
|
||||||
if (!child)
|
if (!child)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DrawEnabledBox();
|
using var c2 = ImRaii.Child("a", new Vector2(300, 5 * ImGui.GetTextLineHeightWithSpacing()), true,
|
||||||
EphemeralCheckbox("Lock Main Window", "Prevent the main window from being resized or moved.", _config.Ephemeral.FixMainWindow,
|
ImGuiWindowFlags.AlwaysVerticalScrollbar);
|
||||||
v => _config.Ephemeral.FixMainWindow = v);
|
TreeLine.Draw(List, 0xFFFFFFFF);
|
||||||
|
|
||||||
ImGui.NewLine();
|
//DrawEnabledBox();
|
||||||
DrawRootFolder();
|
//EphemeralCheckbox("Lock Main Window", "Prevent the main window from being resized or moved.", _config.Ephemeral.FixMainWindow,
|
||||||
DrawDirectoryButtons();
|
// v => _config.Ephemeral.FixMainWindow = v);
|
||||||
ImGui.NewLine();
|
//
|
||||||
ImGui.NewLine();
|
//ImGui.NewLine();
|
||||||
|
//DrawRootFolder();
|
||||||
DrawGeneralSettings();
|
//DrawDirectoryButtons();
|
||||||
_migrationDrawer.Draw();
|
//ImGui.NewLine();
|
||||||
DrawColorSettings();
|
//ImGui.NewLine();
|
||||||
DrawPredefinedTagsSection();
|
//
|
||||||
DrawAdvancedSettings();
|
//DrawGeneralSettings();
|
||||||
DrawSupportButtons();
|
//_migrationDrawer.Draw();
|
||||||
|
//DrawColorSettings();
|
||||||
|
//DrawPredefinedTagsSection();
|
||||||
|
//DrawAdvancedSettings();
|
||||||
|
//DrawSupportButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
|
|
||||||
|
|
@ -1,131 +1,87 @@
|
||||||
using Dalamud.Interface.ImGuiNotification;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Dalamud.Interface.Utility;
|
using ImSharp;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Luna;
|
||||||
using Luna;
|
using ImGuiId = ImSharp.ImGuiId;
|
||||||
using OtterGui;
|
|
||||||
using OtterGui.Raii;
|
namespace Penumbra.UI;
|
||||||
using Penumbra.Interop.Structs;
|
|
||||||
using Penumbra.String;
|
public static class UiHelpers
|
||||||
|
{
|
||||||
namespace Penumbra.UI;
|
/// <summary> The longest support button text. </summary>
|
||||||
|
public static ReadOnlySpan<byte> SupportInfoButtonText
|
||||||
public static class UiHelpers
|
=> "Copy Support Info to Clipboard"u8;
|
||||||
{
|
|
||||||
/// <summary> Draw text given by a ByteString. </summary>
|
/// <summary>
|
||||||
public static unsafe void Text(ByteString s)
|
/// Draw a button that copies the support info to clipboards.
|
||||||
=> ImGuiNative.TextUnformatted(s.Path, s.Path + s.Length);
|
/// </summary>
|
||||||
|
/// <param name="penumbra"></param>
|
||||||
/// <summary> Draw text given by a byte pointer and length. </summary>
|
public static void DrawSupportButton(Penumbra penumbra)
|
||||||
public static unsafe void Text(byte* s, int length)
|
{
|
||||||
=> ImGuiNative.TextUnformatted(s, s + length);
|
if (!Im.Button(SupportInfoButtonText))
|
||||||
|
return;
|
||||||
/// <summary> Draw text given by a byte span. </summary>
|
|
||||||
public static unsafe void Text(ReadOnlySpan<byte> s)
|
var text = penumbra.GatherSupportInformation();
|
||||||
{
|
Im.Clipboard.Set(text);
|
||||||
fixed (byte* pS = s)
|
Penumbra.Messager.NotificationMessage("Copied Support Info to Clipboard.", NotificationType.Success, false);
|
||||||
{
|
}
|
||||||
Text(pS, s.Length);
|
|
||||||
}
|
/// <summary> Draw a button to open a specific directory in a file explorer.</summary>
|
||||||
}
|
/// <param name="id">Specific ID for the given type of directory.</param>
|
||||||
|
/// <param name="directory">The directory to open.</param>
|
||||||
/// <summary> Draw the name of a resource file. </summary>
|
/// <param name="condition">Whether the button is available. </param>
|
||||||
public static unsafe void Text(ResourceHandle* resource)
|
public static void DrawOpenDirectoryButton(ImGuiId id, DirectoryInfo directory, bool condition)
|
||||||
=> Text(resource->CsHandle.FileName.AsSpan());
|
{
|
||||||
|
using var _ = Im.Id.Push(id);
|
||||||
/// <summary> Draw a ByteString as a selectable. </summary>
|
if (ImEx.Button("Open Directory"u8, Vector2.Zero, "Open this directory in your configured file explorer."u8,
|
||||||
public static unsafe bool Selectable(ByteString s, bool selected)
|
!condition || !Directory.Exists(directory.FullName)))
|
||||||
{
|
Process.Start(new ProcessStartInfo(directory.FullName)
|
||||||
var tmp = (byte)(selected ? 1 : 0);
|
{
|
||||||
return ImGuiNative.Selectable(s.Path, tmp, ImGuiSelectableFlags.None, Vector2.Zero) != 0;
|
UseShellExecute = true,
|
||||||
}
|
});
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// A selectable that copies its text to clipboard on selection and provides a on-hover tooltip about that,
|
/// <summary> Draw default vertical space. </summary>
|
||||||
/// using an ByteString.
|
public static void DefaultLineSpace()
|
||||||
/// </summary>
|
=> Im.Dummy(DefaultSpace);
|
||||||
public static unsafe void CopyOnClickSelectable(ByteString text)
|
|
||||||
{
|
/// <summary> Vertical spacing between groups. </summary>
|
||||||
if (ImGuiNative.Selectable(text.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero) != 0)
|
public static Vector2 DefaultSpace;
|
||||||
ImGuiNative.SetClipboardText(text.Path);
|
|
||||||
|
/// <summary> Width of most input fields. </summary>
|
||||||
if (ImGui.IsItemHovered())
|
public static Vector2 InputTextWidth;
|
||||||
ImGui.SetTooltip("Click to copy to clipboard.");
|
|
||||||
}
|
/// <summary> Frame Height for square icon buttons. </summary>
|
||||||
|
public static Vector2 IconButtonSize;
|
||||||
/// <summary> The longest support button text. </summary>
|
|
||||||
public const string SupportInfoButtonText = "Copy Support Info to Clipboard";
|
/// <summary> Input Text Width with space for an additional button with spacing of 3 between them. </summary>
|
||||||
|
public static float InputTextMinusButton3;
|
||||||
/// <summary>
|
|
||||||
/// Draw a button that copies the support info to clipboards.
|
/// <summary> Input Text Width with space for an additional button with spacing of default item spacing between them. </summary>
|
||||||
/// </summary>
|
public static float InputTextMinusButton;
|
||||||
/// <param name="penumbra"></param>
|
|
||||||
public static void DrawSupportButton(Penumbra penumbra)
|
/// <summary> Multiples of the current Global Scale </summary>
|
||||||
{
|
public static float Scale;
|
||||||
if (!ImGui.Button(SupportInfoButtonText))
|
|
||||||
return;
|
public static float ScaleX2;
|
||||||
|
public static float ScaleX3;
|
||||||
var text = penumbra.GatherSupportInformation();
|
public static float ScaleX4;
|
||||||
ImGui.SetClipboardText(text);
|
public static float ScaleX5;
|
||||||
Penumbra.Messager.NotificationMessage($"Copied Support Info to Clipboard.", NotificationType.Success, false);
|
|
||||||
}
|
public static void SetupCommonSizes()
|
||||||
|
{
|
||||||
/// <summary> Draw a button to open a specific directory in a file explorer.</summary>
|
if (Im.Style.GlobalScale != Scale)
|
||||||
/// <param name="id">Specific ID for the given type of directory.</param>
|
{
|
||||||
/// <param name="directory">The directory to open.</param>
|
Scale = Im.Style.GlobalScale;
|
||||||
/// <param name="condition">Whether the button is available. </param>
|
DefaultSpace = new Vector2(0, 10 * Scale);
|
||||||
public static void DrawOpenDirectoryButton(int id, DirectoryInfo directory, bool condition)
|
InputTextWidth = new Vector2(350f * Scale, 0);
|
||||||
{
|
ScaleX2 = Scale * 2;
|
||||||
using var _ = ImRaii.PushId(id);
|
ScaleX3 = Scale * 3;
|
||||||
if (ImGuiUtil.DrawDisabledButton("Open Directory", Vector2.Zero, "Open this directory in your configured file explorer.",
|
ScaleX4 = Scale * 4;
|
||||||
!condition || !Directory.Exists(directory.FullName)))
|
ScaleX5 = Scale * 5;
|
||||||
Process.Start(new ProcessStartInfo(directory.FullName)
|
}
|
||||||
{
|
|
||||||
UseShellExecute = true,
|
IconButtonSize = new Vector2(Im.Style.FrameHeight);
|
||||||
});
|
InputTextMinusButton3 = InputTextWidth.X - IconButtonSize.X - ScaleX3;
|
||||||
}
|
InputTextMinusButton = InputTextWidth.X - IconButtonSize.X - Im.Style.ItemSpacing.X;
|
||||||
|
}
|
||||||
/// <summary> Draw default vertical space. </summary>
|
}
|
||||||
public static void DefaultLineSpace()
|
|
||||||
=> ImGui.Dummy(DefaultSpace);
|
|
||||||
|
|
||||||
/// <summary> Vertical spacing between groups. </summary>
|
|
||||||
public static Vector2 DefaultSpace;
|
|
||||||
|
|
||||||
/// <summary> Width of most input fields. </summary>
|
|
||||||
public static Vector2 InputTextWidth;
|
|
||||||
|
|
||||||
/// <summary> Frame Height for square icon buttons. </summary>
|
|
||||||
public static Vector2 IconButtonSize;
|
|
||||||
|
|
||||||
/// <summary> Input Text Width with space for an additional button with spacing of 3 between them. </summary>
|
|
||||||
public static float InputTextMinusButton3;
|
|
||||||
|
|
||||||
/// <summary> Input Text Width with space for an additional button with spacing of default item spacing between them. </summary>
|
|
||||||
public static float InputTextMinusButton;
|
|
||||||
|
|
||||||
/// <summary> Multiples of the current Global Scale </summary>
|
|
||||||
public static float Scale;
|
|
||||||
|
|
||||||
public static float ScaleX2;
|
|
||||||
public static float ScaleX3;
|
|
||||||
public static float ScaleX4;
|
|
||||||
public static float ScaleX5;
|
|
||||||
|
|
||||||
public static void SetupCommonSizes()
|
|
||||||
{
|
|
||||||
if (ImGuiHelpers.GlobalScale != Scale)
|
|
||||||
{
|
|
||||||
Scale = ImGuiHelpers.GlobalScale;
|
|
||||||
DefaultSpace = new Vector2(0, 10 * Scale);
|
|
||||||
InputTextWidth = new Vector2(350f * Scale, 0);
|
|
||||||
ScaleX2 = Scale * 2;
|
|
||||||
ScaleX3 = Scale * 3;
|
|
||||||
ScaleX4 = Scale * 4;
|
|
||||||
ScaleX5 = Scale * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButtonSize = new Vector2(ImGui.GetFrameHeight());
|
|
||||||
InputTextMinusButton3 = InputTextWidth.X - IconButtonSize.X - ScaleX3;
|
|
||||||
InputTextMinusButton = InputTextWidth.X - IconButtonSize.X - ImGui.GetStyle().ItemSpacing.X;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue