-- Bagshui UI Class: Buttons
Bagshui:AddComponent(function()
-- Scaling for the custom IconButton cooldown shine.
local ICON_BUTTON_SHINE_SCALE = 3
local Ui = Bagshui.prototypes.Ui
--- Create a standard button.
---@param name string Unique name for the button (will be passed to `Ui:CreateElementName()`).
---@param parent table Parent frame.
---@param buttonText string Text to display.
---@param onClick function Click handler.
---@return table button
function Ui:CreateButton(name, parent, buttonText, onClick)
local elementName = self:CreateElementName(name)
local element = _G.CreateFrame(
"Button",
elementName,
parent,
"UIPanelButtonTemplate"
)
element:SetText(buttonText or "")
local buttonTextObject = _G[elementName .. "Text"]
element:SetWidth(buttonTextObject:GetWidth() + 20)
element:SetHeight(buttonTextObject:GetHeight() + 10)
if onClick then
element:SetScript("OnClick", onClick)
end
if type(BsSkin.buttonSkinFunc) == "function" then
BsSkin.buttonSkinFunc(element)
end
return element
end
--- Create a checkbox (or "CheckButton" as Blizzard likes to call them).
---@param name string Unique name for the button (will be passed to `Ui:CreateElementName()`).
---@param parent table Parent frame.
---@param template string? XML template to use.
---@param buttonText string Text to display.
---@param onClick function Click handler.
---@param width number? Initial width.
---@param height number? Initial height.
---@return table button
function Ui:CreateCheckbox(name, parent, template, buttonText, onClick, width, height)
local elementName = self:CreateElementName(name)
template = template or "UIOptionsCheckButtonTemplate"
local element = _G.CreateFrame(
"CheckButton",
elementName,
parent,
template
)
element.bagshuiData = {
text = _G[elementName .. "Text"],
padding = 0,
}
if element.bagshuiData.text then
-- Why is the text so close to the checkbox in the Blizzard templates?
if string.find(template, "UI.-CheckButtonTemplate") then
element.bagshuiData.text:SetPoint("LEFT", element, "RIGHT", 0, 0)
end
if buttonText then
element.bagshuiData.text:SetText(buttonText)
else
element.bagshuiData.text:Hide()
end
end
if onClick then
element:SetScript("OnClick", onClick)
end
if type(BsSkin.checkboxSkinFunc) == "function" then
BsSkin.checkboxSkinFunc(element)
end
element:SetHeight(height or 20)
element:SetWidth(width or 20)
return element
end
--- Create a button with an attached drop-down menu.
---@param name string Unique name for the button (will be passed to `Ui:CreateElementName()`).
---@param parent table Parent frame.
---@param width number
---@param menusInstance table Bagshui `Menus` class instance.
---@param menuType string Identifier of the menu to display in the drop-down.
---@param openFuncArg2 any 2nd parameter for the OpenMenu callback of `menuType`.
---@return table dropDownMenuButton
function Ui:CreateDropDownMenuButton(name, parent, width, menusInstance, menuType, openFuncArg2)
local dropDownName = self:CreateElementName(name)
local dropDown = _G.CreateFrame(
"Frame",
dropDownName,
parent,
"UIDropDownMenuTemplate"
)
dropDown.bagshuiData = {}
-- Hide textures that we don't want to display.
_G[dropDownName .. "Left"]:Hide()
_G[dropDownName .. "Middle"]:Hide()
_G[dropDownName .. "Right"]:Hide()
-- Style to match other Bagshui widgets.
self:SetFrameBackdropAndBorderForEditWidgets(dropDown, "SOLID")
-- Text will be updated when an item is selected, but we need a non-empty string
-- to be able to size the widget.
local dropDownText = _G[dropDownName .. "Text"]
dropDownText:SetText("")
dropDown:SetWidth(width)
dropDown:SetHeight(dropDownText:GetHeight() + 10)
-- Fix drop-down button and text positions so they look right.
local button = _G[dropDownName .. "Button"]
button:ClearAllPoints()
button:SetPoint("RIGHT", dropDown, "RIGHT", 5, 0)
dropDownText:ClearAllPoints()
dropDownText:SetPoint("LEFT", dropDown, "LEFT", 5, 0)
dropDownText:SetJustifyH("LEFT")
-- Skin it.
if type(BsSkin.dropdownSkinFunc) == "function" then
BsSkin.dropdownSkinFunc(dropDown)
end
-- Add OnClick handler to show the drop-down.
local buttonOldOnClick = button:GetScript("OnClick")
button:SetScript("OnClick", function()
local dropDown = _G.this:GetParent()
-- We'll need this after calling the original OnClick.
local originalParentHeight = dropDown:GetHeight()
-- Manually perform the OpenMenu callback that the Menus class would normally do.
if menusInstance.menuList[menuType] and menusInstance.menuList[menuType].openFunc then
menusInstance.menuList[menuType].openFunc(menusInstance.menuList[menuType], dropDown, openFuncArg2)
end
-- ToggleDropDownMenu().
buttonOldOnClick()
-- Reset to reset height because ToggleDropDownMenu's call to UIDropDownMenu_Initialize changes it.
dropDown:SetHeight(originalParentHeight)
-- Fix menu positioning -- it's normally off by the amount by which the height had to be adjusted.
local menuFrame = _G.DropDownList1
if menuFrame:IsVisible() then
menuFrame:ClearAllPoints()
menuFrame:SetPoint("TOPLEFT", dropDown, "BOTTOMLEFT", -3, 3)
end
end)
--- Special considerations to make the menu display correctly.
---@param dropDownWidget any
local function dropDownMenuPrep(dropDownWidget)
local this = dropDownWidget or _G.this
local originalHeight = this:GetHeight()
-- This would normally be handled by `Menus:OpenMenu()` but we need to set it up directly.
_G.UIDropDownMenu_Initialize(
this,
function(level)
menusInstance:LoadMenu(menuType, level)
end
)
-- Clear the selection. Blizzard code won't behave properly unless we do this.
_G.UIDropDownMenu_SetSelectedID(this, nil, 1)
-- Keep the menu width the same as the button.
_G.UIDropDownMenu_SetWidth(width, this)
-- UIDropDownMenu_Initialize messes with the height so let's reset it.
this:SetHeight(originalHeight)
end
dropDown:SetScript("OnShow", dropDownMenuPrep)
-- Call prep once to make sure everything is in order.
dropDownMenuPrep(dropDown)
return dropDown
end
--- Create an icon button with the specified texture.
--- There are a bunch of optional parameters so it's easier to pass a table.
--- See the `assert()`s for which keys are mandatory.
--- ```
--- {
--- name = "InternalButtonName",
--- namePrefix = "ToolbarButton",
--- parentFrame = ,
--- anchorToFrame = ,
--- xOffset = -10,
--- yOffset = 0,
--- width = 14,
--- height = 14,
--- disable = true,
--- onClick = function()
--- -- OnClick action
--- end,
--- texture = "TextureName", -- If only a name is provided it will be prefixed with the addon \ folder path
--- textureDir = "Toolbar",
--- texCoord = { 0, 0, 0, 0 },
--- tooltipTitle = "Text for first line of tooltip",
--- tooltipText = "Text with additional tooltip information",
--- tooltipAnchor = "valid anchor parameter for SetOwner()",
--- tooltipAnchorPoint = "valid anchor point", -- Only used if tooltipAnchor is ANCHOR_NONE or ANCHOR_PRESERVE
--- tooltipAnchorToPoint = "valid anchor point", -- Only used if tooltipAnchor is ANCHOR_NONE or ANCHOR_PRESERVE
--- }
--- ```
---comment
---@param buttonOpts table
---@return table button
function Ui:CreateIconButton(buttonOpts)
assert(type(buttonOpts) == "table", "CreateIconButton() parameter must be a table")
assert(buttonOpts.name, "name property is missing")
assert(buttonOpts.texture, "texture property is missing")
-- Create button.
local button = _G.CreateFrame(
"Button",
self:CreateElementName((buttonOpts.namePrefix or "button") .. buttonOpts.name),
buttonOpts.parentFrame
)
-- Change frame level.
if buttonOpts.frameLevelChange then
button:SetFrameLevel(button:GetFrameLevel() + buttonOpts.frameLevelChange)
end
-- Make the button target bigger.
button:SetHitRectInsets(-4, -4, -4, -4)
-- Set Texture.
self:SetIconButtonTexture(
button,
(
(string.find(buttonOpts.texture, "\\"))
and buttonOpts.texture
or (buttonOpts.textureDir or "Icons") .. "\\" .. buttonOpts.texture
),
buttonOpts.vertexColor,
buttonOpts.hoverVertexColor
)
-- Initialize Bagshui info table.
button.bagshuiData = {
xOffset = buttonOpts.xOffset or -6,
yOffset = buttonOpts.yOffset or 0,
tooltipTitle = buttonOpts.tooltipTitle,
tooltipText = buttonOpts.tooltipText,
tooltipAnchor = buttonOpts.tooltipAnchor or "ANCHOR_TOPLEFT",
tooltipAnchorPoint = buttonOpts.tooltipAnchorPoint,
tooltipAnchorToPoint = buttonOpts.tooltipAnchorToPoint,
tooltipXOffset = buttonOpts.tooltipXOffset or 0,
tooltipYOffset = buttonOpts.tooltipYOffset or 0,
tooltipFunction = buttonOpts.tooltipFunction,
tooltipGroupElement = buttonOpts.tooltipGroupElement,
tooltipDelay = buttonOpts.tooltipDelay,
noTooltipDelay = buttonOpts.noTooltipDelay,
noTooltipDelayShorting = buttonOpts.noTooltipDelayShorting,
tooltipTextDelay = buttonOpts.tooltipTextDelay or BS_TOOLTIP_DELAY_SECONDS.DEFAULT,
noTooltipTextDelay = buttonOpts.noTooltipTextDelay,
highlightTexture = button:GetHighlightTexture(),
}
-- Pushed texture should shift down slightly.
local pushedTexture = button:GetPushedTexture()
if pushedTexture then
pushedTexture:ClearAllPoints()
pushedTexture:SetPoint("TOPLEFT", button, "TOPLEFT", 0, -0.5)
pushedTexture:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 0, -0.5)
end
-- Dimensions.
local buttonWidth = buttonOpts.width or 14
button:SetWidth(buttonWidth)
button:SetHeight(buttonOpts.height or buttonWidth)
-- Position.
button:SetPoint(
buttonOpts.anchorPoint or "RIGHT",
buttonOpts.anchorToFrame or buttonOpts.parentFrame,
buttonOpts.anchorToPoint or "LEFT",
button.bagshuiData.xOffset,
button.bagshuiData.yOffset
)
-- Tooltip management.
if buttonOpts.tooltipTitle or buttonOpts.tooltipFunction then
-- Allow tooltip delays to be handled per-button.
if buttonOpts.independentTooltipDelay then
buttonOpts.tooltipGroupElement = button
end
button:SetScript("OnEnter", function()
_G.this.bagshuiData.mouseIsOver = true
self:ShowIconButtonTooltip(_G.this)
end)
button:SetScript("OnLeave", function()
_G.this.bagshuiData.mouseIsOver = false
if BsIconButtonTooltip:IsOwned(_G.this) then
Bagshui:ShortenTooltipDelay(_G.this, true)
BsIconButtonTooltip:Hide()
end
_G.this.bagshuiData.keepTooltipVisible = nil
end)
end
-- Set click action.
if buttonOpts.onClick then
-- Capture onClick function so table reuse doesn't bite us.
local onClick = buttonOpts.onClick
local onClickBeforeCloseMenusAndClearFocuses = buttonOpts.onClickBeforeCloseMenusAndClearFocuses
button:SetScript("OnClick", function()
if onClickBeforeCloseMenusAndClearFocuses then
onClickBeforeCloseMenusAndClearFocuses()
end
self:CloseMenusAndClearFocuses(true, true, false)
onClick()
end)
-- Shift/unshift HighlightTexture to match pushed/normal texture on mousedown/mouseup.
button:SetScript("OnMouseDown", function()
if not _G.this.bagshuiData.highlightTexture then
_G.this.bagshuiData.highlightTexture = _G.this:GetHighlightTexture()
end
_G.this.bagshuiData.highlightTexture:ClearAllPoints()
_G.this.bagshuiData.highlightTexture:SetPoint("TOPLEFT", _G.this, "TOPLEFT", 0, -0.5)
_G.this.bagshuiData.highlightTexture:SetPoint("BOTTOMRIGHT", _G.this, "BOTTOMRIGHT", 0, -0.5)
end)
button:SetScript("OnMouseUp", function()
_G.this.bagshuiData.highlightTexture:ClearAllPoints()
_G.this.bagshuiData.highlightTexture:SetAllPoints(_G.this)
end)
end
if buttonOpts.mouseButtons then
button:RegisterForClicks(unpack(BsUtil.Split(buttonOpts.mouseButtons, ",")))
else
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
end
-- Set up other scripts.
if buttonOpts.onEnter then
button:SetScript("OnEnter", buttonOpts.onEnter)
end
if buttonOpts.onLeave then
button:SetScript("OnLeave", buttonOpts.onLeave)
end
if buttonOpts.onShow then
button:SetScript("OnShow", buttonOpts.onShow)
end
if buttonOpts.onHide then
button:SetScript("OnHide", buttonOpts.onHide)
end
button:SetScript("OnUpdate", function()
if _G.this.bagshuiData and _G.this.bagshuiData.isOnCooldown then
self:UpdateIconButtonCooldown(_G.this)
end
if buttonOpts.onUpdate then
buttonOpts.onUpdate()
end
end)
-- Disable if requested.
if buttonOpts.disable then
button:Disable()
end
return button
end
--- Set icon button (toolbar buttons, etc) texture.
---@param button table Return value from `Ui:CreateIconButton()`.
---@param texturePath string?
---@param vertexColor number?[] { r, g, b, [a] }
---@param hoverVertexColor number?[] { r, g, b, [a] }
function Ui:SetIconButtonTexture(button, texturePath, vertexColor, hoverVertexColor)
texturePath = texturePath and BsUtil.GetFullTexturePath(texturePath) or nil
-- Set all the button textures to the same thing.
for _, textureName in ipairs(BS_UI_BUTTON_TEXTURES) do
button["Set" .. textureName .. "Texture"](button, texturePath)
end
self:SetIconButtonColors(button, vertexColor, hoverVertexColor)
end
--- Set icon button (toolbar buttons, etc) texture.
---@param button table Return value from `Ui:CreateIconButton()`.
---@param vertexColor number?[] { r, g, b, [a] }
---@param hoverVertexColor number?[] { r, g, b, [a] }
function Ui:SetIconButtonColors(button, vertexColor, hoverVertexColor)
assert(type(button) == "table" and button.GetNormalTexture, "Ui:SetIconButtonColor() - button does not appear to be a WoW UI button")
vertexColor =
vertexColor
or (self.inventory and self.inventory.settings and self.inventory.settings.toolbarButtonColor)
or BS_COLOR.YELLOW
hoverVertexColor = hoverVertexColor or BS_COLOR.ICON_BUTTON_HOVER
-- Ensure color changes are allowed and texture was set successfully before attempting any manipulation.
if
(button.bagshuiData and button.bagshuiData.noRecolor)
or not button:GetNormalTexture()
or not button:GetDisabledTexture()
then
return
end
-- Need RGB to auto-calculate pushed color.
local r = vertexColor[1]
local g = vertexColor[2]
local b = vertexColor[3]
button:GetNormalTexture():SetVertexColor(
r, g, b,
(
-- NormalTexture should be faded while the cooldown is active since
-- the cooldown takes on its opacity.
(button.bagshuiData and button.bagshuiData.isOnCooldown)
and 0.4
or vertexColor[4]
or 1
)
)
-- Keep cooldown colored the same as NormalTexture and inherit its expected opacity.
if button.bagshuiData and button.bagshuiData.cooldownTexture then
button.bagshuiData.cooldownTexture:SetVertexColor(
r, g, b,
(button.bagshuiData.isOnCooldown and (vertexColor[4] or 1) or 0)
)
end
button:GetHighlightTexture():SetVertexColor(
hoverVertexColor[1],
hoverVertexColor[2],
hoverVertexColor[3],
hoverVertexColor[4] or BS_COLOR.ICON_BUTTON_HOVER[4]
)
button:GetPushedTexture():SetVertexColor(r - 0.1, g - 0.1, b - 0.1)
button:GetPushedTexture():SetBlendMode("BLEND")
button:GetDisabledTexture():SetVertexColor(r, g, b, 0.4)
end
--- Start the custom cooldown animation that fills the icon from bottom to top.
---@param button table Return value from `Ui:CreateIconButton()`.
function Ui:SetIconButtonCooldown(button, cooldownStart, cooldownDuration, isOnCooldown)
if not button.bagshuiData then
return
end
-- Create cooldown texture if not yet added.
if not button.bagshuiData.cooldownTexture then
local normalTexture = button:GetNormalTexture()
button.bagshuiData.cooldownTexture = button:CreateTexture(nil, "OVERLAY")
button.bagshuiData.cooldownTexture:SetTexture(normalTexture:GetTexture())
-- Cooldown will be scaled upwards from the bottom.
button.bagshuiData.cooldownTexture:SetPoint("TOP", button, button:GetHeight())
button.bagshuiData.cooldownTexture:SetPoint("RIGHT", button, "RIGHT")
button.bagshuiData.cooldownTexture:SetPoint("BOTTOM", button, "BOTTOM")
button.bagshuiData.cooldownTexture:SetPoint("LEFT", button, "LEFT")
local r, g, b, a = normalTexture:GetVertexColor()
button.bagshuiData.cooldownTexture:SetVertexColor(r, g, b, a)
button.bagshuiData.cooldownTexture:Hide()
end
-- Set appropriate properties to trigger cooldown animation in `UpdateIconButtonCooldown()`.
-- Will make the call; no need to do it here.
button.bagshuiData.cooldownStart = nil
button.bagshuiData.cooldownDuration = nil
button.bagshuiData.isOnCooldown = false
if ( cooldownStart > 0 and cooldownDuration > 0 and isOnCooldown > 0) then
button.bagshuiData.cooldownStart = cooldownStart
button.bagshuiData.cooldownDuration = cooldownDuration
button.bagshuiData.isOnCooldown = true
end
end
--- Custom cooldown animation. Scales a cropped version of NormalTexture from
--- bottom to top while the actual NormalTexture is faded. This gives the appearance
--- of the icon filling up.
--- Called from the IconButton's `OnUpdate` script.
---@param button table Return value from `Ui:CreateIconButton()`.
function Ui:UpdateIconButtonCooldown(button)
-- This isn't a Bagshui button.
if not button.bagshuiData then
return
end
-- Hide cooldown when button is disabled or it's not on cooldown.
if
button.bagshuiData
and button.bagshuiData.cooldownTexture
and button.bagshuiData.cooldownTexture:IsVisible()
and not (
button:IsEnabled()
or button.bagshuiData.isOnCooldown
)
then
button.bagshuiData.cooldownTexture:Hide()
return
end
-- There's no need to update on every frame.
if _G.GetTime() - (button.bagshuiData.lastCooldownUpdate or 0) < 0.5 then
return
end
-- Cooldown time remaining.
button.bagshuiData.cooldownRemaining =
button.bagshuiData.cooldownDuration - (_G.GetTime() - button.bagshuiData.cooldownStart)
if button.bagshuiData.cooldownRemaining <= 0 then
-- Cooldown is done.
button.bagshuiData.isOnCooldown = false
button.bagshuiData.cooldownRemaining = nil
button.bagshuiData.cooldownPercentRemaining = nil
button.bagshuiData.cooldownTexture:Hide()
if not _G.this.bagshuiData.shineFrame or not _G.this.bagshuiData.shineFrame:IsVisible() then
self:ShineIconButton(button)
end
else
button.bagshuiData.isOnCooldown = true
-- Scale the cooldown texture vertically to match the remaining percentage.
button.bagshuiData.cooldownPercentRemaining = button.bagshuiData.cooldownRemaining / button.bagshuiData.cooldownDuration
button.bagshuiData.cooldownTexture:SetTexCoord(0, 1, button.bagshuiData.cooldownPercentRemaining, 1)
button.bagshuiData.cooldownTexture:SetPoint("TOP", button, "BOTTOM", 0, (button:GetHeight() * (1 - button.bagshuiData.cooldownPercentRemaining)))
button.bagshuiData.cooldownTexture:Show()
end
-- Set appropriate opacities for NormalTexture and cooldown.
self:SetIconButtonColors(button)
button.bagshuiData.lastCooldownUpdate = _G.GetTime()
end
-- Variable for use in OnUpdate to avoid GC.
local iconButton_ShineFrame_OnUpdate_alpha
--- Shrink and fade the "cooldown finished" shine, eventually hiding it once the animation is done.
--- Credit: https://github.com/anzz1/OmniCC/blob/master/OmniCC.lua
local function IconButton_ShineFrame_OnUpdate()
-- Control animation speed.
if _G.GetTime() - (_G.this.bagshuiData.lastShineUpdate or 0) < 0.1 then
return
end
iconButton_ShineFrame_OnUpdate_alpha = _G.this.bagshuiData.shine:GetAlpha()
_G.this.bagshuiData.shine:SetAlpha(iconButton_ShineFrame_OnUpdate_alpha * 0.95)
if iconButton_ShineFrame_OnUpdate_alpha < 0.1 then
-- Animation is done, so hide the shine.
_G.this:Hide()
else
-- Shrink the shine as the alpha value decreases.
_G.this.bagshuiData.shine:SetHeight(iconButton_ShineFrame_OnUpdate_alpha * _G.this:GetHeight() * ICON_BUTTON_SHINE_SCALE)
_G.this.bagshuiData.shine:SetWidth(iconButton_ShineFrame_OnUpdate_alpha * _G.this:GetWidth() * ICON_BUTTON_SHINE_SCALE)
_G.this.bagshuiData.lastShineUpdate = _G.GetTime()
end
end
--- Show a shine animation over an IconButton.
--- Credit: https://github.com/anzz1/OmniCC/blob/master/OmniCC.lua
---@param button table Return value from `Ui:CreateIconButton()`.
function Ui:ShineIconButton(button)
if not button.bagshuiData then
return
end
-- Create shine texture.
if not button.bagshuiData.shineFrame then
button.bagshuiData.shineFrame = _G.CreateFrame("Frame", nil, button)
button.bagshuiData.shineFrame:SetAllPoints(button)
button.bagshuiData.shineFrame:Hide()
button.bagshuiData.shineFrame.bagshuiData = {}
local shine = button.bagshuiData.shineFrame:CreateTexture(nil, "OVERLAY")
shine:SetTexture("Interface\\Cooldown\\star4")
shine:SetPoint("CENTER", button.bagshuiData.shineFrame, "CENTER")
shine:SetBlendMode("ADD")
button.bagshuiData.shineFrame.bagshuiData.shine = shine
button.bagshuiData.shineFrame:SetScript("OnUpdate", IconButton_ShineFrame_OnUpdate)
end
-- Initial shine size and opacity.
button.bagshuiData.shineFrame.bagshuiData.shine:SetAlpha(math.min(button:GetAlpha(), 0.75))
button.bagshuiData.shineFrame.bagshuiData.shine:SetHeight(button.bagshuiData.shineFrame:GetHeight() * ICON_BUTTON_SHINE_SCALE)
button.bagshuiData.shineFrame.bagshuiData.shine:SetWidth(button.bagshuiData.shineFrame:GetWidth() * ICON_BUTTON_SHINE_SCALE)
-- OnUpdate will fade and shrink the shine.
button.bagshuiData.shineFrame:Show()
end
--- Display the tooltip for an icon button, taking into consideration the configured
--- anchoring, delay, callback, etc.
---@param button table Bagshui icon button from `Ui:CreateIconButton()`.
---@param tooltipDelayOverride number? Delay tooltip display by this many seconds. If the button has `tooltipDelay` set to 0s or if `noTooltipDelay` is true, the delay will be forced to 0, regardless of this parameter's value.
---@param secondPass boolean?
function Ui:ShowIconButtonTooltip(button, tooltipDelayOverride, secondPass)
-- Avoid incorrectly showing the tooltip if the mouse has moved off the button
-- before the delay period expires.
if secondPass and not button.bagshuiData.mouseIsOver then
return
end
local bagshuiInfo = button.bagshuiData
local tooltip = BsIconButtonTooltip
tooltip:SetOwner(button, bagshuiInfo.tooltipAnchor)
-- Nonstandard anchor location.
if
(bagshuiInfo.tooltipAnchor == "ANCHOR_NONE" or bagshuiInfo.tooltipAnchor == "ANCHOR_PRESERVE")
and bagshuiInfo.tooltipAnchorPoint
and bagshuiInfo.tooltipAnchorToPoint
then
tooltip:ClearAllPoints()
tooltip:SetPoint(
bagshuiInfo.tooltipAnchorPoint,
button,
bagshuiInfo.tooltipAnchorToPoint,
bagshuiInfo.tooltipXOffset,
bagshuiInfo.tooltipYOffset
)
end
tooltip:ClearLines()
if bagshuiInfo.tooltipFunction then
-- When a tooltipFunction is configured, it should handle adding all tooltip content.
-- This isn't currently used.
bagshuiInfo.tooltipFunction(button, tooltip)
else
-- Normal behavior.
tooltip:AddLine(bagshuiInfo.tooltipTitle, 1.0, 1.0, 1.0)
if
bagshuiInfo.tooltipText
and (
-- Add tooltip text if there's no delay.
bagshuiInfo.noTooltipTextDelay
-- Add tooltip text if there was a delay and the delay period has expired.
or (
bagshuiInfo.tooltipTextDelay
and secondPass
)
)
then
tooltip:AddLine(bagshuiInfo.tooltipText, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
end
-- Ensure line wrapping keeps the tooltip as narrow as is allowed.
tooltip:SetWidth(10)
end
-- Don't allow the override delay to make tooltips take longer to display if that's not desired.
if bagshuiInfo.tooltipDelay == 0 or bagshuiInfo.noTooltipDelay then
tooltipDelayOverride = 0
end
-- Actually show the tooltip.
Bagshui:ShowTooltipAfterDelay(
tooltip,
button,
bagshuiInfo.tooltipGroupElement,
(tooltipDelayOverride or button.tooltipDelay or BS_TOOLTIP_DELAY_SECONDS.TOOLBAR_DEFAULT),
button.noTooltipDelayShorting,
function()
-- This will add tooltip text after the additional tooltipTextDelay
-- by calling `ShowIconButtonTooltip()` a second time.
if bagshuiInfo.tooltipTextDelay and not secondPass then
Bagshui:QueueClassCallback(
self,
self.ShowIconButtonTooltip,
bagshuiInfo.tooltipTextDelay,
false,
button,
0, -- tooltipDelayOverride
true -- secondPass
)
end
end
)
end
end)