diff --git a/LightlessSync/Services/NameplateHandler.cs b/LightlessSync/Services/NameplateHandler.cs index 4c8a28c..e0c788e 100644 --- a/LightlessSync/Services/NameplateHandler.cs +++ b/LightlessSync/Services/NameplateHandler.cs @@ -6,7 +6,6 @@ using FFXIVClientStructs.FFXIV.Client.System.Framework; using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Component.GUI; using LightlessSync.LightlessConfiguration; -using LightlessSync.LightlessConfiguration.Configurations; using LightlessSync.PlayerData.Pairs; using LightlessSync.Services.Mediator; using LightlessSync.UI; @@ -43,8 +42,9 @@ public unsafe class NameplateHandler : IMediatorSubscriber private readonly int[] _cachedNameplateTextOffsets = new int[AddonNamePlate.NumNamePlateObjects]; internal const uint mNameplateNodeIDBase = 0x7D99D500; - private const string DefaultLabelText = "Lightfinder"; + private const string DefaultLabelText = "LightFinder"; private const SeIconChar DefaultIcon = SeIconChar.LinkMarker; + private const int ContainerOffsetX = 50; private static readonly string DefaultIconGlyph = SeIconCharExtensions.ToIconString(DefaultIcon); private volatile HashSet _activeBroadcastingCids = []; @@ -266,11 +266,21 @@ public unsafe class NameplateHandler : IMediatorSubscriber var scaleMultiplier = System.Math.Clamp(config.LightfinderLabelScale, 0.5f, 2.0f); var baseScale = config.LightfinderLabelUseIcon ? 1.0f : 0.5f; var effectiveScale = baseScale * scaleMultiplier; - var nodeWidth = (int)System.Math.Round(AtkNodeHelpers.DefaultTextNodeWidth * effectiveScale); - var nodeHeight = (int)System.Math.Round(AtkNodeHelpers.DefaultTextNodeHeight * effectiveScale); + var labelContent = config.LightfinderLabelUseIcon + ? NormalizeIconGlyph(config.LightfinderLabelIconGlyph) + : DefaultLabelText; - int positionX = 58; - AlignmentType alignment = AlignmentType.Bottom; + pNode->FontType = config.LightfinderLabelUseIcon ? FontType.Axis : FontType.MiedingerMed; + pNode->AtkResNode.SetScale(effectiveScale, effectiveScale); + pNode->SetText(labelContent); + var nodeWidth = (int)pNode->AtkResNode.GetWidth(); + if (nodeWidth <= 0) + nodeWidth = (int)System.Math.Round(AtkNodeHelpers.DefaultTextNodeWidth * effectiveScale); + var nodeHeight = (int)System.Math.Round(AtkNodeHelpers.DefaultTextNodeHeight * effectiveScale); + var baseFontSize = config.LightfinderLabelUseIcon ? 36f : 24f; + var computedFontSize = (int)System.Math.Round(baseFontSize * scaleMultiplier); + pNode->FontSize = (byte)System.Math.Clamp(computedFontSize, 1, 255); + AlignmentType alignment; var textScaleY = nameText->AtkResNode.ScaleY; if (textScaleY <= 0f) @@ -349,49 +359,50 @@ public unsafe class NameplateHandler : IMediatorSubscriber { hasValidOffset = false; } + int positionX; if (config.LightfinderAutoAlign && nameContainer != null && hasValidOffset) { var nameplateWidth = (int)nameContainer->Width; - - int labelWidth; - if (config.LightfinderLabelUseIcon) - { - var iconSize = (int)System.Math.Round(config.LightfinderLabelUseIcon ? 36f : 24f * scaleMultiplier); - labelWidth = iconSize; - } - else - { - labelWidth = (int)System.Math.Round(AtkNodeHelpers.DefaultTextNodeWidth * effectiveScale); - } - + + if (!config.LightfinderLabelUseIcon && nodeWidth > nameplateWidth) + nodeWidth = nameplateWidth; + + if (!config.LightfinderLabelUseIcon) + pNode->AtkResNode.Width = (ushort)nodeWidth; + + int leftPos = nameplateWidth / 8; + int rightPos = nameplateWidth - nodeWidth - (nameplateWidth / 8); + int centrePos = (nameplateWidth - nodeWidth) / 2; + int staticMargin = 24; + int calcMargin = (int)(nameplateWidth * 0.15f); + switch (config.LabelAlignment) { case LabelAlignment.Left: - positionX = nameplateWidth / 2 - textWidth / 2; - break; - case LabelAlignment.Center: - positionX = nameplateWidth / 2 - labelWidth / 2; + positionX = config.LightfinderLabelUseIcon ? leftPos + staticMargin : calcMargin; + alignment = AlignmentType.BottomLeft; break; case LabelAlignment.Right: - positionX = nameplateWidth / 2 + textWidth / 2 - labelWidth; + positionX = config.LightfinderLabelUseIcon ? rightPos - staticMargin : nameplateWidth - nodeWidth + calcMargin; + alignment = AlignmentType.BottomRight; + break; + default: + positionX = config.LightfinderLabelUseIcon ? centrePos : centrePos + calcMargin; + alignment = AlignmentType.Bottom; break; } - - alignment = AlignmentType.BottomLeft; } else { + positionX = 58 + config.LightfinderLabelOffsetX; alignment = AlignmentType.Bottom; } - positionX += config.LightfinderLabelOffsetX; positionY += config.LightfinderLabelOffsetY; alignment = (AlignmentType)System.Math.Clamp((int)alignment, 0, 8); - pNode->AtkResNode.SetPositionShort((short)System.Math.Clamp(positionX, short.MinValue, short.MaxValue), (short)System.Math.Clamp(positionY, short.MinValue, short.MaxValue)); pNode->AtkResNode.SetUseDepthBasedPriority(true); - pNode->AtkResNode.SetScale(effectiveScale, effectiveScale); pNode->AtkResNode.Color.A = 255; @@ -405,24 +416,25 @@ public unsafe class NameplateHandler : IMediatorSubscriber pNode->EdgeColor.B = (byte)(edgeColor.Z * 255); pNode->EdgeColor.A = (byte)(edgeColor.W * 255); - var baseFontSize = config.LightfinderLabelUseIcon ? 36f : 24f; - var computedFontSize = (int)System.Math.Round(baseFontSize * scaleMultiplier); - pNode->FontSize = (byte)System.Math.Clamp(computedFontSize, 1, 255); - pNode->AlignmentType = alignment; + + if(!config.LightfinderLabelUseIcon) + { + pNode->AlignmentType = AlignmentType.Bottom; + } + else + { + pNode->AlignmentType = alignment; + } + pNode->AtkResNode.SetPositionShort( + (short)System.Math.Clamp(positionX, short.MinValue, short.MaxValue), + (short)System.Math.Clamp(positionY, short.MinValue, short.MaxValue) + ); var computedLineSpacing = (int)System.Math.Round(24 * scaleMultiplier); pNode->LineSpacing = (byte)System.Math.Clamp(computedLineSpacing, 0, byte.MaxValue); pNode->CharSpacing = 1; - pNode->TextFlags = config.LightfinderLabelUseIcon ? TextFlags.Edge | TextFlags.Glare | TextFlags.AutoAdjustNodeSize - : TextFlags.Edge | TextFlags.Glare; - - var labelContent = config.LightfinderLabelUseIcon - ? NormalizeIconGlyph(config.LightfinderLabelIconGlyph) - : DefaultLabelText; - - pNode->FontType = config.LightfinderLabelUseIcon ? FontType.Axis : FontType.MiedingerMed; - pNode->SetText(labelContent); + : TextFlags.Edge | TextFlags.Glare; } } @@ -558,4 +570,12 @@ public unsafe class NameplateHandler : IMediatorSubscriber FlagRefresh(); } + + public void ClearNameplateCaches() + { + System.Array.Clear(_cachedNameplateTextWidths, 0, _cachedNameplateTextWidths.Length); + System.Array.Clear(_cachedNameplateTextHeights, 0, _cachedNameplateTextHeights.Length); + System.Array.Clear(_cachedNameplateContainerHeights, 0, _cachedNameplateContainerHeights.Length); + System.Array.Fill(_cachedNameplateTextOffsets, int.MinValue); + } } diff --git a/LightlessSync/UI/SettingsUi.cs b/LightlessSync/UI/SettingsUi.cs index 0a592f0..95b0311 100644 --- a/LightlessSync/UI/SettingsUi.cs +++ b/LightlessSync/UI/SettingsUi.cs @@ -1071,6 +1071,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelOffsetX = (short)offsetX; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1081,6 +1082,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelOffsetY = (short)offsetY; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1091,6 +1093,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelScale = labelScale; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1101,6 +1104,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderAutoAlign = autoAlign; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1149,6 +1153,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelShowOwn = showOwn; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1159,6 +1164,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelShowPaired = showPaired; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw(); } @@ -1169,6 +1175,7 @@ public class SettingsUi : WindowMediatorSubscriberBase { _configService.Current.LightfinderLabelUseIcon = useIcon; _configService.Save(); + _nameplateHandler.ClearNameplateCaches(); _nameplateHandler.FlagRefresh(); _nameplateService.RequestRedraw();