fix: dropdown syntax + converted to named click handlers

This commit is contained in:
Bluewhale1337
2026-10-21 22:33:01 +02:00
parent 71b92fe1a6
commit 7b8c0251fc
7 changed files with 334 additions and 21 deletions
+22
View File
@@ -197,6 +197,28 @@ function HealBot_OnUpdate(this, arg1)
if HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1 then
if not HealBot_HoT_Update_Timer or GetTime() >= HealBot_HoT_Update_Timer then
HealBot_HoT_Update_Timer = GetTime() + 0.25
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
-- Icon Overlay mode: dirty-flag units with active Nampower auras
if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then
local now = GetTime()
for guid, auras in pairs(HealBot_Nampower_Auras) do
local hasActive = false
for _, exp in pairs(auras) do
if exp > now then hasActive = true; break end
end
if hasActive then
local unitID = (HealBot_Model and HealBot_Model:GetUnitByGUID(guid))
if not unitID and HealBot_PlayerGUID and guid == HealBot_PlayerGUID then
unitID = "player"
end
if unitID and not string.find(unitID, "pet") then
HealBot_View_DirtyUnits[unitID] = true
end
end
end
end
end
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs()
end
+4
View File
@@ -269,6 +269,8 @@ HealBot_ConfigDefaults = {
HealBot_Integrations_SuperWoW = 0,
HealBot_Integrations_ClassicAPI = 0,
HealBot_Integrations_ShowHoTTimers = 0,
HealBot_Integrations_HoTTimerPosition = "BELOW",
HealBot_Integrations_HoTTimerDisplayMode = 0,
};
HealBot_Config = {};
@@ -621,11 +623,13 @@ HealBot_TrackedAura_Spells = {};
function HealBot_Init_TrackedAuras()
for spell, info in pairs(HealBot_TrackedAuras) do
info.spell = spell
HealBot_TrackedAura_Textures[info.texture] = info
HealBot_TrackedAura_Spells[spell] = info
if info.locKey then
local locName = getglobal(info.locKey)
if locName and locName ~= "" then
info.locName = locName
HealBot_TrackedAura_Spells[locName] = info
end
end
+3
View File
@@ -145,5 +145,8 @@ end
HealBot_Options_Integrations_ShowHoTTimers:SetChecked(0)
HealBot_Config.HealBot_Integrations_ShowHoTTimers = 0
end
if HealBot_Options_Integrations_UpdateDropdownStates then
HealBot_Options_Integrations_UpdateDropdownStates()
end
end
end
+119
View File
@@ -1,3 +1,34 @@
-- HealBot_Options_Integrations.lua
local function HealBot_Options_SetDropDownState(frame, enabled)
if not frame then return end
local button = getglobal(frame:GetName() .. "Button")
local text = getglobal(frame:GetName() .. "Text")
if button then
if enabled then
button:Enable()
else
button:Disable()
end
end
if text then
if enabled then
text:SetTextColor(1, 1, 1)
else
text:SetTextColor(0.5, 0.5, 0.5)
end
end
end
-- Update enabled/disabled state of dropdowns based on current config
function HealBot_Options_Integrations_UpdateDropdownStates()
local timersEnabled = HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
HealBot_Options_SetDropDownState(HealBot_Options_Integrations_DisplayModeDropdown, timersEnabled)
HealBot_Options_SetDropDownState(HealBot_Options_Integrations_PositionDropdown, timersEnabled and (displayMode == 0))
end
-- HealBot_Options_Integrations_OnShow: UI handler for OnShow options panel.
function HealBot_Options_Integrations_OnShow(this)
HealBot_Options_Integrations_UnitXP:SetChecked(HealBot_Config.HealBot_Integrations_UnitXP);
@@ -5,4 +36,92 @@ function HealBot_Options_Integrations_OnShow(this)
HealBot_Options_Integrations_SuperWoW:SetChecked(HealBot_Config.HealBot_Integrations_SuperWoW);
HealBot_Options_Integrations_ClassicAPI:SetChecked(HealBot_Config.HealBot_Integrations_ClassicAPI);
HealBot_Options_Integrations_ShowHoTTimers:SetChecked(HealBot_Config.HealBot_Integrations_ShowHoTTimers);
-- Set display mode dropdown text
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
UIDropDownMenu_SetText("Icon Overlay", HealBot_Options_Integrations_DisplayModeDropdown)
else
UIDropDownMenu_SetText("List", HealBot_Options_Integrations_DisplayModeDropdown)
end
-- Set position dropdown text
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
local posLabels = { BELOW = "Below", ABOVE = "Above", LEFT = "Left", RIGHT = "Right" }
UIDropDownMenu_SetText(posLabels[pos] or "Below", HealBot_Options_Integrations_PositionDropdown)
-- Update enabled/disabled state
HealBot_Options_Integrations_UpdateDropdownStates()
end
-- Display Mode dropdown click handler (relying on global this)
function HealBot_Options_Integrations_DisplayModeDropdown_OnClick()
UIDropDownMenu_SetSelectedID(HealBot_Options_Integrations_DisplayModeDropdown, this:GetID())
HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode = this.value
UIDropDownMenu_SetText(this:GetText(), HealBot_Options_Integrations_DisplayModeDropdown)
HealBot_Options_Integrations_UpdateDropdownStates()
if HealBot_Action_UnitButtons then
for u in pairs(HealBot_Action_UnitButtons) do
HealBot_View_DirtyUnits[u] = true
end
end
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs()
end
end
-- Display Mode dropdown init
function HealBot_Options_Integrations_DisplayModeDropdown_Init()
local mode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
local info
info = {}
info.text = "List"
info.value = 0
info.func = HealBot_Options_Integrations_DisplayModeDropdown_OnClick
if mode == 0 then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
info = {}
info.text = "Icon Overlay"
info.value = 1
info.func = HealBot_Options_Integrations_DisplayModeDropdown_OnClick
if mode == 1 then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
-- Position dropdown click handler (relying on global this)
function HealBot_Options_Integrations_PositionDropdown_OnClick()
UIDropDownMenu_SetSelectedID(HealBot_Options_Integrations_PositionDropdown, this:GetID())
HealBot_Config.HealBot_Integrations_HoTTimerPosition = this.value
UIDropDownMenu_SetText(this:GetText(), HealBot_Options_Integrations_PositionDropdown)
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs()
end
end
-- Position dropdown init
function HealBot_Options_Integrations_PositionDropdown_Init()
local positions = {
{ value = "BELOW", label = "Below" },
{ value = "ABOVE", label = "Above" },
{ value = "LEFT", label = "Left" },
{ value = "RIGHT", label = "Right" },
}
local currentPos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
for _, p in ipairs(positions) do
local info = {}
info.text = p.label
info.value = p.value
info.func = HealBot_Options_Integrations_PositionDropdown_OnClick
if currentPos == p.value then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
end
+74 -2
View File
@@ -94,9 +94,81 @@
</OnLoad>
<OnClick>
HealBot_Config.HealBot_Integrations_ShowHoTTimers = this:GetChecked() and 1 or 0;
HealBot_Options_Integrations_UpdateDropdownStates();
if HealBot_Action_UnitButtons then
for u in pairs(HealBot_Action_UnitButtons) do
HealBot_View_DirtyUnits[u] = true;
end
end
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs();
end
</OnClick>
</Scripts>
</CheckButton>
<!-- HoT Timer Display Mode Dropdown -->
<Frame name="HealBot_Options_Integrations_DisplayModeDropdown" inherits="UIDropDownMenuTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_ShowHoTTimers" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-15" y="-22"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString name="HealBot_Options_Integrations_DisplayModeLabel" inherits="GameFontHighlightSmall" justifyH="LEFT" text="Timer Display Mode:">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="20" y="2"/>
</Offset>
</Anchor>
</Anchors>
<Color r="1" g="0.82" b="0"/>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
UIDropDownMenu_SetWidth(120, this);
UIDropDownMenu_Initialize(this, HealBot_Options_Integrations_DisplayModeDropdown_Init);
</OnLoad>
</Scripts>
</Frame>
<!-- HoT Timer Position Dropdown -->
<Frame name="HealBot_Options_Integrations_PositionDropdown" inherits="UIDropDownMenuTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_DisplayModeDropdown" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-22"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString name="HealBot_Options_Integrations_PositionLabel" inherits="GameFontHighlightSmall" justifyH="LEFT" text="Timer List Position:">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="20" y="2"/>
</Offset>
</Anchor>
</Anchors>
<Color r="1" g="0.82" b="0"/>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
UIDropDownMenu_SetWidth(120, this);
UIDropDownMenu_Initialize(this, HealBot_Options_Integrations_PositionDropdown_Init);
</OnLoad>
</Scripts>
</Frame>
<Frame setAllPoints="true">
<Layers>
<Layer level="ARTWORK">
@@ -114,9 +186,9 @@
<FontString name="HealBot_Options_Integrations_HoTInfo" inherits="GameFontHighlightSmall" justifyH="LEFT" justifyV="TOP" text="Note: HoT Timers require Nampower to be enabled and active to provide accurate aura times.">
<Size x="340" y="30"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_ShowHoTTimers" relativePoint="BOTTOMLEFT">
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_PositionDropdown" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="20" y="-4"/>
<AbsDimension x="20" y="-6"/>
</Offset>
</Anchor>
</Anchors>
+111 -19
View File
@@ -283,6 +283,10 @@ function HealBot_Action_EnableButton(button)
end
local iconSize = HealBot_Config.biconsize[HealBot_Config.Current_Skin] or 12
local isPet = string.find(unit, "pet") ~= nil
local overlayMode = (HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1) and ((HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0) == 1) and not isPet
local unitGUID = overlayMode and ((HealBot_GetUnitGUID and HealBot_GetUnitGUID(unit)) or (unit == "player" and HealBot_PlayerGUID))
local currentTime = overlayMode and GetTime()
for i = 1, 10 do
local icon = button["icon"..i]
if not icon then
@@ -305,10 +309,54 @@ function HealBot_Action_EnableButton(button)
if not icon:IsVisible() then
icon:Show()
end
-- Icon overlay timer text
local iconText = button["iconText"..i]
if not iconText then
iconText = button:CreateFontString(nil, "OVERLAY")
iconText:SetFont("Fonts\\ARIALN.TTF", 10, "OUTLINE")
iconText:SetPoint("CENTER", icon, "CENTER", 0, 0)
iconText:SetTextColor(1, 1, 1, 1)
button["iconText"..i] = iconText
end
if overlayMode and unitGUID and HealBot_Nampower_Auras and HealBot_Nampower_Auras[unitGUID] then
local texturePath = HealBot_UnitIcons[unit][i]
local auraInfo = HealBot_TrackedAura_Textures and HealBot_TrackedAura_Textures[texturePath]
if auraInfo and auraInfo.showTimer then
local expiration = (auraInfo.locName and HealBot_Nampower_Auras[unitGUID][auraInfo.locName])
or (auraInfo.spell and HealBot_Nampower_Auras[unitGUID][auraInfo.spell])
if not expiration and HealBot_TrackedAura_Spells then
for spellName, spInfo in pairs(HealBot_TrackedAura_Spells) do
if spInfo.texture == texturePath and spInfo.showTimer then
expiration = HealBot_Nampower_Auras[unitGUID][spellName]
if expiration then break end
end
end
end
if expiration and expiration > currentTime then
local timeLeft = math.floor(expiration - currentTime)
iconText:SetText(timeLeft)
iconText:Show()
else
iconText:SetText("")
iconText:Hide()
end
else
iconText:SetText("")
iconText:Hide()
end
else
iconText:SetText("")
iconText:Hide()
end
else
if icon:IsVisible() then
icon:Hide()
end
local iconText = button["iconText"..i]
if iconText and iconText:IsVisible() then
iconText:Hide()
end
end
end
end
@@ -1380,22 +1428,65 @@ local function HealBot_PlayerHoTs_SortComparator(a, b)
return (a.expires or 0) < (b.expires or 0)
end
-- Reposition the HoT timer list frame based on config
local function HealBot_HoTTimerList_Reanchor()
if not HealBot_PlayerHoTsListFrame then return end
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
HealBot_PlayerHoTsListFrame:ClearAllPoints()
if pos == "ABOVE" then
HealBot_PlayerHoTsListFrame:SetPoint("BOTTOMLEFT", HealBot_Action, "TOPLEFT", 0, 2)
elseif pos == "RIGHT" then
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "TOPRIGHT", 2, 0)
elseif pos == "LEFT" then
HealBot_PlayerHoTsListFrame:SetPoint("TOPRIGHT", HealBot_Action, "TOPLEFT", -2, 0)
else -- BELOW (default)
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "BOTTOMLEFT", 0, -2)
end
end
-- Reposition child HoT frames for stacking direction
local function HealBot_HoTTimerList_StackChild(frame, index)
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
frame:ClearAllPoints()
if pos == "ABOVE" then
if index == 1 then
frame:SetPoint("BOTTOMLEFT", HealBot_PlayerHoTsListFrame, "BOTTOMLEFT", 0, 0)
else
frame:SetPoint("BOTTOMLEFT", HealBot_PlayerHoTFrames[index-1], "TOPLEFT", 0, 2)
end
else
if index == 1 then
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTsListFrame, "TOPLEFT", 0, 0)
else
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTFrames[index-1], "BOTTOMLEFT", 0, -2)
end
end
end
function HealBot_Action_UpdatePlayerHoTs()
if not HealBot_PlayerHoTsListFrame then
HealBot_PlayerHoTsListFrame = CreateFrame("Frame", "HealBot_PlayerHoTsListFrame", HealBot_Action)
HealBot_PlayerHoTsListFrame:SetWidth(128)
HealBot_PlayerHoTsListFrame:SetHeight(1)
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "BOTTOMLEFT", 0, -2)
HealBot_PlayerHoTsListFrame:Show()
end
HealBot_HoTTimerList_Reanchor()
if HealBot_Config.HealBot_Integrations_ShowHoTTimers ~= 1 then
HealBot_PlayerHoTsListFrame:Hide()
return
else
HealBot_PlayerHoTsListFrame:Show()
end
-- If display mode is Icon Overlay, hide the list and return
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
HealBot_PlayerHoTsListFrame:Hide()
return
end
HealBot_PlayerHoTsListFrame:Show()
local currentTime = GetTime()
-- Clear cache instead of reallocating
@@ -1403,17 +1494,20 @@ function HealBot_Action_UpdatePlayerHoTs()
if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then
for targetName, auras in pairs(HealBot_Nampower_Auras) do
for spellName, expiration in pairs(auras) do
local auraInfo = HealBot_TrackedAura_Spells and HealBot_TrackedAura_Spells[spellName]
if auraInfo and auraInfo.showTimer then
if expiration > currentTime then
numHoTs = numHoTs + 1
if not HealBot_PlayerHoTs_ListCache[numHoTs] then
HealBot_PlayerHoTs_ListCache[numHoTs] = {}
local unitID = HealBot_Model:GetUnitByGUID(targetName) or HealBot_Model:GetUnitIDByName(targetName)
if not (unitID and string.find(unitID, "pet")) then
for spellName, expiration in pairs(auras) do
local auraInfo = HealBot_TrackedAura_Spells and HealBot_TrackedAura_Spells[spellName]
if auraInfo and auraInfo.showTimer then
if expiration > currentTime then
numHoTs = numHoTs + 1
if not HealBot_PlayerHoTs_ListCache[numHoTs] then
HealBot_PlayerHoTs_ListCache[numHoTs] = {}
end
HealBot_PlayerHoTs_ListCache[numHoTs].name = targetName
HealBot_PlayerHoTs_ListCache[numHoTs].spell = spellName
HealBot_PlayerHoTs_ListCache[numHoTs].expires = expiration
end
HealBot_PlayerHoTs_ListCache[numHoTs].name = targetName
HealBot_PlayerHoTs_ListCache[numHoTs].spell = spellName
HealBot_PlayerHoTs_ListCache[numHoTs].expires = expiration
end
end
end
@@ -1435,11 +1529,6 @@ function HealBot_Action_UpdatePlayerHoTs()
frame = CreateFrame("Frame", "HealBot_PlayerHoT" .. i, HealBot_PlayerHoTsListFrame)
frame:SetWidth(128)
frame:SetHeight(16)
if i == 1 then
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTsListFrame, "TOPLEFT", 0, 0)
else
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTFrames[i-1], "BOTTOMLEFT", 0, -2)
end
local icon = frame:CreateTexture(nil, "ARTWORK")
icon:SetWidth(14)
@@ -1454,6 +1543,9 @@ function HealBot_Action_UpdatePlayerHoTs()
HealBot_PlayerHoTFrames[i] = frame
end
-- Reposition child for stacking direction
HealBot_HoTTimerList_StackChild(frame, i)
local hot = HealBot_PlayerHoTs_ListCache[i]
local timeLeft = math.floor(hot.expires - currentTime)
+1
View File
@@ -51,6 +51,7 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
### Change Log
**v1.7.6**
* **Feature - HoT Timer Position & Icon Overlay Display Modes** - Added configurable HoT Timer list position dropdown (`Below`, `Above`, `Left`, `Right`) relative to raid frames. Added alternative `Icon Overlay` display mode rendering countdown numbers directly on unit bar HoT icons. Excluded pets from timer lists and overlay numbers. Optimized expiration lookup with O(1) cached texture-to-spell mappings.
* **Refactor & Feature - Unified Aura & HoT Tracking** - Unified bar icons and HoT timers into a single master dictionary (`HealBot_TrackedAuras`) in `HealBot_Data.lua`. Added Weakened Soul, Fear Ward, Abolish Disease, and Abolish Poison to active timer bars with localized client support and debuff-aware pruning.
**v1.7.5**