You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
14 KiB

---@type string
local AddonName = ...
---@class OptionsPrivate
local OptionsPrivate = select(2, ...)
if not WeakAuras.IsLibsOK() then
return
end
local keepOpenForReload = {}
local widgetType, widgetVersion = "WeakAurasMiniTalent", 3
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(widgetType) or 0) >= widgetVersion then
return
end
local L = WeakAuras.L
local buttonSize = 32
local buttonSizePadded = 45
local function Button_ShowToolTip(self)
if self.spellId then
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetSpellByID(self.spellId, false, false, true)
end
end
local function Button_HideToolTip()
GameTooltip:Hide()
end
local function CreateTalentButton()
local button = CreateFrame("Button")
button:SetSize(buttonSize, buttonSize)
local cover = button:CreateTexture(nil, "OVERLAY")
cover:SetTexture("interface/buttons/checkbuttonglow")
cover:SetIgnoreParentScale(true)
cover:SetPoint("TOPLEFT", button, "TOPLEFT", -10, 10)
cover:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 10, -10)
cover:SetBlendMode("ADD")
cover:Hide()
button.cover = cover
button:SetHighlightTexture("Interface/Buttons/ButtonHilight-Square", "ADD")
function button:Yellow()
self.cover:Show()
self.cover:SetVertexColor(1, 1, 0, 1)
local normalTexture = self:GetNormalTexture()
if normalTexture then
normalTexture:SetVertexColor(1, 1, 1, 1)
end
if self.line1 then
self.line1:Hide()
self.line2:Hide()
end
end
function button:Red()
self.cover:Show()
self.cover:SetVertexColor(1, 0, 0, 1)
local normalTexture = self:GetNormalTexture()
if normalTexture then
normalTexture:SetVertexColor(1, 0, 0, 1)
end
if not self.line1 then
local line1 = button:CreateLine()
line1:SetColorTexture(1, 0, 0, 1)
line1:SetStartPoint("TOPLEFT", 3, -3)
line1:SetEndPoint("BOTTOMRIGHT", -3, 3)
line1:SetBlendMode("ADD")
line1:SetThickness(2)
local line2 = button:CreateLine()
line2:SetColorTexture(1, 0, 0, 1)
line2:SetStartPoint("TOPRIGHT", -3, -3)
line2:SetEndPoint("BOTTOMLEFT", 3, 3)
line2:SetBlendMode("ADD")
line2:SetThickness(2)
self.line1 = line1
self.line2 = line2
end
self.line1:Show()
self.line2:Show()
end
function button:Clear()
self.cover:Hide()
local normalTexture = self:GetNormalTexture()
if normalTexture then
normalTexture:SetVertexColor(0.3, 0.3, 0.3, 1)
end
if self.line1 then
self.line1:Hide()
self.line2:Hide()
end
end
function button:UpdateTexture()
if self.state == nil then
self:Clear()
elseif self.state == true then
self:Yellow()
elseif self.state == false then
self:Red()
end
end
function button:SetValue(value)
self.state = value
self:UpdateTexture()
end
function button:LineGetPoint()
if self.offset == nil then
return "CENTER"
elseif self.offset == "left" then
return "RIGHT"
elseif self.offset == "right" then
return "LEFT"
end
end
button:SetScript("OnClick", function(self)
if self.state == true then
self:SetValue(false)
elseif self.state == false then
self:SetValue(nil)
else
self:SetValue(true)
end
self.obj.obj:Fire("OnValueChanged", self.index, self.state)
end)
button:Clear()
button:SetScript("OnEnter", Button_ShowToolTip)
button:SetScript("OnLeave", Button_HideToolTip)
button:SetMotionScriptsWhileDisabled(true)
return button
end
local function resetLine(pool, line)
line:Hide()
line:ClearAllPoints()
end
local function TalentFrame_Update(self)
local buttonShownCount = 0
self.linePool:ReleaseAll()
if self.list then
for _, button in ipairs(self.buttons) do
if self.open then
local posX = button.posX
local posY = - button.posY
local point = "CENTER"
if button.offset then
if button.offset == "left" then
point = "RIGHT"
elseif button.offset == "right" then
point = "LEFT"
end
else
point = "CENTER"
end
button:ClearAllPoints()
button:SetPoint(point, button.obj, "TOPLEFT", posX, posY)
button:SetEnabled(true)
button:SetMouseClickEnabled(true)
button:SetSize((buttonSize/self.scale) * .5, (buttonSize/self.scale) * .5)
button:SetScale(self.scale)
button.cover:ClearAllPoints()
button.cover:SetPoint("TOPLEFT", button, "TOPLEFT", -5, 5)
button.cover:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 5, -5)
button:Show()
for _, target in pairs(button.targets) do
if self.talentIdToButton[target] == nil then
-- print("Talent connect to unknown talent", button.talentId, target)
elseif button.offset == "right" then
-- don't trace line for right buttons
else
local line = self.linePool:Acquire()
line:SetStartPoint(button:LineGetPoint(), button)
local targetButton = self.talentIdToButton[target]
line:SetEndPoint(targetButton:LineGetPoint(), targetButton)
line:SetColorTexture(1,1,1,0.2)
line:SetThickness(1)
line:Show()
end
end
else
if button.state ~= nil then
buttonShownCount = buttonShownCount + 1
button:ClearAllPoints()
button:SetPoint(
"TOPLEFT",
button.obj,
"TOPLEFT",
7 + ((buttonShownCount - 1) % 9) * (buttonSizePadded + 4),
-7 + -1 * (ceil(buttonShownCount / 9) - 1) * (buttonSizePadded + 4)
)
button:SetEnabled(false)
button:SetMouseClickEnabled(false)
button:SetSize(buttonSize, buttonSize)
button:SetScale(1)
button.cover:ClearAllPoints()
button.cover:SetPoint("TOPLEFT", button, "TOPLEFT", -10, 10)
button.cover:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 10, -10)
button:Show()
else
button:Hide()
end
end
end
end
if self.open then
self.frame:SetHeight(self.saveSize.fullHeight)
self.background:Show()
else
local rows = ceil(buttonShownCount / 11)
if rows > 0 then
self.frame:SetHeight(self.saveSize.collapsedRowHeight * rows)
else
self.frame:SetHeight(1)
end
self.background:Hide()
end
end
local methods = {
OnAcquire = function(self)
self:SetDisabled(false)
self.acquired = true
end,
OnRelease = function(self)
self:SetDisabled(true)
self:SetMultiselect(false)
self.buttonPool:ReleaseAll()
self.linePool:ReleaseAll()
self.value = nil
self.list = nil
self.acquired = false
end,
SetList = function(self, list)
self.list = list or {}
self.buttonPool:ReleaseAll()
self.linePool:ReleaseAll()
self.buttons = {}
self.talentIdToButton = {}
local extraOffset = self.list[1000]
for index, data in pairs(self.list) do
if index < 999 then -- background index & extraOffset
local button = self.buttonPool:Acquire()
button.index = index
button:SetParent(self.frame)
button.obj = self.frame
local talentId = data[1]
button.talentId = talentId
self.talentIdToButton[talentId] = button
local spellId = data[2]
button.spellId = spellId
local icon = select(8, OptionsPrivate.Private.ExecEnv.GetSpellInfo(spellId))
if icon then
button:SetNormalTexture(icon)
end
local multiTalent, multiTalentTotal, subTreePosition = 0, 0, nil
button.posX, button.posY, multiTalent, multiTalentTotal, subTreePosition = unpack(data[3])
button.posX = button.posX / 10 - (extraOffset and extraOffset.offsetX or 0)
button.posY = button.posY / 10 - (extraOffset and extraOffset.offsetY or 0)
if multiTalentTotal > 1 then
if multiTalent == 1 then
button.offset = "left"
else
button.offset = "right"
end
else
button.offset = nil
end
if subTreePosition then
button.side = subTreePosition == 1 and "left" or "right"
end
button.targets = data[4]
button:UpdateTexture()
button:ClearAllPoints()
tinsert(self.buttons, button)
end
end
-- zoom both panel in their center
local isSubTree = self.list[1001]
local talentWidth
local talentHeight
local talentIconSize = 36
local scale
if not isSubTree then
talentWidth = 1612
talentHeight = 856
local cutmid = 120
local LeftPanelCenter = { x = (talentWidth / 2 - cutmid) / 2, y = talentHeight / 2 }
local RightPanelCenter = { x = ((talentWidth / 2 + cutmid) + talentWidth) / 2 , y = talentHeight / 2 }
scale = 1.3
for _, b in pairs(self.buttons) do
if b.posX < talentWidth / 2 then -- left panel
b.posX = b.posX - LeftPanelCenter.x
b.posX = b.posX * scale
b.posX = b.posX + LeftPanelCenter.x - talentIconSize / 2
b.posY = b.posY - LeftPanelCenter.y
b.posY = b.posY * scale
b.posY = b.posY + LeftPanelCenter.y * scale
else -- right panel
b.posX = b.posX - RightPanelCenter.x
b.posX = b.posX * scale
b.posX = b.posX + RightPanelCenter.x + talentIconSize / 2
b.posY = b.posY - RightPanelCenter.y
b.posY = b.posY * scale
b.posY = b.posY + RightPanelCenter.y * scale
end
end
else
talentWidth = 200
talentHeight = 300
local midLeft, midRight = talentWidth / 4, (talentWidth / 4) * 3
scale = 0.3
for _, b in pairs(self.buttons) do
b.posX = b.posX * scale
b.posY = b.posY * scale
b.posY = b.posY + 10
if b.side == "left" then
b.posX = b.posX + midLeft
else
b.posX = b.posX + midRight
end
end
end
self.scale = self.saveSize.fullWidth / talentWidth
self.saveSize.fullHeight = talentHeight * self.scale * scale
if self.list[999] then
self.background:SetAtlas(self.list[999])
self.background:SetBlendMode("ADD")
end
TalentFrame_Update(self)
end,
SetDisabled = function(self, disabled)
if disabled then
for _, button in pairs(self.buttons) do
button:Hide()
end
self.background:Hide()
self.open = nil
self.toggle.frame:Hide()
self.frame:Hide()
else
self.open = nil
TalentFrame_Update(self)
self.toggle.frame:Show()
self.frame:Show()
end
end,
SetItemValue = function(self, item, value)
if self.buttons[item] then
self.buttons[item]:SetValue(value)
TalentFrame_Update(self)
end
end,
SetValue = function(self, value) end,
SetLabel = function(self, text) end,
SetMultiselect = function(self, multi) end,
ToggleView = function(self, force)
if force ~= nil then
self.open = force
else
if not self.open then
self.open = true
else
self.open = nil
end
end
TalentFrame_Update(self)
self.parent:DoLayout()
end,
}
local function Constructor()
local name = widgetType .. AceGUI:GetNextWidgetNum(widgetType)
local talentFrame = CreateFrame("Button", name, UIParent)
talentFrame:SetFrameStrata("FULLSCREEN_DIALOG")
local buttons = {}
talentFrame:SetWidth(440)
talentFrame:SetScript("OnClick", function(self)
self.obj:ToggleView()
end)
local background = talentFrame:CreateTexture(nil, "BACKGROUND")
background:SetAllPoints(talentFrame)
local toggle = AceGUI:Create("WeakAurasToolbarButton")
toggle:SetText(L["Select Talent"])
toggle:SetTexture("interface/buttons/ui-microbutton-talents-up")
toggle.icon:ClearAllPoints()
toggle.icon:SetPoint("LEFT", toggle.frame, "LEFT", 0, 10)
toggle.icon:SetSize(28, 58)
toggle.icon:SetScale(0.6)
toggle.frame:SetPoint("BOTTOMRIGHT", talentFrame, "TOPRIGHT", 0, 2)
toggle.frame:SetParent(talentFrame)
toggle.frame.obj.text:SetVertexColor(1, 1, 1, 1)
toggle.frame:Show()
toggle:SetCallback("OnClick", function(self)
local parent = self.frame:GetParent()
parent.obj:ToggleView(parent.obj)
end)
local widget = {
frame = talentFrame,
type = widgetType,
buttons = buttons,
toggle = toggle,
background = background,
saveSize = {
fullWidth = 440,
fullHeight = 0,
collapsedRowHeight = (buttonSizePadded + 5),
},
linePool = CreateObjectPool(
function(pool)
return talentFrame:CreateLine()
end,
resetLine
),
buttonPool = CreateObjectPool(CreateTalentButton)
}
for method, func in pairs(methods) do
widget[method] = func
end
talentFrame.obj = widget
local function OnBeforeReload()
if widget.acquired then
local user = widget:GetUserDataTable()
if user and user.path then
keepOpenForReload[user.path[#user.path]] = widget.open
end
end
end
local function OnAfterReload()
if widget.acquired then
local user = widget:GetUserDataTable()
if user and user.path then
if keepOpenForReload[user.path[#user.path]] then
widget:ToggleView(true)
keepOpenForReload[user.path[#user.path]] = nil
end
end
end
end
OptionsPrivate.Private.callbacks:RegisterCallback("BeforeReload", OnBeforeReload)
OptionsPrivate.Private.callbacks:RegisterCallback("AfterReload", OnAfterReload)
return AceGUI:RegisterAsWidget(widget)
end
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)