Compare commits

...

3 Commits

12 changed files with 120 additions and 120 deletions
-1
View File
@@ -724,7 +724,6 @@ namespace HSUI.Config
// Visibility // Visibility
typeof(GlobalVisibilityConfig), typeof(GlobalVisibilityConfig),
typeof(HotbarsVisibilityConfig),
// Misc // Misc
typeof(HUDOptionsConfig), typeof(HUDOptionsConfig),
+3 -3
View File
@@ -9,9 +9,9 @@
<PropertyGroup> <PropertyGroup>
<AssemblyName>HSUI</AssemblyName> <AssemblyName>HSUI</AssemblyName>
<AssemblyVersion>1.0.8.17</AssemblyVersion> <AssemblyVersion>1.0.8.20</AssemblyVersion>
<FileVersion>1.0.8.17</FileVersion> <FileVersion>1.0.8.20</FileVersion>
<InformationalVersion>1.0.8.17</InformationalVersion> <InformationalVersion>1.0.8.20</InformationalVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
+1 -1
View File
@@ -2,7 +2,7 @@
"Author": "Knack117", "Author": "Knack117",
"Name": "HSUI", "Name": "HSUI",
"InternalName": "HSUI", "InternalName": "HSUI",
"AssemblyVersion": "1.0.8.17", "AssemblyVersion": "1.0.8.20",
"Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.", "Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.",
"ApplicableVersion": "any", "ApplicableVersion": "any",
"RepoUrl": "https://github.com/Knack117/HSUI", "RepoUrl": "https://github.com/Knack117/HSUI",
+51
View File
@@ -1,3 +1,4 @@
using Dalamud.Game.ClientState.Conditions;
using HSUI.Config; using HSUI.Config;
using HSUI.Interface.GeneralElements; using HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
@@ -335,6 +336,56 @@ namespace HSUI.Helpers
return null; return null;
} }
/// <summary>
/// Returns true when the given area overlaps a game addon (e.g. dialogue box) and should not be drawn on top of it.
/// Used by hotbars when "Show HUD during dialogue" is on, to avoid cooldown overlays bleeding through dialogue.
/// Uses full clip rects when Window Clipping is enabled, otherwise a minimal dialogue-addon check.
/// </summary>
public bool SlotOverlapsGameAddon(Vector2 pos, Vector2 size)
{
// When Window Clipping is enabled, use full clip rects (all game addons)
ClipRect? clipRect = GetClipRectForArea(pos, size);
if (clipRect.HasValue) { return true; }
// When "Show HUD during dialogue" is on and we're in dialogue, check dialogue addons
// (works even when full Window Clipping is disabled)
var hudOptions = ConfigurationManager.Instance?.GetConfigObject<HUDOptionsConfig>();
if (hudOptions?.ShowHudDuringDialogue != true) { return false; }
if (!Plugin.Condition[ConditionFlag.OccupiedInQuestEvent] && !Plugin.Condition[ConditionFlag.OccupiedInEvent])
{ return false; }
return GetClipRectForDialogueAddon(pos, size).HasValue;
}
private static readonly string[] _dialogueAddonNames = { "Talk", "SelectString", "SelectIconString", "Journal" };
private unsafe ClipRect? GetClipRectForDialogueAddon(Vector2 pos, Vector2 size)
{
ClipRect area = new ClipRect(pos, pos + size);
foreach (string addonName in _dialogueAddonNames)
{
try
{
var addon = (AtkUnitBase*)Plugin.GameGui.GetAddonByName(addonName, 1).Address;
if (addon == null || addon->RootNode == null || !addon->IsVisible) { continue; }
float margin = 5 * addon->Scale;
Vector2 addonPos = new Vector2(addon->X + addon->RootNode->X * addon->Scale + margin,
addon->Y + addon->RootNode->Y * addon->Scale + margin);
Vector2 addonSize = new Vector2(
addon->RootNode->Width * addon->Scale - margin * 2,
addon->RootNode->Height * addon->Scale - margin * 2);
ClipRect addonRect = new ClipRect(addonPos, addonPos + addonSize);
if (addonRect.IntersectsWith(area)) { return addonRect; }
}
catch { }
}
return null;
}
public static ClipRect[] GetInvertedClipRects(ClipRect clipRect) public static ClipRect[] GetInvertedClipRects(ClipRect clipRect)
{ {
float maxX = ImGui.GetMainViewport().Size.X; float maxX = ImGui.GetMainViewport().Size.X;
+7
View File
@@ -256,6 +256,13 @@ namespace HSUI.Interface
{ {
return (new List<Vector2>(), new List<Vector2>()); return (new List<Vector2>(), new List<Vector2>());
} }
/// <summary>Returns the screen-space bounding box of the element for hover detection (e.g. visibility "hide unless hovered").</summary>
public virtual (Vector2 min, Vector2 max) GetScreenBounds(Vector2 origin)
{
var basePos = origin + ParentPos();
return (basePos + MinPos, basePos + MaxPos);
}
#endregion #endregion
} }
+15 -20
View File
@@ -72,19 +72,9 @@ namespace HSUI.Interface.GeneralElements
} }
/// <summary> /// <summary>
/// Visibility for HSUI Action Bars is driven by Visibility → Hotbars (Hotbar 110), not the per-element config. /// Visibility for HSUI Action Bars is configured per hotbar in each Hotbar 110 menu.
/// </summary> /// </summary>
public VisibilityConfig VisibilityConfig => GetHotbarVisibilityConfig(); public VisibilityConfig VisibilityConfig => Config.VisibilityConfig;
private VisibilityConfig GetHotbarVisibilityConfig()
{
var hotbars = ConfigurationManager.Instance?.GetConfigObject<HotbarsVisibilityConfig>();
if (hotbars == null) return Config.VisibilityConfig;
var list = hotbars.GetHotbarConfigs();
int idx = Config.HotbarIndex - 1;
if (idx < 0 || idx >= list.Count) return Config.VisibilityConfig;
return list[idx];
}
public IGameObject? Actor { get; set; } public IGameObject? Actor { get; set; }
@@ -187,15 +177,20 @@ namespace HSUI.Interface.GeneralElements
if (showCd && slot.CooldownPercent > 0 && _pendingSlotIconIndex != i) if (showCd && slot.CooldownPercent > 0 && _pendingSlotIconIndex != i)
{ {
float total = 100f; // Skip cooldown overlay when slot overlaps game UI (e.g. dialogue box)
float elapsed = total - slot.CooldownPercent; // to avoid hotbar cooldowns showing through during "Show HUD during dialogue"
DrawHelper.DrawIconCooldown(pos, size, elapsed, total, drawList); if (!ClipRectsHelper.Instance.SlotOverlapsGameAddon(pos, size))
if (showCdNumbers && slot.CooldownSecondsLeft > 0)
{ {
string cdText = slot.CooldownSecondsLeft.ToString(); float total = 100f;
Vector2 textSize = ImGui.CalcTextSize(cdText); float elapsed = total - slot.CooldownPercent;
Vector2 textPos = pos + (size - textSize) * 0.5f; DrawHelper.DrawIconCooldown(pos, size, elapsed, total, drawList);
DrawHelper.DrawOutlinedText(cdText, textPos, 0xFFFFFFFF, 0xFF000000, drawList, 1); if (showCdNumbers && slot.CooldownSecondsLeft > 0)
{
string cdText = slot.CooldownSecondsLeft.ToString();
Vector2 textSize = ImGui.CalcTextSize(cdText);
Vector2 textPos = pos + (size - textSize) * 0.5f;
DrawHelper.DrawOutlinedText(cdText, textPos, 0xFFFFFFFF, 0xFF000000, drawList, 1);
}
} }
} }
+13 -8
View File
@@ -317,15 +317,20 @@ namespace HSUI.Interface.GeneralElements
if (showCd && slot.CooldownPercent > 0 && _pendingSlotIconIndex != i) if (showCd && slot.CooldownPercent > 0 && _pendingSlotIconIndex != i)
{ {
float total = 100f; // Skip cooldown overlay when slot overlaps game UI (e.g. dialogue box)
float elapsed = total - slot.CooldownPercent; // to avoid hotbar cooldowns showing through during "Show HUD during dialogue"
DrawHelper.DrawIconCooldown(pos, size, elapsed, total, drawList); if (!ClipRectsHelper.Instance.SlotOverlapsGameAddon(pos, size))
if (showCdNumbers && slot.CooldownSecondsLeft > 0)
{ {
string cdText = slot.CooldownSecondsLeft.ToString(); float total = 100f;
Vector2 textSize = ImGui.CalcTextSize(cdText); float elapsed = total - slot.CooldownPercent;
Vector2 textPos = pos + (size - textSize) * 0.5f; DrawHelper.DrawIconCooldown(pos, size, elapsed, total, drawList);
DrawHelper.DrawOutlinedText(cdText, textPos, 0xFFFFFFFF, 0xFF000000, drawList, 1); if (showCdNumbers && slot.CooldownSecondsLeft > 0)
{
string cdText = slot.CooldownSecondsLeft.ToString();
Vector2 textSize = ImGui.CalcTextSize(cdText);
Vector2 textPos = pos + (size - textSize) * 0.5f;
DrawHelper.DrawOutlinedText(cdText, textPos, 0xFFFFFFFF, 0xFF000000, drawList, 1);
}
} }
} }
+1 -15
View File
@@ -153,23 +153,9 @@ namespace HSUI.Interface.GeneralElements
{ {
if (bar == null) continue; if (bar == null) continue;
bar.Enabled = true; bar.Enabled = true;
bar.VisibilityConfig.CopyFrom(new VisibilityConfig());
HotbarBarConfig.ApplyDefaults(bar, idx); HotbarBarConfig.ApplyDefaults(bar, idx);
} }
var vis = cfg.GetConfigObject<HotbarsVisibilityConfig>();
if (vis != null)
{
var defaults = new VisibilityConfig();
vis.HotbarConfig1.CopyFrom(defaults);
vis.HotbarConfig2.CopyFrom(defaults);
vis.HotbarConfig3.CopyFrom(defaults);
vis.HotbarConfig4.CopyFrom(defaults);
vis.HotbarConfig5.CopyFrom(defaults);
vis.HotbarConfig6.CopyFrom(defaults);
vis.HotbarConfig7.CopyFrom(defaults);
vis.HotbarConfig8.CopyFrom(defaults);
vis.HotbarConfig9.CopyFrom(defaults);
vis.HotbarConfig10.CopyFrom(defaults);
}
} }
} }
@@ -1,71 +0,0 @@
using HSUI.Config;
using HSUI.Config.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HSUI.Interface.GeneralElements
{
[Disableable(false)]
[Exportable(false)]
[Section("Visibility")]
[SubSection("Hotbars", 0)]
public class HotbarsVisibilityConfig : PluginConfigObject
{
public new static HotbarsVisibilityConfig DefaultConfig() { return new HotbarsVisibilityConfig(); }
[NestedConfig("Hotbar 1", 50)]
public VisibilityConfig HotbarConfig1 = new VisibilityConfig();
[NestedConfig("Hotbar 2", 51)]
public VisibilityConfig HotbarConfig2 = new VisibilityConfig();
[NestedConfig("Hotbar 3", 52)]
public VisibilityConfig HotbarConfig3 = new VisibilityConfig();
[NestedConfig("Hotbar 4", 53)]
public VisibilityConfig HotbarConfig4 = new VisibilityConfig();
[NestedConfig("Hotbar 5", 54)]
public VisibilityConfig HotbarConfig5 = new VisibilityConfig();
[NestedConfig("Hotbar 6", 55)]
public VisibilityConfig HotbarConfig6 = new VisibilityConfig();
[NestedConfig("Hotbar 7", 56)]
public VisibilityConfig HotbarConfig7 = new VisibilityConfig();
[NestedConfig("Hotbar 8", 57)]
public VisibilityConfig HotbarConfig8 = new VisibilityConfig();
[NestedConfig("Hotbar 9", 58)]
public VisibilityConfig HotbarConfig9 = new VisibilityConfig();
[NestedConfig("Hotbar 10", 59)]
public VisibilityConfig HotbarConfig10 = new VisibilityConfig();
[NestedConfig("Cross Hotbar", 60)]
public VisibilityConfig HotbarConfigCross = new VisibilityConfig();
private List<VisibilityConfig> _configs;
public List<VisibilityConfig> GetHotbarConfigs() => _configs;
public HotbarsVisibilityConfig()
{
_configs = new List<VisibilityConfig>() {
HotbarConfig1,
HotbarConfig2,
HotbarConfig3,
HotbarConfig4,
HotbarConfig5,
HotbarConfig6,
HotbarConfig7,
HotbarConfig8,
HotbarConfig9,
HotbarConfig10
};
}
}
}
@@ -1,3 +1,4 @@
using Dalamud.Bindings.ImGui;
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
@@ -6,12 +7,17 @@ using HSUI.Config.Attributes;
using HSUI.Interface.GeneralElements; using HSUI.Interface.GeneralElements;
using HSUI.Interface.Party; using HSUI.Interface.Party;
using System.Linq; using System.Linq;
using System.Numerics;
namespace HSUI.Interface namespace HSUI.Interface
{ {
[Exportable(false)] [Exportable(false)]
public class VisibilityConfig : PluginConfigObject public class VisibilityConfig : PluginConfigObject
{ {
[Checkbox("Hide unless hovered", help = "When enabled, the element is hidden until the cursor hovers over it. Requires HUD to be locked.")]
[Order(4)]
public bool HideUnlessHovered = false;
[Checkbox("Hide outside of combat")] [Checkbox("Hide outside of combat")]
[Order(5)] [Order(5)]
public bool HideOutsideOfCombat = false; public bool HideOutsideOfCombat = false;
@@ -96,6 +102,18 @@ namespace HSUI.Interface
if (element != null && element.GetType() == typeof(PlayerCastbarHud)) { return true; } if (element != null && element.GetType() == typeof(PlayerCastbarHud)) { return true; }
if (element != null && !element.GetConfig().Enabled) { return false; } if (element != null && !element.GetConfig().Enabled) { return false; }
// Hide unless hovered: element is visible only when the cursor is over it
if (HideUnlessHovered && element is DraggableHudElement draggable)
{
Vector2 origin = ImGui.GetMainViewport().Size / 2f;
var hudOptions = ConfigurationManager.Instance?.GetConfigObject<HUDOptionsConfig>();
if (hudOptions != null && hudOptions.UseGlobalHudShift)
origin += hudOptions.HudOffset;
var (min, max) = draggable.GetScreenBounds(origin);
if (!ImGui.IsMouseHoveringRect(min, max))
return false;
}
// Alliance frames only matter in alliance raids (duty). HideInDuty would hide them exactly when needed. // Alliance frames only matter in alliance raids (duty). HideInDuty would hide them exactly when needed.
bool isAllianceFrames = element != null && element.GetType() == typeof(AllianceFramesHud); bool isAllianceFrames = element != null && element.GetType() == typeof(AllianceFramesHud);
@@ -144,6 +162,7 @@ namespace HSUI.Interface
{ {
Enabled = config.Enabled; Enabled = config.Enabled;
HideUnlessHovered = config.HideUnlessHovered;
HideOutsideOfCombat = config.HideOutsideOfCombat; HideOutsideOfCombat = config.HideOutsideOfCombat;
HideInCombat = config.HideInCombat; HideInCombat = config.HideInCombat;
HideInGoldSaucer = config.HideInGoldSaucer; HideInGoldSaucer = config.HideInGoldSaucer;
+9
View File
@@ -1,3 +1,12 @@
# 1.0.8.20
- **Hotbars**: Fixed cooldown overlays showing through game UI (e.g. dialogue box) when "Show HUD during dialogue and interaction" is enabled. Hotbar cooldown timers and numbers are now skipped for slots that overlap dialogue, select, or journal addons.
# 1.0.8.19
- **Hotbars**: Visibility settings moved from Visibility → Hotbars to each Hotbar 110 menu. The Visibility → Hotbars tab has been removed.
# 1.0.8.18
- **Visibility**: "Hide unless hovered" — per-element option in Visibility to hide any UI element unless the cursor is over it (requires HUD locked).
# 1.0.8.17 # 1.0.8.17
- **Controller Hotbars**: Add 8 cross bars (L2/R2 style) separate from normal hotbars 1-8. Controller bar slot data stored in config (not game StandardHotbars) so layouts can differ per mode. Drag-and-drop on controller bars: from game, shift+drag rearrange, release outside to clear. Independent keybinds with modifier+trigger combinations (e.g. L2+South). Optional sync bar mode with game client (Character Config Mouse/Gamepad toggle). Clone/copy actions: normal hotbars ↔ controller bars. Restore controller bar layout button. - **Controller Hotbars**: Add 8 cross bars (L2/R2 style) separate from normal hotbars 1-8. Controller bar slot data stored in config (not game StandardHotbars) so layouts can differ per mode. Drag-and-drop on controller bars: from game, shift+drag rearrange, release outside to clear. Independent keybinds with modifier+trigger combinations (e.g. L2+South). Optional sync bar mode with game client (Character Config Mouse/Gamepad toggle). Clone/copy actions: normal hotbars ↔ controller bars. Restore controller bar layout button.
+1 -1
View File
@@ -1 +1 @@
[{"Author":"Knack117","Name":"HSUI","Punchline":"A modern HUD replacement built for customization.","Description":"HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.","Changelog":"1.0.8.16: Show HUD during dialogue and interaction (hotbars stay visible when talking to NPCs or interacting). 1.0.8.15: Tooltips game-style formatting (section labels, tail alignment, config). 1.0.8.14: Mouse GCD Indicator (ring around cursor). 1.0.8.13: Item tooltips now show. 1.0.8.12: Item/HQ icons now draw on hotbar. 1.0.8.11: Hotbar tooltip crash fix (Lumina GetRow). 1.0.8.10: Hotbar crash fix when dragging inventory items; Release builds strip PDBs. 1.0.8.9: Gearset persists on slot (fix CommandId 0 treated as empty). 1.0.8.8: Gearset drag-drop fix; allow first gearset (index 0) on bar. 1.0.8.7: Fixed Gearset/Job Gear Set icon clearing when first equipment slot changes. 1.0.8.6: Crafting action tooltips now show full description instead of action name. 1.0.8.4: Alliance Frames 1 and 2 fix in raids; crafting action tooltips; Hide in duty no longer hides alliance frames. 1.0.8.3: Fix left-click staying broken after disable. 1.0.8.2: Charge icons stay lit until all charges spent.","InternalName":"HSUI","AssemblyVersion":"1.0.8.16","RepoUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI","ApplicableVersion":"any","Tags":["UI","HUD","Unit Frames","Nameplates","Party Frames","Hotbars"],"CategoryTags":["UI"],"DalamudApiLevel":14,"IconUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/raw/branch/main/Media/Images/icon.png","ImageUrls":[],"DownloadLinkInstall":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.16/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.16/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.16/latest.zip","LastUpdate":"1761609600"}] [{"Author":"Knack117","Name":"HSUI","Punchline":"A modern HUD replacement built for customization.","Description":"HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.","Changelog":"1.0.8.20: Fixed cooldown overlays showing through game UI (dialogue box) when Show HUD during dialogue enabled. 1.0.8.19: Hotbar visibility moved to per-hotbar menus; removed Visibility Hotbars tab. 1.0.8.18: Visibility \"Hide unless hovered\" option. 1.0.8.17: Controller hotbars (cross layout, separate storage, sync with game). 1.0.8.16: Show HUD during dialogue and interaction. 1.0.8.15: Tooltips game-style formatting. 1.0.8.14: Mouse GCD Indicator. 1.0.8.13: Item tooltips now show. 1.0.8.12: Item/HQ icons now draw on hotbar. 1.0.8.11: Hotbar tooltip crash fix. 1.0.8.10: Hotbar crash fix when dragging inventory items. 1.0.8.9: Gearset persists on slot. 1.0.8.8: Gearset drag-drop fix. 1.0.8.7: Fixed Gearset icon clearing. 1.0.8.6: Crafting action tooltips full description. 1.0.8.4: Alliance Frames 1 and 2 fix; Hide in duty no longer hides alliance frames. 1.0.8.3: Fix left-click staying broken after disable. 1.0.8.2: Charge icons stay lit until all charges spent.","InternalName":"HSUI","AssemblyVersion":"1.0.8.20","RepoUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI","ApplicableVersion":"any","Tags":["UI","HUD","Unit Frames","Nameplates","Party Frames","Hotbars"],"CategoryTags":["UI"],"DalamudApiLevel":14,"IconUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/raw/branch/main/Media/Images/icon.png","ImageUrls":[],"DownloadLinkInstall":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.20/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.20/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSUI/releases/download/v1.0.8.20/latest.zip","LastUpdate":"1772378453"}]