Initial release: HSUI v1.0.0.0 - HUD replacement with configurable hotbars

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-01-30 23:52:46 -05:00
commit f37369cdda
202 changed files with 40137 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using Dalamud.Interface;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Logging;
using HSUI.Config;
using HSUI.Interface.GeneralElements;
using Dalamud.Bindings.ImGui;
namespace HSUI.Helpers
{
public struct BarTextureData
{
public string Name;
public string Path;
public bool IsCustom;
public BarTextureData(string name, string path, bool isCustom)
{
Name = name;
Path = path;
IsCustom = isCustom;
}
}
public class BarTexturesManager : IDisposable
{
#region Singleton
private BarTexturesManager(string basePath)
{
DefaultBarTexturesPath = Path.GetDirectoryName(basePath) + "\\Media\\Images\\textures\\";
}
public static void Initialize(string basePath)
{
Instance = new BarTexturesManager(basePath);
}
public static BarTexturesManager Instance { get; private set; } = null!;
private BarTexturesConfig? _config;
public void LoadConfig()
{
if (_config != null)
{
return;
}
_config = ConfigurationManager.Instance.GetConfigObject<BarTexturesConfig>();
ConfigurationManager.Instance.ResetEvent += OnConfigReset;
ReloadTextures();
}
private void OnConfigReset(ConfigurationManager sender)
{
_config = sender.GetConfigObject<BarTexturesConfig>();
}
~BarTexturesManager()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
ConfigurationManager.Instance.ResetEvent -= OnConfigReset;
Instance = null!;
}
#endregion
public readonly string DefaultBarTexturesPath;
public static readonly string DefaultBarTextureName = "Default";
public bool DefaultFontBuilt { get; private set; }
public ImFontPtr DefaultFont { get; private set; } = null;
private List<BarTextureData> _textures = new List<BarTextureData>();
public IReadOnlyCollection<BarTextureData> BarTextures => _textures.AsReadOnly();
private List<string> _textureNames = new List<string>();
public IReadOnlyCollection<string> BarTextureNames => _textureNames.AsReadOnly();
private Dictionary<string, ISharedImmediateTexture> _cache = new();
public IDalamudTextureWrap? GetBarTexture(string? name)
{
if (name == null || name == DefaultBarTextureName) { return null; }
// get cached texture
if (_cache.TryGetValue(name, out ISharedImmediateTexture? cachedTexture) && cachedTexture != null)
{
return cachedTexture.GetWrapOrDefault();
}
// lazy load
BarTextureData? data = _textures.FirstOrDefault(o => o.Name == name);
if (!data.HasValue) { return null; }
if (File.Exists(data.Value.Path))
{
try
{
ISharedImmediateTexture? texture = Plugin.TextureProvider.GetFromFile(data.Value.Path);
if (texture != null)
{
_cache.Add(name, texture);
}
return texture?.GetWrapOrDefault();
}
catch
(Exception ex)
{
Plugin.Logger.Warning($"Image failed to load. {data.Value.Path}: " + ex.Message);
}
}
return null;
}
public void ReloadTextures()
{
_textures.Clear();
// embedded textures
_textures.AddRange(TexturesFromPath(DefaultBarTexturesPath, true));
// custom textures
if (_config != null)
{
_textures.AddRange(TexturesFromPath(_config.ValidatedBarTexturesPath, true));
}
// sort by name
_textures = _textures.OrderBy(o => o.Name).ToList();
// default always first
_textures.Insert(0, new BarTextureData(DefaultBarTextureName, "", false));
_textureNames = _textures.Select(o => o.Name).ToList();
}
private List<BarTextureData> TexturesFromPath(string path, bool isCustom)
{
string[] textures;
try
{
string[] allowedExtensions = new string[] { ".png", ".tga" };
textures = Directory
.GetFiles(path)
.Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
.ToArray();
}
catch
{
textures = new string[0];
}
List<BarTextureData> result = new List<BarTextureData>(textures.Length);
for (int i = 0; i < textures.Length; i++)
{
string name = SanitizedTextureName(textures[i].Replace(path, ""));
result.Add(new BarTextureData(name, textures[i], isCustom));
}
return result;
}
private string SanitizedTextureName(string name)
{
return name
.Replace(".png", "")
.Replace(".PNG", "")
.Replace(".tga", "")
.Replace(".TGA", "");
}
}
}