|
|
|
|
local SLE, T, E, L, V, P, G = unpack(select(2, ...))
|
|
|
|
|
local DD = SLE.Dropdowns
|
|
|
|
|
|
|
|
|
|
DD.RegisteredMenus = {}
|
|
|
|
|
|
|
|
|
|
--Cache global variables
|
|
|
|
|
local tinsert, format = tinsert, format
|
|
|
|
|
local GetTime = GetTime
|
|
|
|
|
|
|
|
|
|
--WoW API / Variables
|
|
|
|
|
local CreateFrame = CreateFrame
|
|
|
|
|
local ToggleFrame = ToggleFrame
|
|
|
|
|
local GetCursorPosition = GetCursorPosition
|
|
|
|
|
|
|
|
|
|
--Global variables that we don't cache, list them here for the mikk's Find Globals script
|
|
|
|
|
-- GLOBALS: UIParent, UISpecialFrames
|
|
|
|
|
local _G = _G
|
|
|
|
|
|
|
|
|
|
local PADDING = 10
|
|
|
|
|
local BUTTON_HEIGHT = 16
|
|
|
|
|
local BUTTON_WIDTH = 135
|
|
|
|
|
local TITLE_OFFSET = 10
|
|
|
|
|
|
|
|
|
|
local function OnClick(btn)
|
|
|
|
|
if btn.func then btn.func() end
|
|
|
|
|
|
|
|
|
|
btn:GetParent():Hide()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function OnEnter(btn)
|
|
|
|
|
if not btn.nohighlight then btn.hoverTex:Show() end
|
|
|
|
|
if btn.UseTooltip then
|
|
|
|
|
_G['GameTooltip']:SetOwner(btn, 'ANCHOR_BOTTOMLEFT', -9)
|
|
|
|
|
if btn.TooltipText then
|
|
|
|
|
_G['GameTooltip']:SetText(btn.TooltipText)
|
|
|
|
|
elseif btn.secure.isToy then
|
|
|
|
|
_G['GameTooltip']:SetToyByItemID(btn.secure.ID)
|
|
|
|
|
elseif btn.secure.buttonType == 'item' then
|
|
|
|
|
_G['GameTooltip']:SetItemByID(btn.secure.ID)
|
|
|
|
|
elseif btn.secure.buttonType == 'spell' then
|
|
|
|
|
_G['GameTooltip']:SetSpellByID(btn.secure.ID)
|
|
|
|
|
end
|
|
|
|
|
_G['GameTooltip']:Show()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function OnLeave(btn)
|
|
|
|
|
_G['GameTooltip']:Hide()
|
|
|
|
|
btn.hoverTex:Hide()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function CreateListButton(frame)
|
|
|
|
|
local button = CreateFrame('Button', nil, frame, 'SecureActionButtonTemplate')
|
|
|
|
|
|
|
|
|
|
button:RegisterForClicks('AnyUp', 'AnyDown')
|
|
|
|
|
button.hoverTex = button:CreateTexture(nil, 'OVERLAY')
|
|
|
|
|
button.hoverTex:SetAllPoints()
|
|
|
|
|
button.hoverTex:SetTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]])
|
|
|
|
|
button.hoverTex:SetBlendMode('ADD')
|
|
|
|
|
button.hoverTex:Hide()
|
|
|
|
|
|
|
|
|
|
button.text = button:CreateFontString(nil, 'BORDER')
|
|
|
|
|
button.text:SetAllPoints()
|
|
|
|
|
button.text:FontTemplate()
|
|
|
|
|
|
|
|
|
|
button:SetScript('OnEnter', OnEnter)
|
|
|
|
|
button:SetScript('OnLeave', OnLeave)
|
|
|
|
|
button:HookScript('OnClick', OnClick)
|
|
|
|
|
|
|
|
|
|
return button
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function SLE:DropdownList(list, frame, customWidth, justify)
|
|
|
|
|
for i=1, #list do
|
|
|
|
|
frame.buttons[i] = frame.buttons[i] or CreateListButton(frame)
|
|
|
|
|
local btn = frame.buttons[i]
|
|
|
|
|
|
|
|
|
|
btn.func = list[i].func or nil
|
|
|
|
|
btn.nohighlight = list[i].nohighlight
|
|
|
|
|
btn.text:SetJustifyH(justify or 'LEFT')
|
|
|
|
|
btn:Show()
|
|
|
|
|
btn:Height(BUTTON_HEIGHT)
|
|
|
|
|
|
|
|
|
|
local icon = ''
|
|
|
|
|
if list[i].icon then
|
|
|
|
|
icon = '|T'..list[i].icon..':14:14:0:0:64:64:4:60:4:60|t '
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
btn.text:SetText(icon..list[i].text)
|
|
|
|
|
if list[i].title then
|
|
|
|
|
frame.TitleCount = frame.TitleCount + 1
|
|
|
|
|
btn.text:SetTextColor(0.98, 0.95, 0.05)
|
|
|
|
|
if list[i].ending or i == 1 or list[i-1].title then
|
|
|
|
|
frame.AddOffset = frame.AddOffset + 1
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
btn.text:SetTextColor(1, 1, 1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if customWidth and customWidth == 'auto' then
|
|
|
|
|
if frame.maxWidth < btn.text:GetStringWidth() then
|
|
|
|
|
frame.maxWidth = btn.text:GetStringWidth()
|
|
|
|
|
frame.TitleCount = 0
|
|
|
|
|
frame.AddOffset = 0
|
|
|
|
|
SLE:DropdownList(list, frame, customWidth, justify)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
btn:Width(frame.maxWidth)
|
|
|
|
|
else
|
|
|
|
|
btn:Width(customWidth or BUTTON_WIDTH)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if list[i].secure then
|
|
|
|
|
btn:SetAttribute('type', nil)
|
|
|
|
|
-- btn:SetAttribute('item', nil)
|
|
|
|
|
-- btn:SetAttribute('spell', nil)
|
|
|
|
|
-- btn:SetAttribute('macrotext', nil)
|
|
|
|
|
btn.secure = list[i].secure
|
|
|
|
|
btn:SetAttribute('type', btn.secure.buttonType)
|
|
|
|
|
if btn.secure.buttonType == 'item' then
|
|
|
|
|
local name = GetItemInfo(btn.secure.ID)
|
|
|
|
|
btn:SetAttribute('item', name)
|
|
|
|
|
elseif btn.secure.buttonType == 'spell' then
|
|
|
|
|
local name = GetSpellInfo(btn.secure.ID)
|
|
|
|
|
btn:SetAttribute('spell', name)
|
|
|
|
|
elseif btn.secure.buttonType == 'macro' then
|
|
|
|
|
btn:SetAttribute('macrotext', btn.secure.ID)
|
|
|
|
|
else
|
|
|
|
|
SLE:Print('Wrong argument for button type: '..btn.secure.buttonType, 'error')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
btn.UseTooltip = list[i].UseTooltip
|
|
|
|
|
if list[i].TooltipText then btn.TooltipText = list[i].TooltipText end
|
|
|
|
|
|
|
|
|
|
local MARGIN = 10
|
|
|
|
|
if justify then
|
|
|
|
|
if justify == 'RIGHT' then MARGIN = -10 end
|
|
|
|
|
if justify == 'CENTER' then MARGIN = 0 end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if i == 1 then
|
|
|
|
|
btn:Point('TOPLEFT', frame, 'TOPLEFT', MARGIN, -PADDING)
|
|
|
|
|
else
|
|
|
|
|
btn:Point('TOPLEFT', frame.buttons[i-1], 'BOTTOMLEFT', 0, -((list[i-1].title or list[i].title) and TITLE_OFFSET or 0))
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function SLE:DropDown(list, frame, MenuAnchor, FramePoint, xOffset, yOffset, parent, customWidth, justify)
|
|
|
|
|
if InCombatLockdown() then return end
|
|
|
|
|
frame.maxWidth = BUTTON_WIDTH
|
|
|
|
|
frame.TitleCount = 0
|
|
|
|
|
frame.AddOffset = 0
|
|
|
|
|
if not frame.buttons then
|
|
|
|
|
frame.buttons = {}
|
|
|
|
|
frame:SetFrameStrata('DIALOG')
|
|
|
|
|
frame:SetClampedToScreen(true)
|
|
|
|
|
tinsert(UISpecialFrames, frame:GetName())
|
|
|
|
|
frame:Hide()
|
|
|
|
|
end
|
|
|
|
|
for i=1, #frame.buttons do
|
|
|
|
|
local btn = frame.buttons[i]
|
|
|
|
|
btn.UseTooltip = false
|
|
|
|
|
btn.func = nil
|
|
|
|
|
btn.secure = nil
|
|
|
|
|
btn.TooltipText = nil
|
|
|
|
|
btn.text:SetText('')
|
|
|
|
|
btn:Hide()
|
|
|
|
|
end
|
|
|
|
|
if not frame:IsShown() then
|
|
|
|
|
xOffset = xOffset or 0
|
|
|
|
|
yOffset = yOffset or 0
|
|
|
|
|
|
|
|
|
|
if not parent then FramePoint = 'CURSOR' end
|
|
|
|
|
SLE:DropdownList(list, frame, customWidth, justify)
|
|
|
|
|
|
|
|
|
|
frame:Height((#list * BUTTON_HEIGHT) + PADDING * 2 + frame.TitleCount * (2 * TITLE_OFFSET) - frame.AddOffset * TITLE_OFFSET)
|
|
|
|
|
if customWidth and customWidth == 'auto' then
|
|
|
|
|
frame:Width(frame.maxWidth + PADDING * 2)
|
|
|
|
|
else
|
|
|
|
|
frame:Width(customWidth or (BUTTON_WIDTH + PADDING * 2))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
frame:ClearAllPoints()
|
|
|
|
|
if FramePoint == 'CURSOR' then
|
|
|
|
|
local UIScale = UIParent:GetScale()
|
|
|
|
|
local x, y = GetCursorPosition()
|
|
|
|
|
x = x/UIScale
|
|
|
|
|
y = y/UIScale
|
|
|
|
|
frame:Point(MenuAnchor, UIParent, 'BOTTOMLEFT', x + xOffset, y + yOffset)
|
|
|
|
|
else
|
|
|
|
|
frame:Point(MenuAnchor, parent, FramePoint, xOffset, yOffset)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
ToggleFrame(frame)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DD:GetCooldown(CDtype, id)
|
|
|
|
|
local cd, formatID
|
|
|
|
|
local start, duration = _G['Get'..CDtype..'Cooldown'](id)
|
|
|
|
|
if start > 0 then
|
|
|
|
|
cd = duration - (GetTime() - start)
|
|
|
|
|
cd, formatID = E:GetTimeInfo(cd, 0)
|
|
|
|
|
cd = format(E.TimeFormats[formatID][3], cd)
|
|
|
|
|
return cd
|
|
|
|
|
end
|
|
|
|
|
return nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DD:HideMenus(event)
|
|
|
|
|
if event == 'PLAYER_ENTERING_WORLD' then self:UnregisterEvent(event) end
|
|
|
|
|
for _, menu in pairs(DD.RegisteredMenus) do
|
|
|
|
|
menu:Hide()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DD:RegisterMenu(menu)
|
|
|
|
|
local name = menu:GetName()
|
|
|
|
|
if name then
|
|
|
|
|
DD.RegisteredMenus[name] = menu
|
|
|
|
|
else
|
|
|
|
|
SLE:Print('Dropdown not registered. Please check if it has a name.')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function DD:Initialize()
|
|
|
|
|
self:RegisterEvent('PLAYER_ENTERING_WORLD', 'HideMenus')
|
|
|
|
|
self:RegisterEvent('LOADING_SCREEN_DISABLED', 'HideMenus')
|
|
|
|
|
self:RegisterEvent('PLAYER_REGEN_DISABLED', 'HideMenus')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
SLE:RegisterModule(DD:GetName())
|