mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
This commit is contained in:
parent
5a2fddab89
commit
9aa1121410
28 changed files with 616 additions and 719 deletions
2
Luna
2
Luna
|
|
@ -1 +1 @@
|
|||
Subproject commit 2e984d9c21370c778d172ab955def18c0dbe8c7d
|
||||
Subproject commit cb294f476476f7a3d8b56a0072dbd300b3d54c4f
|
||||
|
|
@ -10,7 +10,7 @@ public sealed class SelectTab(Logger log) : EventBase<SelectTab.Arguments, Selec
|
|||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="UI.Tabs.ConfigTabBar.OnSelectTab"/>
|
||||
ConfigTabBar = 0,
|
||||
MainTabBar = 0,
|
||||
}
|
||||
|
||||
/// <summary> The arguments for a SelectTab event. </summary>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Penumbra.UI;
|
|||
using Penumbra.UI.ResourceWatcher;
|
||||
using Penumbra.UI.Tabs;
|
||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||
using TabType = Penumbra.Api.Enums.TabType;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public class Penumbra : IDalamudPlugin
|
|||
AsyncTask.Run(() =>
|
||||
{
|
||||
var system = _services.GetService<PenumbraWindowSystem>();
|
||||
system.Window.Setup(this, _services.GetService<ConfigTabBar>());
|
||||
system.Window.Setup(this, _services.GetService<MainTabBar>());
|
||||
_services.GetService<CommandHandler>();
|
||||
if (!_disposed)
|
||||
{
|
||||
|
|
@ -199,8 +199,12 @@ public class Penumbra : IDalamudPlugin
|
|||
{
|
||||
ReadOnlySpan<string> relevantPlugins =
|
||||
[
|
||||
"Glamourer", "MareSynchronos", "CustomizePlus", "SimpleHeels", "VfxEditor", "heliosphere-plugin", "Ktisis", "Brio", "DynamicBridge",
|
||||
"IllusioVitae", "Aetherment", "LoporritSync", "GagSpeak", "ProjectGagSpeak", "RoleplayingVoiceDalamud", "AQuestReborn",
|
||||
"Glamourer", "CustomizePlus", "SimpleHeels",
|
||||
"Ktisis", "Brio",
|
||||
"heliosphere-plugin", "VfxEditor", "IllusioVitae", "Aetherment",
|
||||
"DynamicBridge", "GagSpeak", "ProjectGagSpeak", "RoleplayingVoiceDalamud", "AQuestReborn",
|
||||
"MareSynchronos", "LoporritSync", "KittenSync", "Snowcloak", "LightlessSync", "Sphene", "XivSync", "MareSempiterne" /* PlayerSync */, "AnatoliIliou", "LaciSynchroni"
|
||||
|
||||
];
|
||||
var plugins = _services.GetService<IDalamudPluginInterface>().InstalledPlugins
|
||||
.GroupBy(p => p.InternalName)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ using Penumbra.UI;
|
|||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ResourceWatcher;
|
||||
using Penumbra.UI.Tabs;
|
||||
using TabType = Penumbra.Api.Enums.TabType;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using ImSharp;
|
|||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
|
|
@ -25,6 +24,7 @@ using Penumbra.Mods.SubMods;
|
|||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ModsTab;
|
||||
using ITab = OtterGui.Widgets.ITab;
|
||||
using MouseWheelType = OtterGui.Widgets.MouseWheelType;
|
||||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using Dalamud.Plugin;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.Tabs;
|
||||
using TabType = Penumbra.Api.Enums.TabType;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ public sealed class ConfigWindow : Window
|
|||
private readonly Configuration _config;
|
||||
private readonly ValidityChecker _validityChecker;
|
||||
private Penumbra? _penumbra;
|
||||
private ConfigTabBar _configTabs = null!;
|
||||
private MainTabBar _configTabs = null!;
|
||||
private string? _lastException;
|
||||
|
||||
public ConfigWindow(IDalamudPluginInterface pi, Configuration config, ValidityChecker checker,
|
||||
|
|
@ -32,15 +32,15 @@ public sealed class ConfigWindow : Window
|
|||
|
||||
public void OpenSettings()
|
||||
{
|
||||
_configTabs.SelectTab = TabType.Settings;
|
||||
_configTabs.NextTab = TabType.Settings;
|
||||
IsOpen = true;
|
||||
}
|
||||
|
||||
public void Setup(Penumbra penumbra, ConfigTabBar configTabs)
|
||||
public void Setup(Penumbra penumbra, MainTabBar configTabs)
|
||||
{
|
||||
_penumbra = penumbra;
|
||||
_configTabs = configTabs;
|
||||
_configTabs.SelectTab = _config.Ephemeral.SelectedTab;
|
||||
_configTabs.NextTab = _config.Ephemeral.SelectedTab;
|
||||
}
|
||||
|
||||
public override bool DrawConditions()
|
||||
|
|
@ -98,12 +98,7 @@ public sealed class ConfigWindow : Window
|
|||
}
|
||||
else
|
||||
{
|
||||
var type = _configTabs.Draw();
|
||||
if (type != _config.Ephemeral.SelectedTab)
|
||||
{
|
||||
_config.Ephemeral.SelectedTab = type;
|
||||
_config.Ephemeral.Save();
|
||||
}
|
||||
_configTabs.Draw();
|
||||
}
|
||||
|
||||
_lastException = null;
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ public class IncognitoService(TutorialService tutorial, Configuration config) :
|
|||
config.Ephemeral.IncognitoMode = !IncognitoMode;
|
||||
config.Ephemeral.Save();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hold)
|
||||
Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"\nHold {config.IncognitoModifier} while clicking to toggle.");
|
||||
}
|
||||
|
||||
tutorial.OpenTutorial(BasicTutorialSteps.Incognito);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using Luna;
|
|||
using OtterGui;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -23,7 +22,7 @@ public class ModPanelChangedItemsTab(
|
|||
ImGuiCacheService cacheService,
|
||||
Configuration config,
|
||||
ModDataEditor dataEditor)
|
||||
: ITab, Luna.IUiService
|
||||
: ITab<ModPanelTab>
|
||||
{
|
||||
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
||||
|
||||
|
|
@ -209,6 +208,9 @@ public class ModPanelChangedItemsTab(
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Changed Items"u8;
|
||||
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.ChangedItems;
|
||||
|
||||
public bool IsVisible
|
||||
=> selector.Selected!.ChangedItems.Count > 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImSharp;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Luna;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods;
|
||||
|
|
@ -11,7 +8,7 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSelector selector) : ITab, Luna.IUiService
|
||||
public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSelector selector) : ITab<ModPanelTab>
|
||||
{
|
||||
private enum ModState
|
||||
{
|
||||
|
|
@ -25,18 +22,21 @@ public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSele
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Collections"u8;
|
||||
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.Collections;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
var (direct, inherited) = CountUsage(selector.Selected!);
|
||||
Im.Line.New();
|
||||
if (direct == 1)
|
||||
ImUtf8.Text("This Mod is directly configured in 1 collection."u8);
|
||||
else if (direct == 0)
|
||||
ImUtf8.Text("This mod is entirely unused."u8, Colors.RegexWarningBorder);
|
||||
else
|
||||
ImUtf8.Text($"This Mod is directly configured in {direct} collections.");
|
||||
switch (direct)
|
||||
{
|
||||
case 1: Im.Text("This Mod is directly configured in 1 collection."u8); break;
|
||||
case 0: Im.Text("This mod is entirely unused."u8, Colors.RegexWarningBorder); break;
|
||||
default: Im.Text($"This Mod is directly configured in {direct} collections."); break;
|
||||
}
|
||||
if (inherited > 0)
|
||||
ImUtf8.Text($"It is also implicitly used in {inherited} {(inherited == 1 ? "collection" : "collections")} through inheritance.");
|
||||
Im.Text($"It is also implicitly used in {inherited} {(inherited == 1 ? "collection" : "collections")} through inheritance.");
|
||||
|
||||
Im.Line.New();
|
||||
Im.Separator();
|
||||
|
|
@ -45,7 +45,7 @@ public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSele
|
|||
if (!table)
|
||||
return;
|
||||
|
||||
var size = ImUtf8.CalcTextSize(ToText(ModState.Unconfigured)).X + 20 * Im.Style.GlobalScale;
|
||||
var size = Im.Font.CalculateSize(ToText(ModState.Unconfigured)).X + 20 * Im.Style.GlobalScale;
|
||||
var collectionSize = 200 * Im.Style.GlobalScale;
|
||||
table.SetupColumn("Collection"u8, TableColumnFlags.WidthFixed, collectionSize);
|
||||
table.SetupColumn("State"u8, TableColumnFlags.WidthFixed, size);
|
||||
|
|
@ -54,21 +54,21 @@ public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSele
|
|||
ImGui.TableHeadersRow();
|
||||
foreach (var (idx, (collection, parent, color, state)) in _cache.Index())
|
||||
{
|
||||
using var id = ImUtf8.PushId(idx);
|
||||
ImUtf8.DrawTableColumn(collection.Identity.Name);
|
||||
using var id = Im.Id.Push(idx);
|
||||
table.DrawColumn(collection.Identity.Name);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImUtf8.Text(ToText(state), color);
|
||||
table.NextColumn();
|
||||
Im.Text(ToText(state), color);
|
||||
|
||||
using (var context = ImUtf8.PopupContextItem("Context"u8))
|
||||
using (var context = Im.Popup.BeginContextItem("Context"u8))
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
ImUtf8.Text(collection.Identity.Name);
|
||||
Im.Text(collection.Identity.Name);
|
||||
Im.Separator();
|
||||
using (ImRaii.Disabled(state is ModState.Enabled && parent == collection))
|
||||
using (Im.Disabled(state is ModState.Enabled && parent == collection))
|
||||
{
|
||||
if (ImUtf8.MenuItem("Enable"u8))
|
||||
if (Im.Menu.Item("Enable"u8))
|
||||
{
|
||||
if (parent != collection)
|
||||
manager.Editor.SetModInheritance(collection, selector.Selected!, false);
|
||||
|
|
@ -76,9 +76,9 @@ public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSele
|
|||
}
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(state is ModState.Disabled && parent == collection))
|
||||
using (Im.Disabled(state is ModState.Disabled && parent == collection))
|
||||
{
|
||||
if (ImUtf8.MenuItem("Disable"u8))
|
||||
if (Im.Menu.Item("Disable"u8))
|
||||
{
|
||||
if (parent != collection)
|
||||
manager.Editor.SetModInheritance(collection, selector.Selected!, false);
|
||||
|
|
@ -86,15 +86,15 @@ public class ModPanelCollectionsTab(CollectionManager manager, ModFileSystemSele
|
|||
}
|
||||
}
|
||||
|
||||
using (ImRaii.Disabled(parent != collection))
|
||||
using (Im.Disabled(parent != collection))
|
||||
{
|
||||
if (ImUtf8.MenuItem("Inherit"u8))
|
||||
if (Im.Menu.Item("Inherit"u8))
|
||||
manager.Editor.SetModInheritance(collection, selector.Selected!, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImUtf8.DrawTableColumn(parent == collection ? string.Empty : parent.Identity.Name);
|
||||
table.DrawColumn(parent == collection ? StringU8.Empty : parent.Identity.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,14 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class ModPanelConflictsTab(CollectionManager collectionManager, ModFileSystemSelector selector) : ITab, IUiService
|
||||
public class ModPanelConflictsTab(CollectionManager collectionManager, ModFileSystemSelector selector) : ITab<ModPanelTab>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Conflicts"u8;
|
||||
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.Conflicts;
|
||||
|
||||
public bool IsVisible
|
||||
=> collectionManager.Active.Current.Conflicts(selector.Selected!).Any(c => !GetPriority(c).IsHidden);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using ImSharp;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui;
|
||||
using Luna;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
|
|
@ -12,7 +11,7 @@ public class ModPanelDescriptionTab(
|
|||
TutorialService tutorial,
|
||||
ModManager modManager,
|
||||
PredefinedTagManager predefinedTagsConfig)
|
||||
: ITab, Luna.IUiService
|
||||
: ITab<ModPanelTab>
|
||||
{
|
||||
private readonly TagButtons _localTags = new();
|
||||
private readonly TagButtons _modTags = new();
|
||||
|
|
@ -20,15 +19,17 @@ public class ModPanelDescriptionTab(
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Description"u8;
|
||||
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.Description;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
using var child = ImRaii.Child("##description");
|
||||
using var child = Im.Child.Begin("##description"u8);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
ImGui.Dummy(ImEx.ScaledVector(2));
|
||||
|
||||
ImGui.Dummy(ImEx.ScaledVector(2));
|
||||
Im.ScaledDummy(2, 2);
|
||||
Im.ScaledDummy(2, 2);
|
||||
var (predefinedTagsEnabled, predefinedTagButtonOffset) = predefinedTagsConfig.Enabled
|
||||
? (true, Im.Style.FrameHeight + Im.Style.WindowPadding.X + (ImGui.GetScrollMaxY() > 0 ? Im.Style.ScrollbarSize : 0))
|
||||
: (false, 0);
|
||||
|
|
@ -49,9 +50,9 @@ public class ModPanelDescriptionTab(
|
|||
selector.Selected!.ModTags, out _, false,
|
||||
ImGui.CalcTextSize("Local ").X - ImGui.CalcTextSize("Mod ").X);
|
||||
|
||||
ImGui.Dummy(ImEx.ScaledVector(2));
|
||||
Im.ScaledDummy(2, 2);
|
||||
Im.Separator();
|
||||
|
||||
ImGuiUtil.TextWrapped(selector.Selected!.Description);
|
||||
Im.TextWrapped(selector.Selected!.Description);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,12 @@
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.UI.ModsTab.Groups;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
|
@ -29,7 +23,7 @@ public class ModPanelEditTab(
|
|||
ModGroupEditDrawer groupEditDrawer,
|
||||
DescriptionEditPopup descriptionPopup,
|
||||
AddGroupDrawer addGroupDrawer)
|
||||
: ITab, IUiService
|
||||
: ITab<ModPanelTab>
|
||||
{
|
||||
private readonly TagButtons _modTags = new();
|
||||
|
||||
|
|
@ -39,9 +33,12 @@ public class ModPanelEditTab(
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Edit Mod"u8;
|
||||
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.Edit;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
using var child = ImRaii.Child("##editChild", -Vector2.One);
|
||||
using var child = Im.Child.Begin("##editChild"u8, Im.ContentRegion.Available);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
|
|
@ -54,7 +51,7 @@ public class ModPanelEditTab(
|
|||
EditLocalData();
|
||||
UiHelpers.DefaultLineSpace();
|
||||
|
||||
if (Input.Text("Mod Path", Input.Path, Input.None, _leaf.FullName(), out var newPath, 256, UiHelpers.InputTextWidth.X))
|
||||
if (Input.Text("Mod Path"u8, Input.Path, Input.None, _leaf.FullName(), out var newPath, UiHelpers.InputTextWidth.X))
|
||||
try
|
||||
{
|
||||
fileSystem.RenameAndMove(_leaf, newPath);
|
||||
|
|
@ -100,15 +97,14 @@ public class ModPanelEditTab(
|
|||
{
|
||||
var buttonSize = new Vector2(150 * Im.Style.GlobalScale, 0);
|
||||
var folderExists = Directory.Exists(_mod.ModPath.FullName);
|
||||
var tt = folderExists
|
||||
if (ImEx.Button("Open Mod Directory"u8, buttonSize, folderExists
|
||||
? $"Open \"{_mod.ModPath.FullName}\" in the file explorer of your choice."
|
||||
: $"Mod directory \"{_mod.ModPath.FullName}\" does not exist.";
|
||||
if (ImGuiUtil.DrawDisabledButton("Open Mod Directory", buttonSize, tt, !folderExists))
|
||||
: $"Mod directory \"{_mod.ModPath.FullName}\" does not exist.", !folderExists))
|
||||
Process.Start(new ProcessStartInfo(_mod.ModPath.FullName) { UseShellExecute = true });
|
||||
|
||||
Im.Line.Same();
|
||||
if (ImGuiUtil.DrawDisabledButton("Reload Mod", buttonSize, "Reload the current mod from its files.\n"
|
||||
+ "If the mod directory or meta file do not exist anymore or if the new mod name is empty, the mod is deleted instead.",
|
||||
if (ImEx.Button("Reload Mod"u8, buttonSize, "Reload the current mod from its files.\n"u8
|
||||
+ "If the mod directory or meta file do not exist anymore or if the new mod name is empty, the mod is deleted instead."u8,
|
||||
false))
|
||||
modManager.ReloadMod(_mod);
|
||||
|
||||
|
|
@ -121,81 +117,76 @@ public class ModPanelEditTab(
|
|||
private void BackupButtons(Vector2 buttonSize)
|
||||
{
|
||||
var backup = new ModBackup(modExportManager, _mod);
|
||||
var tt = ModBackup.CreatingBackup
|
||||
if (ImEx.Button("Export Mod"u8, buttonSize, ModBackup.CreatingBackup
|
||||
? "Already exporting a mod."
|
||||
: backup.Exists
|
||||
? $"Overwrite current exported mod \"{backup.Name}\" with current mod."
|
||||
: $"Create exported archive of current mod at \"{backup.Name}\".";
|
||||
if (ImUtf8.ButtonEx("Export Mod"u8, tt, buttonSize, ModBackup.CreatingBackup))
|
||||
: $"Create exported archive of current mod at \"{backup.Name}\".", ModBackup.CreatingBackup))
|
||||
backup.CreateAsync();
|
||||
|
||||
if (Im.Item.RightClicked())
|
||||
ImUtf8.OpenPopup("context"u8);
|
||||
Im.Popup.Open("context"u8);
|
||||
|
||||
Im.Line.Same();
|
||||
tt = backup.Exists
|
||||
if (ImEx.Button("Delete Export"u8, buttonSize, backup.Exists
|
||||
? $"Delete existing mod export \"{backup.Name}\" (hold {config.DeleteModModifier} while clicking)."
|
||||
: $"Exported mod \"{backup.Name}\" does not exist.";
|
||||
if (ImUtf8.ButtonEx("Delete Export"u8, tt, buttonSize, !backup.Exists || !config.DeleteModModifier.IsActive()))
|
||||
: $"Exported mod \"{backup.Name}\" does not exist.", !backup.Exists || !config.DeleteModModifier.IsActive()))
|
||||
backup.Delete();
|
||||
|
||||
tt = backup.Exists
|
||||
? $"Restore mod from exported file \"{backup.Name}\" (hold {config.DeleteModModifier} while clicking)."
|
||||
: $"Exported mod \"{backup.Name}\" does not exist.";
|
||||
Im.Line.Same();
|
||||
if (ImUtf8.ButtonEx("Restore From Export"u8, tt, buttonSize, !backup.Exists || !config.DeleteModModifier.IsActive()))
|
||||
if (ImEx.Button("Restore From Export"u8, buttonSize, backup.Exists
|
||||
? $"Restore mod from exported file \"{backup.Name}\" (hold {config.DeleteModModifier} while clicking)."
|
||||
: $"Exported mod \"{backup.Name}\" does not exist.", !backup.Exists || !config.DeleteModModifier.IsActive()))
|
||||
backup.Restore(modManager);
|
||||
if (backup.Exists)
|
||||
{
|
||||
Im.Line.Same();
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImUtf8.Text(FontAwesomeIcon.CheckCircle.ToIconString());
|
||||
}
|
||||
|
||||
ImEx.Icon.Draw(FontAwesomeIcon.CheckCircle.Icon());
|
||||
Im.Tooltip.OnHover($"Export exists in \"{backup.Name}\".");
|
||||
}
|
||||
|
||||
using var context = ImUtf8.Popup("context"u8);
|
||||
using var context = Im.Popup.Begin("context"u8);
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (ImUtf8.Selectable("Open Backup Directory"u8))
|
||||
if (Im.Selectable("Open Backup Directory"u8))
|
||||
Process.Start(new ProcessStartInfo(modExportManager.ExportDirectory.FullName) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
/// <summary> Anything about editing the regular meta information about the mod. </summary>
|
||||
private void EditRegularMeta()
|
||||
{
|
||||
if (Input.Text("Name", Input.Name, Input.None, _mod.Name, out var newName, 256, UiHelpers.InputTextWidth.X))
|
||||
if (Input.Text("Name"u8, Input.Name, Input.None, _mod.Name, out var newName, UiHelpers.InputTextWidth.X))
|
||||
modManager.DataEditor.ChangeModName(_mod, newName);
|
||||
|
||||
if (Input.Text("Author", Input.Author, Input.None, _mod.Author, out var newAuthor, 256, UiHelpers.InputTextWidth.X))
|
||||
if (Input.Text("Author"u8, Input.Author, Input.None, _mod.Author, out var newAuthor, UiHelpers.InputTextWidth.X))
|
||||
modManager.DataEditor.ChangeModAuthor(_mod, newAuthor);
|
||||
|
||||
if (Input.Text("Version", Input.Version, Input.None, _mod.Version, out var newVersion, 32,
|
||||
if (Input.Text("Version"u8, Input.Version, Input.None, _mod.Version, out var newVersion,
|
||||
UiHelpers.InputTextWidth.X))
|
||||
modManager.DataEditor.ChangeModVersion(_mod, newVersion);
|
||||
|
||||
if (Input.Text("Website", Input.Website, Input.None, _mod.Website, out var newWebsite, 256,
|
||||
if (Input.Text("Website"u8, Input.Website, Input.None, _mod.Website, out var newWebsite,
|
||||
UiHelpers.InputTextWidth.X))
|
||||
modManager.DataEditor.ChangeModWebsite(_mod, newWebsite);
|
||||
|
||||
using var style = ImStyleDouble.ItemSpacing.Push(new Vector2(Im.Style.GlobalScale * 3));
|
||||
|
||||
var reducedSize = new Vector2(UiHelpers.InputTextMinusButton3, 0);
|
||||
if (ImGui.Button("Edit Description", reducedSize))
|
||||
if (Im.Button("Edit Description"u8, reducedSize))
|
||||
descriptionPopup.Open(_mod);
|
||||
|
||||
|
||||
Im.Line.Same();
|
||||
var fileExists = File.Exists(filenames.ModMetaPath(_mod));
|
||||
var tt = fileExists
|
||||
? "Open the metadata json file in the text editor of your choice."
|
||||
: "The metadata json file does not exist.";
|
||||
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.FileExport.ToIconString()}##metaFile", UiHelpers.IconButtonSize, tt,
|
||||
!fileExists, true))
|
||||
? "Open the metadata json file in the text editor of your choice."u8
|
||||
: "The metadata json file does not exist."u8;
|
||||
using (Im.Id.Push("meta"))
|
||||
{
|
||||
if (ImEx.Icon.Button(LunaStyle.FileExportIcon, tt, !fileExists))
|
||||
Process.Start(new ProcessStartInfo(filenames.ModMetaPath(_mod)) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
DrawOpenDefaultMod();
|
||||
}
|
||||
|
|
@ -213,14 +204,13 @@ public class ModPanelEditTab(
|
|||
Im.Line.Same(0, 3 * Im.Style.GlobalScale);
|
||||
|
||||
var canRefresh = config.DeleteModModifier.IsActive();
|
||||
var tt = canRefresh
|
||||
? "Reset the import date to the current date and time."
|
||||
: $"Reset the import date to the current date and time.\nHold {config.DeleteModModifier} while clicking to refresh.";
|
||||
|
||||
if (ImUtf8.IconButton(FontAwesomeIcon.Sync, tt, disabled: !canRefresh))
|
||||
if (ImEx.Icon.Button(LunaStyle.RefreshIcon, canRefresh
|
||||
? "Reset the import date to the current date and time."u8
|
||||
: $"Reset the import date to the current date and time.\nHold {config.DeleteModModifier} while clicking to refresh.",
|
||||
!canRefresh))
|
||||
modManager.DataEditor.ResetModImportDate(_mod);
|
||||
Im.Line.SameInner();
|
||||
ImUtf8.Text("Import Date"u8);
|
||||
Im.Text("Import Date"u8);
|
||||
}
|
||||
|
||||
private void DrawOpenLocalData()
|
||||
|
|
@ -230,7 +220,7 @@ public class ModPanelEditTab(
|
|||
var tt = fileExists
|
||||
? "Open the local mod data file in the text editor of your choice."u8
|
||||
: "The local mod data file does not exist."u8;
|
||||
if (ImUtf8.ButtonEx("Open Local Data"u8, tt, UiHelpers.InputTextWidth, !fileExists))
|
||||
if (ImEx.Button("Open Local Data"u8, UiHelpers.InputTextWidth, tt, !fileExists))
|
||||
Process.Start(new ProcessStartInfo(file) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
|
|
@ -239,9 +229,9 @@ public class ModPanelEditTab(
|
|||
var file = filenames.OptionGroupFile(_mod, -1, false);
|
||||
var fileExists = File.Exists(file);
|
||||
var tt = fileExists
|
||||
? "Open the default mod data file in the text editor of your choice."
|
||||
: "The default mod data file does not exist.";
|
||||
if (ImGuiUtil.DrawDisabledButton("Open Default Data", UiHelpers.InputTextWidth, tt, !fileExists))
|
||||
? "Open the default mod data file in the text editor of your choice."u8
|
||||
: "The default mod data file does not exist."u8;
|
||||
if (ImEx.Button("Open Default Data"u8, UiHelpers.InputTextWidth, tt, !fileExists))
|
||||
Process.Start(new ProcessStartInfo(file) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
|
|
@ -262,7 +252,7 @@ public class ModPanelEditTab(
|
|||
{
|
||||
Im.Item.SetNextWidth(buttonSize.X * 2 + Im.Style.ItemSpacing.X);
|
||||
var tmp = _currentModDirectory ?? mod.ModPath.Name;
|
||||
if (ImGui.InputText("##newModMove", ref tmp, 64))
|
||||
if (Im.Input.Text("##newModMove"u8, ref tmp))
|
||||
{
|
||||
_currentModDirectory = tmp;
|
||||
_state = modManager.NewDirectoryValid(mod.ModPath.Name, _currentModDirectory, out _);
|
||||
|
|
@ -281,16 +271,17 @@ public class ModPanelEditTab(
|
|||
_ => (true, "Unknown error."),
|
||||
};
|
||||
Im.Line.Same();
|
||||
if (ImGuiUtil.DrawDisabledButton("Rename Mod Directory", buttonSize, tt, disabled) && _currentModDirectory != null)
|
||||
if (ImEx.Button("Rename Mod Directory"u8, buttonSize, tt, disabled) && _currentModDirectory is not null)
|
||||
{
|
||||
modManager.MoveModDirectory(mod, _currentModDirectory);
|
||||
Reset();
|
||||
}
|
||||
|
||||
Im.Line.Same();
|
||||
ImGuiComponents.HelpMarker(
|
||||
"The mod directory name is used to correspond stored settings and sort orders, otherwise it has no influence on anything that is displayed.\n"
|
||||
+ "This can currently not be used on pre-existing folders and does not support merges or overwriting.");
|
||||
if (LunaStyle.DrawAlignedHelpMarker())
|
||||
Im.Tooltip.Set(
|
||||
"The mod directory name is used to correspond stored settings and sort orders, otherwise it has no influence on anything that is displayed.\n"u8
|
||||
+ "This can currently not be used on pre-existing folders and does not support merges or overwriting."u8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,35 +295,32 @@ public class ModPanelEditTab(
|
|||
public const int Version = -4;
|
||||
public const int Website = -5;
|
||||
public const int Path = -6;
|
||||
public const int Description = -7;
|
||||
|
||||
// Temporary strings
|
||||
private static string? _currentEdit;
|
||||
private static ModPriority? _currentGroupPriority;
|
||||
private static int _currentField = None;
|
||||
private static int _optionIndex = None;
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
_currentEdit = null;
|
||||
_currentGroupPriority = null;
|
||||
_currentField = None;
|
||||
_optionIndex = None;
|
||||
}
|
||||
|
||||
public static bool Text(string label, int field, int option, string oldValue, out string value, uint maxLength, float width)
|
||||
public static bool Text(ReadOnlySpan<byte> label, int field, int option, string oldValue, out string value, float width)
|
||||
{
|
||||
var tmp = field == _currentField && option == _optionIndex ? _currentEdit ?? oldValue : oldValue;
|
||||
Im.Item.SetNextWidth(width);
|
||||
|
||||
if (ImGui.InputText(label, ref tmp))
|
||||
if (Im.Input.Text(label, ref tmp))
|
||||
{
|
||||
_currentEdit = tmp;
|
||||
_optionIndex = option;
|
||||
_currentField = field;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentEdit != null)
|
||||
if (Im.Item.DeactivatedAfterEdit && _currentEdit is not null)
|
||||
{
|
||||
var ret = _currentEdit != oldValue;
|
||||
value = _currentEdit;
|
||||
|
|
@ -343,28 +331,5 @@ public class ModPanelEditTab(
|
|||
value = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Priority(string label, int field, int option, ModPriority oldValue, out ModPriority value, float width)
|
||||
{
|
||||
var tmp = (field == _currentField && option == _optionIndex ? _currentGroupPriority ?? oldValue : oldValue).Value;
|
||||
Im.Item.SetNextWidth(width);
|
||||
if (ImGui.InputInt(label, ref tmp, 0, 0))
|
||||
{
|
||||
_currentGroupPriority = new ModPriority(tmp);
|
||||
_optionIndex = option;
|
||||
_currentField = field;
|
||||
}
|
||||
|
||||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentGroupPriority != null)
|
||||
{
|
||||
var ret = _currentGroupPriority != oldValue;
|
||||
value = _currentGroupPriority.Value;
|
||||
Reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
value = ModPriority.Default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
|
|
@ -22,7 +22,7 @@ public class ModPanelSettingsTab(
|
|||
CommunicatorService communicator,
|
||||
ModGroupDrawer modGroupDrawer,
|
||||
Configuration config)
|
||||
: ITab, Luna.IUiService
|
||||
: ITab<ModPanelTab>
|
||||
{
|
||||
private bool _inherited;
|
||||
private bool _temporary;
|
||||
|
|
@ -32,7 +32,10 @@ public class ModPanelSettingsTab(
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Settings"u8;
|
||||
|
||||
public void DrawHeader()
|
||||
public ModPanelTab Identifier
|
||||
=> ModPanelTab.Settings;
|
||||
|
||||
public void PostTabButton()
|
||||
=> tutorial.OpenTutorial(BasicTutorialSteps.ModOptions);
|
||||
|
||||
public void Reset()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
|
|
@ -12,138 +7,88 @@ using ImGuiColor = ImSharp.ImGuiColor;
|
|||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class ModPanelTabBar : IUiService
|
||||
public enum ModPanelTab
|
||||
{
|
||||
private enum ModPanelTabType
|
||||
{
|
||||
Description,
|
||||
Settings,
|
||||
ChangedItems,
|
||||
Conflicts,
|
||||
Collections,
|
||||
Edit,
|
||||
};
|
||||
};
|
||||
|
||||
public class ModPanelTabBar : TabBar<ModPanelTab>
|
||||
{
|
||||
public readonly ModPanelSettingsTab Settings;
|
||||
public readonly ModPanelDescriptionTab Description;
|
||||
public readonly ModPanelCollectionsTab Collections;
|
||||
public readonly ModPanelConflictsTab Conflicts;
|
||||
public readonly ModPanelChangedItemsTab ChangedItems;
|
||||
public readonly ModPanelEditTab Edit;
|
||||
private readonly ModEditWindowFactory _modEditWindowFactory;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly TutorialService _tutorial;
|
||||
|
||||
public readonly ITab[] Tabs;
|
||||
private ModPanelTabType _preferredTab = ModPanelTabType.Settings;
|
||||
private Mod? _lastMod;
|
||||
|
||||
public ModPanelTabBar(ModEditWindowFactory modEditWindowFactory, ModPanelSettingsTab settings, ModPanelDescriptionTab description,
|
||||
ModPanelConflictsTab conflicts, ModPanelChangedItemsTab changedItems, ModPanelEditTab edit, ModManager modManager,
|
||||
TutorialService tutorial, ModPanelCollectionsTab collections)
|
||||
TutorialService tutorial, ModPanelCollectionsTab collections, Logger log)
|
||||
: base(nameof(ModPanelTabBar), log, settings, description, conflicts, changedItems, collections, edit)
|
||||
{
|
||||
_modEditWindowFactory = modEditWindowFactory;
|
||||
Flags = TabBarFlags.NoTooltip;
|
||||
Settings = settings;
|
||||
Description = description;
|
||||
Conflicts = conflicts;
|
||||
ChangedItems = changedItems;
|
||||
Edit = edit;
|
||||
_modManager = modManager;
|
||||
_tutorial = tutorial;
|
||||
Collections = collections;
|
||||
Buttons.AddButton(new AdvancedEditingButton(this, modEditWindowFactory), 0);
|
||||
}
|
||||
|
||||
Tabs =
|
||||
[
|
||||
Settings,
|
||||
Description,
|
||||
Conflicts,
|
||||
ChangedItems,
|
||||
Collections,
|
||||
Edit,
|
||||
];
|
||||
private sealed class AdvancedEditingButton(ModPanelTabBar parent, ModEditWindowFactory editFactory) : BaseButton
|
||||
{
|
||||
public override ReadOnlySpan<byte> Label
|
||||
=> "Advanced Editing"u8;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (parent._lastMod is { } mod)
|
||||
editFactory.OpenForMod(mod);
|
||||
}
|
||||
|
||||
public override bool HasTooltip
|
||||
=> true;
|
||||
|
||||
public override void DrawTooltip()
|
||||
=> Im.Text(
|
||||
"Clicking this will open a new window in which you can\nedit the following things per option for this mod:\n\n"u8
|
||||
+ "\t\t- file redirections\n"u8
|
||||
+ "\t\t- file swaps\n"u8
|
||||
+ "\t\t- metadata manipulations\n"u8
|
||||
+ "\t\t- model materials\n"u8
|
||||
+ "\t\t- duplicates\n"u8
|
||||
+ "\t\t- textures"u8);
|
||||
}
|
||||
|
||||
public void Draw(Mod mod)
|
||||
{
|
||||
var tabBarHeight = ImGui.GetCursorPosY();
|
||||
if (_lastMod != mod)
|
||||
{
|
||||
var tabBarHeight = Im.Cursor.Y;
|
||||
_lastMod = mod;
|
||||
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(_preferredTab), out _, () => DrawAdvancedEditingButton(mod), Tabs);
|
||||
}
|
||||
else
|
||||
{
|
||||
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ReadOnlySpan<byte>.Empty, out var label, () => DrawAdvancedEditingButton(mod),
|
||||
Tabs);
|
||||
_preferredTab = ToType(label);
|
||||
}
|
||||
base.Draw();
|
||||
|
||||
DrawFavoriteButton(mod, tabBarHeight);
|
||||
}
|
||||
|
||||
private ReadOnlySpan<byte> ToLabel(ModPanelTabType type)
|
||||
=> type switch
|
||||
{
|
||||
ModPanelTabType.Description => Description.Label,
|
||||
ModPanelTabType.Settings => Settings.Label,
|
||||
ModPanelTabType.ChangedItems => ChangedItems.Label,
|
||||
ModPanelTabType.Conflicts => Conflicts.Label,
|
||||
ModPanelTabType.Collections => Collections.Label,
|
||||
ModPanelTabType.Edit => Edit.Label,
|
||||
_ => ReadOnlySpan<byte>.Empty,
|
||||
};
|
||||
|
||||
private ModPanelTabType ToType(ReadOnlySpan<byte> label)
|
||||
{
|
||||
if (label == Description.Label)
|
||||
return ModPanelTabType.Description;
|
||||
if (label == Settings.Label)
|
||||
return ModPanelTabType.Settings;
|
||||
if (label == ChangedItems.Label)
|
||||
return ModPanelTabType.ChangedItems;
|
||||
if (label == Conflicts.Label)
|
||||
return ModPanelTabType.Conflicts;
|
||||
if (label == Collections.Label)
|
||||
return ModPanelTabType.Collections;
|
||||
if (label == Edit.Label)
|
||||
return ModPanelTabType.Edit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void DrawAdvancedEditingButton(Mod mod)
|
||||
{
|
||||
if (ImGui.TabItemButton("Advanced Editing", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
|
||||
{
|
||||
_modEditWindowFactory.OpenForMod(mod);
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverTooltip(
|
||||
"Clicking this will open a new window in which you can\nedit the following things per option for this mod:\n\n"
|
||||
+ "\t\t- file redirections\n"
|
||||
+ "\t\t- file swaps\n"
|
||||
+ "\t\t- metadata manipulations\n"
|
||||
+ "\t\t- model materials\n"
|
||||
+ "\t\t- duplicates\n"
|
||||
+ "\t\t- textures");
|
||||
}
|
||||
|
||||
private void DrawFavoriteButton(Mod mod, float height)
|
||||
{
|
||||
var size = ImEx.Icon.CalculateSize(LunaStyle.FavoriteIcon) + Im.Style.FramePadding * 2;
|
||||
var newPos = new Vector2(ImGui.GetWindowWidth() - size.X - Im.Style.ItemSpacing.X, height);
|
||||
if (ImGui.GetScrollMaxX() > 0)
|
||||
newPos.X += ImGui.GetScrollX();
|
||||
var newPos = new Vector2(Im.Window.Width - size.X - Im.Style.ItemSpacing.X, height);
|
||||
if (Im.Scroll.MaximumX > 0)
|
||||
newPos.X += Im.Scroll.X;
|
||||
|
||||
var rectUpper = ImGui.GetWindowPos() + newPos;
|
||||
var color = ImGui.IsMouseHoveringRect(rectUpper, rectUpper + size) ? Im.Style[ImGuiColor.Text] :
|
||||
var rectUpper = Im.Window.Position + newPos;
|
||||
var color = Im.Mouse.IsHoveringRectangle(rectUpper, rectUpper + size) ? Im.Style[ImGuiColor.Text] :
|
||||
mod.Favorite ? LunaStyle.FavoriteColor : Im.Style[ImGuiColor.TextDisabled];
|
||||
using var c = ImGuiColor.Text.Push(color)
|
||||
.Push(ImGuiColor.Button, Vector4.Zero)
|
||||
.Push(ImGuiColor.ButtonHovered, Vector4.Zero)
|
||||
.Push(ImGuiColor.ButtonActive, Vector4.Zero);
|
||||
|
||||
ImGui.SetCursorPos(newPos);
|
||||
Im.Cursor.Position = newPos;
|
||||
if (ImEx.Icon.Button(LunaStyle.FavoriteIcon))
|
||||
_modManager.DataEditor.ChangeModFavorite(mod, !mod.Favorite);
|
||||
|
||||
|
|
@ -151,6 +96,6 @@ public class ModPanelTabBar : IUiService
|
|||
_tutorial.OpenTutorial(BasicTutorialSteps.Favorites);
|
||||
|
||||
if (hovered)
|
||||
ImGui.SetTooltip("Favorite");
|
||||
Im.Tooltip.Set("Favorite"u8);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using Dalamud.Bindings.ImGui;
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using ImSharp;
|
||||
using OtterGui.Widgets;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Actors;
|
||||
|
|
@ -16,7 +16,7 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.ResourceWatcher;
|
||||
|
||||
public sealed class ResourceWatcher : IDisposable, ITab, Luna.IUiService
|
||||
public sealed class ResourceWatcher : IDisposable, ITab<TabType>
|
||||
{
|
||||
public const int DefaultMaxEntries = 1024;
|
||||
public const RecordType AllRecords = RecordType.Request | RecordType.ResourceLoad | RecordType.FileLoad | RecordType.Destruction;
|
||||
|
|
@ -96,6 +96,9 @@ public sealed class ResourceWatcher : IDisposable, ITab, Luna.IUiService
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Resource Logger"u8;
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.ResourceWatcher;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
UpdateRecords();
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@ using Dalamud.Bindings.ImGui;
|
|||
using Dalamud.Interface;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Table;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.String;
|
||||
|
|
@ -54,16 +51,16 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
=> DrawByteString(item.Path, 280 * Im.Style.GlobalScale);
|
||||
}
|
||||
|
||||
private static unsafe void DrawByteString(CiByteString path, float length)
|
||||
private static void DrawByteString(CiByteString path, float length)
|
||||
{
|
||||
if (path.IsEmpty)
|
||||
return;
|
||||
|
||||
var size = ImUtf8.CalcTextSize(path.Span);
|
||||
var size = Im.Font.CalculateSize(path.Span);
|
||||
var clicked = false;
|
||||
if (size.X <= length)
|
||||
{
|
||||
clicked = ImUtf8.Selectable(path.Span);
|
||||
clicked = Im.Selectable(path.Span);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -71,10 +68,11 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
using (Im.Group())
|
||||
{
|
||||
CiByteString shortPath;
|
||||
if (fileName != -1)
|
||||
var icon = FontAwesomeIcon.EllipsisH.Icon();
|
||||
if (fileName is not -1)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
clicked = ImUtf8.Selectable(FontAwesomeIcon.EllipsisH.ToIconString());
|
||||
using var font = AwesomeIcon.Font.Push();
|
||||
clicked = Im.Selectable(icon.Span);
|
||||
Im.Line.SameInner();
|
||||
shortPath = path.Substring(fileName, path.Length - fileName);
|
||||
}
|
||||
|
|
@ -83,14 +81,14 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
shortPath = path;
|
||||
}
|
||||
|
||||
clicked |= ImUtf8.Selectable(shortPath.Span, false, ImGuiSelectableFlags.AllowItemOverlap);
|
||||
clicked |= Im.Selectable(shortPath.Span, false, SelectableFlags.AllowOverlap);
|
||||
}
|
||||
|
||||
Im.Tooltip.OnHover(path.Span);
|
||||
}
|
||||
|
||||
if (clicked)
|
||||
ImUtf8.SetClipboardText(path.Span);
|
||||
Im.Clipboard.Set(path.Span);
|
||||
}
|
||||
|
||||
private sealed class RecordTypeColumn : ColumnFlags<RecordType, Record>
|
||||
|
|
@ -153,13 +151,13 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
public override float Width
|
||||
=> UiBuilder.MonoFont.GetCharAdvance('0') * 17;
|
||||
|
||||
public override unsafe string ToName(Record item)
|
||||
=> item.Crc64 != 0 ? $"{item.Crc64:X16}" : string.Empty;
|
||||
public override string ToName(Record item)
|
||||
=> item.Crc64 is not 0 ? $"{item.Crc64:X16}" : string.Empty;
|
||||
|
||||
public override unsafe void DrawColumn(Record item, int _)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont, item.Handle != null);
|
||||
ImUtf8.Text(ToName(item));
|
||||
using var font = item.Handle is null ? null : Im.Font.PushMono();
|
||||
Im.Text(ToName(item));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,17 +332,17 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
var (icon, color, tt) = item.LoadState switch
|
||||
{
|
||||
LoadState.Success => (FontAwesomeIcon.CheckCircle, ColorId.IncreasedMetaValue.Value(),
|
||||
$"Successfully loaded ({(byte)item.LoadState})."),
|
||||
new StringU8($"Successfully loaded ({(byte)item.LoadState}).")),
|
||||
LoadState.FailedSubResource => (FontAwesomeIcon.ExclamationCircle, ColorId.DecreasedMetaValue.Value(),
|
||||
$"Dependencies failed to load ({(byte)item.LoadState})."),
|
||||
new StringU8($"Dependencies failed to load ({(byte)item.LoadState}).")),
|
||||
<= LoadState.Constructed => (FontAwesomeIcon.QuestionCircle, ColorId.UndefinedMod.Value(),
|
||||
$"Not yet loaded ({(byte)item.LoadState})."),
|
||||
< LoadState.Success => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), $"Loading asynchronously ({(byte)item.LoadState})."),
|
||||
new StringU8($"Not yet loaded ({(byte)item.LoadState}).")),
|
||||
< LoadState.Success => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), new StringU8($"Loading asynchronously ({(byte)item.LoadState}).")),
|
||||
> LoadState.Success => (FontAwesomeIcon.Times, ColorId.DecreasedMetaValue.Value(),
|
||||
$"Failed to load ({(byte)item.LoadState})."),
|
||||
new StringU8($"Failed to load ({(byte)item.LoadState}).")),
|
||||
};
|
||||
ImEx.Icon.Draw(icon.Icon(), color);
|
||||
ImGuiUtil.HoverTooltip(tt);
|
||||
Im.Tooltip.OnHover(tt);
|
||||
}
|
||||
|
||||
public override int Compare(Record lhs, Record rhs)
|
||||
|
|
@ -361,8 +359,8 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
|
||||
public override unsafe void DrawColumn(Record item, int _)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont, item.Handle != null);
|
||||
ImGuiUtil.RightAlign(ToName(item));
|
||||
using var font = item.Handle is null ? null : Im.Font.PushMono();
|
||||
ImEx.TextRightAligned(ToName(item));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +445,7 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
=> 30 * Im.Style.GlobalScale;
|
||||
|
||||
public override void DrawColumn(Record item, int _)
|
||||
=> ImGuiUtil.RightAlign(item.RefCount.ToString());
|
||||
=> ImEx.TextRightAligned($"{item.RefCount}");
|
||||
|
||||
public override int Compare(Record lhs, Record rhs)
|
||||
=> lhs.RefCount.CompareTo(rhs.RefCount);
|
||||
|
|
@ -462,7 +460,7 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
=> item.OsThreadId.ToString();
|
||||
|
||||
public override void DrawColumn(Record item, int _)
|
||||
=> ImGuiUtil.RightAlign(ToName(item));
|
||||
=> ImEx.TextRightAligned($"{item.OsThreadId}");
|
||||
|
||||
public override int Compare(Record lhs, Record rhs)
|
||||
=> lhs.OsThreadId.CompareTo(rhs.OsThreadId);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
|
|
@ -15,16 +15,19 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class ChangedItemsTab(
|
||||
public sealed class ChangedItemsTab(
|
||||
CollectionManager collectionManager,
|
||||
CollectionSelectHeader collectionHeader,
|
||||
ChangedItemDrawer drawer,
|
||||
CommunicatorService communicator)
|
||||
: ITab, Luna.IUiService
|
||||
: ITab<TabType>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Changed Items"u8;
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.ChangedItems;
|
||||
|
||||
private string _changedItemFilter = string.Empty;
|
||||
private string _changedItemModFilter = string.Empty;
|
||||
private Vector2 _buttonSize;
|
||||
|
|
@ -105,7 +108,7 @@ public class ChangedItemsTab(
|
|||
if (ImUtf8.Selectable(first.Name, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 })
|
||||
&& ImGui.GetIO().KeyCtrl
|
||||
&& first is Mod mod)
|
||||
communicator.SelectTab.Invoke(new SelectTab.Arguments(TabType.Mods, mod));
|
||||
communicator.SelectTab.Invoke(new SelectTab.Arguments(Api.Enums.TabType.Mods, mod));
|
||||
|
||||
if (!Im.Item.Hovered())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ using Dalamud.Bindings.ImGui;
|
|||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Plugin;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
|
@ -12,7 +13,7 @@ using Penumbra.UI.CollectionTab;
|
|||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public sealed class CollectionsTab : IDisposable, ITab, Luna.IUiService
|
||||
public sealed class CollectionsTab : ITab<TabType>, IDisposable
|
||||
{
|
||||
private readonly EphemeralConfig _config;
|
||||
private readonly CollectionSelector _selector;
|
||||
|
|
@ -38,6 +39,9 @@ public sealed class CollectionsTab : IDisposable, ITab, Luna.IUiService
|
|||
}
|
||||
}
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.Collections;
|
||||
|
||||
public CollectionsTab(IDalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator, IncognitoService incognito,
|
||||
CollectionManager collectionManager, ModStorage modStorage, ActorManager actors, ITargetManager targets, TutorialService tutorial, SaveService saveService)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Tabs.Debug;
|
||||
using Watcher = Penumbra.UI.ResourceWatcher.ResourceWatcher;
|
||||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class ConfigTabBar : IDisposable, Luna.IUiService
|
||||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
|
||||
public readonly SettingsTab Settings;
|
||||
public readonly ModsTab Mods;
|
||||
public readonly CollectionsTab Collections;
|
||||
public readonly ChangedItemsTab ChangedItems;
|
||||
public readonly EffectiveTab Effective;
|
||||
public readonly DebugTab Debug;
|
||||
public readonly ResourceTab Resource;
|
||||
public readonly Watcher Watcher;
|
||||
public readonly OnScreenTab OnScreen;
|
||||
public readonly MessagesTab Messages;
|
||||
|
||||
public readonly ITab[] Tabs;
|
||||
|
||||
/// <summary> The tab to select on the next Draw call, if any. </summary>
|
||||
public TabType SelectTab = TabType.None;
|
||||
|
||||
public ConfigTabBar(CommunicatorService communicator, SettingsTab settings, ModsTab mods, CollectionsTab collections,
|
||||
ChangedItemsTab changedItems, EffectiveTab effective, DebugTab debug, ResourceTab resource, Watcher watcher,
|
||||
OnScreenTab onScreen, MessagesTab messages)
|
||||
{
|
||||
_communicator = communicator;
|
||||
|
||||
Settings = settings;
|
||||
Mods = mods;
|
||||
Collections = collections;
|
||||
ChangedItems = changedItems;
|
||||
Effective = effective;
|
||||
Debug = debug;
|
||||
Resource = resource;
|
||||
Watcher = watcher;
|
||||
OnScreen = onScreen;
|
||||
Messages = messages;
|
||||
Tabs =
|
||||
[
|
||||
Settings,
|
||||
Collections,
|
||||
Mods,
|
||||
ChangedItems,
|
||||
Effective,
|
||||
OnScreen,
|
||||
Debug,
|
||||
Resource,
|
||||
Watcher,
|
||||
Messages,
|
||||
];
|
||||
_communicator.SelectTab.Subscribe(OnSelectTab, Communication.SelectTab.Priority.ConfigTabBar);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _communicator.SelectTab.Unsubscribe(OnSelectTab);
|
||||
|
||||
public TabType Draw()
|
||||
{
|
||||
if (TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(SelectTab), out var currentLabel, () => { }, Tabs))
|
||||
SelectTab = TabType.None;
|
||||
|
||||
return FromLabel(currentLabel);
|
||||
}
|
||||
|
||||
private ReadOnlySpan<byte> ToLabel(TabType type)
|
||||
=> type switch
|
||||
{
|
||||
TabType.Settings => Settings.Label,
|
||||
TabType.Mods => Mods.Label,
|
||||
TabType.Collections => Collections.Label,
|
||||
TabType.ChangedItems => ChangedItems.Label,
|
||||
TabType.EffectiveChanges => Effective.Label,
|
||||
TabType.OnScreen => OnScreen.Label,
|
||||
TabType.ResourceWatcher => Watcher.Label,
|
||||
TabType.Debug => Debug.Label,
|
||||
TabType.ResourceManager => Resource.Label,
|
||||
TabType.Messages => Messages.Label,
|
||||
_ => ReadOnlySpan<byte>.Empty,
|
||||
};
|
||||
|
||||
private TabType FromLabel(ReadOnlySpan<byte> label)
|
||||
{
|
||||
// @formatter:off
|
||||
if (label == Mods.Label) return TabType.Mods;
|
||||
if (label == Collections.Label) return TabType.Collections;
|
||||
if (label == Settings.Label) return TabType.Settings;
|
||||
if (label == ChangedItems.Label) return TabType.ChangedItems;
|
||||
if (label == Effective.Label) return TabType.EffectiveChanges;
|
||||
if (label == OnScreen.Label) return TabType.OnScreen;
|
||||
if (label == Messages.Label) return TabType.Messages;
|
||||
if (label == Watcher.Label) return TabType.ResourceWatcher;
|
||||
if (label == Debug.Label) return TabType.Debug;
|
||||
if (label == Resource.Label) return TabType.ResourceManager;
|
||||
// @formatter:on
|
||||
return TabType.None;
|
||||
}
|
||||
|
||||
private void OnSelectTab(in SelectTab.Arguments arguments)
|
||||
{
|
||||
SelectTab = arguments.Tab;
|
||||
if (arguments.Mod is not null)
|
||||
Mods.SelectMod = arguments.Mod;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,8 +14,8 @@ using Luna;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OtterGui;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.DataContainers;
|
||||
|
|
@ -67,7 +67,7 @@ public class Diagnostics(ServiceManager provider) : IUiService
|
|||
}
|
||||
}
|
||||
|
||||
public class DebugTab : Window, ITab
|
||||
public sealed class DebugTab : Window, ITab<TabType>
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly CollectionManager _collectionManager;
|
||||
|
|
@ -173,6 +173,9 @@ public class DebugTab : Window, ITab
|
|||
public bool IsVisible
|
||||
=> _config is { DebugMode: true, Ephemeral.DebugSeparateWindow: false };
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.Debug;
|
||||
|
||||
#if DEBUG
|
||||
private const string DebugVersionString = "(Debug)";
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Cache;
|
||||
using Penumbra.Collections.Manager;
|
||||
|
|
@ -15,12 +16,15 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class EffectiveTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader)
|
||||
: ITab, Luna.IUiService
|
||||
public sealed class EffectiveTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader)
|
||||
: ITab<TabType>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Effective Changes"u8;
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.EffectiveChanges;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
SetupEffectiveSizes();
|
||||
|
|
|
|||
55
Penumbra/UI/Tabs/MainTabBar.cs
Normal file
55
Penumbra/UI/Tabs/MainTabBar.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Tabs.Debug;
|
||||
using Watcher = Penumbra.UI.ResourceWatcher.ResourceWatcher;
|
||||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public sealed class MainTabBar : TabBar<TabType>, IDisposable
|
||||
{
|
||||
public readonly ModsTab Mods;
|
||||
private readonly EphemeralConfig _config;
|
||||
private readonly SelectTab _selectTab;
|
||||
|
||||
public MainTabBar(Logger log,
|
||||
SettingsTab settings,
|
||||
ModsTab mods,
|
||||
CollectionsTab collections,
|
||||
ChangedItemsTab changedItems,
|
||||
EffectiveTab effectiveChanges,
|
||||
DebugTab debug,
|
||||
ResourceTab resources,
|
||||
Watcher watcher,
|
||||
OnScreenTab onScreen,
|
||||
MessagesTab messages, EphemeralConfig config, CommunicatorService communicator)
|
||||
: base(nameof(MainTabBar), log, settings, collections, mods, changedItems, effectiveChanges, onScreen,
|
||||
resources, watcher, debug, messages)
|
||||
{
|
||||
Mods = mods;
|
||||
_config = config;
|
||||
_selectTab = communicator.SelectTab;
|
||||
|
||||
_selectTab.Subscribe(OnSelectTab, SelectTab.Priority.MainTabBar);
|
||||
TabSelected.Subscribe(OnTabSelected, 0);
|
||||
}
|
||||
|
||||
private void OnSelectTab(in SelectTab.Arguments arguments)
|
||||
{
|
||||
NextTab = arguments.Tab;
|
||||
if (arguments.Mod is not null)
|
||||
Mods.SelectMod = arguments.Mod;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_selectTab.Unsubscribe(OnSelectTab);
|
||||
}
|
||||
|
||||
private void OnTabSelected(in TabType type)
|
||||
{
|
||||
_config.SelectedTab = type;
|
||||
_config.Save();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
using OtterGui.Widgets;
|
||||
using Penumbra.Services;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using MessageService = Penumbra.Services.MessageService;
|
||||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class MessagesTab(MessageService messages) : ITab, Luna.IUiService
|
||||
public sealed class MessagesTab(MessageService messages) : ITab<TabType>
|
||||
{
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Messages"u8;
|
||||
|
|
@ -13,4 +14,7 @@ public class MessagesTab(MessageService messages) : ITab, Luna.IUiService
|
|||
|
||||
public void DrawContent()
|
||||
=> messages.DrawNotificationLog();
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.Messages;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Dalamud.Interface;
|
|||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using ImSharp;
|
||||
using OtterGui.Widgets;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Mods;
|
||||
|
|
@ -19,7 +19,7 @@ using Penumbra.GameData.Interop;
|
|||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class ModsTab(
|
||||
public sealed class ModsTab(
|
||||
ModManager modManager,
|
||||
CollectionManager collectionManager,
|
||||
ModFileSystemSelector selector,
|
||||
|
|
@ -31,7 +31,7 @@ public class ModsTab(
|
|||
CollectionSelectHeader collectionHeader,
|
||||
ITargetManager targets,
|
||||
ObjectManager objects)
|
||||
: ITab, Luna.IUiService
|
||||
: ITab<TabType>
|
||||
{
|
||||
private readonly ActiveCollections _activeCollections = collectionManager.Active;
|
||||
|
||||
|
|
@ -41,7 +41,10 @@ public class ModsTab(
|
|||
public ReadOnlySpan<byte> Label
|
||||
=> "Mods"u8;
|
||||
|
||||
public void DrawHeader()
|
||||
public TabType Identifier
|
||||
=> TabType.Mods;
|
||||
|
||||
public void PostTabButton()
|
||||
=> tutorial.OpenTutorial(BasicTutorialSteps.Mods);
|
||||
|
||||
public Mod SelectMod
|
||||
|
|
@ -60,7 +63,8 @@ public class ModsTab(
|
|||
collectionHeader.Draw(false);
|
||||
|
||||
using var style = ImStyleDouble.ItemSpacing.Push(Vector2.Zero);
|
||||
using (var child = ImRaii.Child("##ModsTabMod", Im.ContentRegion.Available with { Y = config.HideRedrawBar ? 0 : -Im.Style.FrameHeight },
|
||||
using (var child = ImRaii.Child("##ModsTabMod",
|
||||
Im.ContentRegion.Available with { Y = config.HideRedrawBar ? 0 : -Im.Style.FrameHeight },
|
||||
true, ImGuiWindowFlags.HorizontalScrollbar))
|
||||
{
|
||||
style.Pop();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
using OtterGui.Widgets;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class OnScreenTab(ResourceTreeViewerFactory resourceTreeViewerFactory) : ITab, Luna.IUiService
|
||||
public sealed class OnScreenTab(ResourceTreeViewerFactory resourceTreeViewerFactory) : ITab<TabType>
|
||||
{
|
||||
private readonly ResourceTreeViewer _viewer = resourceTreeViewerFactory.Create(0, delegate { }, delegate { });
|
||||
|
||||
|
|
@ -12,4 +13,7 @@ public class OnScreenTab(ResourceTreeViewerFactory resourceTreeViewerFactory) :
|
|||
|
||||
public void DrawContent()
|
||||
=> _viewer.Draw();
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.OnScreen;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,17 +4,21 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.STD;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Interop.Hooks.ResourceLoading;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class ResourceTab(Configuration config, ResourceManagerService resourceManager, ISigScanner sigScanner)
|
||||
: ITab, Luna.IUiService
|
||||
public sealed class ResourceTab(Configuration config, ResourceManagerService resourceManager, ISigScanner sigScanner)
|
||||
: ITab<TabType>
|
||||
{
|
||||
public TabType Identifier
|
||||
=> TabType.ResourceManager;
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Resource Manager"u8;
|
||||
|
||||
|
|
@ -52,7 +56,8 @@ public class ResourceTab(Configuration config, ResourceManagerService resourceMa
|
|||
private string _resourceManagerFilter = string.Empty;
|
||||
|
||||
/// <summary> Draw a single resource map. </summary>
|
||||
private unsafe void DrawResourceMap(ResourceCategory category, uint ext, StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>* map)
|
||||
private unsafe void DrawResourceMap(ResourceCategory category, uint ext,
|
||||
StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>* map)
|
||||
{
|
||||
if (map == null)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
|
|
@ -12,6 +11,7 @@ using OtterGui.Raii;
|
|||
using OtterGui.Text;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Interop.Hooks.PostProcessing;
|
||||
|
|
@ -23,10 +23,13 @@ using Penumbra.UI.ModsTab;
|
|||
|
||||
namespace Penumbra.UI.Tabs;
|
||||
|
||||
public class SettingsTab : ITab, IUiService
|
||||
public sealed class SettingsTab : ITab<TabType>
|
||||
{
|
||||
public const int RootDirectoryMaxLength = 64;
|
||||
|
||||
public TabType Identifier
|
||||
=> TabType.Settings;
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Settings"u8;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue